mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
# 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 adds the organization settings endpoints to the settings service v2. This was split from #10909, since that PR targets v4.x and the corresponding feature is not yet available in v4.x, but only v5. - The comments and have been improved and, where not already done, moved from swagger annotations to proto. # Additional Changes None # Additional Context - relates to #10909 - relates to #10772
314 lines
12 KiB
Go
314 lines
12 KiB
Go
package settings
|
|
|
|
import (
|
|
"context"
|
|
|
|
"connectrpc.com/connect"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
|
|
"github.com/zitadel/zitadel/internal/api/authz"
|
|
"github.com/zitadel/zitadel/internal/api/grpc/filter/v2"
|
|
"github.com/zitadel/zitadel/internal/api/grpc/object/v2"
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
"github.com/zitadel/zitadel/internal/i18n"
|
|
"github.com/zitadel/zitadel/internal/query"
|
|
"github.com/zitadel/zitadel/internal/zerrors"
|
|
filter_pb "github.com/zitadel/zitadel/pkg/grpc/filter/v2"
|
|
object_pb "github.com/zitadel/zitadel/pkg/grpc/object/v2"
|
|
"github.com/zitadel/zitadel/pkg/grpc/settings/v2"
|
|
)
|
|
|
|
func (s *Server) GetLoginSettings(ctx context.Context, req *connect.Request[settings.GetLoginSettingsRequest]) (*connect.Response[settings.GetLoginSettingsResponse], error) {
|
|
current, err := s.query.LoginPolicyByID(ctx, true, object.ResourceOwnerFromReq(ctx, req.Msg.GetCtx()), false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&settings.GetLoginSettingsResponse{
|
|
Settings: loginSettingsToPb(current),
|
|
Details: &object_pb.Details{
|
|
Sequence: current.Sequence,
|
|
CreationDate: timestamppb.New(current.CreationDate),
|
|
ChangeDate: timestamppb.New(current.ChangeDate),
|
|
ResourceOwner: current.OrgID,
|
|
},
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) GetPasswordComplexitySettings(ctx context.Context, req *connect.Request[settings.GetPasswordComplexitySettingsRequest]) (*connect.Response[settings.GetPasswordComplexitySettingsResponse], error) {
|
|
current, err := s.query.PasswordComplexityPolicyByOrg(ctx, true, object.ResourceOwnerFromReq(ctx, req.Msg.GetCtx()), false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&settings.GetPasswordComplexitySettingsResponse{
|
|
Settings: passwordComplexitySettingsToPb(current),
|
|
Details: &object_pb.Details{
|
|
Sequence: current.Sequence,
|
|
CreationDate: timestamppb.New(current.CreationDate),
|
|
ChangeDate: timestamppb.New(current.ChangeDate),
|
|
ResourceOwner: current.ResourceOwner,
|
|
},
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) GetPasswordExpirySettings(ctx context.Context, req *connect.Request[settings.GetPasswordExpirySettingsRequest]) (*connect.Response[settings.GetPasswordExpirySettingsResponse], error) {
|
|
current, err := s.query.PasswordAgePolicyByOrg(ctx, true, object.ResourceOwnerFromReq(ctx, req.Msg.GetCtx()), false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&settings.GetPasswordExpirySettingsResponse{
|
|
Settings: passwordExpirySettingsToPb(current),
|
|
Details: &object_pb.Details{
|
|
Sequence: current.Sequence,
|
|
CreationDate: timestamppb.New(current.CreationDate),
|
|
ChangeDate: timestamppb.New(current.ChangeDate),
|
|
ResourceOwner: current.ResourceOwner,
|
|
},
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) GetBrandingSettings(ctx context.Context, req *connect.Request[settings.GetBrandingSettingsRequest]) (*connect.Response[settings.GetBrandingSettingsResponse], error) {
|
|
current, err := s.query.ActiveLabelPolicyByOrg(ctx, object.ResourceOwnerFromReq(ctx, req.Msg.GetCtx()), false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&settings.GetBrandingSettingsResponse{
|
|
Settings: brandingSettingsToPb(current, s.assetsAPIDomain(ctx)),
|
|
Details: &object_pb.Details{
|
|
Sequence: current.Sequence,
|
|
CreationDate: timestamppb.New(current.CreationDate),
|
|
ChangeDate: timestamppb.New(current.ChangeDate),
|
|
ResourceOwner: current.ResourceOwner,
|
|
},
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) GetDomainSettings(ctx context.Context, req *connect.Request[settings.GetDomainSettingsRequest]) (*connect.Response[settings.GetDomainSettingsResponse], error) {
|
|
current, err := s.query.DomainPolicyByOrg(ctx, true, object.ResourceOwnerFromReq(ctx, req.Msg.GetCtx()), false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&settings.GetDomainSettingsResponse{
|
|
Settings: domainSettingsToPb(current),
|
|
Details: &object_pb.Details{
|
|
Sequence: current.Sequence,
|
|
CreationDate: timestamppb.New(current.CreationDate),
|
|
ChangeDate: timestamppb.New(current.ChangeDate),
|
|
ResourceOwner: current.ResourceOwner,
|
|
},
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) GetLegalAndSupportSettings(ctx context.Context, req *connect.Request[settings.GetLegalAndSupportSettingsRequest]) (*connect.Response[settings.GetLegalAndSupportSettingsResponse], error) {
|
|
current, err := s.query.PrivacyPolicyByOrg(ctx, true, object.ResourceOwnerFromReq(ctx, req.Msg.GetCtx()), false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&settings.GetLegalAndSupportSettingsResponse{
|
|
Settings: legalAndSupportSettingsToPb(current),
|
|
Details: &object_pb.Details{
|
|
Sequence: current.Sequence,
|
|
CreationDate: timestamppb.New(current.CreationDate),
|
|
ChangeDate: timestamppb.New(current.ChangeDate),
|
|
ResourceOwner: current.ResourceOwner,
|
|
},
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) GetLockoutSettings(ctx context.Context, req *connect.Request[settings.GetLockoutSettingsRequest]) (*connect.Response[settings.GetLockoutSettingsResponse], error) {
|
|
current, err := s.query.LockoutPolicyByOrg(ctx, true, object.ResourceOwnerFromReq(ctx, req.Msg.GetCtx()))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&settings.GetLockoutSettingsResponse{
|
|
Settings: lockoutSettingsToPb(current),
|
|
Details: &object_pb.Details{
|
|
Sequence: current.Sequence,
|
|
CreationDate: timestamppb.New(current.CreationDate),
|
|
ChangeDate: timestamppb.New(current.ChangeDate),
|
|
ResourceOwner: current.ResourceOwner,
|
|
},
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) GetActiveIdentityProviders(ctx context.Context, req *connect.Request[settings.GetActiveIdentityProvidersRequest]) (*connect.Response[settings.GetActiveIdentityProvidersResponse], error) {
|
|
queries, err := activeIdentityProvidersToQuery(req.Msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
links, err := s.query.IDPLoginPolicyLinks(ctx, object.ResourceOwnerFromReq(ctx, req.Msg.GetCtx()), &query.IDPLoginPolicyLinksSearchQuery{Queries: queries}, false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return connect.NewResponse(&settings.GetActiveIdentityProvidersResponse{
|
|
Details: object.ToListDetails(links.SearchResponse),
|
|
IdentityProviders: identityProvidersToPb(links.Links),
|
|
}), nil
|
|
}
|
|
|
|
func activeIdentityProvidersToQuery(req *settings.GetActiveIdentityProvidersRequest) (_ []query.SearchQuery, err error) {
|
|
q := make([]query.SearchQuery, 0, 4)
|
|
if req.CreationAllowed != nil {
|
|
creationQuery, err := query.NewIDPTemplateIsCreationAllowedSearchQuery(*req.CreationAllowed)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
q = append(q, creationQuery)
|
|
}
|
|
if req.LinkingAllowed != nil {
|
|
creationQuery, err := query.NewIDPTemplateIsLinkingAllowedSearchQuery(*req.LinkingAllowed)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
q = append(q, creationQuery)
|
|
}
|
|
if req.AutoCreation != nil {
|
|
creationQuery, err := query.NewIDPTemplateIsAutoCreationSearchQuery(*req.AutoCreation)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
q = append(q, creationQuery)
|
|
}
|
|
if req.AutoLinking != nil {
|
|
compare := query.NumberEquals
|
|
if *req.AutoLinking {
|
|
compare = query.NumberNotEquals
|
|
}
|
|
creationQuery, err := query.NewIDPTemplateAutoLinkingSearchQuery(0, compare)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
q = append(q, creationQuery)
|
|
}
|
|
return q, nil
|
|
}
|
|
|
|
func (s *Server) GetGeneralSettings(ctx context.Context, _ *connect.Request[settings.GetGeneralSettingsRequest]) (*connect.Response[settings.GetGeneralSettingsResponse], error) {
|
|
instance := authz.GetInstance(ctx)
|
|
return connect.NewResponse(&settings.GetGeneralSettingsResponse{
|
|
SupportedLanguages: domain.LanguagesToStrings(i18n.SupportedLanguages()),
|
|
DefaultOrgId: instance.DefaultOrganisationID(),
|
|
DefaultLanguage: instance.DefaultLanguage().String(),
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) GetSecuritySettings(ctx context.Context, req *connect.Request[settings.GetSecuritySettingsRequest]) (*connect.Response[settings.GetSecuritySettingsResponse], error) {
|
|
policy, err := s.query.SecurityPolicy(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&settings.GetSecuritySettingsResponse{
|
|
Settings: securityPolicyToSettingsPb(policy),
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) GetHostedLoginTranslation(ctx context.Context, req *connect.Request[settings.GetHostedLoginTranslationRequest]) (*connect.Response[settings.GetHostedLoginTranslationResponse], error) {
|
|
translation, err := s.query.GetHostedLoginTranslation(ctx, req.Msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return connect.NewResponse(translation), nil
|
|
}
|
|
|
|
func (s *Server) ListOrganizationSettings(ctx context.Context, req *connect.Request[settings.ListOrganizationSettingsRequest]) (*connect.Response[settings.ListOrganizationSettingsResponse], error) {
|
|
queries, err := s.listOrganizationSettingsRequestToModel(req.Msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp, err := s.query.SearchOrganizationSettings(ctx, queries, s.checkPermission)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return connect.NewResponse(&settings.ListOrganizationSettingsResponse{
|
|
OrganizationSettings: organizationSettingsListToPb(resp.OrganizationSettingsList),
|
|
Pagination: filter.QueryToPaginationPb(queries.SearchRequest, resp.SearchResponse),
|
|
}), nil
|
|
}
|
|
|
|
func (s *Server) listOrganizationSettingsRequestToModel(req *settings.ListOrganizationSettingsRequest) (*query.OrganizationSettingsSearchQueries, error) {
|
|
offset, limit, asc, err := filter.PaginationPbToQuery(s.systemDefaults, req.Pagination)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
queries, err := organizationSettingsFiltersToQuery(req.Filters)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &query.OrganizationSettingsSearchQueries{
|
|
SearchRequest: query.SearchRequest{
|
|
Offset: offset,
|
|
Limit: limit,
|
|
Asc: asc,
|
|
SortingColumn: organizationSettingsFieldNameToSortingColumn(req.SortingColumn),
|
|
},
|
|
Queries: queries,
|
|
}, nil
|
|
}
|
|
|
|
func organizationSettingsFieldNameToSortingColumn(field *settings.OrganizationSettingsFieldName) query.Column {
|
|
if field == nil {
|
|
return query.OrganizationSettingsColumnCreationDate
|
|
}
|
|
switch *field {
|
|
case settings.OrganizationSettingsFieldName_ORGANIZATION_SETTINGS_FIELD_NAME_CREATION_DATE:
|
|
return query.OrganizationSettingsColumnCreationDate
|
|
case settings.OrganizationSettingsFieldName_ORGANIZATION_SETTINGS_FIELD_NAME_ORGANIZATION_ID:
|
|
return query.OrganizationSettingsColumnID
|
|
case settings.OrganizationSettingsFieldName_ORGANIZATION_SETTINGS_FIELD_NAME_CHANGE_DATE:
|
|
return query.OrganizationSettingsColumnChangeDate
|
|
case settings.OrganizationSettingsFieldName_ORGANIZATION_SETTINGS_FIELD_NAME_UNSPECIFIED:
|
|
return query.OrganizationSettingsColumnCreationDate
|
|
default:
|
|
return query.OrganizationSettingsColumnCreationDate
|
|
}
|
|
}
|
|
|
|
func organizationSettingsFiltersToQuery(queries []*settings.OrganizationSettingsSearchFilter) (_ []query.SearchQuery, err error) {
|
|
q := make([]query.SearchQuery, len(queries))
|
|
for i, qry := range queries {
|
|
q[i], err = organizationSettingsToModel(qry)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return q, nil
|
|
}
|
|
|
|
func organizationSettingsToModel(filter *settings.OrganizationSettingsSearchFilter) (query.SearchQuery, error) {
|
|
switch q := filter.Filter.(type) {
|
|
case *settings.OrganizationSettingsSearchFilter_InOrganizationIdsFilter:
|
|
return organizationInIDsFilterToQuery(q.InOrganizationIdsFilter)
|
|
case *settings.OrganizationSettingsSearchFilter_OrganizationScopedUsernamesFilter:
|
|
return organizationScopedUsernamesFilterToQuery(q.OrganizationScopedUsernamesFilter)
|
|
default:
|
|
return nil, zerrors.ThrowInvalidArgument(nil, "SETTINGS-uvTDqZHlvS", "List.Query.Invalid")
|
|
}
|
|
}
|
|
|
|
func organizationInIDsFilterToQuery(q *filter_pb.InIDsFilter) (query.SearchQuery, error) {
|
|
return query.NewOrganizationSettingsOrganizationIDSearchQuery(q.Ids)
|
|
}
|
|
|
|
func organizationScopedUsernamesFilterToQuery(q *settings.OrganizationScopedUsernamesFilter) (query.SearchQuery, error) {
|
|
return query.NewOrganizationSettingsOrganizationScopedUsernamesSearchQuery(q.OrganizationScopedUsernames)
|
|
}
|
|
|
|
func organizationSettingsListToPb(settingsList []*query.OrganizationSettings) []*settings.OrganizationSettings {
|
|
o := make([]*settings.OrganizationSettings, len(settingsList))
|
|
for i, organizationSettings := range settingsList {
|
|
o[i] = organizationSettingsToPb(organizationSettings)
|
|
}
|
|
return o
|
|
}
|
|
|
|
func organizationSettingsToPb(organizationSettings *query.OrganizationSettings) *settings.OrganizationSettings {
|
|
return &settings.OrganizationSettings{
|
|
OrganizationId: organizationSettings.ID,
|
|
CreationDate: timestamppb.New(organizationSettings.CreationDate),
|
|
ChangeDate: timestamppb.New(organizationSettings.ChangeDate),
|
|
OrganizationScopedUsernames: organizationSettings.OrganizationScopedUsernames,
|
|
}
|
|
}
|