fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! Merge branch 'main' into org_api

This commit is contained in:
Iraq Jaber
2025-05-19 17:22:50 +02:00
parent 07ffc92481
commit fe74d6b88d
5 changed files with 204 additions and 144 deletions

View File

@@ -28,7 +28,7 @@ func listOrgRequestToModel(systemDefaults systemdefaults.SystemDefaults, request
if err != nil { if err != nil {
return nil, err return nil, err
} }
queries, err := OrgQueriesToModel(request.OrganizationSearchFilter) queries, err := OrgQueriesToModel(request.Filter)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -85,7 +85,7 @@ func createdOrganizationToPb(createdOrg *command.CreatedOrg) (_ *org.CreateOrgan
} }
} }
return &org.CreateOrganizationResponse{ return &org.CreateOrganizationResponse{
CreatedDate: timestamppb.New(createdOrg.ObjectDetails.EventDate), CreationDate: timestamppb.New(createdOrg.ObjectDetails.EventDate),
Id: createdOrg.ObjectDetails.ResourceOwner, Id: createdOrg.ObjectDetails.ResourceOwner,
CreatedAdmins: admins, CreatedAdmins: admins,
}, nil }, nil
@@ -99,7 +99,7 @@ func OrgViewsToPb(orgs []*query.Org) []*v2beta_org.Organization {
return o return o
} }
func OrgQueriesToModel(queries []*v2beta_org.OrgQueryFilter) (_ []query.SearchQuery, err error) { func OrgQueriesToModel(queries []*v2beta_org.OrganizationSearchFilter) (_ []query.SearchQuery, err error) {
q := make([]query.SearchQuery, len(queries)) q := make([]query.SearchQuery, len(queries))
for i, query := range queries { for i, query := range queries {
q[i], err = OrgQueryToModel(query) q[i], err = OrgQueryToModel(query)
@@ -110,15 +110,20 @@ func OrgQueriesToModel(queries []*v2beta_org.OrgQueryFilter) (_ []query.SearchQu
return q, nil return q, nil
} }
func OrgQueryToModel(apiQuery *v2beta_org.OrgQueryFilter) (query.SearchQuery, error) { // *OrganizationSearchFilter_NameQuery
// *OrganizationSearchFilter_DomainQuery
// *OrganizationSearchFilter_StateQuery
// *OrganizationSearchFilter_IdQuery
func OrgQueryToModel(apiQuery *v2beta_org.OrganizationSearchFilter) (query.SearchQuery, error) {
switch q := apiQuery.Query.(type) { switch q := apiQuery.Query.(type) {
case *v2beta_org.OrgQueryFilter_DomainQuery: case *v2beta_org.OrganizationSearchFilter_DomainQuery:
return query.NewOrgVerifiedDomainSearchQuery(v2beta_object.TextMethodToQuery(q.DomainQuery.Method), q.DomainQuery.Domain) return query.NewOrgVerifiedDomainSearchQuery(v2beta_object.TextMethodToQuery(q.DomainQuery.Method), q.DomainQuery.Domain)
case *v2beta_org.OrgQueryFilter_NameQuery: case *v2beta_org.OrganizationSearchFilter_NameQuery:
return query.NewOrgNameSearchQuery(v2beta_object.TextMethodToQuery(q.NameQuery.Method), q.NameQuery.Name) return query.NewOrgNameSearchQuery(v2beta_object.TextMethodToQuery(q.NameQuery.Method), q.NameQuery.Name)
case *v2beta_org.OrgQueryFilter_StateQuery: case *v2beta_org.OrganizationSearchFilter_StateQuery:
return query.NewOrgStateSearchQuery(OrgStateToDomain(q.StateQuery.State)) return query.NewOrgStateSearchQuery(OrgStateToDomain(q.StateQuery.State))
case *v2beta_org.OrgQueryFilter_IdQuery: case *v2beta_org.OrganizationSearchFilter_IdQuery:
return query.NewOrgIDSearchQuery(q.IdQuery.Id) return query.NewOrgIDSearchQuery(q.IdQuery.Id)
default: default:
return nil, zerrors.ThrowInvalidArgument(nil, "ORG-vR9nC", "List.Query.Invalid") return nil, zerrors.ThrowInvalidArgument(nil, "ORG-vR9nC", "List.Query.Invalid")
@@ -229,7 +234,7 @@ func RemoveOrgDomainRequestToDomain(ctx context.Context, req *v2beta_org.DeleteO
func GenerateOrgDomainValidationRequestToDomain(ctx context.Context, req *v2beta_org.GenerateOrganizationDomainValidationRequest) *domain.OrgDomain { func GenerateOrgDomainValidationRequestToDomain(ctx context.Context, req *v2beta_org.GenerateOrganizationDomainValidationRequest) *domain.OrgDomain {
return &domain.OrgDomain{ return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: req.Id, AggregateID: req.OrganizationId,
}, },
Domain: req.Domain, Domain: req.Domain,
ValidationType: v2beta_object.DomainValidationTypeToDomain(req.Type), ValidationType: v2beta_object.DomainValidationTypeToDomain(req.Type),
@@ -239,7 +244,7 @@ func GenerateOrgDomainValidationRequestToDomain(ctx context.Context, req *v2beta
func ValidateOrgDomainRequestToDomain(ctx context.Context, req *v2beta_org.VerifyOrganizationDomainRequest) *domain.OrgDomain { func ValidateOrgDomainRequestToDomain(ctx context.Context, req *v2beta_org.VerifyOrganizationDomainRequest) *domain.OrgDomain {
return &domain.OrgDomain{ return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: req.Id, AggregateID: req.OrganizationId,
}, },
Domain: req.Domain, Domain: req.Domain,
} }

View File

@@ -5,7 +5,6 @@ package org_test
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"os" "os"
"strings" "strings"
"testing" "testing"
@@ -42,7 +41,6 @@ func TestMain(m *testing.M) {
Client = Instance.Client.OrgV2beta Client = Instance.Client.OrgV2beta
AdminClient = Instance.Client.Admin AdminClient = Instance.Client.Admin
CTX = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner)
CTX = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner) CTX = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner)
User = Instance.CreateHumanUser(CTX) User = Instance.CreateHumanUser(CTX)
return m.Run() return m.Run()
@@ -194,7 +192,7 @@ func TestServer_CreateOrganization(t *testing.T) {
} }
func TestServer_UpdateOrganization(t *testing.T) { func TestServer_UpdateOrganization(t *testing.T) {
orgs, orgsName, err := createOrgs(1) orgs, orgsName, err := createOrgs(CTX, Client, 1)
if err != nil { if err != nil {
assert.Fail(t, "unable to create org") assert.Fail(t, "unable to create org")
} }
@@ -225,7 +223,7 @@ func TestServer_UpdateOrganization(t *testing.T) {
}, },
}, },
{ {
name: "update org with non existanet org id", name: "update org with non existent org id",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
req: &v2beta_org.UpdateOrganizationRequest{ req: &v2beta_org.UpdateOrganizationRequest{
Id: "non existant org id", Id: "non existant org id",
@@ -237,8 +235,8 @@ func TestServer_UpdateOrganization(t *testing.T) {
name: "update org with no id", name: "update org with no id",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
req: &v2beta_org.UpdateOrganizationRequest{ req: &v2beta_org.UpdateOrganizationRequest{
Id: orgId, Id: "",
// Name: "", Name: orgName,
}, },
wantErr: true, wantErr: true,
}, },
@@ -261,14 +259,21 @@ func TestServer_UpdateOrganization(t *testing.T) {
} }
func TestServer_ListOrganization(t *testing.T) { func TestServer_ListOrganization(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
defer cancel()
ListOrgIinstance := integration.NewInstance(ctx)
listOrgIAmOwnerCtx := ListOrgIinstance.WithAuthorization(ctx, integration.UserTypeIAMOwner)
listOrgClient := ListOrgIinstance.Client.OrgV2beta
noOfOrgs := 3 noOfOrgs := 3
orgs, orgsName, err := createOrgs(noOfOrgs) orgs, orgsName, err := createOrgs(listOrgIAmOwnerCtx, listOrgClient, noOfOrgs)
if err != nil { if err != nil {
assert.Fail(t, "unable to create orgs") require.NoError(t, err)
return
} }
// deactivat org[1] // deactivat org[1]
_, err = Client.DeactivateOrganization(CTX, &v2beta_org.DeactivateOrganizationRequest{ _, err = listOrgClient.DeactivateOrganization(listOrgIAmOwnerCtx, &v2beta_org.DeactivateOrganizationRequest{
Id: orgs[1].Id, Id: orgs[1].Id,
}) })
require.NoError(t, err) require.NoError(t, err)
@@ -282,8 +287,12 @@ func TestServer_ListOrganization(t *testing.T) {
}{ }{
{ {
name: "list organizations happy path, no filter", name: "list organizations happy path, no filter",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: ListOrgIinstance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
want: []*v2beta_org.Organization{ want: []*v2beta_org.Organization{
{
// default org
Name: "testinstance",
},
{ {
Id: orgs[0].Id, Id: orgs[0].Id,
Name: orgsName[0], Name: orgsName[0],
@@ -300,7 +309,7 @@ func TestServer_ListOrganization(t *testing.T) {
}, },
{ {
name: "list organizations by id happy path", name: "list organizations by id happy path",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: ListOrgIinstance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
query: []*v2beta_org.OrgQueryFilter{ query: []*v2beta_org.OrgQueryFilter{
{ {
Query: &v2beta_org.OrgQueryFilter_IdQuery{ Query: &v2beta_org.OrgQueryFilter_IdQuery{
@@ -319,7 +328,7 @@ func TestServer_ListOrganization(t *testing.T) {
}, },
{ {
name: "list organizations by state active", name: "list organizations by state active",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: ListOrgIinstance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
query: []*v2beta_org.OrgQueryFilter{ query: []*v2beta_org.OrgQueryFilter{
{ {
Query: &v2beta_org.OrgQueryFilter_StateQuery{ Query: &v2beta_org.OrgQueryFilter_StateQuery{
@@ -330,6 +339,10 @@ func TestServer_ListOrganization(t *testing.T) {
}, },
}, },
want: []*v2beta_org.Organization{ want: []*v2beta_org.Organization{
{
// default org
Name: "testinstance",
},
{ {
Id: orgs[0].Id, Id: orgs[0].Id,
Name: orgsName[0], Name: orgsName[0],
@@ -342,7 +355,7 @@ func TestServer_ListOrganization(t *testing.T) {
}, },
{ {
name: "list organizations by state inactive", name: "list organizations by state inactive",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: ListOrgIinstance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
query: []*v2beta_org.OrgQueryFilter{ query: []*v2beta_org.OrgQueryFilter{
{ {
Query: &v2beta_org.OrgQueryFilter_StateQuery{ Query: &v2beta_org.OrgQueryFilter_StateQuery{
@@ -361,7 +374,7 @@ func TestServer_ListOrganization(t *testing.T) {
}, },
{ {
name: "list organizations by id bad id", name: "list organizations by id bad id",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: ListOrgIinstance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
query: []*v2beta_org.OrgQueryFilter{ query: []*v2beta_org.OrgQueryFilter{
{ {
Query: &v2beta_org.OrgQueryFilter_IdQuery{ Query: &v2beta_org.OrgQueryFilter_IdQuery{
@@ -374,7 +387,7 @@ func TestServer_ListOrganization(t *testing.T) {
}, },
{ {
name: "list organizations specify org name equals", name: "list organizations specify org name equals",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: ListOrgIinstance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
query: []*v2beta_org.OrgQueryFilter{ query: []*v2beta_org.OrgQueryFilter{
{ {
Query: &v2beta_org.OrgQueryFilter_NameQuery{ Query: &v2beta_org.OrgQueryFilter_NameQuery{
@@ -394,7 +407,7 @@ func TestServer_ListOrganization(t *testing.T) {
}, },
{ {
name: "list organizations specify org name contains", name: "list organizations specify org name contains",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: ListOrgIinstance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
query: []*v2beta_org.OrgQueryFilter{ query: []*v2beta_org.OrgQueryFilter{
{ {
Query: &v2beta_org.OrgQueryFilter_NameQuery{ Query: &v2beta_org.OrgQueryFilter_NameQuery{
@@ -416,7 +429,7 @@ func TestServer_ListOrganization(t *testing.T) {
}, },
{ {
name: "list organizations specify org name contains IGNORE CASE", name: "list organizations specify org name contains IGNORE CASE",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: ListOrgIinstance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
query: []*v2beta_org.OrgQueryFilter{ query: []*v2beta_org.OrgQueryFilter{
{ {
Query: &v2beta_org.OrgQueryFilter_NameQuery{ Query: &v2beta_org.OrgQueryFilter_NameQuery{
@@ -438,13 +451,13 @@ func TestServer_ListOrganization(t *testing.T) {
}, },
{ {
name: "list organizations specify domain name equals", name: "list organizations specify domain name equals",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: ListOrgIinstance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
query: []*v2beta_org.OrgQueryFilter{ query: []*v2beta_org.OrgQueryFilter{
{ {
Query: &org.OrgQueryFilter_DomainQuery{ Query: &org.OrgQueryFilter_DomainQuery{
DomainQuery: &org.OrgDomainQuery{ DomainQuery: &org.OrgDomainQuery{
Domain: func() string { Domain: func() string {
listOrgRes, err := Client.ListOrganizations(CTX, &v2beta_org.ListOrganizationsRequest{ listOrgRes, err := listOrgClient.ListOrganizations(listOrgIAmOwnerCtx, &v2beta_org.ListOrganizationsRequest{
OrganizationSearchFilter: []*v2beta_org.OrgQueryFilter{ OrganizationSearchFilter: []*v2beta_org.OrgQueryFilter{
{ {
Query: &v2beta_org.OrgQueryFilter_IdQuery{ Query: &v2beta_org.OrgQueryFilter_IdQuery{
@@ -473,7 +486,7 @@ func TestServer_ListOrganization(t *testing.T) {
}, },
{ {
name: "list organizations specify domain name contains", name: "list organizations specify domain name contains",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: ListOrgIinstance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
query: []*v2beta_org.OrgQueryFilter{ query: []*v2beta_org.OrgQueryFilter{
{ {
Query: &org.OrgQueryFilter_DomainQuery{ Query: &org.OrgQueryFilter_DomainQuery{
@@ -496,7 +509,7 @@ func TestServer_ListOrganization(t *testing.T) {
}, },
{ {
name: "list organizations specify org name contains IGNORE CASE", name: "list organizations specify org name contains IGNORE CASE",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: ListOrgIinstance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
query: []*v2beta_org.OrgQueryFilter{ query: []*v2beta_org.OrgQueryFilter{
{ {
Query: &org.OrgQueryFilter_DomainQuery{ Query: &org.OrgQueryFilter_DomainQuery{
@@ -522,7 +535,7 @@ func TestServer_ListOrganization(t *testing.T) {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(context.Background(), 10*time.Minute) retryDuration, tick := integration.WaitForAndTickWithMaxDuration(context.Background(), 10*time.Minute)
require.EventuallyWithT(t, func(ttt *assert.CollectT) { require.EventuallyWithT(t, func(ttt *assert.CollectT) {
got, err := Client.ListOrganizations(tt.ctx, &v2beta_org.ListOrganizationsRequest{ got, err := listOrgClient.ListOrganizations(tt.ctx, &v2beta_org.ListOrganizationsRequest{
OrganizationSearchFilter: tt.query, OrganizationSearchFilter: tt.query,
}) })
@@ -532,9 +545,25 @@ func TestServer_ListOrganization(t *testing.T) {
} }
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, uint64(len(tt.want)), got.Pagination.GetTotalResult())
foundOrgs := 0 foundOrgs := 0
for _, got := range got.Organizations { for _, got := range got.Organizations {
for _, org := range tt.want { for _, org := range tt.want {
// created/chagned date
gotCD := got.Details.GetCreationDate().AsTime()
now := time.Now()
assert.WithinRange(t, gotCD, now.Add(-time.Minute), now.Add(time.Minute))
gotCD = got.Details.GetChangeDate().AsTime()
assert.WithinRange(t, gotCD, now.Add(-time.Minute), now.Add(time.Minute))
// default org
if org.Name == got.Name && got.Name == "testinstance" {
foundOrgs += 1
continue
}
if org.Name == got.Name && if org.Name == got.Name &&
org.Id == got.Id { org.Id == got.Id {
foundOrgs += 1 foundOrgs += 1
@@ -554,13 +583,14 @@ func TestServer_DeleteOrganization(t *testing.T) {
createOrgFunc func() string createOrgFunc func() string
req *v2beta_org.DeleteOrganizationRequest req *v2beta_org.DeleteOrganizationRequest
want *v2beta_org.DeleteOrganizationResponse want *v2beta_org.DeleteOrganizationResponse
dontCheckTime bool
err error err error
}{ }{
{ {
name: "delete org happy path", name: "delete org happy path",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
createOrgFunc: func() string { createOrgFunc: func() string {
orgs, _, err := createOrgs(1) orgs, _, err := createOrgs(CTX, Client, 1)
if err != nil { if err != nil {
assert.Fail(t, "unable to create org") assert.Fail(t, "unable to create org")
} }
@@ -568,13 +598,30 @@ func TestServer_DeleteOrganization(t *testing.T) {
}, },
req: &v2beta_org.DeleteOrganizationRequest{}, req: &v2beta_org.DeleteOrganizationRequest{},
}, },
{
name: "delete already deleted org",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
createOrgFunc: func() string {
orgs, _, err := createOrgs(CTX, Client, 1)
if err != nil {
assert.Fail(t, "unable to create org")
}
// delete org
_, err = Client.DeleteOrganization(CTX, &v2beta_org.DeleteOrganizationRequest{Id: orgs[0].Id})
require.NoError(t, err)
return orgs[0].Id
},
req: &v2beta_org.DeleteOrganizationRequest{},
dontCheckTime: true,
},
{ {
name: "delete non existent org", name: "delete non existent org",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner), ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeIAMOwner),
req: &v2beta_org.DeleteOrganizationRequest{ req: &v2beta_org.DeleteOrganizationRequest{
Id: "non existent org id", Id: "non existent org id",
}, },
err: fmt.Errorf("Organisation not found"), dontCheckTime: true,
}, },
} }
for _, tt := range tests { for _, tt := range tests {
@@ -592,8 +639,10 @@ func TestServer_DeleteOrganization(t *testing.T) {
// check details // check details
gotCD := got.GetChangeDate().AsTime() gotCD := got.GetChangeDate().AsTime()
now := time.Now() if !tt.dontCheckTime {
assert.WithinRange(t, gotCD, now.Add(-time.Minute), now.Add(time.Minute)) now := time.Now()
assert.WithinRange(t, gotCD, now.Add(-time.Minute), now.Add(time.Minute))
}
listOrgRes, err := Client.ListOrganizations(tt.ctx, &v2beta_org.ListOrganizationsRequest{ listOrgRes, err := Client.ListOrganizations(tt.ctx, &v2beta_org.ListOrganizationsRequest{
OrganizationSearchFilter: []*v2beta_org.OrgQueryFilter{ OrganizationSearchFilter: []*v2beta_org.OrgQueryFilter{
@@ -630,7 +679,7 @@ func TestServer_DeactivateReactivateNonExistentOrganization(t *testing.T) {
func TestServer_DeactivateReactivateOrganization(t *testing.T) { func TestServer_DeactivateReactivateOrganization(t *testing.T) {
// 1. create organization // 1. create organization
orgs, _, err := createOrgs(1) orgs, _, err := createOrgs(CTX, Client, 1)
if err != nil { if err != nil {
assert.Fail(t, "unable to create orgs") assert.Fail(t, "unable to create orgs")
} }
@@ -748,7 +797,7 @@ func TestServer_DeactivateReactivateOrganization(t *testing.T) {
func TestServer_AddOListDeleterganizationDomain(t *testing.T) { func TestServer_AddOListDeleterganizationDomain(t *testing.T) {
// 1. create organization // 1. create organization
orgs, _, err := createOrgs(1) orgs, _, err := createOrgs(CTX, Client, 1)
if err != nil { if err != nil {
assert.Fail(t, "unable to create org") assert.Fail(t, "unable to create org")
} }
@@ -858,7 +907,7 @@ func TestServer_AddOListDeleterganizationDomain(t *testing.T) {
} }
func TestServer_ValidateOrganizationDomain(t *testing.T) { func TestServer_ValidateOrganizationDomain(t *testing.T) {
orgs, _, err := createOrgs(1) orgs, _, err := createOrgs(CTX, Client, 1)
if err != nil { if err != nil {
assert.Fail(t, "unable to create org") assert.Fail(t, "unable to create org")
} }
@@ -951,7 +1000,7 @@ func TestServer_ValidateOrganizationDomain(t *testing.T) {
} }
func TestServer_SetOrganizationMetadata(t *testing.T) { func TestServer_SetOrganizationMetadata(t *testing.T) {
orgs, _, err := createOrgs(1) orgs, _, err := createOrgs(CTX, Client, 1)
if err != nil { if err != nil {
assert.Fail(t, "unable to create org") assert.Fail(t, "unable to create org")
} }
@@ -1068,7 +1117,7 @@ func TestServer_SetOrganizationMetadata(t *testing.T) {
} }
func TestServer_ListOrganizationMetadata(t *testing.T) { func TestServer_ListOrganizationMetadata(t *testing.T) {
orgs, _, err := createOrgs(1) orgs, _, err := createOrgs(CTX, Client, 1)
if err != nil { if err != nil {
assert.Fail(t, "unable to create org") assert.Fail(t, "unable to create org")
} }
@@ -1178,7 +1227,7 @@ func TestServer_ListOrganizationMetadata(t *testing.T) {
} }
func TestServer_DeleteOrganizationMetadata(t *testing.T) { func TestServer_DeleteOrganizationMetadata(t *testing.T) {
orgs, _, err := createOrgs(1) orgs, _, err := createOrgs(CTX, Client, 1)
if err != nil { if err != nil {
assert.Fail(t, "unable to create org") assert.Fail(t, "unable to create org")
} }
@@ -1371,8 +1420,8 @@ func TestServer_DeleteOrganizationMetadata(t *testing.T) {
// run delete // run delete
_, err = Client.DeleteOrganizationMetadata(tt.ctx, &v2beta_org.DeleteOrganizationMetadataRequest{ _, err = Client.DeleteOrganizationMetadata(tt.ctx, &v2beta_org.DeleteOrganizationMetadataRequest{
Id: tt.orgId, OrganizationId: tt.orgId,
Keys: keys, Keys: keys,
}) })
if tt.err != nil { if tt.err != nil {
require.Contains(t, err.Error(), tt.err.Error()) require.Contains(t, err.Error(), tt.err.Error())
@@ -1415,7 +1464,7 @@ func TestServer_DeleteOrganizationMetadata(t *testing.T) {
} }
} }
func createOrgs(noOfOrgs int) ([]*v2beta_org.CreateOrganizationResponse, []string, error) { func createOrgs(ctx context.Context, client v2beta_org.OrganizationServiceClient, noOfOrgs int) ([]*v2beta_org.CreateOrganizationResponse, []string, error) {
var err error var err error
orgs := make([]*v2beta_org.CreateOrganizationResponse, noOfOrgs) orgs := make([]*v2beta_org.CreateOrganizationResponse, noOfOrgs)
orgsName := make([]string, noOfOrgs) orgsName := make([]string, noOfOrgs)
@@ -1423,7 +1472,7 @@ func createOrgs(noOfOrgs int) ([]*v2beta_org.CreateOrganizationResponse, []strin
for i := range noOfOrgs { for i := range noOfOrgs {
orgName := gofakeit.Name() orgName := gofakeit.Name()
orgsName[i] = orgName orgsName[i] = orgName
orgs[i], err = Client.CreateOrganization(CTX, orgs[i], err = client.CreateOrganization(ctx,
&v2beta_org.CreateOrganizationRequest{ &v2beta_org.CreateOrganizationRequest{
Name: orgName, Name: orgName,
}, },

View File

@@ -2,6 +2,7 @@ package org
import ( import (
"context" "context"
"errors"
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
@@ -44,7 +45,7 @@ func (s *Server) ListOrganizations(ctx context.Context, request *v2beta_org.List
if err != nil { if err != nil {
return nil, err return nil, err
} }
orgs, err := s.query.SearchOrgs(ctx, queries, nil) orgs, err := s.query.SearchOrgs(ctx, queries, s.checkPermission)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -60,10 +61,14 @@ func (s *Server) ListOrganizations(ctx context.Context, request *v2beta_org.List
func (s *Server) DeleteOrganization(ctx context.Context, request *v2beta_org.DeleteOrganizationRequest) (*v2beta_org.DeleteOrganizationResponse, error) { func (s *Server) DeleteOrganization(ctx context.Context, request *v2beta_org.DeleteOrganizationRequest) (*v2beta_org.DeleteOrganizationResponse, error) {
details, err := s.command.RemoveOrg(ctx, request.Id) details, err := s.command.RemoveOrg(ctx, request.Id)
if err != nil { if err != nil {
var notFoundError *zerrors.NotFoundError
if errors.As(err, &notFoundError) {
return &v2beta_org.DeleteOrganizationResponse{}, nil
}
return nil, err return nil, err
} }
return &v2beta_org.DeleteOrganizationResponse{ return &v2beta_org.DeleteOrganizationResponse{
ChangeDate: timestamppb.New(details.EventDate), DeletionDate: timestamppb.New(details.EventDate),
}, nil }, nil
} }
@@ -82,7 +87,7 @@ func (s *Server) ListOrganizationMetadata(ctx context.Context, request *v2beta_o
if err != nil { if err != nil {
return nil, err return nil, err
} }
res, err := s.query.SearchOrgMetadata(ctx, true, request.Id, metadataQueries, false) res, err := s.query.SearchOrgMetadata(ctx, true, request.OrganizationId, metadataQueries, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -96,7 +101,7 @@ func (s *Server) ListOrganizationMetadata(ctx context.Context, request *v2beta_o
} }
func (s *Server) DeleteOrganizationMetadata(ctx context.Context, request *v2beta_org.DeleteOrganizationMetadataRequest) (*v2beta_org.DeleteOrganizationMetadataResponse, error) { func (s *Server) DeleteOrganizationMetadata(ctx context.Context, request *v2beta_org.DeleteOrganizationMetadataRequest) (*v2beta_org.DeleteOrganizationMetadataResponse, error) {
result, err := s.command.BulkRemoveOrgMetadata(ctx, request.Id, request.Keys...) result, err := s.command.BulkRemoveOrgMetadata(ctx, request.OrganizationId, request.Keys...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -135,7 +140,7 @@ func (s *Server) AddOrganizationDomain(ctx context.Context, request *org.AddOrga
return nil, err return nil, err
} }
return &org.AddOrganizationDomainResponse{ return &org.AddOrganizationDomainResponse{
CreatedDate: timestamppb.New(details.EventDate), CreationDate: timestamppb.New(details.EventDate),
}, nil }, nil
} }
@@ -185,7 +190,7 @@ func (s *Server) GenerateOrganizationDomainValidation(ctx context.Context, req *
} }
func (s *Server) VerifyOrganizationDomain(ctx context.Context, request *org.VerifyOrganizationDomainRequest) (*org.VerifyOrganizationDomainResponse, error) { func (s *Server) VerifyOrganizationDomain(ctx context.Context, request *org.VerifyOrganizationDomainRequest) (*org.VerifyOrganizationDomainResponse, error) {
userIDs, err := s.getClaimedUserIDsOfOrgDomain(ctx, request.Domain, request.Id) userIDs, err := s.getClaimedUserIDsOfOrgDomain(ctx, request.Domain, request.OrganizationId)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -45,7 +45,7 @@ enum OrgFieldName {
ORG_FIELD_NAME_CREATION_DATE = 2; ORG_FIELD_NAME_CREATION_DATE = 2;
} }
message OrgQueryFilter { message OrganizationSearchFilter{
oneof query { oneof query {
option (validate.required) = true; option (validate.required) = true;

View File

@@ -19,93 +19,93 @@ import "zitadel/filter/v2beta/filter.proto";
option go_package = "github.com/zitadel/zitadel/pkg/grpc/org/v2beta;org"; option go_package = "github.com/zitadel/zitadel/pkg/grpc/org/v2beta;org";
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
// info: { info: {
// title: "Organization Service (Beta)"; title: "Organization Service (Beta)";
// version: "2.0-beta"; version: "2.0-beta";
// description: "This API is intended to manage organizations in a ZITADEL instance. This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login."; description: "This API is intended to manage organizations in a ZITADEL instance. This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login.";
// contact:{ contact:{
// name: "ZITADEL" name: "ZITADEL"
// url: "https://zitadel.com" url: "https://zitadel.com"
// email: "hi@zitadel.com" email: "hi@zitadel.com"
// } }
// license: { license: {
// name: "Apache 2.0", name: "Apache 2.0",
// url: "https://github.com/zitadel/zitadel/blob/main/LICENSING.md"; url: "https://github.com/zitadel/zitadel/blob/main/LICENSING.md";
// }; };
// }; };
// schemes: HTTPS; schemes: HTTPS;
// schemes: HTTP; schemes: HTTP;
// consumes: "application/json"; consumes: "application/json";
// consumes: "application/grpc"; consumes: "application/grpc";
// produces: "application/json"; produces: "application/json";
// produces: "application/grpc"; produces: "application/grpc";
// consumes: "application/grpc-web+proto"; consumes: "application/grpc-web+proto";
// produces: "application/grpc-web+proto"; produces: "application/grpc-web+proto";
// host: "$CUSTOM-DOMAIN"; host: "$CUSTOM-DOMAIN";
// base_path: "/"; base_path: "/";
// external_docs: { external_docs: {
// description: "Detailed information about ZITADEL", description: "Detailed information about ZITADEL",
// url: "https://zitadel.com/docs" url: "https://zitadel.com/docs"
// } }
// security_definitions: { security_definitions: {
// security: { security: {
// key: "OAuth2"; key: "OAuth2";
// value: { value: {
// type: TYPE_OAUTH2; type: TYPE_OAUTH2;
// flow: FLOW_ACCESS_CODE; flow: FLOW_ACCESS_CODE;
// authorization_url: "$CUSTOM-DOMAIN/oauth/v2/authorize"; authorization_url: "$CUSTOM-DOMAIN/oauth/v2/authorize";
// token_url: "$CUSTOM-DOMAIN/oauth/v2/token"; token_url: "$CUSTOM-DOMAIN/oauth/v2/token";
// scopes: { scopes: {
// scope: { scope: {
// key: "openid"; key: "openid";
// value: "openid"; value: "openid";
// } }
// scope: { scope: {
// key: "urn:zitadel:iam:org:project:id:zitadel:aud"; key: "urn:zitadel:iam:org:project:id:zitadel:aud";
// value: "urn:zitadel:iam:org:project:id:zitadel:aud"; value: "urn:zitadel:iam:org:project:id:zitadel:aud";
// } }
// } }
// } }
// } }
// } }
// security: { security: {
// security_requirement: { security_requirement: {
// key: "OAuth2"; key: "OAuth2";
// value: { value: {
// scope: "openid"; scope: "openid";
// scope: "urn:zitadel:iam:org:project:id:zitadel:aud"; scope: "urn:zitadel:iam:org:project:id:zitadel:aud";
// } }
// } }
// } }
// responses: { responses: {
// key: "403"; key: "403";
// value: { value: {
// description: "Returned when the user does not have permission to access the resource."; description: "Returned when the user does not have permission to access the resource.";
// schema: { schema: {
// json_schema: { json_schema: {
// ref: "#/definitions/rpcStatus"; ref: "#/definitions/rpcStatus";
// } }
// } }
// } }
// } }
// responses: { responses: {
// key: "404"; key: "404";
// value: { value: {
// description: "Returned when the resource does not exist."; description: "Returned when the resource does not exist.";
// schema: { schema: {
// json_schema: { json_schema: {
// ref: "#/definitions/rpcStatus"; ref: "#/definitions/rpcStatus";
// } }
// } }
// } }
// } }
// }; };
service OrganizationService { service OrganizationService {
@@ -371,7 +371,7 @@ service OrganizationService {
// - `org.write` // - `org.write`
rpc DeactivateOrganization(DeactivateOrganizationRequest) returns (DeactivateOrganizationResponse) { rpc DeactivateOrganization(DeactivateOrganizationRequest) returns (DeactivateOrganizationResponse) {
option (google.api.http) = { option (google.api.http) = {
post: "/v2beta/organizations/_deactivate" post: "/v2beta/organizations/deactivate"
body: "*" body: "*"
}; };
@@ -438,7 +438,7 @@ message CreatedAdmin {
message CreateOrganizationResponse{ message CreateOrganizationResponse{
// The timestamp of the organization was created. // The timestamp of the organization was created.
google.protobuf.Timestamp created_date = 1 [ google.protobuf.Timestamp creation_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2024-12-18T07:50:47.492Z\""; example: "\"2024-12-18T07:50:47.492Z\"";
} }
@@ -499,7 +499,7 @@ message ListOrganizationsRequest {
zitadel.org.v2beta.OrgFieldName sorting_column = 2; zitadel.org.v2beta.OrgFieldName sorting_column = 2;
// Define the criteria to query for. // Define the criteria to query for.
// repeated ProjectRoleFilter filters = 4; // repeated ProjectRoleFilter filters = 4;
repeated zitadel.org.v2beta.OrgQueryFilter OrganizationSearchFilter = 3; repeated zitadel.org.v2beta.OrganizationSearchFilter filter = 3;
} }
message ListOrganizationsResponse { message ListOrganizationsResponse {
@@ -529,7 +529,7 @@ message DeleteOrganizationRequest {
message DeleteOrganizationResponse { message DeleteOrganizationResponse {
// The timestamp of the deletion of the organization. // The timestamp of the deletion of the organization.
google.protobuf.Timestamp change_date = 1 [ google.protobuf.Timestamp deletion_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2025-01-23T10:34:18.051Z\""; example: "\"2025-01-23T10:34:18.051Z\"";
} }
@@ -604,7 +604,7 @@ message AddOrganizationDomainRequest {
message AddOrganizationDomainResponse { message AddOrganizationDomainResponse {
// The timestamp of the organization was created. // The timestamp of the organization was created.
google.protobuf.Timestamp created_date = 1 [ google.protobuf.Timestamp creation_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2024-12-18T07:50:47.492Z\""; example: "\"2024-12-18T07:50:47.492Z\"";
} }
@@ -670,7 +670,8 @@ message DeleteOrganizationDomainResponse {
message GenerateOrganizationDomainValidationRequest { message GenerateOrganizationDomainValidationRequest {
// Organization Id for the Organization which doman to be validated. // Organization Id for the Organization which doman to be validated.
string id = 1 [ string organization_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED, (google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@@ -709,7 +710,7 @@ message GenerateOrganizationDomainValidationResponse {
message VerifyOrganizationDomainRequest { message VerifyOrganizationDomainRequest {
// Organization Id for the Organization doman to be verified. // Organization Id for the Organization doman to be verified.
string id = 1 [ string organization_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED, (google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@@ -767,7 +768,7 @@ message SetOrganizationMetadataResponse{
message ListOrganizationMetadataRequest { message ListOrganizationMetadataRequest {
// Organization ID of Orgalization which metadata is to be listed. // Organization ID of Orgalization which metadata is to be listed.
string id = 1 [ string organization_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED, (google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@@ -792,7 +793,7 @@ message ListOrganizationMetadataResponse {
message DeleteOrganizationMetadataRequest { message DeleteOrganizationMetadataRequest {
// Organization ID of Orgalization which metadata is to be deleted is stored on. // Organization ID of Orgalization which metadata is to be deleted is stored on.
string id = 1; string organization_id = 1;
// The key for the Organization metadata to be deleted. // The key for the Organization metadata to be deleted.
repeated string keys = 2 [(validate.rules).repeated.items.string = {min_len: 1, max_len: 200}]; repeated string keys = 2 [(validate.rules).repeated.items.string = {min_len: 1, max_len: 200}];
} }