Documentation ¶
Index ¶
- Constants
- Variables
- func GiveRoleTo(roleID uuid.UUID, actors ...uuid.UUID) command.Cmd[[]uuid.UUID]
- func GrantToActor(actorID uuid.UUID, ref aggregate.Ref, actions ...string) command.Cmd[grantActorPayload]
- func GrantToRole(roleID uuid.UUID, ref aggregate.Ref, actions ...string) command.Cmd[grantRolePayload]
- func HandleCommands(ctx context.Context, bus command.Bus, actorRepos ActorRepositories, ...) (<-chan error, error)
- func IdentifyActor[ID comparable](uid uuid.UUID, id ID) command.Cmd[ID]
- func IdentifyRole(id uuid.UUID, name string) command.Cmd[string]
- func ParseKind(v any) (string, error)
- func RegisterCommands(r *codec.Registry)
- func RegisterEvents(r *codec.Registry)
- func RemoveRoleFrom(roleID uuid.UUID, actors ...uuid.UUID) command.Cmd[[]uuid.UUID]
- func RevokeFromActor(actorID uuid.UUID, ref aggregate.Ref, actions ...string) command.Cmd[revokeActorPayload]
- func RevokeFromRole(roleID uuid.UUID, ref aggregate.Ref, actions ...string) command.Cmd[revokeRolePayload]
- type Actions
- type Actor
- func (a *Actor) ActorID() any
- func (a *Actor) ActorKind() string
- func (a *Actor) Allows(action string, ref aggregate.Ref) bool
- func (a *Actor) Disallows(action string, ref aggregate.Ref) bool
- func (a *Actor) Grant(ref aggregate.Ref, actions ...string) error
- func (a *Actor) Identify(id any) error
- func (a *Actor) Revoke(ref aggregate.Ref, actions ...string) error
- type ActorConfig
- type ActorIdentifiedData
- type ActorRepositories
- type ActorRepository
- type ActorRepositoryRegistry
- type CommandClient
- type Granter
- type GranterOption
- type Lookup
- type LookupTable
- type PermissionFetcher
- type PermissionFetcherFunc
- type PermissionGrantedData
- type PermissionGranterEvent
- type PermissionProjector
- type PermissionRepository
- type PermissionRevokedData
- type Permissions
- type PermissionsDTO
- func (perms PermissionsDTO) ActorAllows(action string, ref aggregate.Ref) bool
- func (perms PermissionsDTO) Allows(action string, ref aggregate.Ref) bool
- func (perms PermissionsDTO) Disallows(action string, ref aggregate.Ref) bool
- func (perms PermissionsDTO) Equal(other PermissionsDTO) bool
- func (perms PermissionsDTO) ModelID() uuid.UUID
- func (perms PermissionsDTO) RoleAllows(action string, ref aggregate.Ref) bool
- type QueryClient
- type Role
- func (r *Role) Add(actors ...uuid.UUID) error
- func (r *Role) Allows(action string, ref aggregate.Ref) bool
- func (r *Role) Disallows(action string, ref aggregate.Ref) bool
- func (r *Role) Grant(ref aggregate.Ref, actions ...string) error
- func (r *Role) Identify(name string) error
- func (r *Role) IsMember(actorID uuid.UUID) bool
- func (r *Role) Name() string
- func (r *Role) Remove(actors ...uuid.UUID) error
- func (r *Role) Revoke(ref aggregate.Ref, actions ...string) error
- type RoleIdentifiedData
- type RoleRepository
- type TargetedGranter
Constants ¶
const ( UUIDActor = "uuid" StringActor = "string" )
Built-in Actor kinds
const ( IdentifyActorCmd = "goes.contrib.auth.actor.identify" IdentifyRoleCmd = "goes.contrib.auth.role.identify" GiveRoleToCmd = "goes.contrib.auth.role.give" RemoveRoleFromCmd = "goes.contrib.auth.role.remove" GrantToActorCmd = "goes.contib.auth.actor.grant" RevokeFromActorCmd = "goes.contib.auth.actor.revoke" GrantToRoleCmd = "goes.contib.auth.role.grant" RevokeFromRoleCmd = "goes.contib.auth.role.revoke" )
Commands
const ( ActorIdentified = "goes.contrib.auth.actor.identified" RoleIdentified = "goes.contrib.auth.role.identified" RoleGiven = "goes.contrib.auth.role.given" RoleRemoved = "goes.contrib.auth.role.removed" // Permission events are used by both the Permission and Role aggregate. PermissionGranted = "goes.contrib.auth.permission_granted" PermissionRevoked = "goes.contrib.auth.permission_revoked" )
const ( // LookupActor looks up the aggregate id of an actor from a given actor id. LookupActor = "actor" // LookupRole looks up the aggregate id of a role from a given role name. LookupRole = "role" )
const ActorAggregate = "goes.contrib.auth.actor"
ActorAggregate is the name of the Actor aggregate.
const RoleAggregate = "goes.contrib.auth.role"
RoleAggregate is the name of the Role aggregate.
Variables ¶
var ( // ErrIDType is returned when trying to identify an actor with an id that // has a type other that the configured type. ErrIDType = errors.New("invalid id type") // ErrMissingActorID is returned when trying to grant or revoke permissions // to or from a non-UUID-Actor before the actor has been identified. ErrMissingActorID = errors.New("missing actor id") )
var ( // ErrEmptyName is returned when trying to create a role with an empty name. ErrEmptyName = errors.New("empty name") // ErrMissingRoleName is returned when trying to grant or revoke permissions // to or from a role before giving the role a name. ErrMissingRoleName = errors.New("missing role name") )
var ( // ErrInvalidRef is returned when providing an invalid aggregate reference // to a Grant() or Revoke() call. ErrInvalidRef = errors.New("invalid aggregate reference") )
var ErrUnknownActorKind = errors.New("unknown actor kind")
ErrUnknownActorKind is returned by ParseKind() if the passed id type is not a builtin actor id type.
Functions ¶
func GiveRoleTo ¶
GiveRoleTo returns the command to give the given role to the given actors.
func GrantToActor ¶
func GrantToActor(actorID uuid.UUID, ref aggregate.Ref, actions ...string) command.Cmd[grantActorPayload]
GrantToActor returns the command to grant the the given actions to the given actor.
func GrantToRole ¶
func GrantToRole(roleID uuid.UUID, ref aggregate.Ref, actions ...string) command.Cmd[grantRolePayload]
GrantToRole returns the command to grant the the given actions to the given role.
func HandleCommands ¶
func HandleCommands( ctx context.Context, bus command.Bus, actorRepos ActorRepositories, roles RoleRepository, ) (<-chan error, error)
HandleCommands handles commands until ctx is canceled.
func IdentifyActor ¶
func IdentifyActor[ID comparable](uid uuid.UUID, id ID) command.Cmd[ID]
IdentifyActor returns the command to specify the id of an actor that is not a UUID-Actor.
func IdentifyRole ¶
IdentifyRole returns the command to specify the name of the given role.
func ParseKind ¶
ParseKind is the builtin implementation of ActorRepositories.ParseKind and is used by default if the provided `parseKind` argument that is passed to NewActorRepositories is nil. ParseKind supports parsing of string-Actors and UUID-Actors. If v is neither a string nor a UUID, an error that satisfies errors.Is(err, ErrUnknownActorKind) is returned. To add support for custom actor kinds, pass a custom ParseKind implementation to NewActorRepositories.
func RegisterCommands ¶
RegisterCommands registers the commands of the auth package into a registry.
func RegisterEvents ¶
RegisterEvents registers the events of the auth package into a registry.
func RemoveRoleFrom ¶
RemoveFoleFrom returns the command to remove the given actors as members from the given role.
Types ¶
type Actions ¶
Actions is a map that stores granted permissions:
map[AGGREGATE]map[ACTION]GRANT_COUNT
Within the Actor and Role aggregates, GRANT_COUNT is always either 0 or 1.
type Actor ¶
An Actor represents any kind of user in the system. Actors are granted permissions to perform actions on specific aggregates within an application.
Note that an Actor itself does not provide the full set of permissions that the actor may have. This can be the case if the actor is a member of a role (roles grant permissions to a group of actors). To get the full set of permissions of a specific actor, project the Permissions read-model for that specific actor.
Actors for users that are identified by a UUID can be created using NewUUIDActor.
var userID uuid.UUID ref := aggregate.Ref{Name: "<aggregate-name>", ID: "<aggregate-id>"} actor := auth.NewUUIDActor(userID) actor.Grant(ref, "action-1", "action-2", "...") actor.Revoke(ref, "action-1", "action-2", "...")
Actors for users that are identified by a string can be created using NewStringActor. Note that the string is not used as the aggregate id (UUID) of the actor. Instead, the string must be passed to the Identify() method of the actor before the actor can be granted or revoked permissions.
ref := aggregate.Ref{Name: "<aggregate-name>", ID: "<aggregate-id>"} actor := auth.NewStringActor(uuid.New()) actor.Identify("<some-string-id>") actor.Grant(ref, "action-1", "action-2", "...") actor.Revoke(ref, "action-1", "action-2", "...")
func NewActor ¶
func NewActor[ID comparable](id uuid.UUID, cfg ActorConfig[ID]) *Actor
NewActor creates a generic actor that uses the provided ActorConfig to format and parse the actor's id (not the aggregate id). NewActor can be used to implement additional actor types besides UUID-Actors and string-Actors. If cfg.ParseID or cfg.FormatID is not provided, NewActor panics.
func NewStringActor ¶
NewStringActor returns an actor that is identified by a string. A string-Actor may refer to any kind of user that is identified by a simple string. Most commonly, this would be some kind of API key or token.
Example ¶
Imagine an ecommerce app that doesn't force customers to create an account to order products. Customers receive an email with a link that allows them to view and update their order. The links that are sent to the customers include a token that the API uses to authorize the customer's requests.
var orderID uuid.UUID var token string // generated by the application actor := auth.NewStringActor(uuid.New()) actor.Identify(token) actor.Grant("order", orderID, "view", "cancel", ...)
func NewUUIDActor ¶
NewUUIDActor returns the actor that is identified by the provided UUID. A UUID-Actor may refer to any kind of user that is identified by a UUID. Most commonly, this would simply be a user aggregate but it can actually be anything that provides a UUID.
func (*Actor) ActorKind ¶
ActorKind returns the kind of the actor. Built-in kinds are "uuid" and "string".
func (*Actor) Allows ¶
Allows returns whether the actor is allowed to perform the given action. Allows does not account for the roles the actor is a member of (use the Permissions read-model instead).
func (*Actor) Disallows ¶
Disallows returns whether the actor is allowed to perform the given action. Disallows does not account for the roles the actor is a member of (use the Permissions read-model instead).
func (*Actor) Grant ¶
Grant grants the actor the permission to perform the given actions on the given aggregate. Grant does not affect the permissions that were granted to the actor through a role.
Wildcards ¶
Grant supports wildcards in the aggregate reference and actions. Pass in a "*" where a string is expected or uuid.Nil where a UUID is expected to match all values.
Example – Grant "view" permission on all aggregates with a specific id:
var id uuid.UUID actor.Grant(aggregate.Ref{Name: "*", ID: id}, "view")
Example – Grant "view" permission on "foo" aggregates with any id:
actor.Grant(aggregate.Ref{Name: "foo", ID: uuid.Nil}, "view")
Example – Grant "view" permission on all aggregates:
actor.Grant(aggregate.Ref{Name: "*", ID: uuid.Nil}, "view")
Example – Grant all permissions on all aggregates:
actor.Grant(aggregate.Ref{Name: "*", ID: uuid.Nil}, "*")
func (*Actor) Identify ¶
Identify sets the provided id as the actor id of the actor. This must be done for any actor that is not a UUID-Actor before the actor can be granted permissions. If the actor is a UUID-Actor, Identify() is a no-op.
func (*Actor) Revoke ¶
Revoke revokes the permission to perform the given actions on the given aggregate from the actor. Revoke does not affect the permissions that were granted to the actor through a role.
Wildcards ¶
Revoke supports wildcards in the aggregate reference and actions. Pass in a "*" where a string is expected or uuid.Nil where a UUID is expected to match all values.
Example – Revoke "view" permission on all aggregates with a specific id:
var id uuid.UUID actor.Revoke(aggregate.Ref{Name: "*", ID: id}, "view")
Example – Revoke "view" permission on "foo" aggregates with any id:
actor.Revoke(aggregate.Ref{Name: "foo", ID: uuid.Nil}, "view")
Example – Revoke "view" permission on all aggregates:
actor.Revoke(aggregate.Ref{Name: "*", ID: uuid.Nil}, "view")
Example – Revoke all permissions on all aggregates:
actor.Revoke(aggregate.Ref{Name: "*", ID: uuid.Nil}, "*")
type ActorConfig ¶
type ActorConfig[ID comparable] struct { // Kind is the type of the actor's id. A string-Actor has the "string" kind, // a UUID-Actor has the "uuid" kind. The kind is used to get the correct // Actor repository from ActorRepositories. Kind string // ParseID parses the formatted actor id that is returned by FormatID back // to the actual ID. ParseID func(string) (ID, error) // FormatID formats the actor id to a string. The formatted string is used // as the event data of the ActorIdentified event. FormatID func(ID) string }
ActorConfig is used by NewActor to configure the actor.
type ActorIdentifiedData ¶
type ActorIdentifiedData string
ActorIdentifiedData is the event data for ActorIdentified.
func (ActorIdentifiedData) ProvideLookup ¶
func (data ActorIdentifiedData) ProvideLookup(p lookup.Provider)
ProvideLookup implements lookup.Event.
type ActorRepositories ¶
type ActorRepositories interface { // ParseKind parses actor kinds from ids. ParseKind(any) (string, error) // Repository returns the repository for the given actor kind. Repository(kind string) (ActorRepository, error) }
ActorRepositories provides Actor repositories for different kinds of actors.
type ActorRepository ¶
type ActorRepository = aggregate.TypedRepository[*Actor]
ActorRepository is the repository for Actors.
func NewStringActorRepository ¶
func NewStringActorRepository(repo aggregate.Repository) ActorRepository
NewStringActorRepository returns the repository for string-Actors.
func NewUUIDActorRepository ¶
func NewUUIDActorRepository(repo aggregate.Repository) ActorRepository
NewUUIDActorRepository returns the repository for UUID-Actors.
type ActorRepositoryRegistry ¶
ActorRepositoryRegistry is a registry for Actor repositories of different kinds.
func NewActorRepositories ¶
func NewActorRepositories(repo aggregate.Repository, parseKind func(any) (string, error)) *ActorRepositoryRegistry
NewActorRepositories returns an ActorRepositoryRegistry that provides repositories for builtin actor kinds (UUIDActor and StringActor).
func NewEmptyActorRepositories ¶
func NewEmptyActorRepositories(parseKind func(any) (string, error)) *ActorRepositoryRegistry
NewEmptyActorRepositories returns a fresh ActorRepositoryRegistry. If provided, the parseKind function is used to parse actor kinds from formatted actor ids.
func (*ActorRepositoryRegistry) Add ¶
func (repos *ActorRepositoryRegistry) Add(kind string, repo ActorRepository)
Add adds the ActorRepository for the given actor kind to the registry.
func (*ActorRepositoryRegistry) ParseKind ¶
func (repos *ActorRepositoryRegistry) ParseKind(v any) (string, error)
ParseKind implements ActorRepositories.ParseKind.
func (*ActorRepositoryRegistry) Repository ¶
func (repos *ActorRepositoryRegistry) Repository(kind string) (ActorRepository, error)
Repository returns the actor repository for the given actor kind.
type CommandClient ¶
type CommandClient interface { // GrantToActor grants the given actor the permission to perform the given actions. GrantToActor(context.Context, uuid.UUID, aggregate.Ref, ...string) error // GrantToRole grants the given role the permission to perform the given actions. GrantToRole(context.Context, uuid.UUID, aggregate.Ref, ...string) error // RevokeFromActor revokes from the given actor the permission to perform the given actions. RevokeFromActor(context.Context, uuid.UUID, aggregate.Ref, ...string) error // RevokeFromRole revokes from the given role the permission to perform the given actions. RevokeFromRole(context.Context, uuid.UUID, aggregate.Ref, ...string) error }
CommandClient defines the command client for the authorization module. It exposes the commands to grant and revoke permissions as an interface. Each of these commands is also available as a "standalone" command:
- auth.CommandClient.GrantToActor() -> auth.GrantToActor()
- auth.CommandClient.GrantToRole() -> auth.GrantToRole()
- auth.CommandClient.RevokeFromActor() -> auth.RevokeFromActor()
- auth.CommandClient.RevokeFromRole() -> auth.RevokeFromRole()
Use the CommandBusClient() constructor to create a CommandClient from an underlying command bus. Alternatively, use the RepositoryCommandClient() to create a CommandClient from actor and role repositories, or use authrpc.NewClient() to create a gRPC CommandClient.
func CommandBusClient ¶
func CommandBusClient(bus command.Bus, opts ...command.DispatchOption) CommandClient
CommandBusClient returns a CommandClient that executes commands by dispatching them via the provided command bus. The provided dispatch options are applied to all dispatched commands.
func RepositoryCommandClient ¶
func RepositoryCommandClient(actors ActorRepositories, roles RoleRepository) CommandClient
RepositoryCommandClient returns a CommandClient that executes commands directly on the Actor and Role aggregates within the provided repositories.
type Granter ¶
type Granter struct {
// contains filtered or unexported fields
}
Granter subscribes to user-provided events to trigger permission changes. Granter can be used to automatically grant or revoke permissions to and from actors and roles when a specified event is published over the underlying event bus.
Granter applies permission changes retrospectively for past events on startup to ensure that new permissions are applied to existing actors and roles.
func NewGranter ¶
func NewGranter( events []string, client CommandClient, lookup Lookup, bus event.Bus, store event.Store, opts ...GranterOption, ) *Granter
NewGranter returns a new permission granter background task.
var events []string var actors auth.ActorRepositories var roles auth.RoleRepository var lookup *auth.Lookup var bus event.Bus g := auth.NewGranter(events, actors, roles, lookup, bus) errs, err := g.Run(context.TODO())
func (*Granter) GrantOn ¶
GrantOn registers a manual handler for the given event. See the package-level GrantOn function for more details and type parameterized handler registration.
func (*Granter) Ready ¶
func (g *Granter) Ready() <-chan struct{}
Ready returns a channel that blocks until the granter applied a projection job for the first time. Waiting for <-g.Ready() ensures that the permissions of all actors are up-to-date. Ready should not be called before g.Run() is called, otherwise it will return a nil-channel that blocks forever. Ready must not be called before g.Run() returns, to avoid race conditions.
type GranterOption ¶
type GranterOption func(*Granter)
GranterOption is a permission granter option.
func GrantOn ¶
func GrantOn[Data any](handler func(TargetedGranter, event.Of[Data]) error, eventNames ...string) GranterOption
GrantOn returns a GranterOption that registers a manual handler for the given events. Instead of checking if the event data implements PermissionGranterEvent, the handler is called directly with the same TargetedGranter that would be passed to a PermissionGranterEvent.
Event names that are registered using the GrantOn() option do not have to be provided to NewGranter(); they are automatically added to the list of events that are subscribed to:
// <nil> events provided, but "foo", "bar", and "baz" events are subscribed to g := auth.NewGranter(nil, ..., auth.GrantOn(..., "foo", "bar", "baz"))
Alternatively, if you already have an exisiting *Granter g, call g.GrantOn() to register additional handlers.
type Lookup ¶
type Lookup interface { // Actor returns the aggregate id of the actor with the given string-formatted actor id. Actor(context.Context, string) (uuid.UUID, bool) // Role returns the aggregate id of the role with the given name. Role(context.Context, string) (uuid.UUID, bool) }
Lookup provides lookups of actor ids and role ids.
func ClientLookup ¶
func ClientLookup(client QueryClient) Lookup
ClientLookup returns a Lookup that uses the provided client to do the lookups.
type LookupTable ¶
LookupTable provides lookups from actor ids to aggregate ids of those actors.
func NewLookup ¶
func NewLookup(store event.Store, bus event.Bus, opts ...schedule.ContinuousOption) *LookupTable
NewLookup returns a new lookup for aggregate ids of actors.
type PermissionFetcher ¶
type PermissionFetcher interface { // Fetch fetches the permissions of the given actor. Fetch(context.Context, uuid.UUID) (PermissionsDTO, error) }
PermissionFetcher fetches permissions of actors.
type PermissionFetcherFunc ¶
PermissionFetcherFunc allows a function to be used as a PermissionFetcher.
func ClientPermissionFetcher ¶
func ClientPermissionFetcher(client QueryClient) PermissionFetcherFunc
ClientPermissionFetcher returns a PermissionFetcher that fetches permissions using the provided client. ClientPermissionFetcher simply returns the client.Permissions method, which is a PermissionFetcherFunc.
func RepositoryPermissionFetcher ¶
func RepositoryPermissionFetcher(repo PermissionRepository) PermissionFetcherFunc
RepositoryPermissionFetcher returns a PermissionFetcher that fetches permissions using the provided PermissionRepository.
func (PermissionFetcherFunc) Fetch ¶
func (fetch PermissionFetcherFunc) Fetch(ctx context.Context, actorID uuid.UUID) (PermissionsDTO, error)
type PermissionGrantedData ¶
PermissionGrantedData is the event data for PermissionGranted.
type PermissionGranterEvent ¶
type PermissionGranterEvent interface { // GrantPermissions is called by *Granter when the event that implements // this interface is published. GrantPermissions(TargetedGranter) error }
PermissionGranterEvent must be implemented by event data to be used within a *Granter. Event data that implements this interface can grant and revoke permissions to and from actors and roles. When such an event is published over the event bus, the running *Granter calls the event data's GrantPermissions() method with a TargetedGranter. The aggregate of the event is used as the permission target.
type PermissionProjector ¶
type PermissionProjector struct {
// contains filtered or unexported fields
}
PermissionProjector continuously projects the Permissions read-model for all actors.
func NewPermissionProjector ¶
func NewPermissionProjector( perms PermissionRepository, roles RoleRepository, bus event.Bus, store event.Store, opts ...schedule.ContinuousOption, ) *PermissionProjector
NewPermissionProjector returns a new permission projector.
type PermissionRepository ¶
type PermissionRepository = model.Repository[*Permissions, uuid.UUID]
PermissionRepository is the repository for the permission read-models.
func InMemoryPermissionRepository ¶
func InMemoryPermissionRepository() PermissionRepository
InMemoryPerissionRepository returns an in-memory repository for the permission read-models.
func MongoPermissionRepository ¶
func MongoPermissionRepository(ctx context.Context, col *gomongo.Collection) (PermissionRepository, error)
MongoPermissionRepository returns a MongoDB repository for the permission read-models. An index for the "actorId" field is automatically created if it does not exist yet.
TODO(bounoable): This should move somewhere else to not pollute this package with backend implementations.
type PermissionRevokedData ¶
PermissionRevokedData is the event data for PermissionRevoked.
type Permissions ¶
type Permissions struct { *projection.Base *projection.Progressor PermissionsDTO // contains filtered or unexported fields }
Permissions is the read-model for the permissions of a specific actor. Permissions uses the actor and role events to project the permissions of a specific actor. An actor is allowed to perform a given action if either the actor itself was granted the permission, or if the actor is a member of a role that was granted the permission.
In order to fully remove a permission of an actor, the permission needs to be revoked from the Actor itself and also from all roles the actor is a member of (or the actor must be removed from these roles).
For example, if an actor is a member of an "admin" role, and the following permissions are granted and revoked in the following order:
- Actor is granted "view" permission on a "foo" aggregate.
- Role is granted "view" permission on the same "foo" aggregate.
- Role is revoked "view" permission on the aggregate.
Then the actor is still allowed to perform the "view" action on the aggregate.
Another example:
- Role is granted "view" permission on a "foo" aggregate.
- Actor is granted "view" permission on the same aggregate.
- Actor is revoked "view" permission on the aggregate.
Then the actor is also allowed to perform the "view" action on the aggregate because the role still grants the permission its members.
func PermissionsOf ¶
func PermissionsOf(actorID uuid.UUID) *Permissions
PermissionsOf returns the permissions read-model of the given actor. The returned projection has an empty state. A *Projector can be used to continuously project the permission read-models for all actors. Use a PermissionRepository to fetch the projected permissions of an actor:
var repo auth.PermissionRepository var actorID uuid.UUID perms, err := repo.Fetch(context.TODO(), actorID) // handle err allowed := perms.Allows("<action>", aggregate.Ref{Name: "...", ID: uuid.UUID{...}}) disallowed := perms.Disallows("<action>", aggregate.Ref{Name: "...", ID: uuid.UUID{...}})
type PermissionsDTO ¶
type PermissionsDTO struct { ActorID uuid.UUID `json:"actorId"` Roles []uuid.UUID `json:"roles"` OfActor Actions `json:"ofActor"` OfRoles Actions `json:"ofRoles"` }
PermissionsDTO is the DTO of Permissions.
func (PermissionsDTO) ActorAllows ¶
func (perms PermissionsDTO) ActorAllows(action string, ref aggregate.Ref) bool
ActorAllows returns whether the actor is allowed to perform the given action on the given aggregate, ignoring permissions of any roles the actor is member of.
func (PermissionsDTO) Allows ¶
func (perms PermissionsDTO) Allows(action string, ref aggregate.Ref) bool
Allows returns whether the actor is allowed to perform the given action on the given aggregate. An actor is allowed to perform a given action if either the actor itself was granted the permission, or if the actor is a member of a role that was granted the permission.
Read the documentation of Permissions for more details.
func (PermissionsDTO) Disallows ¶
func (perms PermissionsDTO) Disallows(action string, ref aggregate.Ref) bool
Disallows returns whether the actor is disallows to perform the given action on the given aggregate. Disallows simply returns !perms.Allows(action, ref).
Read the documentation of Permissions for more details.
func (PermissionsDTO) Equal ¶
func (perms PermissionsDTO) Equal(other PermissionsDTO) bool
Equal returns whether perms and other contain exactly the same values.
func (PermissionsDTO) ModelID ¶
func (perms PermissionsDTO) ModelID() uuid.UUID
ModelID returns the aggregate id of the actor. ModelID implements goes/persistence/model.Model.
func (PermissionsDTO) RoleAllows ¶
func (perms PermissionsDTO) RoleAllows(action string, ref aggregate.Ref) bool
RoleAllows returns whether the actor is allowed to perform the given action on the given aggregate, using only the permissions of the roles the actor is member of.
type QueryClient ¶
type QueryClient interface { // Permissions returns the permission read-model of the given actor. Permissions(ctx context.Context, actorID uuid.UUID) (PermissionsDTO, error) // Allows returns whether the given actor has the permission to perform the // given action on the given aggregate. Allows(ctx context.Context, actorID uuid.UUID, ref aggregate.Ref, action string) (bool, error) // LookupActor looks up the aggregate id of the actor with the given // formatted actor id. LookupActor(ctx context.Context, sid string) (uuid.UUID, error) // LookupRole looks up the agggregate id of the role with the given name. LookupRole(ctx context.Context, name string) (uuid.UUID, error) }
QueryClient defines the query client for the authorization module.
QueryClient is implemented by goes/contrib/auth/authrpc.Client.
type Role ¶
Role represents a named authorization role. Like actors, roles can be granted permissions to perform actions on specific aggregates. Actors can be added to and removed from roles. Actors that are members of a role inherit the role's permissions. A role must be given a name before it can be granted permissions.
Example: "admin" role
role := auth.NewRole(uuid.New()) role.Identify("admin") role.Grant(aggregate.Ref{Name: "foo", ID: uuid.UUID{...}}, "read", "write")
func (*Role) Allows ¶
Allows returns whether the role has the permission to perform the given action.
func (*Role) Disallows ¶
Disallows returns whether the role does not have the permission to perform the given action.
func (*Role) Grant ¶
Grant grants the role the permission to perform the given actions on the given aggregate.
Wildcards ¶
Grant supports wildcards in the aggregate reference and actions. Pass in a "*" where a string is expected or uuid.Nil where a UUID is expected to match all values.
Example – Grant "view" permission on all aggregates with a specific id:
var id uuid.UUID role.Grant(aggregate.Ref{Name: "*", ID: id}, "view")
Example – Grant "view" permission on "foo" aggregates with any id:
role.Grant(aggregate.Ref{Name: "foo", ID: uuid.Nil}, "view")
Example – Grant "view" permission on all aggregates:
role.Grant(aggregate.Ref{Name: "*", ID: uuid.Nil}, "view")
Example – Grant all permissions on all aggregates:
role.Grant(aggregate.Ref{Name: "*", ID: uuid.Nil}, "*")
func (*Role) Identify ¶
Identify identifies the role with the given name, which must must not be empty. Identify must be called before r.Grant() or r.Revoke() is called; otherwise these methods will return an error that satisfies errors.Is(err, ErrMissingRoleName).
func (*Role) Revoke ¶
Revoke revokes the role's permission to perform the given actions on the given aggregate.
Wildcards ¶
Revoke supports wildcards in the aggregate reference and actions. Pass in a "*" where a string is expected or uuid.Nil where a UUID is expected to match all values.
Example – Revoke "view" permission on all aggregates with a specific id:
var id uuid.UUID role.Revoke(aggregate.Ref{Name: "*", ID: id}, "view")
Example – Revoke "view" permission on "foo" aggregates with any id:
role.Revoke(aggregate.Ref{Name: "foo", ID: uuid.Nil}, "view")
Example – Revoke "view" permission on all aggregates:
role.Revoke(aggregate.Ref{Name: "*", ID: uuid.Nil}, "view")
Example – Revoke all permissions on all aggregates:
role.Revoke(aggregate.Ref{Name: "*", ID: uuid.Nil}, "*")
type RoleIdentifiedData ¶
type RoleIdentifiedData string
RoleIdentifiedData is the event data for RoleIdentified.
func (RoleIdentifiedData) ProvideLookup ¶
func (data RoleIdentifiedData) ProvideLookup(p lookup.Provider)
ProvideLookup implements lookup.Event.
type RoleRepository ¶
type RoleRepository = aggregate.TypedRepository[*Role]
RoleRepository is the repository for Roles.
func NewRoleRepository ¶
func NewRoleRepository(repo aggregate.Repository) RoleRepository
NewRoleRepository returns the repository for Roles.
type TargetedGranter ¶
type TargetedGranter interface { // Context is the context of the underlying *Granter. Context() context.Context // Target returns the permission target for the granted and revoked permissions. Target() aggregate.Ref // Lookup returns the lookup that can be used to resolve actor and role ids. Lookup() Lookup // GrantToActor grants the given actor the permission to perform the given // actions on the aggregate referenced by Target(). GrantToActor(ctx context.Context, actorID uuid.UUID, actions ...string) error // RevokeFromActor revokes from the given actor the permission to perform // the given actions on the aggregate referenced by Target(). RevokeFromActor(ctx context.Context, actorID uuid.UUID, actions ...string) error // GrantToRole grants the given role the permission to perform the given // actions on the aggregate referenced by Target(). GrantToRole(ctx context.Context, roleID uuid.UUID, actions ...string) error // RevokeFromRole revokes from the given role the permission to perform // the given actions on the aggregate referenced by Target(). RevokeFromRole(ctx context.Context, roleID uuid.UUID, actions ...string) error }
TargetedGranter provides grant and revoke methods for the actions on a specific aggregate. The provided GrantToXXX() and RevokeFromXXX() methods grant the given actor or role permission to perform the given actions on the aggregate referenced by Target().
TargetedGranter is passed to PermissionGranterEvent implementations by a *Granter when an event with such data is published over the *Granter's underlying event bus.