mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:17:32 +00:00
feat: User metadata (#2025)
* feat: user meta data events * feat: user meta data set tests * feat: user meta data tests * feat: user meta data in protos * feat: user meta data command api * feat: user meta data query side * feat: proto correct order, fix handlers * feat: proto correct order * feat: fixes of pr comments * feat: fixes of pr comments * feat: value as byte array * feat: metadata feature * Update internal/auth/repository/eventsourcing/handler/meta_data.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update internal/command/user_meta_data.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update proto/zitadel/metadata.proto Co-authored-by: Silvan <silvan.reusser@gmail.com> * Update proto/zitadel/metadata.proto Co-authored-by: Silvan <silvan.reusser@gmail.com> * fix: rename metadata files and table * fix: rename meta data to metadat in protos * Update internal/domain/metadata.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * fix: rename vars * fix: rebiuld docs * Update internal/iam/repository/view/metadata_view.go Co-authored-by: Silvan <silvan.reusser@gmail.com> Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import "zitadel/object.proto";
|
||||
import "zitadel/options.proto";
|
||||
import "zitadel/policy.proto";
|
||||
import "zitadel/idp.proto";
|
||||
import "zitadel/metadata.proto";
|
||||
import "validate/validate.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
@@ -76,6 +77,7 @@ service AuthService {
|
||||
rpc ListMyUserChanges(ListMyUserChangesRequest) returns (ListMyUserChangesResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/users/me/changes/_search"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
@@ -87,6 +89,77 @@ service AuthService {
|
||||
rpc ListMyUserSessions(ListMyUserSessionsRequest) returns (ListMyUserSessionsResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/users/me/sessions/_search"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "authenticated"
|
||||
};
|
||||
}
|
||||
|
||||
// Sets a user metadata by key to the authorized user
|
||||
rpc SetMyMetadata(SetMyMetadataRequest) returns (SetMyMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/users/me/metadata/{key}"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "authenticated"
|
||||
};
|
||||
}
|
||||
|
||||
// Set a list of user metadata to the authorized user
|
||||
rpc BulkSetMyMetadata(BulkSetMyMetadataRequest) returns (BulkSetMyMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/users/me/metadata/_bulk"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "authenticated"
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the user metadata of the authorized user
|
||||
rpc ListMyMetadata(ListMyMetadataRequest) returns (ListMyMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/users/me/metadata/_search"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "authenticated"
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the user metadata by key of the authorized user
|
||||
rpc GetMyMetadata(GetMyMetadataRequest) returns (GetMyMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/users/me/metadata/{key}"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "authenticated"
|
||||
};
|
||||
}
|
||||
|
||||
// Removes a user metadata by key to the authorized user
|
||||
rpc RemoveMyMetadata(RemoveMyMetadataRequest) returns (RemoveMyMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
delete: "/users/me/metadata/{key}"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "authenticated"
|
||||
};
|
||||
}
|
||||
|
||||
// Set a list of user metadata to the authorized user
|
||||
rpc BulkRemoveMyMetadata(BulkRemoveMyMetadataRequest) returns (BulkRemoveMyMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
delete: "/users/me/metadata/_bulk"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
@@ -98,6 +171,7 @@ service AuthService {
|
||||
rpc ListMyRefreshTokens(ListMyRefreshTokensRequest) returns (ListMyRefreshTokensResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/users/me/tokens/refresh/_search"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
@@ -120,6 +194,7 @@ service AuthService {
|
||||
rpc RevokeAllMyRefreshTokens(RevokeAllMyRefreshTokensRequest) returns (RevokeAllMyRefreshTokensResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/users/me/tokens/refresh/_revoke_all"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
@@ -592,6 +667,61 @@ message ListMyUserSessionsResponse {
|
||||
repeated zitadel.user.v1.Session result = 1;
|
||||
}
|
||||
|
||||
message ListMyMetadataRequest {
|
||||
zitadel.v1.ListQuery query = 1;
|
||||
repeated zitadel.metadata.v1.MetadataQuery queries = 2;
|
||||
}
|
||||
|
||||
message ListMyMetadataResponse {
|
||||
zitadel.v1.ListDetails details = 1;
|
||||
repeated zitadel.metadata.v1.Metadata result = 2;
|
||||
}
|
||||
|
||||
message GetMyMetadataRequest {
|
||||
string key = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
}
|
||||
|
||||
message GetMyMetadataResponse {
|
||||
zitadel.metadata.v1.Metadata metadata = 1;
|
||||
}
|
||||
|
||||
message SetMyMetadataRequest {
|
||||
string key = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
bytes value = 2 [(validate.rules).bytes = {min_len: 1, max_len: 500000}];
|
||||
}
|
||||
|
||||
message SetMyMetadataResponse {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
}
|
||||
|
||||
message BulkSetMyMetadataRequest {
|
||||
message Metadata {
|
||||
string key = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
bytes value = 2 [(validate.rules).bytes = {min_len: 1, max_len: 500000}];
|
||||
}
|
||||
repeated Metadata metadata = 1;
|
||||
}
|
||||
|
||||
message BulkSetMyMetadataResponse {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
}
|
||||
|
||||
message RemoveMyMetadataRequest {
|
||||
string key = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
}
|
||||
|
||||
message RemoveMyMetadataResponse {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
}
|
||||
|
||||
message BulkRemoveMyMetadataRequest {
|
||||
repeated string keys = 1 [(validate.rules).repeated.items.string = {min_len: 1, max_len: 200}];
|
||||
}
|
||||
|
||||
message BulkRemoveMyMetadataResponse {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
}
|
||||
|
||||
//This is an empty request
|
||||
message ListMyRefreshTokensRequest {}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ import "zitadel/message.proto";
|
||||
import "zitadel/change.proto";
|
||||
import "zitadel/auth_n_key.proto";
|
||||
import "zitadel/features.proto";
|
||||
import "zitadel/metadata.proto";
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
@@ -285,6 +286,82 @@ service ManagementService {
|
||||
};
|
||||
}
|
||||
|
||||
// Sets a user metadata by key
|
||||
rpc SetUserMetadata(SetUserMetadataRequest) returns (SetUserMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/users/{id}/metadata/{key}"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "user.write"
|
||||
feature: "metadata.user"
|
||||
};
|
||||
}
|
||||
|
||||
// Set a list of user metadata
|
||||
rpc BulkSetUserMetadata(BulkSetUserMetadataRequest) returns (BulkSetUserMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/users/{id}/metadata/_bulk"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "user.write"
|
||||
feature: "metadata.user"
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the user metadata
|
||||
rpc ListUserMetadata(ListUserMetadataRequest) returns (ListUserMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/users/{id}/metadata/_search"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "user.read"
|
||||
feature: "metadata.user"
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the user metadata by key
|
||||
rpc GetUserMetadata(GetUserMetadataRequest) returns (GetUserMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/users/{id}/metadata/{key}"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "user.read"
|
||||
feature: "metadata.user"
|
||||
};
|
||||
}
|
||||
|
||||
// Removes a user metadata by key
|
||||
rpc RemoveUserMetadata(RemoveUserMetadataRequest) returns (RemoveUserMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
delete: "/users/{id}/metadata/{key}"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "user.write"
|
||||
feature: "metadata.user"
|
||||
};
|
||||
}
|
||||
|
||||
// Set a list of user metadata
|
||||
rpc BulkRemoveUserMetadata(BulkRemoveUserMetadataRequest) returns (BulkRemoveUserMetadataResponse) {
|
||||
option (google.api.http) = {
|
||||
delete: "/users/{id}/metadata/_bulk"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.v1.auth_option) = {
|
||||
permission: "user.write"
|
||||
feature: "metadata.user"
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the profile of the human
|
||||
rpc GetHumanProfile(GetHumanProfileRequest) returns (GetHumanProfileResponse) {
|
||||
option (google.api.http) = {
|
||||
@@ -2827,6 +2904,68 @@ message UpdateUserNameResponse {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
}
|
||||
|
||||
message ListUserMetadataRequest {
|
||||
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
zitadel.v1.ListQuery query = 2;
|
||||
repeated zitadel.metadata.v1.MetadataQuery queries = 3;
|
||||
}
|
||||
|
||||
message ListUserMetadataResponse {
|
||||
zitadel.v1.ListDetails details = 1;
|
||||
repeated zitadel.metadata.v1.Metadata result = 2;
|
||||
}
|
||||
|
||||
message GetUserMetadataRequest {
|
||||
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
string key = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
}
|
||||
|
||||
message GetUserMetadataResponse {
|
||||
zitadel.metadata.v1.Metadata metadata = 1;
|
||||
}
|
||||
|
||||
message SetUserMetadataRequest {
|
||||
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
string key = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
bytes value = 3 [(validate.rules).bytes = {min_len: 1, max_len: 500000}];
|
||||
}
|
||||
|
||||
message SetUserMetadataResponse {
|
||||
string id = 1;
|
||||
zitadel.v1.ObjectDetails details = 2;
|
||||
}
|
||||
|
||||
message BulkSetUserMetadataRequest {
|
||||
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
message Metadata {
|
||||
string key = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
bytes value = 2 [(validate.rules).bytes = {min_len: 1, max_len: 500000}];
|
||||
}
|
||||
repeated Metadata metadata = 2;
|
||||
}
|
||||
|
||||
message BulkSetUserMetadataResponse {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
}
|
||||
|
||||
message RemoveUserMetadataRequest {
|
||||
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
string key = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
}
|
||||
|
||||
message RemoveUserMetadataResponse {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
}
|
||||
|
||||
message BulkRemoveUserMetadataRequest {
|
||||
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
repeated string keys = 2 [(validate.rules).repeated.items.string = {min_len: 1, max_len: 200}];
|
||||
}
|
||||
|
||||
message BulkRemoveUserMetadataResponse {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
}
|
||||
|
||||
message GetHumanProfileRequest {
|
||||
string user_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
|
||||
}
|
||||
|
45
proto/zitadel/metadata.proto
Normal file
45
proto/zitadel/metadata.proto
Normal file
@@ -0,0 +1,45 @@
|
||||
syntax = "proto3";
|
||||
|
||||
import "zitadel/object.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
|
||||
package zitadel.metadata.v1;
|
||||
|
||||
option go_package ="github.com/caos/zitadel/pkg/grpc/metadata";
|
||||
|
||||
message Metadata {
|
||||
zitadel.v1.ObjectDetails details = 1;
|
||||
string key = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "metadata key"
|
||||
}
|
||||
];
|
||||
bytes value = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "metadata value"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message MetadataQuery {
|
||||
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.v1.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";
|
||||
}
|
||||
];
|
||||
}
|
Reference in New Issue
Block a user