Skip to content

Commit

Permalink
Merge pull request #2367 from influxdata/fix/issue#2252
Browse files Browse the repository at this point in the history
Add org admin and member specific permissions
  • Loading branch information
desa authored Jan 9, 2019
2 parents bcddb83 + 0ec2295 commit 394673c
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 14 deletions.
2 changes: 1 addition & 1 deletion auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (a *Authorization) Allowed(p Permission) bool {
return false
}

return allowed(p, a.Permissions)
return PermissionAllowed(p, a.Permissions)
}

// IsActive is a stub for idpe.
Expand Down
62 changes: 55 additions & 7 deletions authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,25 @@ type Authorizer interface {
Kind() string
}

func allowed(p Permission, ps []Permission) bool {
// PermissionAllowed
func PermissionAllowed(p Permission, ps []Permission) bool {
pID := ID(0)
if p.ID != nil {
pID = *p.ID
if !pID.Valid() {
return false
}
}

for _, perm := range ps {
if perm.Action == p.Action && perm.Resource == p.Resource {
permID := ID(0)
if perm.ID != nil {
permID = *perm.ID
if !permID.Valid() {
return false
}
}
if perm.Action == p.Action && perm.Resource == p.Resource && permID == pID {
return true
}
}
Expand Down Expand Up @@ -99,7 +115,17 @@ var AllResources = []Resource{
UsersResource, // 7
}

// Valid checks if the resource is a member of the Resource enum
// OrgResources is the list of all known resource types that belong to an organization.
var OrgResources = []Resource{
BucketsResource, // 1
DashboardsResource, // 2
SourcesResource, // 4
TasksResource, // 5
TelegrafsResource, // 6
UsersResource, // 7
}

// Valid checks if the resource is a member of the Resource enum.
func (r Resource) Valid() (err error) {
switch r {
case AuthorizationsResource: // 0
Expand Down Expand Up @@ -133,7 +159,7 @@ func (p Permission) String() string {
return str
}

// Valid checks if there the resource and action provided is known
// Valid checks if there the resource and action provided is known.
func (p *Permission) Valid() error {
if err := p.Resource.Valid(); err != nil {
return &Error{
Expand Down Expand Up @@ -162,7 +188,7 @@ func (p *Permission) Valid() error {
return nil
}

// NewPermission returns a permission with provided arguments
// NewPermission returns a permission with provided arguments.
func NewPermission(a Action, r Resource) (*Permission, error) {
p := &Permission{
Action: a,
Expand All @@ -172,7 +198,7 @@ func NewPermission(a Action, r Resource) (*Permission, error) {
return p, p.Valid()
}

// NewPermissionAtID creates a permission with the provided arguments
// NewPermissionAtID creates a permission with the provided arguments.
func NewPermissionAtID(id ID, a Action, r Resource) (*Permission, error) {
p := &Permission{
Action: a,
Expand All @@ -183,7 +209,7 @@ func NewPermissionAtID(id ID, a Action, r Resource) (*Permission, error) {
return p, p.Valid()
}

// OperPermissions are the default permissions for those who setup the application
// OperPermissions are the default permissions for those who setup the application.
func OperPermissions() []Permission {
ps := []Permission{}
for _, r := range AllResources {
Expand All @@ -194,3 +220,25 @@ func OperPermissions() []Permission {

return ps
}

// OrgAdminPermissions are the default permissions for org admins.
func OrgAdminPermissions(orgID ID) []Permission {
ps := []Permission{}
for _, r := range OrgResources {
for _, a := range actions {
ps = append(ps, Permission{ID: &orgID, Action: a, Resource: r})
}
}

return ps
}

// OrgMemberPermissions are the default permissions for org members.
func OrgMemberPermissions(orgID ID) []Permission {
ps := []Permission{}
for _, r := range OrgResources {
ps = append(ps, Permission{ID: &orgID, Action: ReadAction, Resource: r})
}

return ps
}
133 changes: 133 additions & 0 deletions authz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,135 @@ import (
"github.com/influxdata/platform"
)

func TestAuthorizer_PermissionAllowed(t *testing.T) {
tests := []struct {
name string
permission platform.Permission
permissions []platform.Permission
allowed bool
}{
{
name: "bad resource id in permission",
permission: platform.Permission{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
ID: IDPtr(0),
},
permissions: []platform.Permission{
{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
ID: IDPtr(1),
},
},
allowed: false,
},
{
name: "bad resource id in permissions",
permission: platform.Permission{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
ID: IDPtr(1),
},
permissions: []platform.Permission{
{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
ID: IDPtr(0),
},
},
allowed: false,
},
{
name: "matching action resource and ID",
permission: platform.Permission{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
ID: IDPtr(1),
},
permissions: []platform.Permission{
{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
ID: IDPtr(1),
},
},
allowed: true,
},
{
name: "matching action resource no ID",
permission: platform.Permission{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
},
permissions: []platform.Permission{
{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
},
},
allowed: true,
},
{
name: "matching action resource differing ID",
permission: platform.Permission{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
ID: IDPtr(1),
},
permissions: []platform.Permission{
{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
ID: IDPtr(2),
},
},
allowed: false,
},
{
name: "differing action same resource",
permission: platform.Permission{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
ID: IDPtr(1),
},
permissions: []platform.Permission{
{
Action: platform.ReadAction,
Resource: platform.BucketsResource,
ID: IDPtr(1),
},
},
allowed: false,
},
{
name: "same action differing resource",
permission: platform.Permission{
Action: platform.WriteAction,
Resource: platform.BucketsResource,
ID: IDPtr(1),
},
permissions: []platform.Permission{
{
Action: platform.WriteAction,
Resource: platform.TasksResource,
ID: IDPtr(1),
},
},
allowed: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
allowed := platform.PermissionAllowed(tt.permission, tt.permissions)
if allowed != tt.allowed {
t.Errorf("got allowed = %v, expected allowed = %v", allowed, tt.allowed)
}
})
}
}

func TestPermission_Valid(t *testing.T) {
type fields struct {
Action platform.Action
Expand Down Expand Up @@ -159,3 +288,7 @@ func validID() *platform.ID {
id := platform.ID(100)
return &id
}

func IDPtr(id platform.ID) *platform.ID {
return &id
}
15 changes: 14 additions & 1 deletion bolt/onboarding.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,24 @@ func (c *Client) Generate(ctx context.Context, req *platform.OnboardingRequest)
if err = c.CreateBucket(ctx, bucket); err != nil {
return nil, err
}

perms := platform.OperPermissions()
perms = append(perms, platform.OrgAdminPermissions(o.ID)...)
writeBucketPerm, err := platform.NewPermissionAtID(bucket.ID, platform.WriteAction, platform.BucketsResource)
if err != nil {
return nil, err
}
readBucketPerm, err := platform.NewPermissionAtID(bucket.ID, platform.ReadAction, platform.BucketsResource)
if err != nil {
return nil, err
}
perms = append(perms, *writeBucketPerm, *readBucketPerm)

auth := &platform.Authorization{
UserID: u.ID,
Description: fmt.Sprintf("%s's Token", u.Name),
OrgID: o.ID,
Permissions: platform.OperPermissions(),
Permissions: perms,
}
if err = c.CreateAuthorization(ctx, auth); err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion bolt/onboarding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ func initOnboardingService(f platformtesting.OnboardingFields, t *testing.T) (pl
}
}

func TestGenerate(t *testing.T) {
func TestOnboardingService_Generate(t *testing.T) {
platformtesting.Generate(initOnboardingService, t)
}
15 changes: 14 additions & 1 deletion inmem/onboarding.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,24 @@ func (s *Service) Generate(ctx context.Context, req *platform.OnboardingRequest)
if err = s.CreateBucket(ctx, bucket); err != nil {
return nil, err
}

perms := platform.OperPermissions()
perms = append(perms, platform.OrgAdminPermissions(o.ID)...)
writeBucketPerm, err := platform.NewPermissionAtID(bucket.ID, platform.WriteAction, platform.BucketsResource)
if err != nil {
return nil, err
}
readBucketPerm, err := platform.NewPermissionAtID(bucket.ID, platform.ReadAction, platform.BucketsResource)
if err != nil {
return nil, err
}
perms = append(perms, *writeBucketPerm, *readBucketPerm)

auth := &platform.Authorization{
UserID: u.ID,
Description: fmt.Sprintf("%s's Token", u.Name),
OrgID: o.ID,
Permissions: platform.OperPermissions(),
Permissions: perms,
}
if err = s.CreateAuthorization(ctx, auth); err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion session.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (s *Session) Allowed(p Permission) bool {
return false
}

return allowed(p, s.Permissions)
return PermissionAllowed(p, s.Permissions)
}

// Kind returns session and is used for auditing.
Expand Down
2 changes: 1 addition & 1 deletion task/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func NewValidator(ts platform.TaskService, bs platform.BucketService) platform.T
}

func (ts *taskServiceValidator) CreateTask(ctx context.Context, t *platform.Task) error {
p, err := platform.NewPermissionAtID(t.ID, platform.WriteAction, platform.TasksResource)
p, err := platform.NewPermissionAtID(t.Organization, platform.WriteAction, platform.TasksResource)
if err != nil {
return err
}
Expand Down
18 changes: 17 additions & 1 deletion testing/onboarding.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func Generate(
UserID: MustIDBase16(oneID),
Description: "admin's Token",
OrgID: MustIDBase16(twoID),
Permissions: platform.OperPermissions(),
Permissions: mustGeneratePermissions(MustIDBase16(twoID), MustIDBase16(threeID)),
},
},
},
Expand Down Expand Up @@ -203,6 +203,22 @@ func Generate(

}

func mustGeneratePermissions(orgID, bucketID platform.ID) []platform.Permission {
perms := platform.OperPermissions()
perms = append(perms, platform.OrgAdminPermissions(orgID)...)
writeBucketPerm, err := platform.NewPermissionAtID(bucketID, platform.WriteAction, platform.BucketsResource)
if err != nil {
panic(err)
}
readBucketPerm, err := platform.NewPermissionAtID(bucketID, platform.ReadAction, platform.BucketsResource)
if err != nil {
panic(err)
}
perms = append(perms, *writeBucketPerm, *readBucketPerm)

return perms
}

const (
oneID = "020f755c3c082000"
twoID = "020f755c3c082001"
Expand Down
9 changes: 9 additions & 0 deletions user_resource_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ func (m *UserResourceMapping) ownerPerms() ([]Permission, error) {
}

ps = append(ps, *p)

if m.Resource == OrgsResource {
ps = append(ps, OrgAdminPermissions(m.ResourceID)...)
}

}

return ps, nil
Expand All @@ -111,6 +116,10 @@ func (m *UserResourceMapping) memberPerms() ([]Permission, error) {
}

ps = append(ps, *p)

if m.Resource == OrgsResource {
ps = append(ps, OrgMemberPermissions(m.ResourceID)...)
}
}

return ps, nil
Expand Down

0 comments on commit 394673c

Please sign in to comment.