contrib/auth: make `Granter` usable from non-auth services
Closed this issue · 0 comments
Problem
Currently, the Granter
has dependencies on ActorRepositories
and RoleRepository
, which, in a well designed system, are not accessible from other services than an application's auth service. This means the permission granter in its current design could/should only be used within the auth service. Implementing permissions for each service of an app within the auth service makes the auth service dependent on all services that require permissions (because the auth service must handle the permission events of the other services).
Each service should be able to implement its own permission granter that grants and revokes permissions via a command bus.
Proposal
Proposal is to remove the repository dependencies from the granter and replace them with a single CommandClient
dependency. The CommandClient exposes the different grant and revoke commands as an interface so that it can be implemented using an underlying command bus but also using actor and role repositories.
package auth
type CommandClient interface {
GrantToActor(...) error
GrantToRole(...) error
RevokeFromActor(...) error
RevokeFromRole(...) error
}
Using a Command Bus
package example
func example(events []string, bus command.Bus) {
granter := auth.NewGranter([]string{"foo", "bar", "baz"}, auth.CommandBusClient(bus))
}
Using Repositories
It is still possible to implement the granter as described above (with dependencies to other services) using repositories.
package example
func example(events []string, actors ActorRepositories, roles RoleRepository) {
client := auth.RepositoryCommandClient(actors, roles)
g := auth.NewGranter(events, client)
}