feat: add SYSTEM_OWNER role (#6765)

* define roles and permissions

* support system user memberships

* don't limit system users

* cleanup permissions

* restrict memberships to aggregates

* default to SYSTEM_OWNER

* update unit tests

* test: system user token test (#6778)

* update unit tests

* refactor: make authz testable

* move session constants

* cleanup

* comment

* comment

* decode member type string to enum (#6780)

* decode member type string to enum

* handle all membership types

* decode enums where necessary

* decode member type in steps config

* update system api docs

* add technical advisory

* tweak docs a bit

* comment in comment

* lint

* extract token from Bearer header prefix

* review changes

* fix tests

* fix: add fix for activityhandler

* add isSystemUser

* remove IsSystemUser from activity info

* fix: add fix for activityhandler

---------

Co-authored-by: Stefan Benz <stefan@caos.ch>
This commit is contained in:
Elio Bischof
2023-10-25 17:10:45 +02:00
committed by GitHub
parent c8b9b0ac75
commit 4980cd6a0c
34 changed files with 959 additions and 410 deletions

View File

@@ -7,33 +7,6 @@ import (
caos_errs "github.com/zitadel/zitadel/internal/errors"
)
func getTestCtx(userID, orgID string) context.Context {
return context.WithValue(context.Background(), dataKey, CtxData{UserID: userID, OrgID: orgID})
}
type testVerifier struct {
memberships []*Membership
}
func (v *testVerifier) VerifyAccessToken(ctx context.Context, token, clientID, projectID string) (string, string, string, string, string, error) {
return "userID", "agentID", "clientID", "de", "orgID", nil
}
func (v *testVerifier) SearchMyMemberships(ctx context.Context, orgID string, _ bool) ([]*Membership, error) {
return v.memberships, nil
}
func (v *testVerifier) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (string, []string, error) {
return "", nil, nil
}
func (v *testVerifier) ExistsOrg(ctx context.Context, orgID, domain string) (string, error) {
return orgID, nil
}
func (v *testVerifier) VerifierClientID(ctx context.Context, appName string) (string, string, error) {
return "clientID", "projectID", nil
}
func equalStringArray(a, b []string) bool {
if len(a) != len(b) {
return false
@@ -46,12 +19,18 @@ func equalStringArray(a, b []string) bool {
return true
}
type membershipsResolverFunc func(ctx context.Context, orgID string, shouldTriggerBulk bool) ([]*Membership, error)
func (m membershipsResolverFunc) SearchMyMemberships(ctx context.Context, orgID string, shouldTriggerBulk bool) ([]*Membership, error) {
return m(ctx, orgID, shouldTriggerBulk)
}
func Test_GetUserPermissions(t *testing.T) {
type args struct {
ctxData CtxData
verifier *TokenVerifier
requiredPerm string
authConfig Config
ctxData CtxData
membershipsResolver MembershipsResolver
requiredPerm string
authConfig Config
}
tests := []struct {
name string
@@ -64,11 +43,9 @@ func Test_GetUserPermissions(t *testing.T) {
name: "Empty Context",
args: args{
ctxData: CtxData{},
verifier: Start(&testVerifier{memberships: []*Membership{
{
Roles: []string{"ORG_OWNER"},
},
}}, "", nil),
membershipsResolver: membershipsResolverFunc(func(ctx context.Context, orgID string, shouldTriggerBulk bool) ([]*Membership, error) {
return []*Membership{{Roles: []string{"ORG_OWNER"}}}, nil
}),
requiredPerm: "project.read",
authConfig: Config{
RolePermissionMappings: []RoleMapping{
@@ -90,8 +67,10 @@ func Test_GetUserPermissions(t *testing.T) {
{
name: "No Grants",
args: args{
ctxData: CtxData{},
verifier: Start(&testVerifier{memberships: []*Membership{}}, "", nil),
ctxData: CtxData{},
membershipsResolver: membershipsResolverFunc(func(ctx context.Context, orgID string, shouldTriggerBulk bool) ([]*Membership, error) {
return []*Membership{}, nil
}),
requiredPerm: "project.read",
authConfig: Config{
RolePermissionMappings: []RoleMapping{
@@ -112,14 +91,16 @@ func Test_GetUserPermissions(t *testing.T) {
name: "Get Permissions",
args: args{
ctxData: CtxData{UserID: "userID", OrgID: "orgID"},
verifier: Start(&testVerifier{memberships: []*Membership{
{
AggregateID: "IAM",
ObjectID: "IAM",
MemberType: MemberTypeIam,
Roles: []string{"IAM_OWNER"},
},
}}, "", nil),
membershipsResolver: membershipsResolverFunc(func(ctx context.Context, orgID string, shouldTriggerBulk bool) ([]*Membership, error) {
return []*Membership{
{
AggregateID: "IAM",
ObjectID: "IAM",
MemberType: MemberTypeIAM,
Roles: []string{"IAM_OWNER"},
},
}, nil
}),
requiredPerm: "project.read",
authConfig: Config{
RolePermissionMappings: []RoleMapping{
@@ -139,7 +120,7 @@ func Test_GetUserPermissions(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, perms, err := getUserPermissions(context.Background(), tt.args.verifier, tt.args.requiredPerm, tt.args.authConfig.RolePermissionMappings, tt.args.ctxData, tt.args.ctxData.OrgID)
_, perms, err := getUserPermissions(context.Background(), tt.args.membershipsResolver, tt.args.requiredPerm, tt.args.authConfig.RolePermissionMappings, tt.args.ctxData, tt.args.ctxData.OrgID)
if tt.wantErr && err == nil {
t.Errorf("got wrong result, should get err: actual: %v ", err)
@@ -176,7 +157,7 @@ func Test_MapMembershipToPermissions(t *testing.T) {
{
AggregateID: "1",
ObjectID: "1",
MemberType: MemberTypeOrganisation,
MemberType: MemberTypeOrganization,
Roles: []string{"ORG_OWNER"},
},
},
@@ -204,7 +185,7 @@ func Test_MapMembershipToPermissions(t *testing.T) {
{
AggregateID: "1",
ObjectID: "1",
MemberType: MemberTypeOrganisation,
MemberType: MemberTypeOrganization,
Roles: []string{"ORG_OWNER"},
},
},
@@ -232,13 +213,13 @@ func Test_MapMembershipToPermissions(t *testing.T) {
{
AggregateID: "1",
ObjectID: "1",
MemberType: MemberTypeOrganisation,
MemberType: MemberTypeOrganization,
Roles: []string{"ORG_OWNER"},
},
{
AggregateID: "IAM",
ObjectID: "IAM",
MemberType: MemberTypeIam,
MemberType: MemberTypeIAM,
Roles: []string{"IAM_OWNER"},
},
},
@@ -266,7 +247,7 @@ func Test_MapMembershipToPermissions(t *testing.T) {
{
AggregateID: "2",
ObjectID: "2",
MemberType: MemberTypeOrganisation,
MemberType: MemberTypeOrganization,
Roles: []string{"ORG_OWNER"},
},
{
@@ -327,7 +308,7 @@ func Test_MapMembershipToPerm(t *testing.T) {
membership: &Membership{
AggregateID: "Org",
ObjectID: "Org",
MemberType: MemberTypeOrganisation,
MemberType: MemberTypeOrganization,
Roles: []string{"ORG_OWNER"},
},
authConfig: Config{
@@ -355,7 +336,7 @@ func Test_MapMembershipToPerm(t *testing.T) {
membership: &Membership{
AggregateID: "Org",
ObjectID: "Org",
MemberType: MemberTypeOrganisation,
MemberType: MemberTypeOrganization,
Roles: []string{"ORG_OWNER"},
},
authConfig: Config{