mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 17:27:31 +00:00
feat(api): moving organization API resourced based (#9943)
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -9,10 +9,11 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta"
|
||||
)
|
||||
|
||||
func TestDeleteInstace(t *testing.T) {
|
||||
|
@@ -11,12 +11,13 @@ import (
|
||||
"github.com/brianvoe/gofakeit/v6"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
filter "github.com/zitadel/zitadel/pkg/grpc/filter/v2beta"
|
||||
instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/object/v2"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func TestGetInstance(t *testing.T) {
|
||||
|
@@ -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,
|
||||
},
|
||||
|
@@ -901,6 +901,7 @@ func (s *Server) ListHumanLinkedIDPs(ctx context.Context, req *mgmt_pb.ListHuman
|
||||
Details: obj_grpc.ToListDetails(res.Count, res.Sequence, res.LastRun),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) RemoveHumanLinkedIDP(ctx context.Context, req *mgmt_pb.RemoveHumanLinkedIDPRequest) (*mgmt_pb.RemoveHumanLinkedIDPResponse, error) {
|
||||
objectDetails, err := s.command.RemoveUserIDPLink(ctx, RemoveHumanLinkedIDPRequestToDomain(ctx, req))
|
||||
if err != nil {
|
||||
@@ -947,18 +948,21 @@ func cascadingIAMMembership(membership *query.IAMMembership) *command.CascadingI
|
||||
}
|
||||
return &command.CascadingIAMMembership{IAMID: membership.IAMID}
|
||||
}
|
||||
|
||||
func cascadingOrgMembership(membership *query.OrgMembership) *command.CascadingOrgMembership {
|
||||
if membership == nil {
|
||||
return nil
|
||||
}
|
||||
return &command.CascadingOrgMembership{OrgID: membership.OrgID}
|
||||
}
|
||||
|
||||
func cascadingProjectMembership(membership *query.ProjectMembership) *command.CascadingProjectMembership {
|
||||
if membership == nil {
|
||||
return nil
|
||||
}
|
||||
return &command.CascadingProjectMembership{ProjectID: membership.ProjectID}
|
||||
}
|
||||
|
||||
func cascadingProjectGrantMembership(membership *query.ProjectGrantMembership) *command.CascadingProjectGrantMembership {
|
||||
if membership == nil {
|
||||
return nil
|
||||
|
49
internal/api/grpc/metadata/v2beta/metadata.go
Normal file
49
internal/api/grpc/metadata/v2beta/metadata.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package metadata
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
v2beta_object "github.com/zitadel/zitadel/internal/api/grpc/object/v2beta"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
meta_pb "github.com/zitadel/zitadel/pkg/grpc/metadata/v2beta"
|
||||
)
|
||||
|
||||
// code in this file is copied from internal/api/grpc/metadata/metadata.go
|
||||
|
||||
func OrgMetadataListToPb(dataList []*query.OrgMetadata) []*meta_pb.Metadata {
|
||||
mds := make([]*meta_pb.Metadata, len(dataList))
|
||||
for i, data := range dataList {
|
||||
mds[i] = OrgMetadataToPb(data)
|
||||
}
|
||||
return mds
|
||||
}
|
||||
|
||||
func OrgMetadataToPb(data *query.OrgMetadata) *meta_pb.Metadata {
|
||||
return &meta_pb.Metadata{
|
||||
Key: data.Key,
|
||||
Value: data.Value,
|
||||
CreationDate: timestamppb.New(data.CreationDate),
|
||||
ChangeDate: timestamppb.New(data.ChangeDate),
|
||||
}
|
||||
}
|
||||
|
||||
func OrgMetadataQueriesToQuery(queries []*meta_pb.MetadataQuery) (_ []query.SearchQuery, err error) {
|
||||
q := make([]query.SearchQuery, len(queries))
|
||||
for i, query := range queries {
|
||||
q[i], err = OrgMetadataQueryToQuery(query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func OrgMetadataQueryToQuery(metadataQuery *meta_pb.MetadataQuery) (query.SearchQuery, error) {
|
||||
switch q := metadataQuery.Query.(type) {
|
||||
case *meta_pb.MetadataQuery_KeyQuery:
|
||||
return query.NewOrgMetadataKeySearchQuery(q.KeyQuery.Key, v2beta_object.TextMethodToQuery(q.KeyQuery.Method))
|
||||
default:
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "METAD-fdg23", "List.Query.Invalid")
|
||||
}
|
||||
}
|
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
|
||||
org_pb "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
|
||||
)
|
||||
|
||||
func DomainToDetailsPb(objectDetail *domain.ObjectDetails) *object.Details {
|
||||
@@ -34,6 +35,7 @@ func ToListDetails(response query.SearchResponse) *object.ListDetails {
|
||||
|
||||
return details
|
||||
}
|
||||
|
||||
func ListQueryToQuery(query *object.ListQuery) (offset, limit uint64, asc bool) {
|
||||
if query == nil {
|
||||
return 0, 0, false
|
||||
@@ -73,3 +75,56 @@ func TextMethodToQuery(method object.TextQueryMethod) query.TextComparison {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
func ListQueryToModel(query *object.ListQuery) (offset, limit uint64, asc bool) {
|
||||
if query == nil {
|
||||
return 0, 0, false
|
||||
}
|
||||
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{
|
||||
OrganizationId: d.OrgID,
|
||||
DomainName: d.Domain,
|
||||
IsVerified: d.IsVerified,
|
||||
IsPrimary: d.IsPrimary,
|
||||
ValidationType: DomainValidationTypeFromModel(d.ValidationType),
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
case domain.OrgDomainValidationTypeUnspecified:
|
||||
// added to please golangci-lint
|
||||
return org_pb.DomainValidationType_DOMAIN_VALIDATION_TYPE_UNSPECIFIED
|
||||
default:
|
||||
return org_pb.DomainValidationType_DOMAIN_VALIDATION_TYPE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func DomainValidationTypeToDomain(validationType org_pb.DomainValidationType) domain.OrgDomainValidationType {
|
||||
switch validationType {
|
||||
case org_pb.DomainValidationType_DOMAIN_VALIDATION_TYPE_HTTP:
|
||||
return domain.OrgDomainValidationTypeHTTP
|
||||
case org_pb.DomainValidationType_DOMAIN_VALIDATION_TYPE_DNS:
|
||||
return domain.OrgDomainValidationTypeDNS
|
||||
case org_pb.DomainValidationType_DOMAIN_VALIDATION_TYPE_UNSPECIFIED:
|
||||
// added to please golangci-lint
|
||||
return domain.OrgDomainValidationTypeUnspecified
|
||||
default:
|
||||
return domain.OrgDomainValidationTypeUnspecified
|
||||
}
|
||||
}
|
||||
|
256
internal/api/grpc/org/v2beta/helper.go
Normal file
256
internal/api/grpc/org/v2beta/helper.go
Normal file
@@ -0,0 +1,256 @@
|
||||
package org
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
// TODO fix below
|
||||
filter "github.com/zitadel/zitadel/internal/api/grpc/filter/v2beta"
|
||||
metadata "github.com/zitadel/zitadel/internal/api/grpc/metadata/v2beta"
|
||||
v2beta_object "github.com/zitadel/zitadel/internal/api/grpc/object/v2beta"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/config/systemdefaults"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
v2beta "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
|
||||
org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
|
||||
v2beta_org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
|
||||
)
|
||||
|
||||
// NOTE: most of this code is copied from `internal/api/grpc/admin/*`, as we will eventually axe the previous versons of the API,
|
||||
// we will have code duplication until then
|
||||
|
||||
func listOrgRequestToModel(systemDefaults systemdefaults.SystemDefaults, request *v2beta_org.ListOrganizationsRequest) (*query.OrgSearchQueries, error) {
|
||||
offset, limit, asc, err := filter.PaginationPbToQuery(systemDefaults, request.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
queries, err := OrgQueriesToModel(request.Filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &query.OrgSearchQueries{
|
||||
SearchRequest: query.SearchRequest{
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
SortingColumn: FieldNameToOrgColumn(request.SortingColumn),
|
||||
Asc: asc,
|
||||
},
|
||||
Queries: queries,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func OrganizationViewToPb(org *query.Org) *v2beta_org.Organization {
|
||||
return &v2beta_org.Organization{
|
||||
Id: org.ID,
|
||||
State: OrgStateToPb(org.State),
|
||||
Name: org.Name,
|
||||
PrimaryDomain: org.Domain,
|
||||
CreationDate: timestamppb.New(org.CreationDate),
|
||||
ChangedDate: timestamppb.New(org.ChangeDate),
|
||||
}
|
||||
}
|
||||
|
||||
func OrgStateToPb(state domain.OrgState) v2beta_org.OrgState {
|
||||
switch state {
|
||||
case domain.OrgStateActive:
|
||||
return v2beta_org.OrgState_ORG_STATE_ACTIVE
|
||||
case domain.OrgStateInactive:
|
||||
return v2beta_org.OrgState_ORG_STATE_INACTIVE
|
||||
case domain.OrgStateRemoved:
|
||||
// added to please golangci-lint
|
||||
return v2beta_org.OrgState_ORG_STATE_REMOVED
|
||||
case domain.OrgStateUnspecified:
|
||||
// added to please golangci-lint
|
||||
return v2beta_org.OrgState_ORG_STATE_UNSPECIFIED
|
||||
default:
|
||||
return v2beta_org.OrgState_ORG_STATE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func createdOrganizationToPb(createdOrg *command.CreatedOrg) (_ *org.CreateOrganizationResponse, err error) {
|
||||
admins := make([]*org.CreatedAdmin, len(createdOrg.CreatedAdmins))
|
||||
for i, admin := range createdOrg.CreatedAdmins {
|
||||
admins[i] = &org.CreatedAdmin{
|
||||
UserId: admin.ID,
|
||||
EmailCode: admin.EmailCode,
|
||||
PhoneCode: admin.PhoneCode,
|
||||
}
|
||||
}
|
||||
return &org.CreateOrganizationResponse{
|
||||
CreationDate: timestamppb.New(createdOrg.ObjectDetails.EventDate),
|
||||
Id: createdOrg.ObjectDetails.ResourceOwner,
|
||||
CreatedAdmins: admins,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func OrgViewsToPb(orgs []*query.Org) []*v2beta_org.Organization {
|
||||
o := make([]*v2beta_org.Organization, len(orgs))
|
||||
for i, org := range orgs {
|
||||
o[i] = OrganizationViewToPb(org)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func OrgQueriesToModel(queries []*v2beta_org.OrganizationSearchFilter) (_ []query.SearchQuery, err error) {
|
||||
q := make([]query.SearchQuery, len(queries))
|
||||
for i, query := range queries {
|
||||
q[i], err = OrgQueryToModel(query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func OrgQueryToModel(apiQuery *v2beta_org.OrganizationSearchFilter) (query.SearchQuery, error) {
|
||||
switch q := apiQuery.Filter.(type) {
|
||||
case *v2beta_org.OrganizationSearchFilter_DomainFilter:
|
||||
return query.NewOrgVerifiedDomainSearchQuery(v2beta_object.TextMethodToQuery(q.DomainFilter.Method), q.DomainFilter.Domain)
|
||||
case *v2beta_org.OrganizationSearchFilter_NameFilter:
|
||||
return query.NewOrgNameSearchQuery(v2beta_object.TextMethodToQuery(q.NameFilter.Method), q.NameFilter.Name)
|
||||
case *v2beta_org.OrganizationSearchFilter_StateFilter:
|
||||
return query.NewOrgStateSearchQuery(OrgStateToDomain(q.StateFilter.State))
|
||||
case *v2beta_org.OrganizationSearchFilter_IdFilter:
|
||||
return query.NewOrgIDSearchQuery(q.IdFilter.Id)
|
||||
default:
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "ORG-vR9nC", "List.Query.Invalid")
|
||||
}
|
||||
}
|
||||
|
||||
func OrgStateToDomain(state v2beta_org.OrgState) domain.OrgState {
|
||||
switch state {
|
||||
case v2beta_org.OrgState_ORG_STATE_ACTIVE:
|
||||
return domain.OrgStateActive
|
||||
case v2beta_org.OrgState_ORG_STATE_INACTIVE:
|
||||
return domain.OrgStateInactive
|
||||
case v2beta_org.OrgState_ORG_STATE_REMOVED:
|
||||
// added to please golangci-lint
|
||||
return domain.OrgStateRemoved
|
||||
case v2beta_org.OrgState_ORG_STATE_UNSPECIFIED:
|
||||
fallthrough
|
||||
default:
|
||||
return domain.OrgStateUnspecified
|
||||
}
|
||||
}
|
||||
|
||||
func FieldNameToOrgColumn(fieldName v2beta_org.OrgFieldName) query.Column {
|
||||
switch fieldName {
|
||||
case v2beta_org.OrgFieldName_ORG_FIELD_NAME_NAME:
|
||||
return query.OrgColumnName
|
||||
case v2beta_org.OrgFieldName_ORG_FIELD_NAME_CREATION_DATE:
|
||||
return query.OrgColumnCreationDate
|
||||
case v2beta_org.OrgFieldName_ORG_FIELD_NAME_UNSPECIFIED:
|
||||
return query.Column{}
|
||||
default:
|
||||
return query.Column{}
|
||||
}
|
||||
}
|
||||
|
||||
func ListOrgDomainsRequestToModel(systemDefaults systemdefaults.SystemDefaults, request *org.ListOrganizationDomainsRequest) (*query.OrgDomainSearchQueries, error) {
|
||||
offset, limit, asc, err := filter.PaginationPbToQuery(systemDefaults, request.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
queries, err := DomainQueriesToModel(request.Filters)
|
||||
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 []*v2beta_org.DomainSearchFilter) (_ []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 *v2beta_org.DomainSearchFilter) (query.SearchQuery, error) {
|
||||
switch q := searchQuery.Filter.(type) {
|
||||
case *v2beta_org.DomainSearchFilter_DomainNameFilter:
|
||||
return query.NewOrgDomainDomainSearchQuery(v2beta_object.TextMethodToQuery(q.DomainNameFilter.Method), q.DomainNameFilter.Name)
|
||||
default:
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "ORG-Ags89", "List.Query.Invalid")
|
||||
}
|
||||
}
|
||||
|
||||
func RemoveOrgDomainRequestToDomain(ctx context.Context, req *v2beta_org.DeleteOrganizationDomainRequest) *domain.OrgDomain {
|
||||
return &domain.OrgDomain{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: req.OrganizationId,
|
||||
},
|
||||
Domain: req.Domain,
|
||||
}
|
||||
}
|
||||
|
||||
func GenerateOrgDomainValidationRequestToDomain(ctx context.Context, req *v2beta_org.GenerateOrganizationDomainValidationRequest) *domain.OrgDomain {
|
||||
return &domain.OrgDomain{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: req.OrganizationId,
|
||||
},
|
||||
Domain: req.Domain,
|
||||
ValidationType: v2beta_object.DomainValidationTypeToDomain(req.Type),
|
||||
}
|
||||
}
|
||||
|
||||
func ValidateOrgDomainRequestToDomain(ctx context.Context, req *v2beta_org.VerifyOrganizationDomainRequest) *domain.OrgDomain {
|
||||
return &domain.OrgDomain{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: req.OrganizationId,
|
||||
},
|
||||
Domain: req.Domain,
|
||||
}
|
||||
}
|
||||
|
||||
func BulkSetOrgMetadataToDomain(req *v2beta_org.SetOrganizationMetadataRequest) []*domain.Metadata {
|
||||
metadata := make([]*domain.Metadata, len(req.Metadata))
|
||||
for i, data := range req.Metadata {
|
||||
metadata[i] = &domain.Metadata{
|
||||
Key: data.Key,
|
||||
Value: data.Value,
|
||||
}
|
||||
}
|
||||
return metadata
|
||||
}
|
||||
|
||||
func ListOrgMetadataToDomain(systemDefaults systemdefaults.SystemDefaults, request *v2beta_org.ListOrganizationMetadataRequest) (*query.OrgMetadataSearchQueries, error) {
|
||||
offset, limit, asc, err := filter.PaginationPbToQuery(systemDefaults, request.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
queries, err := metadata.OrgMetadataQueriesToQuery(request.Filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &query.OrgMetadataSearchQueries{
|
||||
SearchRequest: query.SearchRequest{
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
Asc: asc,
|
||||
},
|
||||
Queries: queries,
|
||||
}, nil
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -2,16 +2,23 @@ package org
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
metadata "github.com/zitadel/zitadel/internal/api/grpc/metadata/v2beta"
|
||||
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"
|
||||
filter "github.com/zitadel/zitadel/pkg/grpc/filter/v2beta"
|
||||
org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
|
||||
v2beta_org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
|
||||
)
|
||||
|
||||
func (s *Server) AddOrganization(ctx context.Context, request *org.AddOrganizationRequest) (*org.AddOrganizationResponse, error) {
|
||||
orgSetup, err := addOrganizationRequestToCommand(request)
|
||||
func (s *Server) CreateOrganization(ctx context.Context, request *v2beta_org.CreateOrganizationRequest) (*v2beta_org.CreateOrganizationResponse, error) {
|
||||
orgSetup, err := createOrganizationRequestToCommand(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -22,8 +29,182 @@ func (s *Server) AddOrganization(ctx context.Context, request *org.AddOrganizati
|
||||
return createdOrganizationToPb(createdOrg)
|
||||
}
|
||||
|
||||
func addOrganizationRequestToCommand(request *org.AddOrganizationRequest) (*command.OrgSetup, error) {
|
||||
admins, err := addOrganizationRequestAdminsToCommand(request.GetAdmins())
|
||||
func (s *Server) UpdateOrganization(ctx context.Context, request *v2beta_org.UpdateOrganizationRequest) (*v2beta_org.UpdateOrganizationResponse, error) {
|
||||
org, err := s.command.ChangeOrg(ctx, request.Id, request.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &v2beta_org.UpdateOrganizationResponse{
|
||||
ChangeDate: timestamppb.New(org.EventDate),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ListOrganizations(ctx context.Context, request *v2beta_org.ListOrganizationsRequest) (*v2beta_org.ListOrganizationsResponse, error) {
|
||||
queries, err := listOrgRequestToModel(s.systemDefaults, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orgs, err := s.query.SearchOrgs(ctx, queries, s.checkPermission)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v2beta_org.ListOrganizationsResponse{
|
||||
Organizations: OrgViewsToPb(orgs.Orgs),
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: orgs.Count,
|
||||
AppliedLimit: uint64(request.GetPagination().GetLimit()),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) DeleteOrganization(ctx context.Context, request *v2beta_org.DeleteOrganizationRequest) (*v2beta_org.DeleteOrganizationResponse, error) {
|
||||
details, err := s.command.RemoveOrg(ctx, request.Id)
|
||||
if err != nil {
|
||||
var notFoundError *zerrors.NotFoundError
|
||||
if errors.As(err, ¬FoundError) {
|
||||
return &v2beta_org.DeleteOrganizationResponse{}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &v2beta_org.DeleteOrganizationResponse{
|
||||
DeletionDate: timestamppb.New(details.EventDate),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) SetOrganizationMetadata(ctx context.Context, request *v2beta_org.SetOrganizationMetadataRequest) (*v2beta_org.SetOrganizationMetadataResponse, error) {
|
||||
result, err := s.command.BulkSetOrgMetadata(ctx, request.OrganizationId, BulkSetOrgMetadataToDomain(request)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &org.SetOrganizationMetadataResponse{
|
||||
SetDate: timestamppb.New(result.EventDate),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ListOrganizationMetadata(ctx context.Context, request *v2beta_org.ListOrganizationMetadataRequest) (*v2beta_org.ListOrganizationMetadataResponse, error) {
|
||||
metadataQueries, err := ListOrgMetadataToDomain(s.systemDefaults, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := s.query.SearchOrgMetadata(ctx, true, request.OrganizationId, metadataQueries, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v2beta_org.ListOrganizationMetadataResponse{
|
||||
Metadata: metadata.OrgMetadataListToPb(res.Metadata),
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: res.Count,
|
||||
AppliedLimit: uint64(request.GetPagination().GetLimit()),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) DeleteOrganizationMetadata(ctx context.Context, request *v2beta_org.DeleteOrganizationMetadataRequest) (*v2beta_org.DeleteOrganizationMetadataResponse, error) {
|
||||
result, err := s.command.BulkRemoveOrgMetadata(ctx, request.OrganizationId, request.Keys...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v2beta_org.DeleteOrganizationMetadataResponse{
|
||||
DeletionDate: timestamppb.New(result.EventDate),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) DeactivateOrganization(ctx context.Context, request *org.DeactivateOrganizationRequest) (*org.DeactivateOrganizationResponse, error) {
|
||||
objectDetails, err := s.command.DeactivateOrg(ctx, request.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &org.DeactivateOrganizationResponse{
|
||||
ChangeDate: timestamppb.New(objectDetails.EventDate),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ActivateOrganization(ctx context.Context, request *org.ActivateOrganizationRequest) (*org.ActivateOrganizationResponse, error) {
|
||||
objectDetails, err := s.command.ReactivateOrg(ctx, request.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &org.ActivateOrganizationResponse{
|
||||
ChangeDate: timestamppb.New(objectDetails.EventDate),
|
||||
}, 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{
|
||||
CreationDate: timestamppb.New(details.EventDate),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ListOrganizationDomains(ctx context.Context, req *org.ListOrganizationDomainsRequest) (*org.ListOrganizationDomainsResponse, error) {
|
||||
queries, err := ListOrgDomainsRequestToModel(s.systemDefaults, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orgIDQuery, err := query.NewOrgDomainOrgIDSearchQuery(req.OrganizationId)
|
||||
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{
|
||||
Domains: object.DomainsToPb(domains.Domains),
|
||||
Pagination: &filter.PaginationResponse{
|
||||
TotalResult: domains.Count,
|
||||
AppliedLimit: uint64(req.GetPagination().GetLimit()),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) DeleteOrganizationDomain(ctx context.Context, req *org.DeleteOrganizationDomainRequest) (*org.DeleteOrganizationDomainResponse, error) {
|
||||
details, err := s.command.RemoveOrgDomain(ctx, RemoveOrgDomainRequestToDomain(ctx, req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &org.DeleteOrganizationDomainResponse{
|
||||
DeletionDate: timestamppb.New(details.EventDate),
|
||||
}, err
|
||||
}
|
||||
|
||||
func (s *Server) GenerateOrganizationDomainValidation(ctx context.Context, req *org.GenerateOrganizationDomainValidationRequest) (*org.GenerateOrganizationDomainValidationResponse, error) {
|
||||
token, url, err := s.command.GenerateOrgDomainValidation(ctx, GenerateOrgDomainValidationRequestToDomain(ctx, req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &org.GenerateOrganizationDomainValidationResponse{
|
||||
Token: token,
|
||||
Url: url,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) VerifyOrganizationDomain(ctx context.Context, request *org.VerifyOrganizationDomainRequest) (*org.VerifyOrganizationDomainResponse, error) {
|
||||
userIDs, err := s.getClaimedUserIDsOfOrgDomain(ctx, request.Domain, request.OrganizationId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
details, err := s.command.ValidateOrgDomain(ctx, ValidateOrgDomainRequestToDomain(ctx, request), userIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &org.VerifyOrganizationDomainResponse{
|
||||
ChangeDate: timestamppb.New(details.EventDate),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func createOrganizationRequestToCommand(request *v2beta_org.CreateOrganizationRequest) (*command.OrgSetup, error) {
|
||||
admins, err := createOrganizationRequestAdminsToCommand(request.GetAdmins())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -31,14 +212,14 @@ func addOrganizationRequestToCommand(request *org.AddOrganizationRequest) (*comm
|
||||
Name: request.GetName(),
|
||||
CustomDomain: "",
|
||||
Admins: admins,
|
||||
OrgID: request.GetOrgId(),
|
||||
OrgID: request.GetId(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func addOrganizationRequestAdminsToCommand(requestAdmins []*org.AddOrganizationRequest_Admin) (admins []*command.OrgSetupAdmin, err error) {
|
||||
func createOrganizationRequestAdminsToCommand(requestAdmins []*v2beta_org.CreateOrganizationRequest_Admin) (admins []*command.OrgSetupAdmin, err error) {
|
||||
admins = make([]*command.OrgSetupAdmin, len(requestAdmins))
|
||||
for i, admin := range requestAdmins {
|
||||
admins[i], err = addOrganizationRequestAdminToCommand(admin)
|
||||
admins[i], err = createOrganizationRequestAdminToCommand(admin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -46,14 +227,14 @@ func addOrganizationRequestAdminsToCommand(requestAdmins []*org.AddOrganizationR
|
||||
return admins, nil
|
||||
}
|
||||
|
||||
func addOrganizationRequestAdminToCommand(admin *org.AddOrganizationRequest_Admin) (*command.OrgSetupAdmin, error) {
|
||||
func createOrganizationRequestAdminToCommand(admin *v2beta_org.CreateOrganizationRequest_Admin) (*command.OrgSetupAdmin, error) {
|
||||
switch a := admin.GetUserType().(type) {
|
||||
case *org.AddOrganizationRequest_Admin_UserId:
|
||||
case *v2beta_org.CreateOrganizationRequest_Admin_UserId:
|
||||
return &command.OrgSetupAdmin{
|
||||
ID: a.UserId,
|
||||
Roles: admin.GetRoles(),
|
||||
}, nil
|
||||
case *org.AddOrganizationRequest_Admin_Human:
|
||||
case *v2beta_org.CreateOrganizationRequest_Admin_Human:
|
||||
human, err := user.AddUserRequestToAddHuman(a.Human)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -63,22 +244,31 @@ func addOrganizationRequestAdminToCommand(admin *org.AddOrganizationRequest_Admi
|
||||
Roles: admin.GetRoles(),
|
||||
}, nil
|
||||
default:
|
||||
return nil, zerrors.ThrowUnimplementedf(nil, "ORGv2-SD2r1", "userType oneOf %T in method AddOrganization not implemented", a)
|
||||
return nil, zerrors.ThrowUnimplementedf(nil, "ORGv2-SL2r8", "userType oneOf %T in method AddOrganization not implemented", a)
|
||||
}
|
||||
}
|
||||
|
||||
func createdOrganizationToPb(createdOrg *command.CreatedOrg) (_ *org.AddOrganizationResponse, err error) {
|
||||
admins := make([]*org.AddOrganizationResponse_CreatedAdmin, len(createdOrg.CreatedAdmins))
|
||||
for i, admin := range createdOrg.CreatedAdmins {
|
||||
admins[i] = &org.AddOrganizationResponse_CreatedAdmin{
|
||||
UserId: admin.ID,
|
||||
EmailCode: admin.EmailCode,
|
||||
PhoneCode: admin.PhoneCode,
|
||||
}
|
||||
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
|
||||
}
|
||||
return &org.AddOrganizationResponse{
|
||||
Details: object.DomainToDetailsPb(createdOrg.ObjectDetails),
|
||||
OrganizationId: createdOrg.ObjectDetails.ResourceOwner,
|
||||
CreatedAdmins: admins,
|
||||
}, nil
|
||||
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
|
||||
}
|
||||
|
@@ -12,14 +12,13 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
|
||||
org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
|
||||
user "github.com/zitadel/zitadel/pkg/grpc/user/v2beta"
|
||||
)
|
||||
|
||||
func Test_addOrganizationRequestToCommand(t *testing.T) {
|
||||
func Test_createOrganizationRequestToCommand(t *testing.T) {
|
||||
type args struct {
|
||||
request *org.AddOrganizationRequest
|
||||
request *org.CreateOrganizationRequest
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -30,21 +29,21 @@ func Test_addOrganizationRequestToCommand(t *testing.T) {
|
||||
{
|
||||
name: "nil user",
|
||||
args: args{
|
||||
request: &org.AddOrganizationRequest{
|
||||
request: &org.CreateOrganizationRequest{
|
||||
Name: "name",
|
||||
Admins: []*org.AddOrganizationRequest_Admin{
|
||||
Admins: []*org.CreateOrganizationRequest_Admin{
|
||||
{},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: zerrors.ThrowUnimplementedf(nil, "ORGv2-SD2r1", "userType oneOf %T in method AddOrganization not implemented", nil),
|
||||
wantErr: zerrors.ThrowUnimplementedf(nil, "ORGv2-SL2r8", "userType oneOf %T in method AddOrganization not implemented", nil),
|
||||
},
|
||||
{
|
||||
name: "custom org ID",
|
||||
args: args{
|
||||
request: &org.AddOrganizationRequest{
|
||||
Name: "custom org ID",
|
||||
OrgId: gu.Ptr("org-ID"),
|
||||
request: &org.CreateOrganizationRequest{
|
||||
Name: "custom org ID",
|
||||
Id: gu.Ptr("org-ID"),
|
||||
},
|
||||
},
|
||||
want: &command.OrgSetup{
|
||||
@@ -57,11 +56,11 @@ func Test_addOrganizationRequestToCommand(t *testing.T) {
|
||||
{
|
||||
name: "user ID",
|
||||
args: args{
|
||||
request: &org.AddOrganizationRequest{
|
||||
request: &org.CreateOrganizationRequest{
|
||||
Name: "name",
|
||||
Admins: []*org.AddOrganizationRequest_Admin{
|
||||
Admins: []*org.CreateOrganizationRequest_Admin{
|
||||
{
|
||||
UserType: &org.AddOrganizationRequest_Admin_UserId{
|
||||
UserType: &org.CreateOrganizationRequest_Admin_UserId{
|
||||
UserId: "userID",
|
||||
},
|
||||
Roles: nil,
|
||||
@@ -82,11 +81,11 @@ func Test_addOrganizationRequestToCommand(t *testing.T) {
|
||||
{
|
||||
name: "human user",
|
||||
args: args{
|
||||
request: &org.AddOrganizationRequest{
|
||||
request: &org.CreateOrganizationRequest{
|
||||
Name: "name",
|
||||
Admins: []*org.AddOrganizationRequest_Admin{
|
||||
Admins: []*org.CreateOrganizationRequest_Admin{
|
||||
{
|
||||
UserType: &org.AddOrganizationRequest_Admin_Human{
|
||||
UserType: &org.CreateOrganizationRequest_Admin_Human{
|
||||
Human: &user.AddHumanUserRequest{
|
||||
Profile: &user.SetHumanProfile{
|
||||
GivenName: "firstname",
|
||||
@@ -124,7 +123,7 @@ func Test_addOrganizationRequestToCommand(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := addOrganizationRequestToCommand(tt.args.request)
|
||||
got, err := createOrganizationRequestToCommand(tt.args.request)
|
||||
require.ErrorIs(t, err, tt.wantErr)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
@@ -139,7 +138,7 @@ func Test_createdOrganizationToPb(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *org.AddOrganizationResponse
|
||||
want *org.CreateOrganizationResponse
|
||||
wantErr error
|
||||
}{
|
||||
{
|
||||
@@ -160,14 +159,10 @@ func Test_createdOrganizationToPb(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &org.AddOrganizationResponse{
|
||||
Details: &object.Details{
|
||||
Sequence: 1,
|
||||
ChangeDate: timestamppb.New(now),
|
||||
ResourceOwner: "orgID",
|
||||
},
|
||||
OrganizationId: "orgID",
|
||||
CreatedAdmins: []*org.AddOrganizationResponse_CreatedAdmin{
|
||||
want: &org.CreateOrganizationResponse{
|
||||
CreationDate: timestamppb.New(now),
|
||||
Id: "orgID",
|
||||
CreatedAdmins: []*org.CreatedAdmin{
|
||||
{
|
||||
UserId: "id",
|
||||
EmailCode: gu.Ptr("emailCode"),
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/api/grpc/server"
|
||||
"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"
|
||||
org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
|
||||
@@ -15,6 +16,7 @@ var _ org.OrganizationServiceServer = (*Server)(nil)
|
||||
|
||||
type Server struct {
|
||||
org.UnimplementedOrganizationServiceServer
|
||||
systemDefaults systemdefaults.SystemDefaults
|
||||
command *command.Commands
|
||||
query *query.Queries
|
||||
checkPermission domain.PermissionCheck
|
||||
@@ -23,11 +25,13 @@ type Server struct {
|
||||
type Config struct{}
|
||||
|
||||
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,
|
||||
|
Reference in New Issue
Block a user