3
0

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
This commit is contained in:
Tit Petric 2019-02-06 11:18:16 +01:00
parent 1e1a6f8e6a
commit 876a304def
17 changed files with 107 additions and 60 deletions

View File

@ -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"
}

View File

@ -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)
}

View File

@ -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
)

View File

@ -1,4 +1,4 @@
package types
package rules
import (
"fmt"

View File

@ -1,4 +1,4 @@
package types
package rules
import (
"fmt"

View File

@ -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 {

View File

@ -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 {

37
internal/rules/scope.go Normal file
View File

@ -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
}

View File

@ -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) {

View File

@ -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()
})

View File

@ -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()

View File

@ -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",

View File

@ -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
}
)

View File

@ -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()

View File

@ -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",

View File

@ -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()

View File

@ -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",