Skip to content

Commit

Permalink
feat: Add authorizer struct
Browse files Browse the repository at this point in the history
  • Loading branch information
nsklikas committed Nov 27, 2023
1 parent 8628fa6 commit c6170a2
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 0 deletions.
5 changes: 5 additions & 0 deletions internal/authorization/auth_model.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

93 changes: 93 additions & 0 deletions internal/authorization/authorization.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package authorization

import (
"context"
"encoding/json"
"fmt"

"github.com/canonical/identity-platform-login-ui/internal/logging"
"github.com/canonical/identity-platform-login-ui/internal/monitoring"
fga "github.com/openfga/go-sdk"
"go.opentelemetry.io/otel/trace"
)

var ErrInvalidAuthModel = fmt.Errorf("Invalid authorization model schema")

type Authorizer struct {
Client AuthzClientInterface

tracer trace.Tracer
monitor monitoring.MonitorInterface
logger logging.LoggerInterface
}

func (a *Authorizer) Check(ctx context.Context, user string, relation string, object string) (bool, error) {
ctx, span := a.tracer.Start(ctx, "authorization.Authorizer.Check")
defer span.End()

return a.Client.Check(ctx, user, relation, object)
}

func (a *Authorizer) ListObjects(ctx context.Context, user string, relation string, objectType string) ([]string, error) {
ctx, span := a.tracer.Start(ctx, "authorization.Authorizer.ListObjects")
defer span.End()

return a.Client.ListObjects(ctx, user, relation, objectType)
}

func (a *Authorizer) FilterObjects(ctx context.Context, user string, relation string, objectType string, objs []string) ([]string, error) {
ctx, span := a.tracer.Start(ctx, "authorization.Authorizer.FilterObjects")
defer span.End()

allowedObjs, err := a.ListObjects(ctx, user, relation, objectType)
if err != nil {
return nil, err
}

var ret []string
for _, obj := range allowedObjs {
if contains(objs, obj) {
ret = append(ret, obj)
}
}
return ret, nil
}

func (a *Authorizer) ValidateModel(ctx context.Context) error {
ctx, span := a.tracer.Start(ctx, "authorization.Authorizer.ValidateModel")
defer span.End()

var builtinAuthorizationModel fga.AuthorizationModel
err := json.Unmarshal([]byte(authModel), &builtinAuthorizationModel)
if err != nil {
return err
}

eq, err := a.Client.CompareModel(ctx, builtinAuthorizationModel)
if err != nil {
return err
}
if !eq {
return ErrInvalidAuthModel
}
return nil
}

func NewAuthorizer(client AuthzClientInterface, tracer trace.Tracer, monitor monitoring.MonitorInterface, logger logging.LoggerInterface) *Authorizer {
authorizer := new(Authorizer)
authorizer.Client = client
authorizer.tracer = tracer
authorizer.monitor = monitor
authorizer.logger = logger

return authorizer
}

func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
21 changes: 21 additions & 0 deletions internal/authorization/interfaces.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package authorization

import (
"context"

fga "github.com/openfga/go-sdk"
)

type AuthorizerInterface interface {
ListObjects(context.Context, string, string, string) ([]string, error)
Check(context.Context, string, string, string) (bool, error)
FilterObjects(context.Context, string, string, string, []string) ([]string, error)
ValidateModel(context.Context) error
}

type AuthzClientInterface interface {
ListObjects(context.Context, string, string, string) ([]string, error)
Check(context.Context, string, string, string) (bool, error)
ReadModel(context.Context) (*fga.AuthorizationModel, error)
CompareModel(context.Context, fga.AuthorizationModel) (bool, error)
}
14 changes: 14 additions & 0 deletions internal/authorization/schema.openfga
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
model
schema 1.1
type user
type app
type group
relations
define member: [user, group#member]
type app_group
relations
define member: [app, app_group#member]
type provider
relations
define member: [user]
define allowed_access: [app, app_group#member]

0 comments on commit c6170a2

Please sign in to comment.