user_service.proto 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. syntax = "proto3";
  2. package chatto.api.v1;
  3. import "google/protobuf/field_mask.proto";
  4. import "buf/validate/validate.proto";
  5. import "chatto/api/v1/common.proto";
  6. import "chatto/api/v1/member_directory.proto";
  7. import "chatto/api/v1/pagination.proto";
  8. import "chatto/api/v1/users.proto";
  9. // Request for users visible to the authenticated user.
  10. // Results use creation time, oldest first. Users without a creation time
  11. // appear last, ordered by case-insensitive login.
  12. message ListUsersRequest {
  13. reserved 2, 3;
  14. reserved "limit", "offset";
  15. // Optional case-insensitive search against login and display name.
  16. string search = 1 [(buf.validate.field).string.max_len = 100];
  17. // Defaults to 20 results when absent or limit is zero. Maximum: 500.
  18. PageRequest page = 4;
  19. }
  20. // User directory page.
  21. message ListUsersResponse {
  22. reserved 2, 3;
  23. reserved "total_count", "has_more";
  24. // Users in the requested page.
  25. repeated DirectoryMember users = 1;
  26. // Page metadata.
  27. PageInfo page = 4;
  28. }
  29. // Request one visible user by stable user ID or login.
  30. message GetUserRequest {
  31. oneof target {
  32. // Target stable user ID.
  33. string user_id = 1 [(buf.validate.field).string.min_len = 1];
  34. // Target login identifier.
  35. string login = 2 [(buf.validate.field).string.min_len = 1];
  36. }
  37. }
  38. // User directory response.
  39. message GetUserResponse {
  40. // Requested user.
  41. DirectoryMember user = 1;
  42. }
  43. // Request user directory rows for a set of stable user IDs.
  44. message BatchGetUsersRequest {
  45. // Required target user IDs. Unknown IDs are omitted from the response.
  46. repeated string user_ids = 1 [(buf.validate.field).repeated = {
  47. min_items: 1
  48. max_items: 100
  49. items: {
  50. string: {min_len: 1}
  51. }
  52. }];
  53. }
  54. // Batch user directory response.
  55. message BatchGetUsersResponse {
  56. // Found users. The server preserves first-seen request order and
  57. // de-duplicates repeated IDs.
  58. repeated DirectoryMember users = 1;
  59. }
  60. // Request to update one user's public profile. update_mask selects fields
  61. // to apply or reset. Fields outside the mask stay unchanged.
  62. message UpdateUserProfileRequest {
  63. // Required target user ID. Self-updates are allowed. Updating another user
  64. // requires the applicable account-management or bot-management authority.
  65. string user_id = 1 [(buf.validate.field).string.min_len = 1];
  66. // New non-empty display name. The server also rejects control and
  67. // confusing invisible characters.
  68. optional string display_name = 2 [(buf.validate.field).string = {min_len: 1, max_len: 32}];
  69. // New login identifier, when changing it. The server accepts ASCII letters,
  70. // digits, period, underscore, and hyphen, starting with a letter or digit.
  71. optional string login = 3 [(buf.validate.field).string = {
  72. min_len: 2
  73. max_len: 32
  74. }];
  75. // New Markdown biography, when changing it. Empty clears the bio.
  76. optional string bio = 4 [(buf.validate.field).string.max_len = 1000];
  77. // Editable fields to apply or reset: display_name, login, bio.
  78. // Omit to infer populated fields; * selects all editable fields. An explicit
  79. // empty mask is invalid. Unselected values are ignored. Selected absent values
  80. // reset the field to its default, subject to field validation.
  81. google.protobuf.FieldMask update_mask = 5;
  82. }
  83. // Result of a user profile update.
  84. message UpdateUserProfileResponse {
  85. // Updated user profile.
  86. User user = 1;
  87. }
  88. // Request to upload and set one user's avatar.
  89. message UploadAvatarRequest {
  90. reserved 1 to 3;
  91. reserved "filename", "content_type";
  92. // Image payload. The server validates, resizes, and stores a WebP avatar.
  93. ImageUpload image = 4;
  94. // Required target user ID. Self-updates are allowed. Updating another user
  95. // requires the applicable account-management or bot-management authority.
  96. string user_id = 5 [(buf.validate.field).string.min_len = 1];
  97. }
  98. // Result of uploading one user's avatar.
  99. message UploadAvatarResponse {
  100. // Updated user profile.
  101. User user = 1;
  102. }
  103. // Request to delete one user's avatar.
  104. message DeleteAvatarRequest {
  105. // Required target user ID. Self-updates are allowed. Updating another user
  106. // requires the applicable account-management or bot-management authority.
  107. string user_id = 1 [(buf.validate.field).string.min_len = 1];
  108. }
  109. // Result of deleting one user's avatar.
  110. message DeleteAvatarResponse {
  111. // Updated user profile.
  112. User user = 1;
  113. }
  114. // Reads users and manages public user profiles and avatars.
  115. service UserService {
  116. // Lists users visible to the authenticated user. Admin-sensitive account
  117. // fields stay out of this public row shape.
  118. rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
  119. // Gets one visible user by user ID or login. Returns NOT_FOUND when the
  120. // target is unknown.
  121. rpc GetUser(GetUserRequest) returns (GetUserResponse);
  122. // Gets visible user rows for multiple stable user IDs. Unknown IDs are
  123. // omitted from the response.
  124. rpc BatchGetUsers(BatchGetUsersRequest) returns (BatchGetUsersResponse);
  125. // Updates the target user's login, display name, and/or bio. Users can
  126. // update themselves. Updating another human requires user.manage-accounts.
  127. // A human who updates a bot needs ownership of the bot,
  128. // user.manage-accounts, or bot.manage. A bot cannot target another account.
  129. // A login change returns FAILED_PRECONDITION while the target's
  130. // username-change cooldown is active. A successful login change starts a
  131. // new cooldown. This also applies when a bot owner or bot manager changes a
  132. // bot's login. A caller with user.manage-accounts bypasses the cooldown and
  133. // does not start it. A case-only change does not check or start the
  134. // cooldown. Unknown or deleted targets return NOT_FOUND. An invalid ID or a
  135. // request without a selected field returns INVALID_ARGUMENT.
  136. rpc UpdateUserProfile(UpdateUserProfileRequest) returns (UpdateUserProfileResponse);
  137. // Uploads and sets an avatar for the target user. Users can update
  138. // themselves. Updating another human requires user.manage-accounts.
  139. // A human who updates a bot needs ownership of the bot,
  140. // user.manage-accounts, or bot.manage.
  141. // A bot cannot target another account. Unknown or deleted targets return
  142. // NOT_FOUND. Invalid IDs or missing images return INVALID_ARGUMENT.
  143. rpc UploadAvatar(UploadAvatarRequest) returns (UploadAvatarResponse);
  144. // Deletes the target user's avatar. Authorization matches UploadAvatar. The
  145. // call is idempotent. Unknown or deleted targets return NOT_FOUND. An
  146. // invalid ID returns INVALID_ARGUMENT.
  147. rpc DeleteAvatar(DeleteAvatarRequest) returns (DeleteAvatarResponse) {
  148. option idempotency_level = IDEMPOTENT;
  149. }
  150. }