feat: org v2 ListOrganizations (#8411)

# Which Problems Are Solved

Org v2 service does not have a ListOrganizations endpoint.

# How the Problems Are Solved

Implement ListOrganizations endpoint.

# Additional Changes

- moved descriptions in the protos to comments
- corrected the RemoveNoPermissions for the ListUsers, to get the
correct TotalResults

# Additional Context

For new typescript login
This commit is contained in:
Stefan Benz
2024-08-15 06:37:06 +02:00
committed by GitHub
parent 3e3d46ac0d
commit 5fab533e37
25 changed files with 1017 additions and 52 deletions

View File

@@ -0,0 +1,43 @@
syntax = "proto3";
package zitadel.org.v2;
option go_package = "github.com/zitadel/zitadel/pkg/grpc/org/v2;org";
import "google/api/field_behavior.proto";
import "google/protobuf/timestamp.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
import "validate/validate.proto";
import "zitadel/object/v2/object.proto";
message Organization {
// Unique identifier of the organization.
string id = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"69629023906488334\""
}
];
zitadel.object.v2.Details details = 2;
// Current state of the organization, for example active, inactive and deleted.
OrganizationState state = 3;
// Name of the organization.
string name = 4 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"ZITADEL\"";
}
];
// Primary domain used in the organization.
string primary_domain = 5 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"zitadel.cloud\"";
}
];
}
enum OrganizationState {
ORGANIZATION_STATE_UNSPECIFIED = 0;
ORGANIZATION_STATE_ACTIVE = 1;
ORGANIZATION_STATE_INACTIVE = 2;
ORGANIZATION_STATE_REMOVED = 3;
}

View File

@@ -1,6 +1,5 @@
syntax = "proto3";
package zitadel.org.v2;
import "zitadel/object/v2/object.proto";
@@ -18,12 +17,14 @@ import "google/protobuf/duration.proto";
import "google/protobuf/struct.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
import "validate/validate.proto";
import "zitadel/org/v2/org.proto";
import "zitadel/org/v2/query.proto";
option go_package = "github.com/zitadel/zitadel/pkg/grpc/org/v2;org";
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
info: {
title: "User Service";
title: "Organization Service";
version: "2.0";
description: "This API is intended to manage organizations in a ZITADEL instance.";
contact:{
@@ -111,7 +112,9 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
service OrganizationService {
// Create a new organization and grant the user(s) permission to manage it
// Create an Organization
//
// Create a new organization with an administrative user. If no specific roles are sent for the users, they will be granted the role ORG_OWNER.
rpc AddOrganization(AddOrganizationRequest) returns (AddOrganizationResponse) {
option (google.api.http) = {
post: "/v2/organizations"
@@ -128,8 +131,6 @@ service OrganizationService {
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
summary: "Create an Organization";
description: "Create a new organization with an administrative user. If no specific roles are sent for the users, they will be granted the role ORG_OWNER."
responses: {
key: "200"
value: {
@@ -138,6 +139,42 @@ service OrganizationService {
};
};
}
// Search Organizations
//
// Search for Organizations. By default, we will return all organization of the instance. Make sure to include a limit and sorting for pagination..
rpc ListOrganizations(ListOrganizationsRequest) returns (ListOrganizationsResponse) {
option (google.api.http) = {
post: "/v2/organizations/_search";
body: "*";
};
option (zitadel.protoc_gen_zitadel.v2.options) = {
auth_option: {
permission: "authenticated"
}
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
responses: {
key: "200"
value: {
description: "A list of all organizations matching the query";
}
};
responses: {
key: "400";
value: {
description: "invalid list query";
schema: {
json_schema: {
ref: "#/definitions/rpcStatus";
};
};
};
};
};
}
}
message AddOrganizationRequest{
@@ -172,3 +209,18 @@ message AddOrganizationResponse{
string organization_id = 2;
repeated CreatedAdmin created_admins = 3;
}
message ListOrganizationsRequest {
//list limitations and ordering
zitadel.object.v2.ListQuery query = 1;
// the field the result is sorted
zitadel.org.v2.OrganizationFieldName sorting_column = 2;
//criteria the client is looking for
repeated zitadel.org.v2.SearchQuery queries = 3;
}
message ListOrganizationsResponse {
zitadel.object.v2.ListDetails details = 1;
zitadel.org.v2.OrganizationFieldName sorting_column = 2;
repeated zitadel.org.v2.Organization result = 3;
}

View File

@@ -0,0 +1,83 @@
syntax = "proto3";
package zitadel.org.v2;
option go_package = "github.com/zitadel/zitadel/pkg/grpc/org/v2;org";
import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
import "validate/validate.proto";
import "zitadel/org/v2/org.proto";
import "zitadel/object/v2/object.proto";
message SearchQuery {
oneof query {
option (validate.required) = true;
OrganizationNameQuery name_query = 1;
OrganizationDomainQuery domain_query = 2;
OrganizationStateQuery state_query = 3;
OrganizationIDQuery id_query = 4;
}
}
message OrganizationNameQuery {
// Name of the organization.
string name = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
example: "\"gigi-giraffe\"";
}
];
// Defines which text equality method is used.
zitadel.object.v2.TextQueryMethod method = 2 [
(validate.rules).enum.defined_only = true
];
}
message OrganizationDomainQuery {
// Domain used in organization, not necessary primary domain.
string domain = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
example: "\"citadel.cloud\"";
}
];
// Defines which text equality method is used.
zitadel.object.v2.TextQueryMethod method = 2 [
(validate.rules).enum.defined_only = true
];
}
message OrganizationStateQuery {
// Current state of the organization.
OrganizationState state = 1 [
(validate.rules).enum.defined_only = true
];
}
message OrganizationIDQuery {
// Unique identifier of the organization.
string id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
example: "\"69629023906488334\""
}
];
}
enum OrganizationFieldName {
ORGANIZATION_FIELD_NAME_UNSPECIFIED = 0;
ORGANIZATION_FIELD_NAME_NAME = 1;
}

View File

@@ -179,9 +179,6 @@ service UserService {
auth_option: {
permission: "authenticated"
}
http_response: {
success_code: 200
}
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {