fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! refactor(api): moving organization API resourced based

added AddOrganizationDomain & ListOrganizationDomain()
This commit is contained in:
Iraq Jaber
2025-05-02 12:10:30 +02:00
parent 96831fb5f5
commit 4d5cbc94e2
7 changed files with 613 additions and 77 deletions

View File

@@ -28,7 +28,7 @@ func InstanceToPb(instance *query.Instance) *instance_pb.Instance {
Name: instance.Name,
Domains: DomainsToPb(instance.Domains),
Version: build.Version(),
State: instance_pb.State_STATE_RUNNING, //TODO: change when delete is implemented
State: instance_pb.State_STATE_RUNNING, // TODO: change when delete is implemented
}
}
@@ -44,7 +44,7 @@ func InstanceDetailToPb(instance *query.Instance) *instance_pb.InstanceDetail {
Name: instance.Name,
Domains: DomainsToPb(instance.Domains),
Version: build.Version(),
State: instance_pb.State_STATE_RUNNING, //TODO: change when delete is implemented
State: instance_pb.State_STATE_RUNNING, // TODO: change when delete is implemented
}
}

View File

@@ -26,7 +26,7 @@ func ListOrgDomainsRequestToModel(req *mgmt_pb.ListOrgDomainsRequest) (*query.Or
Limit: limit,
Asc: asc,
},
//SortingColumn: //TODO: sorting
// SortingColumn: //TODO: sorting
Queries: queries,
}, nil
}
@@ -89,7 +89,7 @@ func ListOrgMembersRequestToModel(ctx context.Context, req *mgmt_pb.ListOrgMembe
Offset: offset,
Limit: limit,
Asc: asc,
//SortingColumn: //TODO: sorting
// SortingColumn: //TODO: sorting
},
Queries: queries,
},

View File

@@ -2,6 +2,7 @@ package object
import (
"context"
"time"
"google.golang.org/protobuf/types/known/timestamppb"
@@ -9,7 +10,8 @@ import (
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query"
object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
// object_pb "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
org_pb "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
)
func DomainToDetailsPb(objectDetail *domain.ObjectDetails) *object.Details {
@@ -82,3 +84,57 @@ func ListQueryToModel(query *object.ListQuery) (offset, limit uint64, asc bool)
}
return query.Offset, uint64(query.Limit), query.Asc
}
func DomainsToPb(domains []*query.Domain) []*org_pb.Domain {
d := make([]*org_pb.Domain, len(domains))
for i, domain := range domains {
d[i] = DomainToPb(domain)
}
return d
}
func DomainToPb(d *query.Domain) *org_pb.Domain {
return &org_pb.Domain{
OrgId: d.OrgID,
DomainName: d.Domain,
IsVerified: d.IsVerified,
IsPrimary: d.IsPrimary,
ValidationType: DomainValidationTypeFromModel(d.ValidationType),
Details: ToViewDetailsPb(
d.Sequence,
d.CreationDate,
d.ChangeDate,
d.OrgID,
),
}
}
func DomainValidationTypeFromModel(validationType domain.OrgDomainValidationType) org_pb.DomainValidationType {
switch validationType {
case domain.OrgDomainValidationTypeDNS:
return org_pb.DomainValidationType_DOMAIN_VALIDATION_TYPE_DNS
case domain.OrgDomainValidationTypeHTTP:
return org_pb.DomainValidationType_DOMAIN_VALIDATION_TYPE_HTTP
default:
return org_pb.DomainValidationType_DOMAIN_VALIDATION_TYPE_UNSPECIFIED
}
}
func ToViewDetailsPb(
sequence uint64,
creationDate,
changeDate time.Time,
resourceOwner string,
) *object.Details {
details := &object.Details{
Sequence: sequence,
ResourceOwner: resourceOwner,
}
if !creationDate.IsZero() {
details.CreationDate = timestamppb.New(creationDate)
}
if !changeDate.IsZero() {
details.ChangeDate = timestamppb.New(changeDate)
}
return details
}

View File

@@ -53,14 +53,14 @@ func OrganizationViewToPb(org *query.Org) *org_pb.Organization {
}
}
func OrgStateToPb(state domain.OrgState) org_pb.OrganizationState {
func OrgStateToPb(state domain.OrgState) org_pb.OrgState {
switch state {
case domain.OrgStateActive:
return org_pb.OrganizationState_ORGANIZATION_STATE_ACTIVE
return org_pb.OrgState_ORG_STATE_ACTIVE
case domain.OrgStateInactive:
return org_pb.OrganizationState_ORGANIZATION_STATE_INACTIVE
return org_pb.OrgState_ORG_STATE_INACTIVE
default:
return org_pb.OrganizationState_ORGANIZATION_STATE_UNSPECIFIED
return org_pb.OrgState_ORG_STATE_UNSPECIFIED
}
}
@@ -171,3 +171,49 @@ func OrgViewToPb(org *query.Org) *org_pb.Organization {
),
}
}
func ListOrgDomainsRequestToModel(req *org.ListOrganizationDomainsRequest) (*query.OrgDomainSearchQueries, error) {
offset, limit, asc := ListQueryToModel(req.Query)
// queries, err := org_grpc.DomainQueriesToModel(req.Queries)
queries, err := DomainQueriesToModel(req.Queries)
if err != nil {
return nil, err
}
return &query.OrgDomainSearchQueries{
SearchRequest: query.SearchRequest{
Offset: offset,
Limit: limit,
Asc: asc,
},
// SortingColumn: //TODO: sorting
Queries: queries,
}, nil
}
func ListQueryToModel(query *v2beta.ListQuery) (offset, limit uint64, asc bool) {
if query == nil {
return 0, 0, false
}
return query.Offset, uint64(query.Limit), query.Asc
}
func DomainQueriesToModel(queries []*org_pb.DomainSearchQuery) (_ []query.SearchQuery, err error) {
q := make([]query.SearchQuery, len(queries))
for i, query := range queries {
q[i], err = DomainQueryToModel(query)
if err != nil {
return nil, err
}
}
return q, nil
}
func DomainQueryToModel(searchQuery *org_pb.DomainSearchQuery) (query.SearchQuery, error) {
switch q := searchQuery.Query.(type) {
case *org_pb.DomainSearchQuery_DomainNameQuery:
// return query.NewOrgDomainDomainSearchQuery(object.TextMethodToQuery(q.DomainNameQuery.Method), q.DomainNameQuery.Name)
return query.NewOrgDomainDomainSearchQuery(v2beta_object.TextMethodToQuery(q.DomainNameQuery.Method), q.DomainNameQuery.Name)
default:
return nil, zerrors.ThrowInvalidArgument(nil, "ORG-Ags89", "List.Query.Invalid")
}
}

View File

@@ -3,9 +3,11 @@ package org
import (
"context"
"github.com/zitadel/zitadel/internal/api/authz"
object "github.com/zitadel/zitadel/internal/api/grpc/object/v2beta"
user "github.com/zitadel/zitadel/internal/api/grpc/user/v2beta"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/internal/zerrors"
org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
v2beta_org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
@@ -89,6 +91,51 @@ func (s *Server) ReactivateOrganization(ctx context.Context, request *org.Reacti
}, err
}
func (s *Server) AddOrganizationDomain(ctx context.Context, request *org.AddOrganizationDomainRequest) (*org.AddOrganizationDomainResponse, error) {
userIDs, err := s.getClaimedUserIDsOfOrgDomain(ctx, request.Domain, request.OrganizationId)
if err != nil {
return nil, err
}
details, err := s.command.AddOrgDomain(ctx, request.OrganizationId, request.Domain, userIDs)
if err != nil {
return nil, err
}
return &org.AddOrganizationDomainResponse{
Details: object.DomainToDetailsPb(details),
}, nil
}
func (s *Server) ListOrganizationDomains(ctx context.Context, req *org.ListOrganizationDomainsRequest) (*org.ListOrganizationDomainsResponse, error) {
queries, err := ListOrgDomainsRequestToModel(req)
if err != nil {
return nil, err
}
orgIDQuery, err := query.NewOrgDomainOrgIDSearchQuery(authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
queries.Queries = append(queries.Queries, orgIDQuery)
domains, err := s.query.SearchOrgDomains(ctx, queries, false)
if err != nil {
return nil, err
}
return &org.ListOrganizationDomainsResponse{
Result: object.DomainsToPb(domains.Domains),
Details: object.ToListDetails(domains.SearchResponse),
}, nil
}
// func (s *Server) RemoveOrganizagtionDomain(ctx context.Context, req *mgmt_pb.RemoveOrgDomainRequest) (*mgmt_pb.RemoveOrgDomainResponse, error) {
// details, err := s.command.RemoveOrgDomain(ctx, RemoveOrgDomainRequestToDomain(ctx, req))
// if err != nil {
// return nil, err
// }
// return &mgmt_pb.RemoveOrgDomainResponse{
// Details: object.DomainToChangeDetailsPb(details),
// }, err
// }
func createOrganizationRequestToCommand(request *v2beta_org.CreateOrganizationRequest) (*command.OrgSetup, error) {
admins, err := createOrganizationRequestAdminsToCommand(request.GetAdmins())
if err != nil {
@@ -132,3 +179,28 @@ func createOrganizationRequestAdminToCommand(admin *v2beta_org.CreateOrganizatio
return nil, zerrors.ThrowUnimplementedf(nil, "ORGv2-SD2r1", "userType oneOf %T in method AddOrganization not implemented", a)
}
}
func (s *Server) getClaimedUserIDsOfOrgDomain(ctx context.Context, orgDomain, orgID string) ([]string, error) {
queries := make([]query.SearchQuery, 0, 2)
loginName, err := query.NewUserPreferredLoginNameSearchQuery("@"+orgDomain, query.TextEndsWithIgnoreCase)
if err != nil {
return nil, err
}
queries = append(queries, loginName)
if orgID != "" {
owner, err := query.NewUserResourceOwnerSearchQuery(orgID, query.TextNotEquals)
if err != nil {
return nil, err
}
queries = append(queries, owner)
}
users, err := s.query.SearchUsers(ctx, &query.UserSearchQueries{Queries: queries}, nil)
if err != nil {
return nil, err
}
userIDs := make([]string, len(users.Users))
for i, user := range users.Users {
userIDs[i] = user.ID
}
return userIDs, nil
}