Skip to content

Commit

Permalink
Merge pull request #189 from canonical/IAM-655
Browse files Browse the repository at this point in the history
IAM 655 - roles API
  • Loading branch information
shipperizer authored Mar 15, 2024
2 parents 3855c04 + e2bc97d commit 24f6e2d
Show file tree
Hide file tree
Showing 13 changed files with 3,207 additions and 19 deletions.
3 changes: 2 additions & 1 deletion cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,13 @@ func serve() {
logger.Info("Authorization is disabled, using noop authorizer")
authzClient = openfga.NewNoopClient(tracer, monitor, logger)
}

authorizer := authorization.NewAuthorizer(authzClient, tracer, monitor, logger)
if authorizer.ValidateModel(context.Background()) != nil {
panic("Invalid authorization model provided")
}

router := web.NewRouter(idpConfig, schemasConfig, rulesConfig, hAdminClient, kAdminClient, tracer, monitor, logger)
router := web.NewRouter(idpConfig, schemasConfig, rulesConfig, hAdminClient, kAdminClient, authzClient, tracer, monitor, logger)

logger.Infof("Starting server on port %v", specs.Port)

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/go-chi/cors v1.2.1
github.com/google/uuid v1.4.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/openfga/go-sdk v0.3.3
github.com/openfga/go-sdk v0.3.4
github.com/openfga/language/pkg/go v0.0.0-20240122114256-aaa86ab89379
github.com/ory/hydra-client-go/v2 v2.1.1
github.com/ory/kratos-client-go v1.0.0
Expand Down Expand Up @@ -79,7 +79,7 @@ require (
golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/oauth2 v0.13.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
github.com/openfga/api/proto v0.0.0-20231222042535-3037910c90c0 h1:FW+CjkR6GrvJcUj3EZZ75q1Otog4sy+FOwHLeqZ3DKo=
github.com/openfga/api/proto v0.0.0-20231222042535-3037910c90c0/go.mod h1:YSbEQDNGnVlThfExHQ3zDNd+puWXf4zzfL0ms2VbIwI=
github.com/openfga/go-sdk v0.3.3 h1:eMZGCEDW/sz9S3gNxbpO5rNpDezz7cjT+zwjpDgqTt0=
github.com/openfga/go-sdk v0.3.3/go.mod h1:W4SNYMSxptGOtA9aGYxsYUmSC7LaZYP7y9qbT36ouCc=
github.com/openfga/go-sdk v0.3.4 h1:5VsDSmkXUP/XH9L4BtztYVPuthH5Pd3h1QZfqzZttL0=
github.com/openfga/go-sdk v0.3.4/go.mod h1:u1iErzj5E9/bhe+8nsMv0gigcYbJtImcdgcE5DmpbBg=
github.com/openfga/language/pkg/go v0.0.0-20240122114256-aaa86ab89379 h1:j42rKsj3rt2TvTBcEoiWkZ8MFKzRFUA04WD4b/f/KNY=
github.com/openfga/language/pkg/go v0.0.0-20240122114256-aaa86ab89379/go.mod h1:dHJaJ7H5tViBCPidTsfl3IOd152FhYxWFQmZXOhZ2pw=
github.com/ory/hydra-client-go/v2 v2.1.1 h1:3JatU9uFbw5XhF3lgPCas1l1Kok2v5Mq1p26zZwGHNg=
Expand Down Expand Up @@ -190,8 +190,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
78 changes: 67 additions & 11 deletions internal/authorization/schema.openfga
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,73 @@ type role
define privileged: [privileged]
define assignee: [user, group#member] or admin from privileged

define can_create: [user, role#assignee, group#member] or admin from privileged
define can_delete: [user, role#assignee, group#member] or admin from privileged
define can_edit: [user, role#assignee, group#member] or admin from privileged
define can_view: [user, user:*, role#assignee, group#member] or admin from privileged

type group
relations
relations
define privileged: [privileged]
define member: [user, group#member]

type api
relations
define admin: [role#assignee, group#member]
define can_create: editor or admin
define can_delete: [user, role#assignee, group#member] or admin
define can_edit: editor or admin
define can_list: viewer or admin
define can_view: viewer or admin
define editor: [user, role#assignee, group#member]
define viewer: [user, role#assignee, group#member] or editor
define can_create: [user, role#assignee, group#member] or admin from privileged
define can_delete: [user, role#assignee, group#member] or admin from privileged
define can_edit: [user, role#assignee, group#member] or admin from privileged
define can_view: [user, user:*, role#assignee, group#member] or admin from privileged

type identity
relations
define privileged: [privileged]

define can_create: [user, role#assignee, group#member] or admin from privileged
define can_delete: [user, role#assignee, group#member] or admin from privileged
define can_edit: [user, role#assignee, group#member] or admin from privileged
define can_view: [user, user:*, role#assignee, group#member] or admin from privileged

type scheme
relations
define privileged: [privileged]

define can_create: [user, role#assignee, group#member] or admin from privileged
define can_delete: [user, role#assignee, group#member] or admin from privileged
define can_edit: [user, role#assignee, group#member] or admin from privileged
define can_view: [user, user:*, role#assignee, group#member] or admin from privileged

type client
relations
define privileged: [privileged]

define can_create: [user, role#assignee, group#member] or admin from privileged
define can_delete: [user, role#assignee, group#member] or admin from privileged
define can_edit: [user, role#assignee, group#member] or admin from privileged
define can_view: [user, user:*, role#assignee, group#member] or admin from privileged

type provider
relations
define privileged: [privileged]

define can_create: [user, role#assignee, group#member] or admin from privileged
define can_delete: [user, role#assignee, group#member] or admin from privileged
define can_edit: [user, role#assignee, group#member] or admin from privileged
define can_view: [user, user:*, role#assignee, group#member] or admin from privileged

type rule
relations
define privileged: [privileged]

define can_create: [user, role#assignee, group#member] or admin from privileged
define can_delete: [user, role#assignee, group#member] or admin from privileged
define can_edit: [user, role#assignee, group#member] or admin from privileged
define can_view: [user, user:*, role#assignee, group#member] or admin from privileged

# need to model how to assign applications for the login UI, if copying current model or adjusting it
type application
relations
define privileged: [privileged]

define can_create: [user, role#assignee, group#member] or admin from privileged
define can_delete: [user, role#assignee, group#member] or admin from privileged
define can_edit: [user, role#assignee, group#member] or admin from privileged
define can_view: [user, user:*, role#assignee, group#member] or admin from privileged

51 changes: 51 additions & 0 deletions internal/authorization/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2024 Canonical Ltd.
// SPDX-License-Identifier: AGPL

package authorization

import (
"fmt"
"strings"
)

const (
PERMISSION_SEPARATOR = "::"
)

type Urn struct {
relation string
object string
}

func (a *Urn) ID() string {
return fmt.Sprintf("%s%s%s", a.relation, PERMISSION_SEPARATOR, a.object)
}

func (a *Urn) Relation() string {
return a.relation
}

func (a *Urn) Object() string {
return a.object
}

func NewUrn(relation, object string) *Urn {
u := new(Urn)

u.relation = relation
u.object = object

return u
}

func NewUrnFromURLParam(ID string) *Urn {
values := strings.Split(ID, PERMISSION_SEPARATOR)

if len(values) < 2 {
// not a valid Urn
return nil
}

// use only first two elements
return NewUrn(values[0], values[1])
}
102 changes: 102 additions & 0 deletions internal/http/types/token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright 2024 Canonical Ltd.
// SPDX-License-Identifier: AGPL

package types

import (
"context"
"encoding/base64"
"encoding/json"
"net/http"

"github.com/canonical/identity-platform-admin-ui/internal/logging"
"github.com/canonical/identity-platform-admin-ui/internal/tracing"
"go.opentelemetry.io/otel/trace"
)

const (
PAGINATION_HEADER = "X-Token-Pagination"
)

type TokenPaginator struct {
tokens map[string]string

tracer tracing.TracingInterface
logger logging.LoggerInterface
}

func (p *TokenPaginator) LoadFromRequest(ctx context.Context, r *http.Request) error {
_, span := p.tracer.Start(ctx, "types.TokenPaginator.LoadFromRequest")
defer span.End()

header := r.Header.Get(PAGINATION_HEADER)

if header == "" {
return nil
}

tokenMap, err := base64.StdEncoding.DecodeString(header)

if err != nil {
p.logger.Errorf("issues decoding header: %s", err)
return err
}

tokens := map[string]string{}

err = json.Unmarshal(tokenMap, &tokens)

if err != nil {
p.logger.Errorf("issues parsing header: %s", err)
return err
}

p.tokens = tokens

return nil
}

func (p *TokenPaginator) SetToken(ctx context.Context, key, value string) {
p.tokens[key] = value
}

func (p *TokenPaginator) GetToken(ctx context.Context, key string) string {
if token, ok := p.tokens[key]; ok {
return token
}

return ""
}

func (p *TokenPaginator) GetAllTokens(ctx context.Context) map[string]string {
return p.tokens
}

func (p *TokenPaginator) PaginationHeader(ctx context.Context) (string, error) {
_, span := p.tracer.Start(ctx, "types.TokenPaginator.PaginationHeader")
defer span.End()

if len(p.tokens) == 0 {
return "", nil
}

tokenMap, err := json.Marshal(p.tokens)

if err != nil {
p.logger.Errorf("issues parsing tokens: %s", err)
return "", err
}

return base64.StdEncoding.EncodeToString(tokenMap), nil
}

func NewTokenPaginator(tracer trace.Tracer, logger logging.LoggerInterface) *TokenPaginator {
p := new(TokenPaginator)

p.logger = logger
p.tracer = tracer
p.tokens = make(map[string]string)

return p

}
Loading

0 comments on commit 24f6e2d

Please sign in to comment.