Skip to content

Commit

Permalink
More Permissions (#880)
Browse files Browse the repository at this point in the history
  • Loading branch information
FoseFx authored Nov 3, 2024
1 parent 2fcd785 commit ba810a6
Show file tree
Hide file tree
Showing 33 changed files with 821 additions and 86 deletions.
28 changes: 28 additions & 0 deletions libs/hwauthz/commonPerm/userOrg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package commonPerm

import (
"common/auth"
"context"

"github.com/google/uuid"
)

type User uuid.UUID

func (t User) Type() string { return "user" }
func (t User) ID() string { return uuid.UUID(t).String() }

func UserFromCtx(ctx context.Context) User {
userID := auth.MustGetUserID(ctx)
return User(userID)
}

type Organization uuid.UUID

func (p Organization) Type() string { return "organization" }
func (p Organization) ID() string { return uuid.UUID(p).String() }

func OrganizationFromCtx(ctx context.Context) Organization {
organizationID := auth.MustGetOrganizationID(ctx)
return Organization(organizationID)
}
8 changes: 5 additions & 3 deletions services/property-svc/cmd/service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
hwspicedb "hwauthz/spicedb"
propertySet "property-svc/internal/property-set/api"
psh "property-svc/internal/property-set/handlers"
propertySetSpiceDBProjection "property-svc/internal/property-set/projections/spiceDBProjection"
propertyValue "property-svc/internal/property-value/api"
pvh "property-svc/internal/property-value/handlers"
"property-svc/internal/property-value/projections/property_value_postgres_projection"
Expand All @@ -22,7 +23,7 @@ import (
property "property-svc/internal/property/api"
ph "property-svc/internal/property/handlers"
propertyPostgresProjection "property-svc/internal/property/projections/postgres_projection"
propertySpicedbProjection "property-svc/internal/property/projections/spicedb_projection"
propertySpiceDBProjection "property-svc/internal/property/projections/spiceDBProjection"
)

const ServiceName = "property-svc"
Expand Down Expand Up @@ -53,14 +54,15 @@ func Main(version string, ready func()) {
go projections.StartProjections(
ctx,
common.Shutdown,
propertySpicedbProjection.NewProjection(eventStore, ServiceName, authz),
propertySpiceDBProjection.NewProjection(eventStore, ServiceName, authz),
propertySetSpiceDBProjection.NewProjection(eventStore, ServiceName, authz),
propertyPostgresProjection.NewProjection(eventStore, ServiceName, hwdb.GetDB()),
property_value_postgres_projection.NewProjection(eventStore, ServiceName, hwdb.GetDB()),
property_rules_postgres.NewProjection(eventStore, ServiceName),
)

propertyHandlers := ph.NewPropertyHandlers(aggregateStore, authz)
propertySetHandlers := psh.NewPropertySetHandlers(aggregateStore)
propertySetHandlers := psh.NewPropertySetHandlers(aggregateStore, authz)
propertyViewHandlers := pvih.NewPropertyViewHandlers(aggregateStore)
propertyValueHandlers := pvh.NewPropertyValueHandlers(aggregateStore)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import (
"context"
"errors"
"fmt"
"hwauthz"
"hwauthz/commonPerm"
"hwes"

"property-svc/internal/property-set/perm"

"github.com/google/uuid"

"property-svc/internal/property-set/aggregate"
Expand All @@ -20,8 +24,16 @@ type CreatePropertySetCommandHandler func(
name string,
) (common.ConsistencyToken, error)

func NewCreatePropertySetCommandHandler(as hwes.AggregateStore) CreatePropertySetCommandHandler {
func NewCreatePropertySetCommandHandler(as hwes.AggregateStore, authz hwauthz.AuthZ) CreatePropertySetCommandHandler {
return func(ctx context.Context, propertySetID uuid.UUID, name string) (common.ConsistencyToken, error) {
user := commonPerm.UserFromCtx(ctx)
org := commonPerm.OrganizationFromCtx(ctx)

check := hwauthz.NewPermissionCheck(user, perm.OrganizationCanUserCreatePropertySet, org)
if err := authz.Must(ctx, check); err != nil {
return 0, err
}

a := aggregate.NewPropertySetAggregate(propertySetID)

exists, err := as.Exists(ctx, a)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package handlers

import (
"hwauthz"
"hwes"

commandsV1 "property-svc/internal/property-set/commands/v1"
Expand All @@ -20,16 +21,16 @@ type Handlers struct {
Queries *Queries
}

func NewPropertySetHandlers(as hwes.AggregateStore) *Handlers {
func NewPropertySetHandlers(as hwes.AggregateStore, authz hwauthz.AuthZ) *Handlers {
return &Handlers{
Commands: &Commands{
V1: &commandsV1.PropertySetCommands{
CreatePropertySet: commandsV1.NewCreatePropertySetCommandHandler(as),
CreatePropertySet: commandsV1.NewCreatePropertySetCommandHandler(as, authz),
},
},
Queries: &Queries{
V1: &queriesV1.PropertySetQueries{
GetPropertySetByID: queriesV1.NewGetPropertySetByIDQueryHandler(as),
GetPropertySetByID: queriesV1.NewGetPropertySetByIDQueryHandler(as, authz),
},
},
}
Expand Down
26 changes: 26 additions & 0 deletions services/property-svc/internal/property-set/perm/permission.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package perm

import (
"hwauthz"

"github.com/google/uuid"
)

// Types

type PropertySet uuid.UUID

func (t PropertySet) Type() string { return "property_set" }
func (t PropertySet) ID() string { return uuid.UUID(t).String() }

// Direct Relations

const PropertySetOrganization hwauthz.Relation = "organization"

// Permissions

const OrganizationCanUserCreatePropertySet hwauthz.Permission = "create_property_set"

const (
PropertySetCanUserGet hwauthz.Permission = "get"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package spiceDBProjection

import (
"context"
"errors"
"fmt"
"hwauthz"
"hwauthz/commonPerm"
"hwes"
"hwes/eventstoredb/projections/custom"
"hwutil"

"property-svc/internal/property-set/aggregate"

"github.com/EventStore/EventStore-Client-Go/v4/esdb"
"github.com/google/uuid"
zlog "github.com/rs/zerolog/log"

propertySetEventsV1 "property-svc/internal/property-set/events/v1"
"property-svc/internal/property-set/perm"
)

type Projection struct {
*custom.CustomProjection
authz hwauthz.AuthZ
}

func NewProjection(es *esdb.Client, serviceName string, authz hwauthz.AuthZ) *Projection {
subscriptionGroupName := serviceName + "-property-set-spicedb-projection"
p := &Projection{
CustomProjection: custom.NewCustomProjection(
es,
subscriptionGroupName,
&[]string{aggregate.PropertySetAggregateType + "-"},
),
authz: authz,
}
p.initEventListeners()
return p
}

func (p *Projection) initEventListeners() {
p.RegisterEventListener(propertySetEventsV1.PropertySetCreated, p.onPropertySetCreated)
}

func (p *Projection) onPropertySetCreated(ctx context.Context, evt hwes.Event) (error, *esdb.NackAction) {
log := zlog.Ctx(ctx)

// Parse Values
var payload propertySetEventsV1.PropertySetCreatedEvent
if err := evt.GetJsonData(&payload); err != nil {
log.Error().Err(err).Msg("unmarshal failed")
return err, hwutil.PtrTo(esdb.NackActionPark)
}

propertySetID, err := uuid.Parse(payload.ID)
if err != nil {
return err, hwutil.PtrTo(esdb.NackActionPark)
}

if evt.OrganizationID == nil {
return errors.New("organization is missing from event"), hwutil.PtrTo(esdb.NackActionPark)
}
organizationID := *evt.OrganizationID

relationship := hwauthz.NewRelationship(
commonPerm.Organization(organizationID),
perm.PropertySetOrganization,
perm.PropertySet(propertySetID),
)

// add to permission graph
_, err = p.authz.
Create(relationship).
Commit(ctx)
if err != nil {
return fmt.Errorf("could not create spice relationship %s: %w", relationship.DebugString(), err),
hwutil.PtrTo(esdb.NackActionRetry)
}

log.Debug().
Str("relationship", relationship.DebugString()).
Msg("spice relationship created")

return nil, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ package v1
import (
"context"
"fmt"
"hwauthz"
"hwauthz/commonPerm"
"hwes"

"property-svc/internal/property-set/perm"

"github.com/google/uuid"

"property-svc/internal/property-set/aggregate"
Expand All @@ -13,8 +17,16 @@ import (

type GetPropertySetByIDQueryHandler func(ctx context.Context, propertySetID uuid.UUID) (*models.PropertySet, error)

func NewGetPropertySetByIDQueryHandler(as hwes.AggregateStore) GetPropertySetByIDQueryHandler {
func NewGetPropertySetByIDQueryHandler(as hwes.AggregateStore, authz hwauthz.AuthZ) GetPropertySetByIDQueryHandler {
return func(ctx context.Context, propertySetID uuid.UUID) (*models.PropertySet, error) {
user := commonPerm.UserFromCtx(ctx)
set := perm.PropertySet(propertySetID)
check := hwauthz.NewPermissionCheck(user, perm.PropertySetCanUserGet, set)

if err := authz.Must(ctx, check); err != nil {
return nil, err
}

propertySetAggregate, err := aggregate.LoadPropertySetAggregate(ctx, as, propertySetID)
if err != nil {
return nil, fmt.Errorf("GetPropertySetByIDQueryHandler: %w", err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
pb "gen/services/property_svc/v1"
"hwauthz"
"hwauthz/commonPerm"
"hwes"

"github.com/google/uuid"
Expand Down Expand Up @@ -35,8 +36,8 @@ func NewCreatePropertyCommandHandler(as hwes.AggregateStore, authz hwauthz.AuthZ
setID *string,
fieldTypeData *models.FieldTypeData,
) (version common.ConsistencyToken, err error) {
user := perm.UserFromCtx(ctx)
organization := perm.OrganizationFromCtx(ctx)
user := commonPerm.UserFromCtx(ctx)
organization := commonPerm.OrganizationFromCtx(ctx)

check := hwauthz.NewPermissionCheck(user, perm.OrganizationCanUserCreateProperty, organization)
if err = authz.Must(ctx, check); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
pb "gen/services/property_svc/v1"
"hwauthz"
"hwauthz/commonPerm"
"hwes"

"github.com/google/uuid"
Expand Down Expand Up @@ -40,7 +41,7 @@ func NewUpdatePropertyCommandHandler(as hwes.AggregateStore, authz hwauthz.AuthZ
removeOptions []string,
isArchived *bool,
) (common.ConsistencyToken, error) {
user := perm.UserFromCtx(ctx)
user := commonPerm.UserFromCtx(ctx)

check := hwauthz.NewPermissionCheck(user, perm.PropertyCanUserUpdate, perm.Property(propertyID))
if err := authz.Must(ctx, check); err != nil {
Expand Down
22 changes: 0 additions & 22 deletions services/property-svc/internal/property/perm/permission.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package perm

import (
"common/auth"
"context"
"hwauthz"

"github.com/google/uuid"
Expand All @@ -15,26 +13,6 @@ type Property uuid.UUID
func (t Property) Type() string { return "property" }
func (t Property) ID() string { return uuid.UUID(t).String() }

type User uuid.UUID

func (t User) Type() string { return "user" }
func (t User) ID() string { return uuid.UUID(t).String() }

func UserFromCtx(ctx context.Context) User {
userID := auth.MustGetUserID(ctx)
return User(userID)
}

type Organization uuid.UUID

func (p Organization) Type() string { return "organization" }
func (p Organization) ID() string { return uuid.UUID(p).String() }

func OrganizationFromCtx(ctx context.Context) Organization {
organizationID := auth.MustGetOrganizationID(ctx)
return Organization(organizationID)
}

// Direct Relations

const PropertyOrganization hwauthz.Relation = "organization"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package spicedb_projection
package spiceDBProjection

import (
"context"
"errors"
"fmt"
"hwauthz"
"hwauthz/commonPerm"
"hwes"
"hwes/eventstoredb/projections/custom"
"hwutil"
Expand All @@ -25,7 +26,7 @@ type Projection struct {
}

func NewProjection(es *esdb.Client, serviceName string, authz hwauthz.AuthZ) *Projection {
subscriptionGroupName := serviceName + "-spicedb-projection"
subscriptionGroupName := serviceName + "-property-spicedb-projection"
p := &Projection{
CustomProjection: custom.NewCustomProjection(
es,
Expand Down Expand Up @@ -63,9 +64,10 @@ func (p *Projection) onPropertyCreated(ctx context.Context, evt hwes.Event) (err
organizationID := *evt.OrganizationID

relationship := hwauthz.NewRelationship(
perm.Organization(organizationID),
commonPerm.Organization(organizationID),
perm.PropertyOrganization,
perm.Property(propertyID))
perm.Property(propertyID),
)

// add to permission graph
_, err = p.authz.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
pb "gen/services/property_svc/v1"
"hwauthz"
"hwauthz/commonPerm"
"hwdb"
"hwutil"

Expand All @@ -22,7 +23,7 @@ type GetPropertiesQueryHandler func(

func NewGetPropertiesQueryHandler(authz hwauthz.AuthZ) GetPropertiesQueryHandler {
return func(ctx context.Context, subjectType *pb.SubjectType) ([]*models.PropertyWithConsistency, error) {
user := perm.UserFromCtx(ctx)
user := commonPerm.UserFromCtx(ctx)

propertyRepo := property_repo.New(hwdb.GetDB())

Expand Down
Loading

0 comments on commit ba810a6

Please sign in to comment.