accesspolicy

package
v0.0.0-...-6b846f9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 15, 2021 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	FInherit uint8 = 1 << iota
	FExtend
	FSealed
)

policy flags

View Source
const (
	APNoAccess = Right(0)
	APView     = Right(1 << (iota - Right(1)))
	APViewDeleted
	APViewHidden
	APCreate
	APChange
	APDelete
	APRestoreDeleted
	APCopy
	APDuplicate
	APMove
	APRename
	APManageAccess
	APFullAccess = ^Right(0)

	// this flag is used for accesspolicy bits without translation
	APUnrecognizedFlag = "unrecognized accesspolicy flag"
)

declaring discrete rights for all cases

Variables

View Source
var (
	ErrNilDatabase                  = errors.New("data is nil")
	ErrZeroPolicyID                 = errors.New("id is zero")
	ErrNonZeroID                    = errors.New("id is not zero")
	ErrNilStore                     = errors.New("accesspolicy policy store is nil")
	ErrNilAccessPolicyManager       = errors.New("accesspolicy policy container is nil")
	ErrPolicyNotFound               = errors.New("accesspolicy policy not found")
	ErrAccessPolicyEmptyDesignators = errors.New("key, object name and id are empty")
	ErrPolicyKeyTaken               = errors.New("policy name is taken")
	ErrPolicyObjectConflict         = errors.New("id of a kind is taken")
	ErrEmptyKey                     = errors.New("key is empty")
	ErrEmptyObjectName              = errors.New("object name is empty")
	ErrNilRoster                    = errors.New("rights rosters is nil")
	ErrCacheMiss                    = errors.New("roster cache miss")
	ErrEmptyRoster                  = errors.New("rights rosters is empty")
	ErrNilAccessPolicy              = errors.New("accesspolicy policy is nil")
	ErrAccessDenied                 = errors.New("access denied")
	ErrNoViewRight                  = errors.New("user is not allowed to view this")
	ErrZeroGrantorID                = errors.New("grantor user id is zero")
	ErrZeroAssigneeID               = errors.New("grantee user id is zero")
	ErrExcessOfRights               = errors.New("grantor is attempting to set the rights that excess his own")
	ErrSameActor                    = errors.New("grantor and grantee is the same user")
	ErrInvalidParentPolicy          = errors.New("parent policy is invalid")
	ErrNoParent                     = errors.New("parent policy is nil")
	ErrNoBackup                     = errors.New("roster has no backup")
	ErrZeroGroupID                  = errors.New("role group id is zero")
	ErrZeroRoleID                   = errors.New("role id is zero")
	ErrUnrecognizedRosterAction     = errors.New("unrecognized roster action")
	ErrKeyTooLong                   = errors.New("key is too long")
	ErrObjectNameTooLong            = errors.New("object name is too long")
	ErrForbiddenChange              = errors.New("accesspolicy policy key, object name or id is not allowed to rosterChange")
	ErrNilPolicyID                  = errors.New("policy id is nil")
	ErrNothingChanged               = errors.New("nothing changed")
	ErrNilActorID                   = errors.New("actor id is nil")
)

errors

Functions

func Dictionary

func Dictionary() map[uint32]string

Dictionary returns a map of property flag values to their respective names

Types

type AccessResolver

type AccessResolver interface {
	Resolve(
		ctx context.Context,
		parentPolicy Policy,
		parentRight Right,
		ownRight Right,
	) (calculatedRight Right, err error)
}

AccessResolver is responsible for resolving the final access rights when the rights are extended or inherited from a parent

func NewDefaultResolver

func NewDefaultResolver() AccessResolver

type Actor

type Actor struct {
	ID   uuid.UUID
	Kind ActorKind
}

func GroupActor

func GroupActor(id uuid.UUID) Actor

func NewActor

func NewActor(k ActorKind, id uuid.UUID) Actor

func PublicActor

func PublicActor() Actor

func RoleActor

func RoleActor(id uuid.UUID) Actor

func UserActor

func UserActor(id uuid.UUID) Actor

type ActorKind

type ActorKind uint8

everyone, user, group, role_group, etc...

const (
	AKEveryone ActorKind = 1 << iota
	AKUser
	AKGroup
	AKRoleGroup
)

func (ActorKind) String

func (k ActorKind) String() string

type Cell

type Cell struct {
	Key    Actor `json:"key"`
	Rights Right `json:"rights"`
}

Cell represents a single access policy registry entry TODO: consider overrides

type Manager

type Manager struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Manager is the accesspolicy policy registry NOTE: resolver determines the final access rights if policy has a parent

func NewManager

func NewManager(store Store, gm *group.Manager) (*Manager, error)

NewManager initializes a new accesspolicy policy container

func (*Manager) Access

func (m *Manager) Access(ctx context.Context, policyID, userID uuid.UUID) (access Right)

Access returns a summarized accesspolicy bitmask for a given actor

func (*Manager) Create

func (m *Manager) Create(ctx context.Context, key string, ownerID, parentID uuid.UUID, obj Object, flags uint8) (p Policy, err error)

Upsert creates a new accesspolicy policy

func (*Manager) DeletePolicy

func (m *Manager) DeletePolicy(ctx context.Context, p Policy) (err error)

DeletePolicy returns an accesspolicy policy by its ObjectID

func (*Manager) GrantAccess

func (m *Manager) GrantAccess(ctx context.Context, pid uuid.UUID, grantor, grantee Actor, access Right) (err error)

GrantAccess grants accesspolicy rights on a given policy, by grantor to grantee NOTE: can be called multiple times before policy changes are persisted NOTE: rights rosters changes are not persisted unless explicitly saved NOTE: changes made with this function will be cancelled and backup restored if there will be any errors when saving this policy

func (*Manager) GrantGroupAccess

func (m *Manager) GrantGroupAccess(ctx context.Context, pid uuid.UUID, grantor Actor, groupID uuid.UUID, rights Right) (err error)

GrantGroupAccess grants accesspolicy rights to a specific group

func (*Manager) GrantPublicAccess

func (m *Manager) GrantPublicAccess(ctx context.Context, pid uuid.UUID, grantor Actor, rights Right) error

GrantPublicAccess setting base accesspolicy rights for everyone

func (*Manager) GrantRoleAccess

func (m *Manager) GrantRoleAccess(ctx context.Context, pid uuid.UUID, grantor Actor, roleID uuid.UUID, rights Right) error

GrantRoleAccess grants accesspolicy rights to the role

func (*Manager) GrantUserAccess

func (m *Manager) GrantUserAccess(ctx context.Context, pid uuid.UUID, grantor Actor, userID uuid.UUID, rights Right) (err error)

GrantUserAccess grants accesspolicy rights to a specific user actor TODO: consider whether it's right to turn off inheritance (if enabled) when setting/changing anything on each accesspolicy policy instance

func (*Manager) GroupAccess

func (m *Manager) GroupAccess(ctx context.Context, pid, groupID uuid.UUID) (access Right)

GroupAccess returns the rights of a given group if set explicitly, otherwise returns the rights of the first ancestor group that has any rights record explicitly set

func (*Manager) HasGroupRights

func (m *Manager) HasGroupRights(ctx context.Context, policyID, groupID uuid.UUID, rights Right) bool

HasGroupRights checks whether a group has the rights

func (*Manager) HasPublicRights

func (m *Manager) HasPublicRights(ctx context.Context, policyID uuid.UUID, rights Right) bool

HasPublicRights checks whether a given policy has specific public rights NOTE: despite it's narrow purpose, it may still be useful to check public rights alone

func (*Manager) HasRights

func (m *Manager) HasRights(ctx context.Context, pid uuid.UUID, actor Actor, rights Right) bool

hasRights checks whether a given actor entity has the inquired rights

func (*Manager) HasRoleRights

func (m *Manager) HasRoleRights(ctx context.Context, policyID, groupID uuid.UUID, rights Right) bool

HasGroupRights checks whether a role has the rights

func (*Manager) PolicyByID

func (m *Manager) PolicyByID(ctx context.Context, id uuid.UUID) (p Policy, err error)

PolicyByID returns an accesspolicy policy by its ObjectID

func (*Manager) PolicyByKey

func (m *Manager) PolicyByKey(ctx context.Context, name string) (p Policy, err error)

PolicyByKey returns an accesspolicy policy by its key

func (*Manager) PolicyByObject

func (m *Manager) PolicyByObject(ctx context.Context, obj Object) (p Policy, err error)

PolicyByObject returns an accesspolicy policy by its kind and id

func (*Manager) RevokeAccess

func (m *Manager) RevokeAccess(ctx context.Context, pid uuid.UUID, grantor, grantee Actor) (err error)

RevokeAccess takes away current rights of a kind on this policy, from an grantee, as angrantor NOTE: this function only removes exclusive rights of this grantee, but the grantee still retains its public level rights to whatver that this policy protects NOTE: if you wish to completely deny somebody an accesspolicy through this policy, then set exclusive rights explicitly (i.e. APNoAccess, 0)

func (*Manager) RosterByPolicyID

func (m *Manager) RosterByPolicyID(ctx context.Context, id uuid.UUID) (r *Roster, err error)

RosterByPolicy returns the rights roster by its accesspolicy policy

func (*Manager) SetParent

func (m *Manager) SetParent(ctx context.Context, policyID, parentID uuid.UUID) (err error)

SetParentID setting a new parent policy

func (*Manager) SummarizedUserAccess

func (m *Manager) SummarizedUserAccess(ctx context.Context, policyID, userID uuid.UUID) (access Right)

SummarizedUserAccess summarizing the resulting accesspolicy rights of a given user TODO: use access resolver instead of just OR'ing

func (*Manager) Update

func (m *Manager) Update(ctx context.Context, p Policy) (err error)

Update updates given accesspolicy policy

func (*Manager) UserHasAccess

func (m *Manager) UserHasAccess(ctx context.Context, pid uuid.UUID, userID uuid.UUID, rights Right) bool

UserHasAccess checks whether the user has specific rights NOTE: returns true only if the user has every of specified rights permitted TODO: maybe add some sort of a calculated cache with a short lifespan, like 10ms or something

type Object

type Object struct {
	Name string
	ID   uuid.UUID
}

func NewObject

func NewObject(id uuid.UUID, name string) Object

func NilObject

func NilObject() Object

type Policy

type Policy struct {
	Key        string    `db:"key" json:"key"`
	ObjectName string    `db:"object_name" json:"object_name"`
	ID         uuid.UUID `db:"id" json:"id"`
	ParentID   uuid.UUID `db:"parent_id" json:"parent_id"`
	OwnerID    uuid.UUID `db:"owner_id" json:"owner_id"`
	ObjectID   uuid.UUID `db:"object_id" json:"object_id"`
	Flags      uint8     `db:"flags" json:"flags"`
	// contains filtered or unexported fields
}

Policy is a generalized ruleset for an object if IsInherited is true, then the policy's own rosters will point to it's parent and everything else will be ignored as long as it's true NOTE: policy may be shared by multiple entities NOTE: policy ownership basically is the ownership of it's main entity and only affects the very object alone NOTE: owner is the original creator of an entity and has full rights for it NOTE: an accesspolicy policy can have only one object identifier set, either ObjectID or astring TODO: store object rights rosters, name and object name in separate maps TODO: calculate extended rights instantly. rights must be recalculated through all the tree after each rosterChange TODO: add caching mechanism to skip rights summarization TODO: disable inheritance if anything is changed about the current policy and create its own rights rosters and enable extension by default

func NewPolicy

func NewPolicy(key string, ownerID, parentID uuid.UUID, obj Object, flags uint8) (p Policy, err error)

NewPolicy create a new Policy object

func (*Policy) ApplyChangelog

func (ap *Policy) ApplyChangelog(changelog diff.Changelog) (err error)

ApplyChangelog applies changes described by a diff.Diff()'s changelog NOTE: doing a manual update to avoid using reflection

func (Policy) IsExtended

func (ap Policy) IsExtended() bool

func (Policy) IsInherited

func (ap Policy) IsInherited() bool

func (Policy) IsOwner

func (ap Policy) IsOwner(id uuid.UUID) bool

IsOwner checks whether a given user is the owner of this policy NOTE: owner of the policy (meaning: the main entity) has full rights on it WARNING: *** DO NOT remove owner zero check, to reduce the risk of abuse or mistake ***

func (*Policy) SetKey

func (ap *Policy) SetKey(key string) error

SetKey sets a key name to the group

func (*Policy) SetObjectName

func (ap *Policy) SetObjectName(name string) error

SetObjectName sets an object name name

func (Policy) Validate

func (ap Policy) Validate() error

SanitizeAndValidate validates accesspolicy policy by performing basic self-check

type PostgreSQLStore

type PostgreSQLStore struct {
	// contains filtered or unexported fields
}

func (*PostgreSQLStore) CreatePolicy

func (s *PostgreSQLStore) CreatePolicy(ctx context.Context, p Policy, r *Roster) (Policy, *Roster, error)

func (*PostgreSQLStore) CreateRoster

func (s *PostgreSQLStore) CreateRoster(ctx context.Context, policyID uuid.UUID, r *Roster) error

func (*PostgreSQLStore) DeletePolicy

func (s *PostgreSQLStore) DeletePolicy(ctx context.Context, p Policy) error

func (*PostgreSQLStore) DeleteRoster

func (s *PostgreSQLStore) DeleteRoster(ctx context.Context, pid uuid.UUID) (err error)

func (*PostgreSQLStore) FetchPolicyByID

func (s *PostgreSQLStore) FetchPolicyByID(ctx context.Context, id uuid.UUID) (Policy, error)

func (*PostgreSQLStore) FetchPolicyByKey

func (s *PostgreSQLStore) FetchPolicyByKey(ctx context.Context, key string) (p Policy, err error)

func (*PostgreSQLStore) FetchPolicyByObject

func (s *PostgreSQLStore) FetchPolicyByObject(ctx context.Context, obj Object) (p Policy, err error)

func (*PostgreSQLStore) FetchRosterByPolicyID

func (s *PostgreSQLStore) FetchRosterByPolicyID(ctx context.Context, pid uuid.UUID) (*Roster, error)

func (*PostgreSQLStore) UpdatePolicy

func (s *PostgreSQLStore) UpdatePolicy(ctx context.Context, p Policy, r *Roster) (err error)

-???-[ NOTE ]-------------------------------------------------------------- ??? rights rosters keeps track of its changes, thus, update will ??? only affect changes mentioned by the respective Roster object -???-----------------------------------------------------------------------

func (*PostgreSQLStore) UpdateRoster

func (s *PostgreSQLStore) UpdateRoster(ctx context.Context, pid uuid.UUID, r *Roster) (err error)

type RAction

type RAction uint8
const (
	RUnset RAction = iota
	RSet
)

func (RAction) String

func (a RAction) String() string
type Right uint32

Right is a bitmask of access rights

func (Right) String

func (r Right) String() string

AccessExplained returns a human-readable conjunction of comma-separated accesspolicy names for this given context namespace

func (Right) Translate

func (r Right) Translate() string

type Roster

type Roster struct {
	// Resolve calculates the final access right value of a policy
	// which extends (or possibly inherits) from a parent, because sometimes a certain right
	// must be overridden while still preserving extended some values
	Resolve func(extended, current Right) Right

	// represents a mixed list of group/role/user rights
	Registry []Cell `json:"registry"`

	// represents the base public accesspolicy rights
	Everyone Right `json:"everyone"`
	// contains filtered or unexported fields
}

Roster holds metadata to keep track of who has what access to its corresponding access policy

func NewRoster

func NewRoster(regsize int) *Roster

NewRoster is a shorthand initializer function

type RosterEntry

type RosterEntry struct {
	PolicyID        uuid.UUID `db:"policy_id"`
	ActorID         uuid.UUID `db:"actor_id"`
	ActorKind       ActorKind `db:"actor_kind"`
	Access          Right     `db:"accesspolicy"`
	AccessExplained string    `db:"access_explained"`
}

type Store

type Store interface {
	CreatePolicy(ctx context.Context, p Policy, r *Roster) (Policy, *Roster, error)
	UpdatePolicy(ctx context.Context, p Policy, r *Roster) error
	FetchPolicyByID(ctx context.Context, id uuid.UUID) (Policy, error)
	FetchPolicyByKey(ctx context.Context, key string) (p Policy, err error)
	FetchPolicyByObject(ctx context.Context, obj Object) (p Policy, err error)
	DeletePolicy(ctx context.Context, p Policy) error
	CreateRoster(ctx context.Context, policyID uuid.UUID, r *Roster) (err error)
	FetchRosterByPolicyID(ctx context.Context, pid uuid.UUID) (r *Roster, err error)
	UpdateRoster(ctx context.Context, pid uuid.UUID, r *Roster) (err error)
	DeleteRoster(ctx context.Context, pid uuid.UUID) (err error)
}

Store is a storage contract interface for the Policy objects TODO: keep rights separate and segregated by it's kind i.e. Public, Policy, Role, User etc.

func NewPostgreSQLStore

func NewPostgreSQLStore(db *pgx.Conn) (Store, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL