diff --git a/internal/api/grpc/metadata/v2beta/metadata.go b/internal/api/grpc/metadata/v2beta/metadata.go index 56c3adbc94..5d1985d3f8 100644 --- a/internal/api/grpc/metadata/v2beta/metadata.go +++ b/internal/api/grpc/metadata/v2beta/metadata.go @@ -5,6 +5,7 @@ import ( "github.com/zitadel/zitadel/internal/query" "github.com/zitadel/zitadel/internal/zerrors" meta_pb "github.com/zitadel/zitadel/pkg/grpc/metadata/v2beta" + "google.golang.org/protobuf/types/known/timestamppb" ) // code in this file is copied from internal/api/grpc/metadata/metadata.go @@ -19,14 +20,10 @@ func OrgMetadataListToPb(dataList []*query.OrgMetadata) []*meta_pb.Metadata { func OrgMetadataToPb(data *query.OrgMetadata) *meta_pb.Metadata { return &meta_pb.Metadata{ - Key: data.Key, - Value: data.Value, - Details: v2beta_object.ToViewDetailsPb( - data.Sequence, - data.CreationDate, - data.ChangeDate, - data.ResourceOwner, - ), + Key: data.Key, + Value: data.Value, + CreationDate: timestamppb.New(data.CreationDate), + ChangeDate: timestamppb.New(data.ChangeDate), } } diff --git a/internal/api/grpc/object/v2beta/converter.go b/internal/api/grpc/object/v2beta/converter.go index fce7bd747f..73d5f18843 100644 --- a/internal/api/grpc/object/v2beta/converter.go +++ b/internal/api/grpc/object/v2beta/converter.go @@ -2,7 +2,6 @@ package object import ( "context" - "time" "google.golang.org/protobuf/types/known/timestamppb" @@ -116,25 +115,6 @@ func DomainValidationTypeFromModel(validationType domain.OrgDomainValidationType } } -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 -} - func DomainValidationTypeToDomain(validationType org_pb.DomainValidationType) domain.OrgDomainValidationType { switch validationType { case org_pb.DomainValidationType_DOMAIN_VALIDATION_TYPE_HTTP: diff --git a/internal/api/grpc/org/v2beta/helper.go b/internal/api/grpc/org/v2beta/helper.go index 70514f19a1..39bad0dae2 100644 --- a/internal/api/grpc/org/v2beta/helper.go +++ b/internal/api/grpc/org/v2beta/helper.go @@ -150,17 +150,6 @@ func FieldNameToOrgColumn(fieldName v2beta_org.OrgFieldName) query.Column { } } -// func OrgViewToPb(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 ListOrgDomainsRequestToModel(systemDefaults systemdefaults.SystemDefaults, request *org.ListOrganizationDomainsRequest) (*query.OrgDomainSearchQueries, error) { offset, limit, asc, err := filter.PaginationPbToQuery(systemDefaults, request.Pagination) if err != nil { @@ -202,7 +191,6 @@ func DomainQueriesToModel(queries []*v2beta_org.DomainSearchFilter) (_ []query.S func DomainQueryToModel(searchQuery *v2beta_org.DomainSearchFilter) (query.SearchQuery, error) { switch q := searchQuery.Filter.(type) { case *v2beta_org.DomainSearchFilter_DomainNameFilter: - // return query.NewOrgDomainDomainSearchQuery(object.TextMethodToQuery(q.DomainNameQuery.Method), q.DomainNameQuery.Name) return query.NewOrgDomainDomainSearchQuery(v2beta_object.TextMethodToQuery(q.DomainNameFilter.Method), q.DomainNameFilter.Name) default: return nil, zerrors.ThrowInvalidArgument(nil, "ORG-Ags89", "List.Query.Invalid") diff --git a/internal/api/grpc/org/v2beta/integration_test/org_test.go b/internal/api/grpc/org/v2beta/integration_test/org_test.go index 729ed7902e..e6a1ed042b 100644 --- a/internal/api/grpc/org/v2beta/integration_test/org_test.go +++ b/internal/api/grpc/org/v2beta/integration_test/org_test.go @@ -5,6 +5,7 @@ package org_test import ( "context" "errors" + "fmt" "os" "strings" "testing" @@ -25,11 +26,10 @@ import ( ) var ( - CTX context.Context - Instance *integration.Instance - Client v2beta_org.OrganizationServiceClient - AdminClient admin.AdminServiceClient - User *user.AddHumanUserResponse + CTX context.Context + Instance *integration.Instance + Client v2beta_org.OrganizationServiceClient + User *user.AddHumanUserResponse ) func TestMain(m *testing.M) { @@ -39,7 +39,6 @@ func TestMain(m *testing.M) { Instance = integration.NewInstance(ctx) Client = Instance.Client.OrgV2beta - AdminClient = Instance.Client.Admin CTX = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner) User = Instance.CreateHumanUser(CTX) @@ -168,6 +167,7 @@ func TestServer_CreateOrganization(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := Client.CreateOrganization(tt.ctx, tt.req) + fmt.Printf("@@ >>>>>>>>>>>>>>>>>>>>>>>>>>>> err = %+v\n", err) if tt.wantErr { require.Error(t, err) return @@ -279,12 +279,17 @@ func TestServer_ListOrganization(t *testing.T) { require.NoError(t, err) tests := []struct { - name string - ctx context.Context - query []*v2beta_org.OrganizationSearchFilter - want []*v2beta_org.Organization - wantErr bool + name string + ctx context.Context + query []*v2beta_org.OrganizationSearchFilter + want []*v2beta_org.Organization + err error }{ + { + name: "list organizations, without required permissions", + ctx: ListOrgIinstance.WithAuthorization(CTX, integration.UserTypeNoPermission), + err: errors.New("membership not found"), + }, { name: "list organizations happy path, no filter", ctx: listOrgIAmOwnerCtx, @@ -538,9 +543,9 @@ func TestServer_ListOrganization(t *testing.T) { got, err := listOrgClient.ListOrganizations(tt.ctx, &v2beta_org.ListOrganizationsRequest{ Filter: tt.query, }) - - if tt.wantErr { - assert.Error(ttt, err) + if tt.err != nil { + require.ErrorContains(t, err, tt.err.Error()) + return } require.NoError(ttt, err) @@ -585,6 +590,20 @@ func TestServer_DeleteOrganization(t *testing.T) { dontCheckTime bool err error }{ + { + name: "delete org no permission", + ctx: Instance.WithAuthorization(CTX, integration.UserTypeNoPermission), + createOrgFunc: func() string { + orgs, _, err := createOrgs(CTX, Client, 1) + if err != nil { + assert.Fail(t, "unable to create org") + return "" + } + return orgs[0].Id + }, + req: &v2beta_org.DeleteOrganizationRequest{}, + err: errors.New("membership not found"), + }, { name: "delete org happy path", ctx: Instance.WithAuthorization(CTX, integration.UserTypeIAMOwner), @@ -982,7 +1001,7 @@ func TestServer_ValidateOrganizationDomain(t *testing.T) { } orgId := orgs[0].Id - _, err = AdminClient.UpdateDomainPolicy(CTX, &admin.UpdateDomainPolicyRequest{ + _, err = Instance.Client.Admin.UpdateDomainPolicy(CTX, &admin.UpdateDomainPolicyRequest{ ValidateOrgDomains: true, }) if err != nil && !strings.Contains(err.Error(), "Organisation is already deactivated") { diff --git a/internal/query/org_metadata.go b/internal/query/org_metadata.go index 84b204de2b..fe61ad51d9 100644 --- a/internal/query/org_metadata.go +++ b/internal/query/org_metadata.go @@ -194,7 +194,6 @@ func prepareOrgMetadataQuery() (sq.SelectBuilder, func(*sql.Row) (*OrgMetadata, &m.Key, &m.Value, ) - if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, zerrors.ThrowNotFound(err, "QUERY-Rph32", "Errors.Metadata.NotFound") diff --git a/proto/zitadel/metadata/v2beta/metadata.proto b/proto/zitadel/metadata/v2beta/metadata.proto index 7557ffdbee..87fcc51869 100644 --- a/proto/zitadel/metadata/v2beta/metadata.proto +++ b/proto/zitadel/metadata/v2beta/metadata.proto @@ -3,45 +3,55 @@ syntax = "proto3"; import "zitadel/object/v2beta/object.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; +import "google/protobuf/timestamp.proto"; package zitadel.metadata.v2beta; option go_package ="github.com/zitadel/zitadel/pkg/grpc/metadata/v2beta"; message Metadata { - zitadel.object.v2beta.Details details = 1; - string key = 2 [ - (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - description: "metadata key", - example: "\"key1\""; - } - ]; - bytes value = 3 [ - (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - description: "metadata value is base64 encoded, make sure to decode to get the value", - example: "\"VGhpcyBpcyBteSBmaXJzdCB2YWx1ZQ==\""; - } - ]; + google.protobuf.Timestamp creation_date = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2025-01-23T10:34:18.051Z\""; + } + ]; + google.protobuf.Timestamp change_date = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2025-01-23T10:34:18.051Z\""; + } + ]; + string key = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "metadata key", + example: "\"key1\""; + } + ]; + bytes value = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "metadata value is base64 encoded, make sure to decode to get the value", + example: "\"VGhpcyBpcyBteSBmaXJzdCB2YWx1ZQ==\""; + } + ]; } message MetadataQuery { - oneof query { - option (validate.required) = true; - MetadataKeyQuery key_query = 1; - } + oneof query { + option (validate.required) = true; + MetadataKeyQuery key_query = 1; + } } message MetadataKeyQuery { - string key = 1 [ - (validate.rules).string = {max_len: 200}, - (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - example: "\"key\"" - } - ]; - zitadel.object.v2beta.TextQueryMethod method = 2 [ - (validate.rules).enum.defined_only = true, - (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - description: "defines which text equality method is used"; - } - ]; + string key = 1 [ + (validate.rules).string = {max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"key\"" + } + ]; + zitadel.object.v2beta.TextQueryMethod method = 2 [ + (validate.rules).enum.defined_only = true, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "defines which text equality method is used"; + } + ]; }