mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-04 23:45:07 +00:00
fix: internal grant view (#239)
* fix: internal grant view * feat: add orgiam policy in management * fix: roleSuffix
This commit is contained in:
parent
5e39a5f813
commit
add4c103cf
@ -150,11 +150,11 @@ func (u *UserGrant) processProject(event *models.Event) (err error) {
|
||||
case proj_es_model.ProjectMemberAdded, proj_es_model.ProjectMemberChanged, proj_es_model.ProjectMemberRemoved:
|
||||
member := new(proj_es_model.ProjectMember)
|
||||
member.SetData(event)
|
||||
return u.processMember(event, "PROJECT", true, member.UserID, member.Roles)
|
||||
return u.processMember(event, "PROJECT", event.AggregateID, member.UserID, member.Roles)
|
||||
case proj_es_model.ProjectGrantMemberAdded, proj_es_model.ProjectGrantMemberChanged, proj_es_model.ProjectGrantMemberRemoved:
|
||||
member := new(proj_es_model.ProjectGrantMember)
|
||||
member.SetData(event)
|
||||
return u.processMember(event, "PROJECT_GRANT", true, member.UserID, member.Roles)
|
||||
return u.processMember(event, "PROJECT_GRANT", member.GrantID, member.UserID, member.Roles)
|
||||
default:
|
||||
return u.view.ProcessedUserGrantSequence(event.Sequence)
|
||||
}
|
||||
@ -166,7 +166,7 @@ func (u *UserGrant) processOrg(event *models.Event) (err error) {
|
||||
case org_es_model.OrgMemberAdded, org_es_model.OrgMemberChanged, org_es_model.OrgMemberRemoved:
|
||||
member := new(org_es_model.OrgMember)
|
||||
member.SetData(event)
|
||||
return u.processMember(event, "ORG", false, member.UserID, member.Roles)
|
||||
return u.processMember(event, "ORG", "", member.UserID, member.Roles)
|
||||
default:
|
||||
return u.view.ProcessedUserGrantSequence(event.Sequence)
|
||||
}
|
||||
@ -200,7 +200,7 @@ func (u *UserGrant) processIamMember(event *models.Event, rolePrefix string, suf
|
||||
} else {
|
||||
newRoles := member.Roles
|
||||
if grant.RoleKeys != nil {
|
||||
grant.RoleKeys = mergeExistingRoles(rolePrefix, grant.RoleKeys, newRoles)
|
||||
grant.RoleKeys = mergeExistingRoles(rolePrefix, "", grant.RoleKeys, newRoles)
|
||||
} else {
|
||||
grant.RoleKeys = newRoles
|
||||
}
|
||||
@ -221,7 +221,7 @@ func (u *UserGrant) processIamMember(event *models.Event, rolePrefix string, suf
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UserGrant) processMember(event *models.Event, rolePrefix string, suffix bool, userID string, roleKeys []string) error {
|
||||
func (u *UserGrant) processMember(event *models.Event, rolePrefix, roleSuffix string, userID string, roleKeys []string) error {
|
||||
switch event.Type {
|
||||
case org_es_model.OrgMemberAdded, proj_es_model.ProjectMemberAdded, proj_es_model.ProjectGrantMemberAdded,
|
||||
org_es_model.OrgMemberChanged, proj_es_model.ProjectMemberChanged, proj_es_model.ProjectGrantMemberChanged:
|
||||
@ -230,7 +230,7 @@ func (u *UserGrant) processMember(event *models.Event, rolePrefix string, suffix
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
if suffix {
|
||||
if roleSuffix != "" {
|
||||
roleKeys = suffixRoles(event.AggregateID, roleKeys)
|
||||
}
|
||||
if errors.IsNotFound(err) {
|
||||
@ -246,7 +246,7 @@ func (u *UserGrant) processMember(event *models.Event, rolePrefix string, suffix
|
||||
} else {
|
||||
newRoles := roleKeys
|
||||
if grant.RoleKeys != nil {
|
||||
grant.RoleKeys = mergeExistingRoles(rolePrefix, grant.RoleKeys, newRoles)
|
||||
grant.RoleKeys = mergeExistingRoles(rolePrefix, roleSuffix, grant.RoleKeys, newRoles)
|
||||
} else {
|
||||
grant.RoleKeys = newRoles
|
||||
}
|
||||
@ -276,11 +276,15 @@ func suffixRoles(suffix string, roles []string) []string {
|
||||
return suffixedRoles
|
||||
}
|
||||
|
||||
func mergeExistingRoles(rolePrefix string, existingRoles, newRoles []string) []string {
|
||||
func mergeExistingRoles(rolePrefix, suffix string, existingRoles, newRoles []string) []string {
|
||||
mergedRoles := make([]string, 0)
|
||||
for _, existing := range existingRoles {
|
||||
if !strings.HasPrefix(existing, rolePrefix) {
|
||||
mergedRoles = append(mergedRoles, existing)
|
||||
continue
|
||||
}
|
||||
if suffix != "" && !strings.HasSuffix(existing, suffix) {
|
||||
mergedRoles = append(mergedRoles, existing)
|
||||
}
|
||||
}
|
||||
return append(mergedRoles, newRoles...)
|
||||
|
@ -69,11 +69,11 @@ func (u *UserGrant) processProject(event *models.Event) (err error) {
|
||||
case proj_es_model.ProjectMemberAdded, proj_es_model.ProjectMemberChanged, proj_es_model.ProjectMemberRemoved:
|
||||
member := new(proj_es_model.ProjectMember)
|
||||
member.SetData(event)
|
||||
return u.processMember(event, "PROJECT", true, member.UserID, member.Roles)
|
||||
return u.processMember(event, "PROJECT", event.AggregateID, member.UserID, member.Roles)
|
||||
case proj_es_model.ProjectGrantMemberAdded, proj_es_model.ProjectGrantMemberChanged, proj_es_model.ProjectGrantMemberRemoved:
|
||||
member := new(proj_es_model.ProjectGrantMember)
|
||||
member.SetData(event)
|
||||
return u.processMember(event, "PROJECT_GRANT", true, member.UserID, member.Roles)
|
||||
return u.processMember(event, "PROJECT_GRANT", member.GrantID, member.UserID, member.Roles)
|
||||
default:
|
||||
return u.view.ProcessedUserGrantSequence(event.Sequence)
|
||||
}
|
||||
@ -85,7 +85,7 @@ func (u *UserGrant) processOrg(event *models.Event) (err error) {
|
||||
case org_es_model.OrgMemberAdded, org_es_model.OrgMemberChanged, org_es_model.OrgMemberRemoved:
|
||||
member := new(org_es_model.OrgMember)
|
||||
member.SetData(event)
|
||||
return u.processMember(event, "ORG", false, member.UserID, member.Roles)
|
||||
return u.processMember(event, "ORG", "", member.UserID, member.Roles)
|
||||
default:
|
||||
return u.view.ProcessedUserGrantSequence(event.Sequence)
|
||||
}
|
||||
@ -119,7 +119,7 @@ func (u *UserGrant) processIamMember(event *models.Event, rolePrefix string, suf
|
||||
} else {
|
||||
newRoles := member.Roles
|
||||
if grant.RoleKeys != nil {
|
||||
grant.RoleKeys = mergeExistingRoles(rolePrefix, grant.RoleKeys, newRoles)
|
||||
grant.RoleKeys = mergeExistingRoles(rolePrefix, "", grant.RoleKeys, newRoles)
|
||||
} else {
|
||||
grant.RoleKeys = newRoles
|
||||
}
|
||||
@ -140,7 +140,7 @@ func (u *UserGrant) processIamMember(event *models.Event, rolePrefix string, suf
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UserGrant) processMember(event *models.Event, rolePrefix string, suffix bool, userID string, roleKeys []string) error {
|
||||
func (u *UserGrant) processMember(event *models.Event, rolePrefix, roleSuffix string, userID string, roleKeys []string) error {
|
||||
switch event.Type {
|
||||
case org_es_model.OrgMemberAdded, proj_es_model.ProjectMemberAdded, proj_es_model.ProjectGrantMemberAdded,
|
||||
org_es_model.OrgMemberChanged, proj_es_model.ProjectMemberChanged, proj_es_model.ProjectGrantMemberChanged:
|
||||
@ -149,7 +149,7 @@ func (u *UserGrant) processMember(event *models.Event, rolePrefix string, suffix
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
if suffix {
|
||||
if roleSuffix != "" {
|
||||
roleKeys = suffixRoles(event.AggregateID, roleKeys)
|
||||
}
|
||||
if errors.IsNotFound(err) {
|
||||
@ -164,7 +164,7 @@ func (u *UserGrant) processMember(event *models.Event, rolePrefix string, suffix
|
||||
} else {
|
||||
newRoles := roleKeys
|
||||
if grant.RoleKeys != nil {
|
||||
grant.RoleKeys = mergeExistingRoles(rolePrefix, grant.RoleKeys, newRoles)
|
||||
grant.RoleKeys = mergeExistingRoles(rolePrefix, roleSuffix, grant.RoleKeys, newRoles)
|
||||
} else {
|
||||
grant.RoleKeys = newRoles
|
||||
}
|
||||
@ -194,11 +194,15 @@ func suffixRoles(suffix string, roles []string) []string {
|
||||
return suffixedRoles
|
||||
}
|
||||
|
||||
func mergeExistingRoles(rolePrefix string, existingRoles, newRoles []string) []string {
|
||||
func mergeExistingRoles(rolePrefix, suffix string, existingRoles, newRoles []string) []string {
|
||||
mergedRoles := make([]string, 0)
|
||||
for _, existing := range existingRoles {
|
||||
if !strings.HasPrefix(existing, rolePrefix) {
|
||||
mergedRoles = append(mergedRoles, existing)
|
||||
continue
|
||||
}
|
||||
if suffix != "" && !strings.HasSuffix(existing, suffix) {
|
||||
mergedRoles = append(mergedRoles, existing)
|
||||
}
|
||||
}
|
||||
return append(mergedRoles, newRoles...)
|
||||
|
@ -45,6 +45,10 @@ func (repo *OrgRepository) ReactivateOrg(ctx context.Context, id string) (*org_m
|
||||
return repo.OrgEventstore.ReactivateOrg(ctx, id)
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) GetMyOrgIamPolicy(ctx context.Context) (*org_model.OrgIamPolicy, error) {
|
||||
return repo.OrgEventstore.GetOrgIamPolicy(ctx, auth.GetCtxData(ctx).OrgID)
|
||||
}
|
||||
|
||||
func (repo *OrgRepository) SearchMyOrgDomains(ctx context.Context, request *org_model.OrgDomainSearchRequest) (*org_model.OrgDomainSearchResponse, error) {
|
||||
request.EnsureLimit(repo.SearchLimit)
|
||||
request.Queries = append(request.Queries, &org_model.OrgDomainSearchQuery{Key: org_model.ORGDOMAINSEARCHKEY_ORG_ID, Method: global_model.SEARCHMETHOD_EQUALS, Value: auth.GetCtxData(ctx).OrgID})
|
||||
|
@ -24,4 +24,6 @@ type OrgRepository interface {
|
||||
RemoveMyOrgMember(ctx context.Context, userID string) error
|
||||
|
||||
GetOrgMemberRoles() []string
|
||||
|
||||
GetMyOrgIamPolicy(ctx context.Context) (*org_model.OrgIamPolicy, error)
|
||||
}
|
||||
|
@ -250,6 +250,11 @@ var ManagementService_AuthMethods = utils_auth.MethodMapping{
|
||||
CheckParam: "",
|
||||
},
|
||||
|
||||
"/caos.zitadel.management.api.v1.ManagementService/GetMyOrgIamPolicy": utils_auth.Option{
|
||||
Permission: "authenticated",
|
||||
CheckParam: "",
|
||||
},
|
||||
|
||||
"/caos.zitadel.management.api.v1.ManagementService/GetOrgMemberRoles": utils_auth.Option{
|
||||
Permission: "org.member.read",
|
||||
CheckParam: "",
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -302,6 +302,23 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/orgs/me/iampolicy": {
|
||||
"get": {
|
||||
"summary": "ORG_IAM_POLICY",
|
||||
"operationId": "GetMyOrgIamPolicy",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1OrgIamPolicy"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"ManagementService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/orgs/me/members": {
|
||||
"post": {
|
||||
"operationId": "AddMyOrgMember",
|
||||
@ -3475,7 +3492,7 @@
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"type": "object"
|
||||
"$ref": "#/definitions/protobufStruct"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3486,6 +3503,19 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"protobufListValue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"values": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/protobufValue"
|
||||
},
|
||||
"description": "Repeated field of dynamically typed values."
|
||||
}
|
||||
},
|
||||
"description": "`ListValue` is a wrapper around a repeated field of values.\n\nThe JSON representation for `ListValue` is JSON array."
|
||||
},
|
||||
"protobufNullValue": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@ -3494,6 +3524,51 @@
|
||||
"default": "NULL_VALUE",
|
||||
"description": "`NullValue` is a singleton enumeration to represent the null value for the\n`Value` type union.\n\n The JSON representation for `NullValue` is JSON `null`.\n\n - NULL_VALUE: Null value."
|
||||
},
|
||||
"protobufStruct": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fields": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/protobufValue"
|
||||
},
|
||||
"description": "Unordered map of dynamically typed values."
|
||||
}
|
||||
},
|
||||
"description": "`Struct` represents a structured data value, consisting of fields\nwhich map to dynamically typed values. In some languages, `Struct`\nmight be supported by a native representation. For example, in\nscripting languages like JS a struct is represented as an\nobject. The details of that representation are described together\nwith the proto support for the language.\n\nThe JSON representation for `Struct` is JSON object."
|
||||
},
|
||||
"protobufValue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"null_value": {
|
||||
"$ref": "#/definitions/protobufNullValue",
|
||||
"description": "Represents a null value."
|
||||
},
|
||||
"number_value": {
|
||||
"type": "number",
|
||||
"format": "double",
|
||||
"description": "Represents a double value."
|
||||
},
|
||||
"string_value": {
|
||||
"type": "string",
|
||||
"description": "Represents a string value."
|
||||
},
|
||||
"bool_value": {
|
||||
"type": "boolean",
|
||||
"format": "boolean",
|
||||
"description": "Represents a boolean value."
|
||||
},
|
||||
"struct_value": {
|
||||
"$ref": "#/definitions/protobufStruct",
|
||||
"description": "Represents a structured value."
|
||||
},
|
||||
"list_value": {
|
||||
"$ref": "#/definitions/protobufListValue",
|
||||
"description": "Represents a repeated `Value`."
|
||||
}
|
||||
},
|
||||
"description": "`Value` represents a dynamically typed value which can be either\nnull, a number, a string, a boolean, a recursive struct value, or a\nlist of values. A producer of value is expected to set one of that\nvariants, absence of any variant indicates an error.\n\nThe JSON representation for `Value` is JSON value."
|
||||
},
|
||||
"v1AddOrgDomainRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -3786,7 +3861,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"type": "object"
|
||||
"$ref": "#/definitions/protobufStruct"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -4302,6 +4377,25 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1OrgIamPolicy": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"org_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_login_must_be_domain": {
|
||||
"type": "boolean",
|
||||
"format": "boolean"
|
||||
},
|
||||
"default": {
|
||||
"type": "boolean",
|
||||
"format": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1OrgMember": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -777,6 +777,26 @@ func (mr *MockManagementServiceClientMockRecorder) GetIam(arg0, arg1 interface{}
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIam", reflect.TypeOf((*MockManagementServiceClient)(nil).GetIam), varargs...)
|
||||
}
|
||||
|
||||
// GetMyOrgIamPolicy mocks base method
|
||||
func (m *MockManagementServiceClient) GetMyOrgIamPolicy(arg0 context.Context, arg1 *emptypb.Empty, arg2 ...grpc0.CallOption) (*grpc.OrgIamPolicy, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{arg0, arg1}
|
||||
for _, a := range arg2 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "GetMyOrgIamPolicy", varargs...)
|
||||
ret0, _ := ret[0].(*grpc.OrgIamPolicy)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetMyOrgIamPolicy indicates an expected call of GetMyOrgIamPolicy
|
||||
func (mr *MockManagementServiceClientMockRecorder) GetMyOrgIamPolicy(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]interface{}{arg0, arg1}, arg2...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMyOrgIamPolicy", reflect.TypeOf((*MockManagementServiceClient)(nil).GetMyOrgIamPolicy), varargs...)
|
||||
}
|
||||
|
||||
// GetOrgByDomainGlobal mocks base method
|
||||
func (m *MockManagementServiceClient) GetOrgByDomainGlobal(arg0 context.Context, arg1 *grpc.OrgDomain, arg2 ...grpc0.CallOption) (*grpc.Org, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -65,3 +65,11 @@ func (s *Server) OrgChanges(ctx context.Context, changesRequest *ChangeRequest)
|
||||
}
|
||||
return orgChangesToResponse(response, changesRequest.GetSequenceOffset(), changesRequest.GetLimit()), nil
|
||||
}
|
||||
|
||||
func (s *Server) GetMyOrgIamPolicy(ctx context.Context, _ *empty.Empty) (_ *OrgIamPolicy, err error) {
|
||||
policy, err := s.org.GetMyOrgIamPolicy(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return orgIamPolicyFromModel(policy), err
|
||||
}
|
||||
|
@ -179,3 +179,12 @@ func orgChangesToMgtAPI(changes *org_model.OrgChanges) (_ []*Change) {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func orgIamPolicyFromModel(policy *org_model.OrgIamPolicy) *OrgIamPolicy {
|
||||
return &OrgIamPolicy{
|
||||
OrgId: policy.AggregateID,
|
||||
Description: policy.Description,
|
||||
UserLoginMustBeDomain: policy.UserLoginMustBeDomain,
|
||||
Default: policy.Default,
|
||||
}
|
||||
}
|
||||
|
@ -560,6 +560,17 @@ service ManagementService {
|
||||
};
|
||||
}
|
||||
|
||||
//ORG_IAM_POLICY
|
||||
rpc GetMyOrgIamPolicy(google.protobuf.Empty) returns (OrgIamPolicy) {
|
||||
option (google.api.http) = {
|
||||
get: "/orgs/me/iampolicy"
|
||||
};
|
||||
|
||||
option (caos.zitadel.utils.v1.auth_option) = {
|
||||
permission: "authenticated"
|
||||
};
|
||||
}
|
||||
|
||||
//ORG_MEMBERS
|
||||
rpc GetOrgMemberRoles(google.protobuf.Empty) returns (OrgMemberRoles) {
|
||||
option (google.api.http) = {
|
||||
@ -1730,6 +1741,13 @@ enum PolicyState {
|
||||
POLICYSTATE_DELETED = 3;
|
||||
}
|
||||
|
||||
message OrgIamPolicy {
|
||||
string org_id = 1;
|
||||
string description = 2;
|
||||
bool user_login_must_be_domain = 3;
|
||||
bool default = 4;
|
||||
}
|
||||
|
||||
message OrgID {
|
||||
string id = 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user