From 876a304defdff7dc6a0ce9f708f8c02948235d7b Mon Sep 17 00:00:00 2001 From: Tit Petric Date: Wed, 6 Feb 2019 11:18:16 +0100 Subject: [PATCH] upd(all): - moved Access type from system to internal/rules, - moved Resource from system to internal/rules, - update imports for new type locations, - add scope list container to inject permissions, - update permissions API call to return default perms, - update codegen for generated Rules types --- codegen.sh | 6 +-- internal/rules/interfaces.go | 6 +-- internal/rules/operations.go | 16 +------- {system/types => internal/rules}/resource.go | 2 +- .../types => internal/rules}/resource_test.go | 2 +- internal/rules/resources.go | 23 ++++++------ {system/types => internal/rules}/rules.go | 6 +-- internal/rules/scope.go | 37 +++++++++++++++++++ messaging/service/permissions.go | 15 +++++--- messaging/service/service.go | 10 ++++- messaging/types/channel.gen.go | 6 +-- messaging/types/channel.go | 6 +-- messaging/types/permissions.go | 4 +- system/types/organisation.gen.go | 8 +++- system/types/organisation.go | 6 ++- system/types/team.gen.go | 8 +++- system/types/team.go | 6 ++- 17 files changed, 107 insertions(+), 60 deletions(-) rename {system/types => internal/rules}/resource.go (97%) rename {system/types => internal/rules}/resource_test.go (98%) rename {system/types => internal/rules}/rules.go (91%) create mode 100644 internal/rules/scope.go diff --git a/codegen.sh b/codegen.sh index 8b70f3e16..74c713a2e 100755 --- a/codegen.sh +++ b/codegen.sh @@ -43,7 +43,7 @@ function types { --output crm/types/type.other.gen.go ./build/gen-type-set --types MessageAttachment --output messaging/types/attachment.gen.go - ./build/gen-type-set --with-resources=true --types Channel --resource-type "types.Resource" --imports "github.com/crusttech/crust/system/types" --output messaging/types/channel.gen.go + ./build/gen-type-set --with-resources=true --types Channel --resource-type "rules.Resource" --imports "github.com/crusttech/crust/internal/rules" --output messaging/types/channel.gen.go ./build/gen-type-set --with-primary-key=false --types ChannelMember --output messaging/types/channel_member.gen.go ./build/gen-type-set --with-primary-key=false --types Command,CommandParam --output messaging/types/command.gen.go ./build/gen-type-set --types Mention --output messaging/types/mention.gen.go @@ -52,8 +52,8 @@ function types { ./build/gen-type-set --with-primary-key=false --types Unread --output messaging/types/unread.gen.go ./build/gen-type-set --types User --output system/types/user.gen.go - ./build/gen-type-set --with-resources=true --resource-type "Resource" --types Team --output system/types/team.gen.go - ./build/gen-type-set --with-resources=true --resource-type "Resource" --types Organisation --output system/types/organisation.gen.go + ./build/gen-type-set --with-resources=true --resource-type "rules.Resource" --imports "github.com/crusttech/crust/internal/rules" --types Team --output system/types/team.gen.go + ./build/gen-type-set --with-resources=true --resource-type "rules.Resource" --imports "github.com/crusttech/crust/internal/rules" --types Organisation --output system/types/organisation.gen.go ./build/gen-type-set --types Credentials --output system/types/credentials.gen.go green "OK" } diff --git a/internal/rules/interfaces.go b/internal/rules/interfaces.go index c89002d5c..39c8a5d79 100644 --- a/internal/rules/interfaces.go +++ b/internal/rules/interfaces.go @@ -4,8 +4,6 @@ import ( "context" "github.com/titpetric/factory" - - "github.com/crusttech/crust/system/types" ) type ResourcesInterface interface { @@ -14,6 +12,6 @@ type ResourcesInterface interface { CheckAccessMulti(resource string, operation string) error CheckAccess(resource string, operation string) error - Grant(resource string, teamID uint64, operations []string, value types.Access) error - ListGrants(resource string, teamID uint64) ([]types.Rules, error) + Grant(resource string, teamID uint64, operations []string, value Access) error + ListGrants(resource string, teamID uint64) ([]Rules, error) } diff --git a/internal/rules/operations.go b/internal/rules/operations.go index 4a1380452..a30d44eb3 100644 --- a/internal/rules/operations.go +++ b/internal/rules/operations.go @@ -1,9 +1,5 @@ package rules -import ( - "github.com/crusttech/crust/system/types" -) - type ( OperationGroup struct { Title string `json:"title"` @@ -23,11 +19,9 @@ type ( // nil = unset (inherit), // true = checked (allow), // false = unchecked (deny) - Default types.Access `json:"default"` + Default Access `json:"default"` } - Access types.Access - Permission struct { // Scope (organisation, team, channel) Scope string `json:"scope"` @@ -36,12 +30,6 @@ type ( // Operation name (Operation.Key) Operation string `json:"operation"` // Operation state (inherit, allow, deny) - State types.Access `json:"state"` + State Access `json:"state"` } ) - -const ( - Allow = types.Allow - Deny = types.Deny - Inherit = types.Inherit -) diff --git a/system/types/resource.go b/internal/rules/resource.go similarity index 97% rename from system/types/resource.go rename to internal/rules/resource.go index 2b477e67d..852f7866f 100644 --- a/system/types/resource.go +++ b/internal/rules/resource.go @@ -1,4 +1,4 @@ -package types +package rules import ( "fmt" diff --git a/system/types/resource_test.go b/internal/rules/resource_test.go similarity index 98% rename from system/types/resource_test.go rename to internal/rules/resource_test.go index 723511215..6e167f889 100644 --- a/system/types/resource_test.go +++ b/internal/rules/resource_test.go @@ -1,4 +1,4 @@ -package types +package rules import ( "fmt" diff --git a/internal/rules/resources.go b/internal/rules/resources.go index 33adfa731..441be1ffd 100644 --- a/internal/rules/resources.go +++ b/internal/rules/resources.go @@ -8,7 +8,6 @@ import ( "github.com/titpetric/factory" "github.com/crusttech/crust/internal/auth" - "github.com/crusttech/crust/system/types" ) type resources struct { @@ -33,7 +32,7 @@ func (r *resources) identity() uint64 { func (r *resources) CheckAccessMulti(resource string, operation string) error { user := r.identity() - result := []types.Access{} + result := []Access{} query := []string{ // select rules "select r.value from sys_rules r", @@ -50,12 +49,12 @@ func (r *resources) CheckAccessMulti(resource string, operation string) error { // order by deny, allow for _, val := range result { - if val == types.Deny { + if val == Deny { return errors.New("Access not allowed") } } for _, val := range result { - if val == types.Allow { + if val == Allow { return nil } } @@ -64,7 +63,7 @@ func (r *resources) CheckAccessMulti(resource string, operation string) error { func (r *resources) CheckAccess(resource string, operation string) error { user := r.identity() - result := []types.Access{} + result := []Access{} query := []string{ // select rules "select r.value from sys_rules r", @@ -80,20 +79,20 @@ func (r *resources) CheckAccess(resource string, operation string) error { // order by deny, allow for _, val := range result { - if val == types.Deny { + if val == Deny { return errors.New("Access not allowed") } } for _, val := range result { - if val == types.Allow { + if val == Allow { return nil } } return errors.New("Access not allowed") } -func (r *resources) Grant(resource string, teamID uint64, operations []string, value types.Access) error { - row := types.Rules{ +func (r *resources) Grant(resource string, teamID uint64, operations []string, value Access) error { + row := Rules{ TeamID: teamID, Resource: resource, Value: value, @@ -103,7 +102,7 @@ func (r *resources) Grant(resource string, teamID uint64, operations []string, v for _, operation := range operations { row.Operation = operation switch value { - case types.Inherit: + case Inherit: _, err = r.db.NamedExec("delete from sys_rules where rel_team=:rel_team and resource=:resource and operation=:operation", row) default: err = r.db.Replace("sys_rules", row) @@ -115,8 +114,8 @@ func (r *resources) Grant(resource string, teamID uint64, operations []string, v return err } -func (r *resources) ListGrants(resource string, teamID uint64) ([]types.Rules, error) { - result := []types.Rules{} +func (r *resources) ListGrants(resource string, teamID uint64) ([]Rules, error) { + result := []Rules{} query := "select * from sys_rules where rel_team = ? and resource = ?" if err := r.db.Select(&result, query, teamID, resource); err != nil { diff --git a/system/types/rules.go b/internal/rules/rules.go similarity index 91% rename from system/types/rules.go rename to internal/rules/rules.go index 2d4243ed1..8d820d151 100644 --- a/system/types/rules.go +++ b/internal/rules/rules.go @@ -1,4 +1,4 @@ -package types +package rules import ( "encoding/json" @@ -9,8 +9,8 @@ type Access int const ( Allow Access = 2 - Deny Access = 1 - Inherit Access = 0 + Deny = 1 + Inherit = 0 ) type Rules struct { diff --git a/internal/rules/scope.go b/internal/rules/scope.go new file mode 100644 index 000000000..7f979bff3 --- /dev/null +++ b/internal/rules/scope.go @@ -0,0 +1,37 @@ +package rules + +type ( + scope struct { + providers []ScopeItem + } + + ScopeItem struct { + Scope string `json:"scope"` + Permissions []OperationGroup `json:"permissions"` + } + + ScopeProvider interface { + Resource() Resource + Permissions() []OperationGroup + } + + ScopeInterface interface { + Add(ScopeProvider) + List() []ScopeItem + } +) + +func NewScope() ScopeInterface { + return &scope{} +} + +func (s *scope) Add(p ScopeProvider) { + s.providers = append(s.providers, ScopeItem{ + Scope: p.Resource().Scope, + Permissions: p.Permissions(), + }) +} + +func (s *scope) List() []ScopeItem { + return s.providers +} diff --git a/messaging/service/permissions.go b/messaging/service/permissions.go index 580e987e7..c6e136854 100644 --- a/messaging/service/permissions.go +++ b/messaging/service/permissions.go @@ -13,6 +13,8 @@ type ( permissions struct { db db ctx context.Context + + scopes rules.ScopeInterface } PermissionsService interface { @@ -24,20 +26,23 @@ type ( } ) -func Permissions() PermissionsService { - return (&permissions{}).With(context.Background()) +func Permissions(scopes rules.ScopeInterface) PermissionsService { + return (&permissions{ + scopes: scopes, + }).With(context.Background()) } func (svc *permissions) With(ctx context.Context) PermissionsService { db := repository.DB(ctx) return &permissions{ - db: db, - ctx: ctx, + db: db, + ctx: ctx, + scopes: svc.scopes, } } func (p *permissions) List() (interface{}, error) { - return nil, errors.New("service.permissions.list: not implemented") + return p.scopes.List(), nil } func (p *permissions) Get(team string, scope string, resource string) (interface{}, error) { diff --git a/messaging/service/service.go b/messaging/service/service.go index 98b0140fc..17f935339 100644 --- a/messaging/service/service.go +++ b/messaging/service/service.go @@ -5,7 +5,10 @@ import ( "sync" "time" + "github.com/crusttech/crust/internal/rules" "github.com/crusttech/crust/internal/store" + + "github.com/crusttech/crust/messaging/types" ) type ( @@ -31,10 +34,15 @@ func Init() { log.Fatalf("Failed to initialize stor: %v", err) } + scopes := rules.NewScope() + scopes.Add(&types.Organisation{}) + scopes.Add(&types.Team{}) + scopes.Add(&types.Channel{}) + DefaultEvent = Event() DefaultAttachment = Attachment(fs) DefaultMessage = Message() - DefaultPermissions = Permissions() + DefaultPermissions = Permissions(scopes) DefaultChannel = Channel() DefaultPubSub = PubSub() }) diff --git a/messaging/types/channel.gen.go b/messaging/types/channel.gen.go index aba043366..714dc22d5 100644 --- a/messaging/types/channel.gen.go +++ b/messaging/types/channel.gen.go @@ -1,7 +1,7 @@ package types import ( - "github.com/crusttech/crust/system/types" + "github.com/crusttech/crust/internal/rules" ) // Hello! This file is auto-generated. @@ -73,8 +73,8 @@ func (set ChannelSet) IDs() (IDs []uint64) { // Resources returns a slice of types.Resource from all items in the set // // This function is auto-generated. -func (set ChannelSet) Resources() (Resources []types.Resource) { - Resources = make([]types.Resource, len(set)) +func (set ChannelSet) Resources() (Resources []rules.Resource) { + Resources = make([]rules.Resource, len(set)) for i := range set { Resources[i] = set[i].Resource() diff --git a/messaging/types/channel.go b/messaging/types/channel.go index 14b987569..3c3c2e367 100644 --- a/messaging/types/channel.go +++ b/messaging/types/channel.go @@ -5,7 +5,7 @@ import ( "encoding/json" - "github.com/crusttech/crust/system/types" + "github.com/crusttech/crust/internal/rules" ) type ( @@ -56,8 +56,8 @@ type ( ) // Resource returns a system resource ID for this type -func (r *Channel) Resource() types.Resource { - return types.Resource{ +func (r *Channel) Resource() rules.Resource { + return rules.Resource{ ID: r.ID, Name: r.Name, Scope: "channel", diff --git a/messaging/types/permissions.go b/messaging/types/permissions.go index c45712385..dfb119387 100644 --- a/messaging/types/permissions.go +++ b/messaging/types/permissions.go @@ -1,12 +1,12 @@ package types import ( - "github.com/crusttech/crust/system/types" + "github.com/crusttech/crust/internal/rules" ) type ( ResourceProvider interface { - Resource() types.Resource + Resource() rules.Resource } ) diff --git a/system/types/organisation.gen.go b/system/types/organisation.gen.go index f24cbfd6a..6b47abe1d 100644 --- a/system/types/organisation.gen.go +++ b/system/types/organisation.gen.go @@ -1,5 +1,9 @@ package types +import ( + "github.com/crusttech/crust/internal/rules" +) + // Hello! This file is auto-generated. type ( @@ -69,8 +73,8 @@ func (set OrganisationSet) IDs() (IDs []uint64) { // Resources returns a slice of types.Resource from all items in the set // // This function is auto-generated. -func (set OrganisationSet) Resources() (Resources []Resource) { - Resources = make([]Resource, len(set)) +func (set OrganisationSet) Resources() (Resources []rules.Resource) { + Resources = make([]rules.Resource, len(set)) for i := range set { Resources[i] = set[i].Resource() diff --git a/system/types/organisation.go b/system/types/organisation.go index 6fe90030a..15fd01561 100644 --- a/system/types/organisation.go +++ b/system/types/organisation.go @@ -2,6 +2,8 @@ package types import ( "time" + + "github.com/crusttech/crust/internal/rules" ) type ( @@ -22,8 +24,8 @@ type ( ) // Resource returns a system resource ID for this type -func (r *Organisation) Resource() Resource { - return Resource{ +func (r *Organisation) Resource() rules.Resource { + return rules.Resource{ ID: r.ID, Name: r.Name, Scope: "organisation", diff --git a/system/types/team.gen.go b/system/types/team.gen.go index 648e7996c..3804169f4 100644 --- a/system/types/team.gen.go +++ b/system/types/team.gen.go @@ -1,5 +1,9 @@ package types +import ( + "github.com/crusttech/crust/internal/rules" +) + // Hello! This file is auto-generated. type ( @@ -69,8 +73,8 @@ func (set TeamSet) IDs() (IDs []uint64) { // Resources returns a slice of types.Resource from all items in the set // // This function is auto-generated. -func (set TeamSet) Resources() (Resources []Resource) { - Resources = make([]Resource, len(set)) +func (set TeamSet) Resources() (Resources []rules.Resource) { + Resources = make([]rules.Resource, len(set)) for i := range set { Resources[i] = set[i].Resource() diff --git a/system/types/team.go b/system/types/team.go index 035815f89..fdb530d47 100644 --- a/system/types/team.go +++ b/system/types/team.go @@ -2,6 +2,8 @@ package types import ( "time" + + "github.com/crusttech/crust/internal/rules" ) type ( @@ -22,8 +24,8 @@ type ( ) // Resource returns a system resource ID for this type -func (r *Team) Resource() Resource { - return Resource{ +func (r *Team) Resource() rules.Resource { + return rules.Resource{ ID: r.ID, Name: r.Name, Scope: "team",