mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-23 09:08:02 +00:00
feat(api): move internal permission service to GA (and deprecate v2beta) (#10898)
# Which Problems Are Solved
As part of our efforts to simplify the structure and versions of our
APIs, were moving all existing v2beta endpoints to v2 and deprecate
them. They will be removed in Zitadel V5.
# How the Problems Are Solved
- This PR moves the internal permission v2beta service and its endpoints
to a corresponding v2 version. The v2beta service and endpoints are
deprecated.
- The docs are moved to the new GA service and its endpoints. The v2beta
is not displayed anymore.
- The comments and have been improved and, where not already done, moved
from swagger annotations to proto.
- All required fields have been marked with (google.api.field_behavior)
= REQUIRED and validation rules have been added where missing.
- Listing administrators of a project grant can now be done with the
`ProjectGrant` (`project_id` and `organization_id`) instead of a
`project_id`, which corresponds to creation of the administrator ship of
such grant.
- formatted using `buf`
# Additional Changes
None
# Additional Context
- part of https://github.com/zitadel/zitadel/issues/10772
- requires backport to v4.x
---------
Co-authored-by: Gayathri Vijayan <66356931+grvijayan@users.noreply.github.com>
(cherry picked from commit 0f2a349ec1)
This commit is contained in:
@@ -45,6 +45,7 @@ import (
|
||||
feature_v2beta "github.com/zitadel/zitadel/internal/api/grpc/feature/v2beta"
|
||||
idp_v2 "github.com/zitadel/zitadel/internal/api/grpc/idp/v2"
|
||||
instance "github.com/zitadel/zitadel/internal/api/grpc/instance/v2beta"
|
||||
internal_permission_v2 "github.com/zitadel/zitadel/internal/api/grpc/internal_permission/v2"
|
||||
internal_permission_v2beta "github.com/zitadel/zitadel/internal/api/grpc/internal_permission/v2beta"
|
||||
"github.com/zitadel/zitadel/internal/api/grpc/management"
|
||||
oidc_v2 "github.com/zitadel/zitadel/internal/api/grpc/oidc/v2"
|
||||
@@ -535,6 +536,9 @@ func startAPIs(
|
||||
if err := apis.RegisterService(ctx, internal_permission_v2beta.CreateServer(config.SystemDefaults, commands, queries, permissionCheck)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := apis.RegisterService(ctx, internal_permission_v2.CreateServer(config.SystemDefaults, commands, queries, permissionCheck)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := apis.RegisterService(ctx, userschema_v3_alpha.CreateServer(config.SystemDefaults, commands, queries)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ module.exports = {
|
||||
},
|
||||
internal_permission_v2: {
|
||||
specPath:
|
||||
".artifacts/openapi3/zitadel/internal_permission/v2beta/internal_permission_service.openapi.yaml",
|
||||
".artifacts/openapi3/zitadel/internal_permission/v2/internal_permission_service.openapi.yaml",
|
||||
outputDir: "docs/apis/resources/internal_permission_service_v2",
|
||||
sidebarOptions: {
|
||||
groupPathsBy: "tag",
|
||||
|
||||
@@ -890,15 +890,13 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Internal Permissions (Beta)",
|
||||
label: "Internal Permissions",
|
||||
link: {
|
||||
type: "generated-index",
|
||||
title: "Internal Permission Service API (Beta)",
|
||||
title: "Internal Permission Service API",
|
||||
slug: "/apis/resources/internal_permission_service_v2",
|
||||
description:
|
||||
"This API is intended to manage internal permissions in ZITADEL.\n" +
|
||||
"\n" +
|
||||
"This API is in beta state. It can AND will continue breaking until a stable version is released.\n"
|
||||
"This API provides methods to manage permissions for resource and and their management in ZITADEL itself also known as \"administrators\"."
|
||||
},
|
||||
items: sidebar_api_internal_permission_service_v2,
|
||||
},
|
||||
|
||||
220
internal/api/grpc/internal_permission/v2/administrator.go
Normal file
220
internal/api/grpc/internal_permission/v2/administrator.go
Normal file
@@ -0,0 +1,220 @@
|
||||
package internal_permission
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/internal_permission/v2"
|
||||
)
|
||||
|
||||
func (s *Server) CreateAdministrator(ctx context.Context, req *connect.Request[internal_permission.CreateAdministratorRequest]) (*connect.Response[internal_permission.CreateAdministratorResponse], error) {
|
||||
var creationDate *timestamppb.Timestamp
|
||||
|
||||
switch resource := req.Msg.GetResource().GetResource().(type) {
|
||||
case *internal_permission.ResourceType_Instance:
|
||||
if resource.Instance {
|
||||
member, err := s.command.AddInstanceMember(ctx, createAdministratorInstanceToCommand(authz.GetInstance(ctx).InstanceID(), req.Msg.UserId, req.Msg.Roles))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
creationDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
}
|
||||
case *internal_permission.ResourceType_OrganizationId:
|
||||
member, err := s.command.AddOrgMember(ctx, createAdministratorOrganizationToCommand(resource, req.Msg.UserId, req.Msg.Roles))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
creationDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
case *internal_permission.ResourceType_ProjectId:
|
||||
member, err := s.command.AddProjectMember(ctx, createAdministratorProjectToCommand(resource, req.Msg.UserId, req.Msg.Roles))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
creationDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
case *internal_permission.ResourceType_ProjectGrant_:
|
||||
member, err := s.command.AddProjectGrantMember(ctx, createAdministratorProjectGrantToCommand(resource, req.Msg.UserId, req.Msg.Roles))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
creationDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
default:
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "ADMIN-IbPp47HDP5", "Errors.Invalid.Argument")
|
||||
}
|
||||
|
||||
return connect.NewResponse(&internal_permission.CreateAdministratorResponse{
|
||||
CreationDate: creationDate,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func createAdministratorInstanceToCommand(instanceID, userID string, roles []string) *command.AddInstanceMember {
|
||||
return &command.AddInstanceMember{
|
||||
InstanceID: instanceID,
|
||||
UserID: userID,
|
||||
Roles: roles,
|
||||
}
|
||||
}
|
||||
|
||||
func createAdministratorOrganizationToCommand(req *internal_permission.ResourceType_OrganizationId, userID string, roles []string) *command.AddOrgMember {
|
||||
return &command.AddOrgMember{
|
||||
OrgID: req.OrganizationId,
|
||||
UserID: userID,
|
||||
Roles: roles,
|
||||
}
|
||||
}
|
||||
|
||||
func createAdministratorProjectToCommand(req *internal_permission.ResourceType_ProjectId, userID string, roles []string) *command.AddProjectMember {
|
||||
return &command.AddProjectMember{
|
||||
ProjectID: req.ProjectId,
|
||||
UserID: userID,
|
||||
Roles: roles,
|
||||
}
|
||||
}
|
||||
|
||||
func createAdministratorProjectGrantToCommand(req *internal_permission.ResourceType_ProjectGrant_, userID string, roles []string) *command.AddProjectGrantMember {
|
||||
return &command.AddProjectGrantMember{
|
||||
OrganizationID: req.ProjectGrant.OrganizationId,
|
||||
ProjectID: req.ProjectGrant.ProjectId,
|
||||
UserID: userID,
|
||||
Roles: roles,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) UpdateAdministrator(ctx context.Context, req *connect.Request[internal_permission.UpdateAdministratorRequest]) (*connect.Response[internal_permission.UpdateAdministratorResponse], error) {
|
||||
var changeDate *timestamppb.Timestamp
|
||||
|
||||
switch resource := req.Msg.GetResource().GetResource().(type) {
|
||||
case *internal_permission.ResourceType_Instance:
|
||||
if resource.Instance {
|
||||
member, err := s.command.ChangeInstanceMember(ctx, updateAdministratorInstanceToCommand(authz.GetInstance(ctx).InstanceID(), req.Msg.UserId, req.Msg.Roles))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
changeDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
}
|
||||
case *internal_permission.ResourceType_OrganizationId:
|
||||
member, err := s.command.ChangeOrgMember(ctx, updateAdministratorOrganizationToCommand(resource, req.Msg.UserId, req.Msg.Roles))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
changeDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
case *internal_permission.ResourceType_ProjectId:
|
||||
member, err := s.command.ChangeProjectMember(ctx, updateAdministratorProjectToCommand(resource, req.Msg.UserId, req.Msg.Roles))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
changeDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
case *internal_permission.ResourceType_ProjectGrant_:
|
||||
member, err := s.command.ChangeProjectGrantMember(ctx, updateAdministratorProjectGrantToCommand(resource, req.Msg.UserId, req.Msg.Roles))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
changeDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
default:
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "ADMIN-i0V2IbdloZ", "Errors.Invalid.Argument")
|
||||
}
|
||||
|
||||
return connect.NewResponse(&internal_permission.UpdateAdministratorResponse{
|
||||
ChangeDate: changeDate,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func updateAdministratorInstanceToCommand(instanceID, userID string, roles []string) *command.ChangeInstanceMember {
|
||||
return &command.ChangeInstanceMember{
|
||||
InstanceID: instanceID,
|
||||
UserID: userID,
|
||||
Roles: roles,
|
||||
}
|
||||
}
|
||||
|
||||
func updateAdministratorOrganizationToCommand(req *internal_permission.ResourceType_OrganizationId, userID string, roles []string) *command.ChangeOrgMember {
|
||||
return &command.ChangeOrgMember{
|
||||
OrgID: req.OrganizationId,
|
||||
UserID: userID,
|
||||
Roles: roles,
|
||||
}
|
||||
}
|
||||
|
||||
func updateAdministratorProjectToCommand(req *internal_permission.ResourceType_ProjectId, userID string, roles []string) *command.ChangeProjectMember {
|
||||
return &command.ChangeProjectMember{
|
||||
ProjectID: req.ProjectId,
|
||||
UserID: userID,
|
||||
Roles: roles,
|
||||
}
|
||||
}
|
||||
|
||||
func updateAdministratorProjectGrantToCommand(req *internal_permission.ResourceType_ProjectGrant_, userID string, roles []string) *command.ChangeProjectGrantMember {
|
||||
return &command.ChangeProjectGrantMember{
|
||||
OrganizationID: req.ProjectGrant.OrganizationId,
|
||||
ProjectID: req.ProjectGrant.ProjectId,
|
||||
UserID: userID,
|
||||
Roles: roles,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) DeleteAdministrator(ctx context.Context, req *connect.Request[internal_permission.DeleteAdministratorRequest]) (*connect.Response[internal_permission.DeleteAdministratorResponse], error) {
|
||||
var deletionDate *timestamppb.Timestamp
|
||||
|
||||
switch resource := req.Msg.GetResource().GetResource().(type) {
|
||||
case *internal_permission.ResourceType_Instance:
|
||||
if resource.Instance {
|
||||
member, err := s.command.RemoveInstanceMember(ctx, authz.GetInstance(ctx).InstanceID(), req.Msg.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
deletionDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
}
|
||||
case *internal_permission.ResourceType_OrganizationId:
|
||||
member, err := s.command.RemoveOrgMember(ctx, resource.OrganizationId, req.Msg.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
deletionDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
case *internal_permission.ResourceType_ProjectId:
|
||||
member, err := s.command.RemoveProjectMember(ctx, resource.ProjectId, req.Msg.UserId, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
deletionDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
case *internal_permission.ResourceType_ProjectGrant_:
|
||||
member, err := s.command.RemoveProjectGrantMember(ctx, resource.ProjectGrant.ProjectId, req.Msg.UserId, "", resource.ProjectGrant.OrganizationId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !member.EventDate.IsZero() {
|
||||
deletionDate = timestamppb.New(member.EventDate)
|
||||
}
|
||||
default:
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "ADMIN-3UOjLtuohh", "Errors.Invalid.Argument")
|
||||
}
|
||||
|
||||
return connect.NewResponse(&internal_permission.DeleteAdministratorResponse{
|
||||
DeletionDate: deletionDate,
|
||||
}), nil
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
||||
//go:build integration
|
||||
|
||||
package project_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/muhlemmer/gu"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/feature/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
CTX context.Context
|
||||
instance *integration.Instance
|
||||
instanceQuery *integration.Instance
|
||||
instancePermissionV2 *integration.Instance
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(func() int {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
|
||||
defer cancel()
|
||||
CTX = ctx
|
||||
instance = integration.NewInstance(ctx)
|
||||
instanceQuery = integration.NewInstance(ctx) // create a separate one for queries to avoid side effects
|
||||
instancePermissionV2 = integration.NewInstance(CTX)
|
||||
return m.Run()
|
||||
}())
|
||||
}
|
||||
|
||||
func ensureFeaturePermissionV2Enabled(t *testing.T, instance *integration.Instance) {
|
||||
ctx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||
f, err := instance.Client.FeatureV2.GetInstanceFeatures(ctx, &feature.GetInstanceFeaturesRequest{
|
||||
Inheritance: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
if f.PermissionCheckV2.GetEnabled() {
|
||||
return
|
||||
}
|
||||
_, err = instance.Client.FeatureV2.SetInstanceFeatures(ctx, &feature.SetInstanceFeaturesRequest{
|
||||
PermissionCheckV2: gu.Ptr(true),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(ctx, 5*time.Minute)
|
||||
require.EventuallyWithT(t,
|
||||
func(ttt *assert.CollectT) {
|
||||
f, err := instance.Client.FeatureV2.GetInstanceFeatures(ctx, &feature.GetInstanceFeaturesRequest{
|
||||
Inheritance: true,
|
||||
})
|
||||
assert.NoError(ttt, err)
|
||||
if f.PermissionCheckV2.GetEnabled() {
|
||||
return
|
||||
}
|
||||
},
|
||||
retryDuration,
|
||||
tick,
|
||||
"timed out waiting for ensuring instance feature")
|
||||
}
|
||||
208
internal/api/grpc/internal_permission/v2/query.go
Normal file
208
internal/api/grpc/internal_permission/v2/query.go
Normal file
@@ -0,0 +1,208 @@
|
||||
package internal_permission
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/grpc/filter/v2"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
filter_pb "github.com/zitadel/zitadel/pkg/grpc/filter/v2"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/internal_permission/v2"
|
||||
)
|
||||
|
||||
func (s *Server) ListAdministrators(ctx context.Context, req *connect.Request[internal_permission.ListAdministratorsRequest]) (*connect.Response[internal_permission.ListAdministratorsResponse], error) {
|
||||
queries, err := s.listAdministratorsRequestToModel(req.Msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.query.SearchAdministrators(ctx, queries, s.checkPermission)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return connect.NewResponse(&internal_permission.ListAdministratorsResponse{
|
||||
Administrators: administratorsToPb(resp.Administrators),
|
||||
Pagination: filter.QueryToPaginationPb(queries.SearchRequest, resp.SearchResponse),
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *Server) listAdministratorsRequestToModel(req *internal_permission.ListAdministratorsRequest) (*query.MembershipSearchQuery, error) {
|
||||
offset, limit, asc, err := filter.PaginationPbToQuery(s.systemDefaults, req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
queries, err := administratorSearchFiltersToQuery(req.Filters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &query.MembershipSearchQuery{
|
||||
SearchRequest: query.SearchRequest{
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
Asc: asc,
|
||||
SortingColumn: administratorFieldNameToSortingColumn(req.GetSortingColumn()),
|
||||
},
|
||||
Queries: queries,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func administratorFieldNameToSortingColumn(field internal_permission.AdministratorFieldName) query.Column {
|
||||
switch field {
|
||||
case internal_permission.AdministratorFieldName_ADMINISTRATOR_FIELD_NAME_CREATION_DATE:
|
||||
return query.MembershipCreationDate
|
||||
case internal_permission.AdministratorFieldName_ADMINISTRATOR_FIELD_NAME_USER_ID:
|
||||
return query.MembershipUserID
|
||||
case internal_permission.AdministratorFieldName_ADMINISTRATOR_FIELD_NAME_CHANGE_DATE:
|
||||
return query.MembershipChangeDate
|
||||
case internal_permission.AdministratorFieldName_ADMINISTRATOR_FIELD_NAME_UNSPECIFIED:
|
||||
return query.MembershipCreationDate
|
||||
default:
|
||||
return query.MembershipCreationDate
|
||||
}
|
||||
}
|
||||
|
||||
func administratorSearchFiltersToQuery(queries []*internal_permission.AdministratorSearchFilter) (_ []query.SearchQuery, err error) {
|
||||
q := make([]query.SearchQuery, len(queries))
|
||||
for i, qry := range queries {
|
||||
q[i], err = administratorFilterToModel(qry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func administratorFilterToModel(filter *internal_permission.AdministratorSearchFilter) (query.SearchQuery, error) {
|
||||
switch q := filter.Filter.(type) {
|
||||
case *internal_permission.AdministratorSearchFilter_InUserIdsFilter:
|
||||
return inUserIDsFilterToQuery(q.InUserIdsFilter)
|
||||
case *internal_permission.AdministratorSearchFilter_CreationDate:
|
||||
return creationDateFilterToQuery(q.CreationDate)
|
||||
case *internal_permission.AdministratorSearchFilter_ChangeDate:
|
||||
return changeDateFilterToQuery(q.ChangeDate)
|
||||
case *internal_permission.AdministratorSearchFilter_UserOrganizationId:
|
||||
return userResourceOwnerFilterToQuery(q.UserOrganizationId)
|
||||
case *internal_permission.AdministratorSearchFilter_UserPreferredLoginName:
|
||||
return userLoginNameFilterToQuery(q.UserPreferredLoginName)
|
||||
case *internal_permission.AdministratorSearchFilter_UserDisplayName:
|
||||
return userDisplayNameFilterToQuery(q.UserDisplayName)
|
||||
case *internal_permission.AdministratorSearchFilter_Resource:
|
||||
return resourceFilterToQuery(q.Resource)
|
||||
default:
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "ORG-vR9nC", "List.Query.Invalid")
|
||||
}
|
||||
}
|
||||
|
||||
func inUserIDsFilterToQuery(q *filter_pb.InIDsFilter) (query.SearchQuery, error) {
|
||||
return query.NewMemberInUserIDsSearchQuery(q.GetIds())
|
||||
}
|
||||
|
||||
func userResourceOwnerFilterToQuery(q *filter_pb.IDFilter) (query.SearchQuery, error) {
|
||||
return query.NewAdministratorUserResourceOwnerSearchQuery(q.GetId())
|
||||
}
|
||||
|
||||
func userLoginNameFilterToQuery(q *internal_permission.UserPreferredLoginNameFilter) (query.SearchQuery, error) {
|
||||
return query.NewAdministratorUserLoginNameSearchQuery(q.GetPreferredLoginName())
|
||||
}
|
||||
|
||||
func userDisplayNameFilterToQuery(q *internal_permission.UserDisplayNameFilter) (query.SearchQuery, error) {
|
||||
return query.NewAdministratorUserDisplayNameSearchQuery(q.GetDisplayName())
|
||||
}
|
||||
|
||||
func creationDateFilterToQuery(q *filter_pb.TimestampFilter) (query.SearchQuery, error) {
|
||||
return query.NewMembershipCreationDateQuery(q.GetTimestamp().AsTime(), filter.TimestampMethodPbToQuery(q.Method))
|
||||
}
|
||||
|
||||
func changeDateFilterToQuery(q *filter_pb.TimestampFilter) (query.SearchQuery, error) {
|
||||
return query.NewMembershipChangeDateQuery(q.GetTimestamp().AsTime(), filter.TimestampMethodPbToQuery(q.Method))
|
||||
}
|
||||
|
||||
func resourceFilterToQuery(q *internal_permission.ResourceFilter) (query.SearchQuery, error) {
|
||||
switch r := q.GetResource().(type) {
|
||||
case *internal_permission.ResourceFilter_Instance:
|
||||
if q.GetInstance() {
|
||||
return query.NewMembershipIsIAMQuery()
|
||||
}
|
||||
case *internal_permission.ResourceFilter_OrganizationId:
|
||||
return query.NewMembershipOrgIDQuery(r.OrganizationId)
|
||||
case *internal_permission.ResourceFilter_ProjectId:
|
||||
projectIDQuery, err := query.NewMembershipProjectIDQuery(r.ProjectId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
notGrantedQuery, err := query.NewMembershipNotGrantedSearchQuery()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return query.NewAndQuery(projectIDQuery, notGrantedQuery)
|
||||
case *internal_permission.ResourceFilter_ProjectGrant_:
|
||||
projectIDQuery, err := query.NewMembershipProjectIDQuery(r.ProjectGrant.GetProjectId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
grantedOrganizationID, err := query.NewMembershipGrantedOrgIDSearchQuery(r.ProjectGrant.GetOrganizationId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return query.NewAndQuery(projectIDQuery, grantedOrganizationID)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func administratorsToPb(administrators []*query.Administrator) []*internal_permission.Administrator {
|
||||
a := make([]*internal_permission.Administrator, len(administrators))
|
||||
for i, admin := range administrators {
|
||||
a[i] = administratorToPb(admin)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func administratorToPb(admin *query.Administrator) *internal_permission.Administrator {
|
||||
var resource internal_permission.Resource
|
||||
if admin.Instance != nil {
|
||||
resource = &internal_permission.Administrator_Instance{Instance: true}
|
||||
}
|
||||
if admin.Org != nil {
|
||||
resource = &internal_permission.Administrator_Organization{
|
||||
Organization: &internal_permission.Organization{
|
||||
Id: admin.Org.OrgID,
|
||||
Name: admin.Org.Name,
|
||||
},
|
||||
}
|
||||
}
|
||||
if admin.Project != nil {
|
||||
resource = &internal_permission.Administrator_Project{
|
||||
Project: &internal_permission.Project{
|
||||
Id: admin.Project.ProjectID,
|
||||
Name: admin.Project.Name,
|
||||
OrganizationId: admin.Project.ResourceOwner,
|
||||
},
|
||||
}
|
||||
}
|
||||
if admin.ProjectGrant != nil {
|
||||
resource = &internal_permission.Administrator_ProjectGrant{
|
||||
ProjectGrant: &internal_permission.ProjectGrant{
|
||||
Id: admin.ProjectGrant.GrantID,
|
||||
ProjectId: admin.ProjectGrant.ProjectID,
|
||||
ProjectName: admin.ProjectGrant.ProjectName,
|
||||
OrganizationId: admin.ProjectGrant.ResourceOwner,
|
||||
GrantedOrganizationId: admin.ProjectGrant.GrantedOrgID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return &internal_permission.Administrator{
|
||||
CreationDate: timestamppb.New(admin.CreationDate),
|
||||
ChangeDate: timestamppb.New(admin.ChangeDate),
|
||||
User: &internal_permission.User{
|
||||
Id: admin.User.UserID,
|
||||
PreferredLoginName: admin.User.LoginName,
|
||||
DisplayName: admin.User.DisplayName,
|
||||
OrganizationId: admin.User.ResourceOwner,
|
||||
},
|
||||
Resource: resource,
|
||||
Roles: admin.Roles,
|
||||
}
|
||||
}
|
||||
59
internal/api/grpc/internal_permission/v2/server.go
Normal file
59
internal/api/grpc/internal_permission/v2/server.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package internal_permission
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/config/systemdefaults"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/internal_permission/v2"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/internal_permission/v2/internal_permissionconnect"
|
||||
)
|
||||
|
||||
var _ internal_permissionconnect.InternalPermissionServiceHandler = (*Server)(nil)
|
||||
|
||||
type Server struct {
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
command *command.Commands
|
||||
query *query.Queries
|
||||
checkPermission domain.PermissionCheck
|
||||
}
|
||||
|
||||
func CreateServer(
|
||||
systemDefaults systemdefaults.SystemDefaults,
|
||||
command *command.Commands,
|
||||
query *query.Queries,
|
||||
checkPermission domain.PermissionCheck,
|
||||
) *Server {
|
||||
return &Server{
|
||||
systemDefaults: systemDefaults,
|
||||
command: command,
|
||||
query: query,
|
||||
checkPermission: checkPermission,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) RegisterConnectServer(interceptors ...connect.Interceptor) (string, http.Handler) {
|
||||
return internal_permissionconnect.NewInternalPermissionServiceHandler(s, connect.WithInterceptors(interceptors...))
|
||||
}
|
||||
|
||||
func (s *Server) FileDescriptor() protoreflect.FileDescriptor {
|
||||
return internal_permission.File_zitadel_internal_permission_v2_internal_permission_service_proto
|
||||
}
|
||||
|
||||
func (s *Server) AppName() string {
|
||||
return internal_permission.InternalPermissionService_ServiceDesc.ServiceName
|
||||
}
|
||||
|
||||
func (s *Server) MethodPrefix() string {
|
||||
return internal_permission.InternalPermissionService_ServiceDesc.ServiceName
|
||||
}
|
||||
|
||||
func (s *Server) AuthMethods() authz.MethodMapping {
|
||||
return internal_permission.InternalPermissionService_AuthMethods
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
"github.com/zitadel/zitadel/pkg/grpc/idp"
|
||||
idp_pb "github.com/zitadel/zitadel/pkg/grpc/idp/v2"
|
||||
instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta"
|
||||
internal_permission_v2 "github.com/zitadel/zitadel/pkg/grpc/internal_permission/v2"
|
||||
internal_permission_v2beta "github.com/zitadel/zitadel/pkg/grpc/internal_permission/v2beta"
|
||||
mgmt "github.com/zitadel/zitadel/pkg/grpc/management"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/object/v2"
|
||||
@@ -85,6 +86,7 @@ type Client struct {
|
||||
InstanceV2Beta instance.InstanceServiceClient
|
||||
AppV2Beta app.AppServiceClient
|
||||
InternalPermissionv2Beta internal_permission_v2beta.InternalPermissionServiceClient
|
||||
InternalPermissionV2 internal_permission_v2.InternalPermissionServiceClient
|
||||
AuthorizationV2Beta authorization.AuthorizationServiceClient
|
||||
}
|
||||
|
||||
@@ -129,6 +131,7 @@ func newClient(ctx context.Context, target string) (*Client, error) {
|
||||
InstanceV2Beta: instance.NewInstanceServiceClient(cc),
|
||||
AppV2Beta: app.NewAppServiceClient(cc),
|
||||
InternalPermissionv2Beta: internal_permission_v2beta.NewInternalPermissionServiceClient(cc),
|
||||
InternalPermissionV2: internal_permission_v2.NewInternalPermissionServiceClient(cc),
|
||||
AuthorizationV2Beta: authorization.NewAuthorizationServiceClient(cc),
|
||||
}
|
||||
return client, client.pollHealth(ctx)
|
||||
|
||||
@@ -192,7 +192,6 @@ func (q *Queries) searchAdministrators(ctx context.Context, queries *MembershipS
|
||||
return nil, err
|
||||
}
|
||||
queryArgs = append(queryArgs, args...)
|
||||
|
||||
err = q.client.QueryContext(ctx, func(rows *sql.Rows) error {
|
||||
administrators, err = scan(rows)
|
||||
return err
|
||||
|
||||
@@ -90,6 +90,10 @@ func NewMembershipGrantedOrgIDSearchQuery(id string) (SearchQuery, error) {
|
||||
return NewTextQuery(ProjectGrantColumnGrantedOrgID, id, TextEquals)
|
||||
}
|
||||
|
||||
func NewMembershipNotGrantedSearchQuery() (SearchQuery, error) {
|
||||
return NewIsNullQuery(ProjectGrantColumnGrantedOrgID)
|
||||
}
|
||||
|
||||
func NewMembershipProjectIDQuery(value string) (SearchQuery, error) {
|
||||
return NewTextQuery(ProjectMemberProjectID, value, TextEquals)
|
||||
}
|
||||
|
||||
3
pkg/grpc/internal_permission/v2/resource.go
Normal file
3
pkg/grpc/internal_permission/v2/resource.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package internal_permission
|
||||
|
||||
type Resource = isAdministrator_Resource
|
||||
@@ -4050,7 +4050,7 @@ service AdminService {
|
||||
|
||||
// List IAM Members
|
||||
//
|
||||
// Deprecated: use [ListAdministrators](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-list-administrators.api.mdx) instead.
|
||||
// Deprecated: use [ListAdministrators](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-list-administrators.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request returns all users with memberships on the instance level, matching the search queries. The search queries will be AND linked.
|
||||
rpc ListIAMMembers(ListIAMMembersRequest) returns (ListIAMMembersResponse) {
|
||||
@@ -4078,7 +4078,7 @@ service AdminService {
|
||||
|
||||
// Add IAM Member
|
||||
//
|
||||
// Deprecated: use [CreateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-create-administrator.api.mdx) instead.
|
||||
// Deprecated: use [CreateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-create-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request adds a new user to the members list with one or multiple roles.
|
||||
rpc AddIAMMember(AddIAMMemberRequest) returns (AddIAMMemberResponse) {
|
||||
@@ -4117,7 +4117,7 @@ service AdminService {
|
||||
|
||||
// Update IAM Member
|
||||
//
|
||||
// Deprecated: use [UpdateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-update-administrator.api.mdx) instead.
|
||||
// Deprecated: use [UpdateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-update-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request changes the roles of an existing member. The whole roles list will be updated. Make sure to include roles that you don't want to change (remove).
|
||||
rpc UpdateIAMMember(UpdateIAMMemberRequest) returns (UpdateIAMMemberResponse) {
|
||||
@@ -4156,7 +4156,7 @@ service AdminService {
|
||||
|
||||
// Remove IAM Member
|
||||
//
|
||||
// Deprecated: use [DeleteAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-delete-administrator.api.mdx) instead.
|
||||
// Deprecated: use [DeleteAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-delete-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request removes a user from the members list on an instance level. The user can still have roles on another level (organization, project).
|
||||
rpc RemoveIAMMember(RemoveIAMMemberRequest) returns (RemoveIAMMemberResponse) {
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.internal_permission.v2;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/field_behavior.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
import "zitadel/filter/v2/filter.proto";
|
||||
import "zitadel/internal_permission/v2/query.proto";
|
||||
import "zitadel/protoc_gen_zitadel/v2/options.proto";
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/internal_permission/v2;internal_permission";
|
||||
|
||||
// InternalPermissionService provides methods to manage permissions for resource
|
||||
// and their management in ZITADEL itself also known as "administrators".
|
||||
//
|
||||
// If you want to manage permissions and roles within your project or application,
|
||||
// please use the AuthorizationsService.
|
||||
service InternalPermissionService {
|
||||
|
||||
// List Administrators
|
||||
//
|
||||
// ListAdministrators returns all administrators and their roles matching the request and the caller's permissions to retrieve.
|
||||
//
|
||||
// Required permissions depend on the resource type:
|
||||
// - "iam.member.read" for instance administrators
|
||||
// - "org.member.read" for organization administrators
|
||||
// - "project.member.read" for project administrators
|
||||
// - "project.grant.member.read" for project grant administrators
|
||||
// - no permissions required for listing own administrator roles
|
||||
rpc ListAdministrators(ListAdministratorsRequest) returns (ListAdministratorsResponse) {
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {permission: "authenticated"}
|
||||
};
|
||||
}
|
||||
|
||||
// Create Administrator
|
||||
//
|
||||
// CreateAdministrator grants an administrator role to a user for a specific resource.
|
||||
//
|
||||
// Note that the roles are specific to the resource type.
|
||||
// This means that if you want to grant a user the administrator role for an organization and a project,
|
||||
// you need to create two administrator roles.
|
||||
//
|
||||
// Required permissions depend on the resource type:
|
||||
// - "iam.member.write" for instance administrators
|
||||
// - "org.member.write" for organization administrators
|
||||
// - "project.member.write" for project administrators
|
||||
// - "project.grant.member.write" for project grant administrators
|
||||
rpc CreateAdministrator(CreateAdministratorRequest) returns (CreateAdministratorResponse) {
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {permission: "authenticated"}
|
||||
};
|
||||
}
|
||||
|
||||
// Update Administrator
|
||||
//
|
||||
// UpdateAdministrator updates the specific administrator role.
|
||||
//
|
||||
// Note that any role previously granted to the user and not present in the request will be revoked.
|
||||
//
|
||||
// Required permissions depend on the resource type:
|
||||
// - "iam.member.write" for instance administrators
|
||||
// - "org.member.write" for organization administrators
|
||||
// - "project.member.write" for project administrators
|
||||
// - "project.grant.member.write" for project grant administrators
|
||||
rpc UpdateAdministrator(UpdateAdministratorRequest) returns (UpdateAdministratorResponse) {
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {permission: "authenticated"}
|
||||
};
|
||||
}
|
||||
|
||||
// Delete Administrator
|
||||
//
|
||||
// DeleteAdministrator revokes an administrator role from a user.
|
||||
//
|
||||
// In case the administrator role is not found, the request will return a successful response as
|
||||
// the desired state is already achieved.
|
||||
// You can check the deletion date in the response to verify if the administrator role was deleted during the request.
|
||||
//
|
||||
// Required permissions depend on the resource type:
|
||||
// - "iam.member.delete" for instance administrators
|
||||
// - "org.member.delete" for organization administrators
|
||||
// - "project.member.delete" for project administrators
|
||||
// - "project.grant.member.delete" for project grant administrators
|
||||
rpc DeleteAdministrator(DeleteAdministratorRequest) returns (DeleteAdministratorResponse) {
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {permission: "authenticated"}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message ListAdministratorsRequest {
|
||||
// Paginate through the results using a limit, offset and sorting.
|
||||
optional zitadel.filter.v2.PaginationRequest pagination = 1;
|
||||
|
||||
// The field the result is sorted by. The default is the creation date.
|
||||
// Beware that if you change this, your result pagination might be inconsistent.
|
||||
AdministratorFieldName sorting_column = 2;
|
||||
|
||||
// Filter the administrator roles to be returned.
|
||||
repeated AdministratorSearchFilter filters = 3;
|
||||
}
|
||||
|
||||
message ListAdministratorsResponse {
|
||||
// Pagination contains the current sequence and the total result count.
|
||||
zitadel.filter.v2.PaginationResponse pagination = 1;
|
||||
|
||||
// Administrators contains the list of administrators matching the request.
|
||||
repeated Administrator administrators = 2;
|
||||
}
|
||||
|
||||
message CreateAdministratorRequest {
|
||||
// UserID is the ID of the user who should be granted the administrator role.
|
||||
string user_id = 1 [
|
||||
(validate.rules).string = {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
},
|
||||
(google.api.field_behavior) = REQUIRED
|
||||
];
|
||||
|
||||
// Resource is the type of the resource the administrator roles should be granted for.
|
||||
ResourceType resource = 2 [(google.api.field_behavior) = REQUIRED];
|
||||
|
||||
// Roles are the roles that should be granted to the user for the specified resource.
|
||||
// Note that roles are currently specific to the resource type.
|
||||
// This means that if you want to grant a user the administrator role for an organization and a project,
|
||||
// you need to create two administrator roles.
|
||||
repeated string roles = 3 [
|
||||
(validate.rules).repeated = {
|
||||
unique: true
|
||||
items: {
|
||||
string: {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
}
|
||||
}
|
||||
},
|
||||
(google.api.field_behavior) = REQUIRED
|
||||
];
|
||||
}
|
||||
|
||||
message ResourceType {
|
||||
message ProjectGrant {
|
||||
// ProjectID is the unique identifier of the project the project grant belongs to.
|
||||
string project_id = 1 [
|
||||
(validate.rules).string = {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
},
|
||||
(google.api.field_behavior) = REQUIRED
|
||||
];
|
||||
|
||||
// OrganizationID is the unique identifier of the organization the project was granted to
|
||||
// and on which the administrator role should be granted.
|
||||
string organization_id = 2 [
|
||||
(validate.rules).string = {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
},
|
||||
(google.api.field_behavior) = REQUIRED
|
||||
];
|
||||
}
|
||||
|
||||
// Resource is the type of the resource the administrator roles should be granted for.
|
||||
oneof resource {
|
||||
option (validate.required) = true;
|
||||
|
||||
// Instance is the resource type for granting administrator privileges on the instance level.
|
||||
bool instance = 1 [(validate.rules).bool = {const: true}];
|
||||
|
||||
// OrganizationID is required to grant administrator privileges for a specific organization.
|
||||
string organization_id = 2;
|
||||
|
||||
// ProjectID is required to grant administrator privileges for a specific project.
|
||||
string project_id = 3;
|
||||
|
||||
// ProjectGrantID is required to grant administrator privileges for a specific project grant.
|
||||
ProjectGrant project_grant = 4;
|
||||
}
|
||||
}
|
||||
|
||||
message CreateAdministratorResponse {
|
||||
// CreationDate is the timestamp when the administrator role was created.
|
||||
google.protobuf.Timestamp creation_date = 1;
|
||||
}
|
||||
|
||||
message UpdateAdministratorRequest {
|
||||
// UserID is the ID of the user whose administrator roles should be updated.
|
||||
string user_id = 1 [(validate.rules).string = {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
}];
|
||||
|
||||
// Resource is the type of the resource the administrator roles should be granted for.
|
||||
ResourceType resource = 2 [(google.api.field_behavior) = REQUIRED];
|
||||
|
||||
// Roles are the roles that the user should be granted.
|
||||
// Note that any role previously granted to the user and not present in the list will be revoked.
|
||||
repeated string roles = 3 [(validate.rules).repeated = {
|
||||
unique: true
|
||||
items: {
|
||||
string: {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
message UpdateAdministratorResponse {
|
||||
// ChangeDate is the timestamp when the administrator role was last updated.
|
||||
google.protobuf.Timestamp change_date = 1;
|
||||
}
|
||||
|
||||
message DeleteAdministratorRequest {
|
||||
// UserID is the ID of the user whose administrator roles should be removed.
|
||||
string user_id = 1 [(validate.rules).string = {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
}];
|
||||
|
||||
// Resource is the type of the resource the administrator roles should be removed for.
|
||||
ResourceType resource = 2 [(google.api.field_behavior) = REQUIRED];
|
||||
}
|
||||
|
||||
message DeleteAdministratorResponse {
|
||||
// DeletionDate is the timestamp when the administrator role was deleted.
|
||||
// Note that the deletion date is only guaranteed to be set if the deletion was successful during the request.
|
||||
// In case the deletion occurred in a previous request, the deletion date might not be set.
|
||||
google.protobuf.Timestamp deletion_date = 1;
|
||||
}
|
||||
234
proto/zitadel/internal_permission/v2/query.proto
Normal file
234
proto/zitadel/internal_permission/v2/query.proto
Normal file
@@ -0,0 +1,234 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.internal_permission.v2;
|
||||
|
||||
import "google/api/field_behavior.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "validate/validate.proto";
|
||||
import "zitadel/filter/v2/filter.proto";
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/internal_permission/v2;internal_permission";
|
||||
|
||||
message Administrator {
|
||||
// CreationDate is the timestamp when the administrator role was granted.
|
||||
google.protobuf.Timestamp creation_date = 1;
|
||||
|
||||
// ChangeDate is the timestamp when the administrator role was last updated.
|
||||
// In case the administrator role was not updated, this field is equal to the creation date.
|
||||
google.protobuf.Timestamp change_date = 2;
|
||||
|
||||
// User is the user who was granted the administrator role.
|
||||
User user = 3;
|
||||
|
||||
// Resource is the type of the resource the administrator roles were granted for.
|
||||
oneof resource {
|
||||
// Instance is returned if the administrator roles were granted on the instance level.
|
||||
bool instance = 4;
|
||||
|
||||
// Organization provides information about the organization the administrator roles were granted for.
|
||||
Organization organization = 5;
|
||||
|
||||
// Project provides information about the project the administrator roles were granted for.
|
||||
Project project = 6;
|
||||
|
||||
// ProjectGrant provides information about the project grant the administrator roles were granted for.
|
||||
ProjectGrant project_grant = 7;
|
||||
}
|
||||
|
||||
// Roles are the roles that were granted to the user for the specified resource.
|
||||
repeated string roles = 8;
|
||||
}
|
||||
|
||||
message User {
|
||||
// ID is the unique identifier of the user.
|
||||
string id = 1;
|
||||
|
||||
// PreferredLoginName is the preferred login name of the user. This value is unique across the whole instance.
|
||||
string preferred_login_name = 2;
|
||||
|
||||
// DisplayName is the public display name of the user.
|
||||
// By default it's the user's given name and family name, their username or their email address.
|
||||
string display_name = 3;
|
||||
|
||||
// The organization the user belong to.
|
||||
string organization_id = 4;
|
||||
}
|
||||
|
||||
message Organization {
|
||||
// ID is the unique identifier of the organization the user was granted the administrator role for.
|
||||
string id = 1;
|
||||
|
||||
// Name is the name of the organization the user was granted the administrator role for.
|
||||
string name = 2;
|
||||
}
|
||||
|
||||
message Project {
|
||||
// ID is the unique identifier of the project the user was granted the administrator role for.
|
||||
string id = 1;
|
||||
|
||||
// Name is the name of the project the user was granted the administrator role for.
|
||||
string name = 2;
|
||||
|
||||
// OrganizationID is the ID of the organization the project belongs to.
|
||||
string organization_id = 3;
|
||||
}
|
||||
|
||||
message ProjectGrant {
|
||||
// ID is the unique identifier of the project grant the user was granted the administrator role for.
|
||||
string id = 1;
|
||||
|
||||
// ProjectID is the ID of the project the project grant belongs to.
|
||||
string project_id = 2;
|
||||
|
||||
// ProjectName is the name of the project the project grant belongs to.
|
||||
string project_name = 3;
|
||||
|
||||
// OrganizationID is the ID of the organization the project belongs to.
|
||||
string organization_id = 4;
|
||||
|
||||
// GrantedOrganizationID is the ID of the organization the project grant belongs to.
|
||||
string granted_organization_id = 5;
|
||||
}
|
||||
|
||||
message AdministratorSearchFilter {
|
||||
oneof filter {
|
||||
option (validate.required) = true;
|
||||
|
||||
// Search for administrator roles by their creation date.
|
||||
zitadel.filter.v2.TimestampFilter creation_date = 1;
|
||||
|
||||
// Search for administrator roles by their change date.
|
||||
zitadel.filter.v2.TimestampFilter change_date = 2;
|
||||
|
||||
// Search for administrators roles by the IDs of the users who was granted the administrator role.
|
||||
zitadel.filter.v2.InIDsFilter in_user_ids_filter = 3;
|
||||
|
||||
// Search for administrators roles by the ID of the organization the user is part of.
|
||||
zitadel.filter.v2.IDFilter user_organization_id = 4;
|
||||
|
||||
// Search for administrators roles by the preferred login name of the user.
|
||||
UserPreferredLoginNameFilter user_preferred_login_name = 5;
|
||||
|
||||
// Search for administrators roles by the display name of the user.
|
||||
UserDisplayNameFilter user_display_name = 6;
|
||||
|
||||
// Search for administrators roles granted for a specific resource.
|
||||
ResourceFilter resource = 7;
|
||||
|
||||
// Search for administrators roles granted with a specific role.
|
||||
RoleFilter role = 8;
|
||||
|
||||
// Combine multiple authorization queries with an AND operation.
|
||||
AndFilter and = 9;
|
||||
|
||||
// Combine multiple authorization queries with an OR operation.
|
||||
// For example, to search for authorizations of multiple OrganizationIDs.
|
||||
OrFilter or = 10;
|
||||
|
||||
// Negate an authorization query.
|
||||
NotFilter not = 11;
|
||||
}
|
||||
}
|
||||
|
||||
message UserPreferredLoginNameFilter {
|
||||
// Search for administrators by the preferred login name of the user.
|
||||
string preferred_login_name = 1 [
|
||||
(validate.rules).string = {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
},
|
||||
(google.api.field_behavior) = REQUIRED
|
||||
];
|
||||
|
||||
// Specify the method to search for the preferred login name. Default is EQUAL.
|
||||
// For example, to search for all administrator roles of a user with a preferred login name
|
||||
// containing a specific string, use CONTAINS or CONTAINS_IGNORE_CASE.
|
||||
zitadel.filter.v2.TextFilterMethod method = 2 [(validate.rules).enum.defined_only = true];
|
||||
}
|
||||
|
||||
message UserDisplayNameFilter {
|
||||
// Search for administrators by the display name of the user.
|
||||
string display_name = 1 [
|
||||
(validate.rules).string = {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
},
|
||||
(google.api.field_behavior) = REQUIRED
|
||||
];
|
||||
|
||||
// Specify the method to search for the display name. Default is EQUAL.
|
||||
// For example, to search for all administrator roles of a user with a display name
|
||||
// containing a specific string, use CONTAINS or CONTAINS_IGNORE_CASE.
|
||||
zitadel.filter.v2.TextFilterMethod method = 2 [(validate.rules).enum.defined_only = true];
|
||||
}
|
||||
|
||||
message ResourceFilter {
|
||||
message ProjectGrant {
|
||||
// ProjectID is the unique identifier of the project the project grant belongs to.
|
||||
string project_id = 1 [
|
||||
(validate.rules).string = {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
},
|
||||
(google.api.field_behavior) = REQUIRED
|
||||
];
|
||||
|
||||
// OrganizationID is the unique identifier of the organization the project was granted to
|
||||
// and on which the administrator role was granted too.
|
||||
string organization_id = 2 [
|
||||
(validate.rules).string = {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
},
|
||||
(google.api.field_behavior) = REQUIRED
|
||||
];
|
||||
}
|
||||
|
||||
// Search for administrators by the granted resource.
|
||||
oneof resource {
|
||||
option (validate.required) = true;
|
||||
|
||||
// Search for administrators granted on the instance level.
|
||||
bool instance = 1 [(validate.rules).bool = {const: true}];
|
||||
|
||||
// Search for administrators granted on a specific organization.
|
||||
string organization_id = 2;
|
||||
|
||||
// Search for administrators granted on a specific project.
|
||||
string project_id = 3;
|
||||
|
||||
// Search for administrators granted on a specific project grant
|
||||
// by providing both the project ID and the organization ID.
|
||||
ProjectGrant project_grant = 4;
|
||||
}
|
||||
}
|
||||
|
||||
message RoleFilter {
|
||||
// Search for administrators by the granted role.
|
||||
string role_key = 1 [
|
||||
(validate.rules).string = {
|
||||
min_len: 1
|
||||
max_len: 200
|
||||
},
|
||||
(google.api.field_behavior) = REQUIRED
|
||||
];
|
||||
}
|
||||
|
||||
message AndFilter {
|
||||
repeated AdministratorSearchFilter queries = 1;
|
||||
}
|
||||
|
||||
message OrFilter {
|
||||
repeated AdministratorSearchFilter queries = 1;
|
||||
}
|
||||
|
||||
message NotFilter {
|
||||
AdministratorSearchFilter query = 1;
|
||||
}
|
||||
|
||||
enum AdministratorFieldName {
|
||||
ADMINISTRATOR_FIELD_NAME_UNSPECIFIED = 0;
|
||||
ADMINISTRATOR_FIELD_NAME_USER_ID = 1;
|
||||
ADMINISTRATOR_FIELD_NAME_CREATION_DATE = 2;
|
||||
ADMINISTRATOR_FIELD_NAME_CHANGE_DATE = 3;
|
||||
}
|
||||
@@ -111,9 +111,13 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
//
|
||||
// If you want to manage permissions and roles within your project or application,
|
||||
// please use the AuthorizationsService.
|
||||
//
|
||||
// Deprecated: use internal permission service v2 instead. This service will be removed in the next major version of ZITADEL.
|
||||
service InternalPermissionService {
|
||||
// ListAdministrators returns all administrators and its roles matching the request and necessary permissions.
|
||||
//
|
||||
// Deprecated: please move to the corresponding endpoint under internal permission service v2. This endpoint will be removed with the next major version of ZITADEL.
|
||||
//
|
||||
// Required permissions depend on the resource type:
|
||||
// - "iam.member.read" for instance administrators
|
||||
// - "org.member.read" for organization administrators
|
||||
@@ -133,6 +137,7 @@ service InternalPermissionService {
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
deprecated: true;
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
@@ -150,6 +155,8 @@ service InternalPermissionService {
|
||||
|
||||
// CreateAdministrator grants a administrator role to a user for a specific resource.
|
||||
//
|
||||
// Deprecated: please move to the corresponding endpoint under internal permission service v2. This endpoint will be removed with the next major version of ZITADEL.
|
||||
//
|
||||
// Note that the roles are specific to the resource type.
|
||||
// This means that if you want to grant a user the administrator role for an organization and a project,
|
||||
// you need to create two administrator roles.
|
||||
@@ -172,6 +179,7 @@ service InternalPermissionService {
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
deprecated: true;
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
@@ -189,6 +197,8 @@ service InternalPermissionService {
|
||||
|
||||
// UpdateAdministrator updates the specific administrator role.
|
||||
//
|
||||
// Deprecated: please move to the corresponding endpoint under internal permission service v2. This endpoint will be removed with the next major version of ZITADEL.
|
||||
//
|
||||
// Note that any role previously granted to the user and not present in the request will be revoked.
|
||||
//
|
||||
// Required permissions depend on the resource type:
|
||||
@@ -209,6 +219,7 @@ service InternalPermissionService {
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
deprecated: true;
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
@@ -226,6 +237,8 @@ service InternalPermissionService {
|
||||
|
||||
// DeleteAdministrator revokes a administrator role from a user.
|
||||
//
|
||||
// Deprecated: please move to the corresponding endpoint under internal permission service v2. This endpoint will be removed with the next major version of ZITADEL.
|
||||
//
|
||||
// In case the administrator role is not found, the request will return a successful response as
|
||||
// the desired state is already achieved.
|
||||
// You can check the deletion date in the response to verify if the administrator role was deleted during the request.
|
||||
@@ -247,6 +260,7 @@ service InternalPermissionService {
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
deprecated: true;
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
|
||||
@@ -2185,7 +2185,7 @@ service ManagementService {
|
||||
|
||||
// List ZITADEL Permissions
|
||||
//
|
||||
// Deprecated: use [ListAdministrators](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-list-administrators.api.mdx) instead.
|
||||
// Deprecated: use [ListAdministrators](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-list-administrators.api.mdx) instead.
|
||||
//
|
||||
// Show all the permissions the user has in ZITADEL (ZITADEL Manager).
|
||||
rpc ListUserMemberships(ListUserMembershipsRequest) returns (ListUserMembershipsResponse) {
|
||||
@@ -2799,7 +2799,7 @@ service ManagementService {
|
||||
|
||||
// List Organization Members
|
||||
//
|
||||
// Deprecated: use [ListAdministrators](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-list-administrators.api.mdx) instead.
|
||||
// Deprecated: use [ListAdministrators](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-list-administrators.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request returns all users with memberships on the organization level, matching the search queries. The search queries will be AND linked.
|
||||
rpc ListOrgMembers(ListOrgMembersRequest) returns (ListOrgMembersResponse) {
|
||||
@@ -2830,7 +2830,7 @@ service ManagementService {
|
||||
|
||||
// Add Organization Member
|
||||
//
|
||||
// Deprecated: use [CreateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-create-administrator.api.mdx) instead.
|
||||
// Deprecated: use [CreateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-create-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request adds a new user to the members list on the organization level with one or multiple roles.
|
||||
rpc AddOrgMember(AddOrgMemberRequest) returns (AddOrgMemberResponse) {
|
||||
@@ -2861,7 +2861,7 @@ service ManagementService {
|
||||
|
||||
// Update Organization Member
|
||||
//
|
||||
// Deprecated: use [UpdateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-update-administrator.api.mdx) instead.
|
||||
// Deprecated: use [UpdateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-update-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request changes the roles of an existing member. The whole roles list will be updated. Make sure to include roles that you don't want to change (remove).
|
||||
rpc UpdateOrgMember(UpdateOrgMemberRequest) returns (UpdateOrgMemberResponse) {
|
||||
@@ -2892,7 +2892,7 @@ service ManagementService {
|
||||
|
||||
// Remove Organization Member
|
||||
//
|
||||
// Deprecated: use [DeleteAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-delete-administrator.api.mdx) instead.
|
||||
// Deprecated: use [DeleteAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-delete-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request removes a user from the members list on an instance level. The user can still have roles on another level (iam, project).
|
||||
rpc RemoveOrgMember(RemoveOrgMemberRequest) returns (RemoveOrgMemberResponse) {
|
||||
@@ -3415,7 +3415,7 @@ service ManagementService {
|
||||
|
||||
// List Project Members
|
||||
//
|
||||
// Deprecated: use [ListAdministrators](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-list-administrators.api.mdx) instead.
|
||||
// Deprecated: use [ListAdministrators](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-list-administrators.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request returns all users with memberships on the project level, matching the search queries. The search queries will be AND linked.
|
||||
rpc ListProjectMembers(ListProjectMembersRequest) returns (ListProjectMembersResponse) {
|
||||
@@ -3447,7 +3447,7 @@ service ManagementService {
|
||||
|
||||
// Add Project Member
|
||||
//
|
||||
// Deprecated: use [CreateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-create-administrator.api.mdx) instead.
|
||||
// Deprecated: use [CreateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-create-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request adds a new user to the members list on the project level with one or multiple roles.
|
||||
rpc AddProjectMember(AddProjectMemberRequest) returns (AddProjectMemberResponse) {
|
||||
@@ -3479,7 +3479,7 @@ service ManagementService {
|
||||
|
||||
// Update Project Member
|
||||
//
|
||||
// Deprecated: use [UpdateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-update-administrator.api.mdx) instead.
|
||||
// Deprecated: use [UpdateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-update-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request changes the roles of an existing member. The whole roles list will be updated. Make sure to include roles that you don't want to change (remove).
|
||||
rpc UpdateProjectMember(UpdateProjectMemberRequest) returns (UpdateProjectMemberResponse) {
|
||||
@@ -3511,7 +3511,7 @@ service ManagementService {
|
||||
|
||||
// Remove Project Member
|
||||
//
|
||||
// Deprecated: use [DeleteAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-delete-administrator.api.mdx) instead.
|
||||
// Deprecated: use [DeleteAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-delete-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request removes a user from the members list on an project level. The user can still have roles on another level (iam, organization).
|
||||
rpc RemoveProjectMember(RemoveProjectMemberRequest) returns (RemoveProjectMemberResponse) {
|
||||
@@ -4386,7 +4386,7 @@ service ManagementService {
|
||||
|
||||
// List Project Grant Members
|
||||
//
|
||||
// Deprecated: use [ListAdministrators](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-list-administrators.api.mdx) instead.
|
||||
// Deprecated: use [ListAdministrators](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-list-administrators.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request returns all users with memberships on the project grant level, matching the search queries. The search queries will be AND linked.
|
||||
rpc ListProjectGrantMembers(ListProjectGrantMembersRequest) returns (ListProjectGrantMembersResponse) {
|
||||
@@ -4417,7 +4417,7 @@ service ManagementService {
|
||||
|
||||
// Add Project Grant Member
|
||||
//
|
||||
// Deprecated: use [CreateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-create-administrator.api.mdx) instead.
|
||||
// Deprecated: use [CreateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-create-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request returns all users with memberships on the project grant level, matching the search queries. The search queries will be AND linked.
|
||||
rpc AddProjectGrantMember(AddProjectGrantMemberRequest) returns (AddProjectGrantMemberResponse) {
|
||||
@@ -4448,7 +4448,7 @@ service ManagementService {
|
||||
|
||||
// Update Project Grant Member
|
||||
//
|
||||
// Deprecated: use [UpdateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-update-administrator.api.mdx) instead.
|
||||
// Deprecated: use [UpdateAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-update-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request changes the roles of an existing member. The whole roles list will be updated. Make sure to include roles that you don't want to change (remove).
|
||||
rpc UpdateProjectGrantMember(UpdateProjectGrantMemberRequest) returns (UpdateProjectGrantMemberResponse) {
|
||||
@@ -4479,7 +4479,7 @@ service ManagementService {
|
||||
|
||||
// Remove Project Grant Member
|
||||
//
|
||||
// Deprecated: use [DeleteAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-beta-internal-permission-service-delete-administrator.api.mdx) instead.
|
||||
// Deprecated: use [DeleteAdministrator](apis/resources/internal_permission_service_v2/zitadel-internal-permission-v-2-internal-permission-service-delete-administrator.api.mdx) instead.
|
||||
//
|
||||
// Members are users with permission to administrate ZITADEL on different levels. This request removes a user from the members list on a project grant level. The user can still have roles on another level (iam, organization, project).
|
||||
rpc RemoveProjectGrantMember(RemoveProjectGrantMemberRequest) returns (RemoveProjectGrantMemberResponse) {
|
||||
|
||||
Reference in New Issue
Block a user