2020-07-08 13:56:37 +02:00
|
|
|
package authz
|
2020-03-23 07:01:59 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
2025-04-15 19:38:25 +03:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
2023-12-08 16:30:55 +02:00
|
|
|
"github.com/zitadel/zitadel/internal/zerrors"
|
2020-03-23 07:01:59 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type TestRequest struct {
|
|
|
|
Test string
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_CheckUserPermissions(t *testing.T) {
|
|
|
|
type args struct {
|
|
|
|
req *TestRequest
|
|
|
|
perms []string
|
|
|
|
authOpt Option
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
args args
|
|
|
|
wantErr bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "no permissions",
|
|
|
|
args: args{
|
|
|
|
req: &TestRequest{},
|
|
|
|
perms: []string{},
|
|
|
|
},
|
|
|
|
wantErr: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "has permission and no context requested",
|
|
|
|
args: args{
|
|
|
|
req: &TestRequest{},
|
|
|
|
perms: []string{"project.read"},
|
|
|
|
authOpt: Option{CheckParam: ""},
|
|
|
|
},
|
|
|
|
wantErr: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "context requested and has global permission",
|
|
|
|
args: args{
|
|
|
|
req: &TestRequest{Test: "Test"},
|
|
|
|
perms: []string{"project.read", "project.read:1"},
|
|
|
|
authOpt: Option{CheckParam: "Test"},
|
|
|
|
},
|
|
|
|
wantErr: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "context requested and has specific permission",
|
|
|
|
args: args{
|
|
|
|
req: &TestRequest{Test: "Test"},
|
|
|
|
perms: []string{"project.read:Test"},
|
|
|
|
authOpt: Option{CheckParam: "Test"},
|
|
|
|
},
|
|
|
|
wantErr: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "context requested and has no permission",
|
|
|
|
args: args{
|
|
|
|
req: &TestRequest{Test: "Hodor"},
|
|
|
|
perms: []string{"project.read:Test"},
|
|
|
|
authOpt: Option{CheckParam: "Test"},
|
|
|
|
},
|
|
|
|
wantErr: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
err := checkUserPermissions(tt.args.req, tt.args.perms, tt.args.authOpt)
|
|
|
|
if tt.wantErr && err == nil {
|
|
|
|
t.Errorf("got wrong result, should get err: actual: %v ", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !tt.wantErr && err != nil {
|
|
|
|
t.Errorf("shouldn't get err: %v ", err)
|
|
|
|
}
|
|
|
|
|
2023-12-08 16:30:55 +02:00
|
|
|
if tt.wantErr && !zerrors.IsPermissionDenied(err) {
|
2020-03-23 07:01:59 +01:00
|
|
|
t.Errorf("got wrong err: %v ", err)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_SplitPermission(t *testing.T) {
|
|
|
|
type args struct {
|
|
|
|
perm string
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
args args
|
|
|
|
permName string
|
|
|
|
permCtxID string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "permission with context id",
|
|
|
|
args: args{
|
|
|
|
perm: "project.read:ctxID",
|
|
|
|
},
|
|
|
|
permName: "project.read",
|
|
|
|
permCtxID: "ctxID",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "permission without context id",
|
|
|
|
args: args{
|
|
|
|
perm: "project.read",
|
|
|
|
},
|
|
|
|
permName: "project.read",
|
|
|
|
permCtxID: "",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "permission to many parts",
|
|
|
|
args: args{
|
|
|
|
perm: "project.read:1:0",
|
|
|
|
},
|
|
|
|
permName: "project.read",
|
|
|
|
permCtxID: "1",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
name, id := SplitPermission(tt.args.perm)
|
|
|
|
if name != tt.permName {
|
|
|
|
t.Errorf("got wrong result on name, expecting: %v, actual: %v ", tt.permName, name)
|
|
|
|
}
|
|
|
|
if id != tt.permCtxID {
|
|
|
|
t.Errorf("got wrong result on id, expecting: %v, actual: %v ", tt.permCtxID, id)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_HasContextPermission(t *testing.T) {
|
|
|
|
type args struct {
|
|
|
|
req *TestRequest
|
|
|
|
fieldname string
|
|
|
|
perms []string
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
args args
|
|
|
|
result bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "existing context permission",
|
|
|
|
args: args{
|
|
|
|
req: &TestRequest{Test: "right"},
|
|
|
|
fieldname: "Test",
|
|
|
|
perms: []string{"test:wrong", "test:right"},
|
|
|
|
},
|
|
|
|
result: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "not existing context permission",
|
|
|
|
args: args{
|
|
|
|
req: &TestRequest{Test: "test"},
|
|
|
|
fieldname: "Test",
|
|
|
|
perms: []string{"test:wrong", "test:wrong2"},
|
|
|
|
},
|
|
|
|
result: false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
result := hasContextPermission(tt.args.req, tt.args.fieldname, tt.args.perms)
|
|
|
|
if result != tt.result {
|
|
|
|
t.Errorf("got wrong result, expecting: %v, actual: %v ", tt.result, result)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_GetFieldFromReq(t *testing.T) {
|
|
|
|
type args struct {
|
|
|
|
req *TestRequest
|
|
|
|
fieldname string
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
args args
|
|
|
|
result string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "existing field",
|
|
|
|
args: args{
|
|
|
|
req: &TestRequest{Test: "TestValue"},
|
|
|
|
fieldname: "Test",
|
|
|
|
},
|
|
|
|
result: "TestValue",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "not existing field",
|
|
|
|
args: args{
|
|
|
|
req: &TestRequest{Test: "TestValue"},
|
|
|
|
fieldname: "Test2",
|
|
|
|
},
|
|
|
|
result: "",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
result := getFieldFromReq(tt.args.req, tt.args.fieldname)
|
|
|
|
if result != tt.result {
|
|
|
|
t.Errorf("got wrong result, expecting: %v, actual: %v ", tt.result, result)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_HasGlobalPermission(t *testing.T) {
|
|
|
|
type args struct {
|
|
|
|
perms []string
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
args args
|
|
|
|
result bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "global perm existing",
|
|
|
|
args: args{
|
|
|
|
perms: []string{"perm:1", "perm:2", "perm"},
|
|
|
|
},
|
|
|
|
result: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "global perm not existing",
|
|
|
|
args: args{
|
|
|
|
perms: []string{"perm:1", "perm:2", "perm:3"},
|
|
|
|
},
|
|
|
|
result: false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
result := HasGlobalPermission(tt.args.perms)
|
|
|
|
if result != tt.result {
|
|
|
|
t.Errorf("got wrong result, expecting: %v, actual: %v ", tt.result, result)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_GetPermissionCtxIDs(t *testing.T) {
|
|
|
|
type args struct {
|
|
|
|
perms []string
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
args args
|
|
|
|
result []string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "no specific permission",
|
|
|
|
args: args{
|
|
|
|
perms: []string{"perm"},
|
|
|
|
},
|
|
|
|
result: []string{},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "ctx id",
|
|
|
|
args: args{
|
|
|
|
perms: []string{"perm:1", "perm", "perm:3"},
|
|
|
|
},
|
|
|
|
result: []string{"1", "3"},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2020-07-22 14:00:29 +02:00
|
|
|
result := GetAllPermissionCtxIDs(tt.args.perms)
|
2020-03-30 11:52:08 +02:00
|
|
|
if !equalStringArray(result, tt.result) {
|
2020-03-23 07:01:59 +01:00
|
|
|
t.Errorf("got wrong result, expecting: %v, actual: %v ", tt.result, result)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2025-04-15 19:38:25 +03:00
|
|
|
|
|
|
|
func Test_systemMembershipsToUserPermissions(t *testing.T) {
|
|
|
|
roleMap := []RoleMapping{
|
|
|
|
{
|
|
|
|
Role: "FOO_BAR",
|
|
|
|
Permissions: []string{"foo.bar.read", "foo.bar.write"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Role: "BAR_FOO",
|
|
|
|
Permissions: []string{"bar.foo.read", "bar.foo.write", "foo.bar.read"},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
type args struct {
|
|
|
|
memberships Memberships
|
|
|
|
roleMap []RoleMapping
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
args args
|
|
|
|
want []SystemUserPermissions
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "nil memberships",
|
|
|
|
args: args{
|
|
|
|
memberships: nil,
|
|
|
|
roleMap: roleMap,
|
|
|
|
},
|
|
|
|
want: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "empty memberships",
|
|
|
|
args: args{
|
|
|
|
memberships: Memberships{},
|
|
|
|
roleMap: roleMap,
|
|
|
|
},
|
|
|
|
want: []SystemUserPermissions{},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "single membership",
|
|
|
|
args: args{
|
|
|
|
memberships: Memberships{
|
|
|
|
{
|
|
|
|
MemberType: MemberTypeSystem,
|
|
|
|
AggregateID: "1",
|
|
|
|
ObjectID: "2",
|
|
|
|
Roles: []string{"FOO_BAR"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
roleMap: roleMap,
|
|
|
|
},
|
|
|
|
want: []SystemUserPermissions{
|
|
|
|
{
|
|
|
|
MemberType: MemberTypeSystem,
|
|
|
|
AggregateID: "1",
|
|
|
|
ObjectID: "2",
|
|
|
|
Permissions: []string{"foo.bar.read", "foo.bar.write"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "multiple memberships",
|
|
|
|
args: args{
|
|
|
|
memberships: Memberships{
|
|
|
|
{
|
|
|
|
MemberType: MemberTypeSystem,
|
|
|
|
AggregateID: "1",
|
|
|
|
ObjectID: "2",
|
|
|
|
Roles: []string{"FOO_BAR"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
MemberType: MemberTypeIAM,
|
|
|
|
AggregateID: "1",
|
|
|
|
ObjectID: "2",
|
|
|
|
Roles: []string{"BAR_FOO"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
roleMap: roleMap,
|
|
|
|
},
|
|
|
|
want: []SystemUserPermissions{
|
|
|
|
{
|
|
|
|
MemberType: MemberTypeSystem,
|
|
|
|
AggregateID: "1",
|
|
|
|
ObjectID: "2",
|
|
|
|
Permissions: []string{"foo.bar.read", "foo.bar.write"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
MemberType: MemberTypeIAM,
|
|
|
|
AggregateID: "1",
|
|
|
|
ObjectID: "2",
|
|
|
|
Permissions: []string{"bar.foo.read", "bar.foo.write", "foo.bar.read"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "multiple roles",
|
|
|
|
args: args{
|
|
|
|
memberships: Memberships{
|
|
|
|
{
|
|
|
|
MemberType: MemberTypeSystem,
|
|
|
|
AggregateID: "1",
|
|
|
|
ObjectID: "2",
|
|
|
|
Roles: []string{"FOO_BAR", "BAR_FOO"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
roleMap: roleMap,
|
|
|
|
},
|
|
|
|
want: []SystemUserPermissions{
|
|
|
|
{
|
|
|
|
MemberType: MemberTypeSystem,
|
|
|
|
AggregateID: "1",
|
|
|
|
ObjectID: "2",
|
|
|
|
Permissions: []string{"bar.foo.read", "bar.foo.write", "foo.bar.read", "foo.bar.write"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
got := systemMembershipsToUserPermissions(tt.args.memberships, tt.args.roleMap)
|
|
|
|
assert.Equal(t, tt.want, got)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|