refactor: user service

pull/4772/head^2
Steven 2 weeks ago
parent 330282d8b2
commit c9ab03e1a0

@ -7,6 +7,7 @@ import "google/api/annotations.proto";
import "google/api/client.proto"; import "google/api/client.proto";
import "google/api/field_behavior.proto"; import "google/api/field_behavior.proto";
import "google/api/httpbody.proto"; import "google/api/httpbody.proto";
import "google/api/resource.proto";
import "google/protobuf/empty.proto"; import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto"; import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto"; import "google/protobuf/timestamp.proto";
@ -18,21 +19,13 @@ service UserService {
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) { rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) {
option (google.api.http) = {get: "/api/v1/users"}; option (google.api.http) = {get: "/api/v1/users"};
} }
// GetUser gets a user by name. // GetUser gets a user by name.
rpc GetUser(GetUserRequest) returns (User) { rpc GetUser(GetUserRequest) returns (User) {
option (google.api.http) = {get: "/api/v1/{name=users/*}"}; option (google.api.http) = {get: "/api/v1/{name=users/*}"};
option (google.api.method_signature) = "name"; option (google.api.method_signature) = "name";
} }
// GetUserByUsername gets a user by username.
rpc GetUserByUsername(GetUserByUsernameRequest) returns (User) {
option (google.api.http) = {get: "/api/v1/users:username"};
option (google.api.method_signature) = "username";
}
// GetUserAvatarBinary gets the avatar of a user.
rpc GetUserAvatarBinary(GetUserAvatarBinaryRequest) returns (google.api.HttpBody) {
option (google.api.http) = {get: "/file/{name=users/*}/avatar"};
option (google.api.method_signature) = "name";
}
// CreateUser creates a new user. // CreateUser creates a new user.
rpc CreateUser(CreateUserRequest) returns (User) { rpc CreateUser(CreateUserRequest) returns (User) {
option (google.api.http) = { option (google.api.http) = {
@ -41,6 +34,7 @@ service UserService {
}; };
option (google.api.method_signature) = "user"; option (google.api.method_signature) = "user";
} }
// UpdateUser updates a user. // UpdateUser updates a user.
rpc UpdateUser(UpdateUserRequest) returns (User) { rpc UpdateUser(UpdateUserRequest) returns (User) {
option (google.api.http) = { option (google.api.http) = {
@ -49,147 +43,288 @@ service UserService {
}; };
option (google.api.method_signature) = "user,update_mask"; option (google.api.method_signature) = "user,update_mask";
} }
// DeleteUser deletes a user. // DeleteUser deletes a user.
rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty) { rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {delete: "/api/v1/{name=users/*}"}; option (google.api.http) = {delete: "/api/v1/{name=users/*}"};
option (google.api.method_signature) = "name"; option (google.api.method_signature) = "name";
} }
// ListAllUserStats returns all user stats.
// SearchUsers searches for users based on query.
rpc SearchUsers(SearchUsersRequest) returns (SearchUsersResponse) {
option (google.api.http) = {get: "/api/v1/users:search"};
option (google.api.method_signature) = "query";
}
// GetUserAvatar gets the avatar of a user.
rpc GetUserAvatar(GetUserAvatarRequest) returns (google.api.HttpBody) {
option (google.api.http) = {get: "/api/v1/{name=users/*}/avatar"};
option (google.api.method_signature) = "name";
}
// ListAllUserStats returns statistics for all users.
rpc ListAllUserStats(ListAllUserStatsRequest) returns (ListAllUserStatsResponse) { rpc ListAllUserStats(ListAllUserStatsRequest) returns (ListAllUserStatsResponse) {
option (google.api.http) = {post: "/api/v1/users/-/stats"}; option (google.api.http) = {get: "/api/v1/users:stats"};
} }
// GetUserStats returns the stats of a user.
// GetUserStats returns statistics for a specific user.
rpc GetUserStats(GetUserStatsRequest) returns (UserStats) { rpc GetUserStats(GetUserStatsRequest) returns (UserStats) {
option (google.api.http) = {get: "/api/v1/{name=users/*}/stats"}; option (google.api.http) = {get: "/api/v1/{name=users/*}:getStats"};
option (google.api.method_signature) = "name"; option (google.api.method_signature) = "name";
} }
// GetUserSetting gets the setting of a user.
// GetUserSetting returns the user setting.
rpc GetUserSetting(GetUserSettingRequest) returns (UserSetting) { rpc GetUserSetting(GetUserSettingRequest) returns (UserSetting) {
option (google.api.http) = {get: "/api/v1/{name=users/*}/setting"}; option (google.api.http) = {get: "/api/v1/{name=users/*}:getSetting"};
option (google.api.method_signature) = "name"; option (google.api.method_signature) = "name";
} }
// UpdateUserSetting updates the setting of a user.
// UpdateUserSetting updates the user setting.
rpc UpdateUserSetting(UpdateUserSettingRequest) returns (UserSetting) { rpc UpdateUserSetting(UpdateUserSettingRequest) returns (UserSetting) {
option (google.api.http) = { option (google.api.http) = {
patch: "/api/v1/{setting.name=users/*/setting}" patch: "/api/v1/{setting.name=users/*}:updateSetting"
body: "setting" body: "setting"
}; };
option (google.api.method_signature) = "setting,update_mask"; option (google.api.method_signature) = "setting,update_mask";
} }
// ListUserAccessTokens returns a list of access tokens for a user. // ListUserAccessTokens returns a list of access tokens for a user.
rpc ListUserAccessTokens(ListUserAccessTokensRequest) returns (ListUserAccessTokensResponse) { rpc ListUserAccessTokens(ListUserAccessTokensRequest) returns (ListUserAccessTokensResponse) {
option (google.api.http) = {get: "/api/v1/{name=users/*}/access_tokens"}; option (google.api.http) = {get: "/api/v1/{parent=users/*}/accessTokens"};
option (google.api.method_signature) = "name"; option (google.api.method_signature) = "parent";
} }
// CreateUserAccessToken creates a new access token for a user. // CreateUserAccessToken creates a new access token for a user.
rpc CreateUserAccessToken(CreateUserAccessTokenRequest) returns (UserAccessToken) { rpc CreateUserAccessToken(CreateUserAccessTokenRequest) returns (UserAccessToken) {
option (google.api.http) = { option (google.api.http) = {
post: "/api/v1/{name=users/*}/access_tokens" post: "/api/v1/{parent=users/*}/accessTokens"
body: "*" body: "access_token"
}; };
option (google.api.method_signature) = "name"; option (google.api.method_signature) = "parent,access_token";
} }
// DeleteUserAccessToken deletes an access token for a user.
// DeleteUserAccessToken deletes an access token.
rpc DeleteUserAccessToken(DeleteUserAccessTokenRequest) returns (google.protobuf.Empty) { rpc DeleteUserAccessToken(DeleteUserAccessTokenRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {delete: "/api/v1/{name=users/*}/access_tokens/{access_token}"}; option (google.api.http) = {delete: "/api/v1/{name=users/*/accessTokens/*}"};
option (google.api.method_signature) = "name,access_token"; option (google.api.method_signature) = "name";
} }
} }
message User { message User {
// The name of the user. option (google.api.resource) = {
// Format: users/{id}, id is the system generated auto-incremented id. type: "memos.api.v1/User"
string name = 1 [ pattern: "users/{user}"
(google.api.field_behavior) = OUTPUT_ONLY, name_field: "name"
(google.api.field_behavior) = IDENTIFIER singular: "user"
]; plural: "users"
};
enum Role { // The resource name of the user.
ROLE_UNSPECIFIED = 0; // Format: users/{user}
HOST = 1; string name = 1 [(google.api.field_behavior) = IDENTIFIER];
ADMIN = 2;
USER = 3;
}
Role role = 3;
string username = 4; // Output only. The system generated unique identifier.
string uid = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
string email = 5; // The role of the user.
Role role = 3 [(google.api.field_behavior) = REQUIRED];
string nickname = 6; // Required. The unique username for login.
string username = 4 [(google.api.field_behavior) = REQUIRED];
string avatar_url = 7; // Optional. The email address of the user.
string email = 5 [(google.api.field_behavior) = OPTIONAL];
string description = 8; // Optional. The display name of the user.
string display_name = 6 [(google.api.field_behavior) = OPTIONAL];
// Optional. The avatar URL of the user.
string avatar_url = 7 [(google.api.field_behavior) = OPTIONAL];
// Optional. The description of the user.
string description = 8 [(google.api.field_behavior) = OPTIONAL];
// Input only. The password for the user.
string password = 9 [(google.api.field_behavior) = INPUT_ONLY]; string password = 9 [(google.api.field_behavior) = INPUT_ONLY];
State state = 10; // The state of the user.
State state = 10 [(google.api.field_behavior) = REQUIRED];
// Output only. The creation timestamp.
google.protobuf.Timestamp create_time = 11 [(google.api.field_behavior) = OUTPUT_ONLY]; google.protobuf.Timestamp create_time = 11 [(google.api.field_behavior) = OUTPUT_ONLY];
// Output only. The last update timestamp.
google.protobuf.Timestamp update_time = 12 [(google.api.field_behavior) = OUTPUT_ONLY]; google.protobuf.Timestamp update_time = 12 [(google.api.field_behavior) = OUTPUT_ONLY];
// Output only. The etag for this resource.
string etag = 13 [(google.api.field_behavior) = OUTPUT_ONLY];
// User role enumeration.
enum Role {
// Unspecified role.
ROLE_UNSPECIFIED = 0;
// Host role with full system access.
HOST = 1;
// Admin role with administrative privileges.
ADMIN = 2;
// Regular user role.
USER = 3;
}
} }
message ListUsersRequest {} message ListUsersRequest {
// Optional. The maximum number of users to return.
// The service may return fewer than this value.
// If unspecified, at most 50 users will be returned.
// The maximum value is 1000; values above 1000 will be coerced to 1000.
int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];
// Optional. A page token, received from a previous `ListUsers` call.
// Provide this to retrieve the subsequent page.
string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
// Optional. Filter to apply to the list results.
// Example: "state=ACTIVE" or "role=USER" or "email:@example.com"
// Supported operators: =, !=, <, <=, >, >=, :
// Supported fields: username, email, role, state, create_time, update_time
string filter = 3 [(google.api.field_behavior) = OPTIONAL];
// Optional. The order to sort results by.
// Example: "create_time desc" or "username asc"
string order_by = 4 [(google.api.field_behavior) = OPTIONAL];
// Optional. If true, show deleted users in the response.
bool show_deleted = 5 [(google.api.field_behavior) = OPTIONAL];
}
message ListUsersResponse { message ListUsersResponse {
// The list of users.
repeated User users = 1; repeated User users = 1;
}
message GetUserRequest { // A token that can be sent as `page_token` to retrieve the next page.
// The name of the user. // If this field is omitted, there are no subsequent pages.
string name = 1; string next_page_token = 2;
}
message GetUserByUsernameRequest { // The total count of users (may be approximate).
// The username of the user. int32 total_size = 3;
string username = 1;
} }
message GetUserAvatarBinaryRequest { message GetUserRequest {
// The name of the user. // Required. The resource name of the user.
string name = 1; // Format: users/{user}
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/User"}
];
// The raw HTTP body is bound to this field. // Optional. The fields to return in the response.
google.api.HttpBody http_body = 2; // If not specified, all fields are returned.
google.protobuf.FieldMask read_mask = 2 [(google.api.field_behavior) = OPTIONAL];
} }
message CreateUserRequest { message CreateUserRequest {
User user = 1; // Required. The user to create.
User user = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.field_behavior) = INPUT_ONLY
];
// Optional. The user ID to use for this user.
// If empty, a unique ID will be generated.
// Must match the pattern [a-z0-9-]+
string user_id = 2 [(google.api.field_behavior) = OPTIONAL];
// Optional. If set, validate the request but don't actually create the user.
bool validate_only = 3 [(google.api.field_behavior) = OPTIONAL];
// Optional. An idempotency token that can be used to ensure that multiple
// requests to create a user have the same result.
string request_id = 4 [(google.api.field_behavior) = OPTIONAL];
} }
message UpdateUserRequest { message UpdateUserRequest {
// Required. The user to update.
User user = 1 [(google.api.field_behavior) = REQUIRED]; User user = 1 [(google.api.field_behavior) = REQUIRED];
google.protobuf.FieldMask update_mask = 2; // Required. The list of fields to update.
google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED];
// Optional. If set to true, allows updating sensitive fields.
bool allow_missing = 3 [(google.api.field_behavior) = OPTIONAL];
} }
message DeleteUserRequest { message DeleteUserRequest {
// The name of the user. // Required. The resource name of the user to delete.
string name = 1; // Format: users/{user}
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/User"}
];
// Optional. If set to true, the user will be deleted even if they have associated data.
bool force = 2 [(google.api.field_behavior) = OPTIONAL];
}
message SearchUsersRequest {
// Required. The search query.
string query = 1 [(google.api.field_behavior) = REQUIRED];
// Optional. The maximum number of users to return.
int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];
// Optional. A page token for pagination.
string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
}
message SearchUsersResponse {
// The list of users matching the search query.
repeated User users = 1;
// A token for the next page of results.
string next_page_token = 2;
// The total count of matching users.
int32 total_size = 3;
}
message GetUserAvatarRequest {
// Required. The resource name of the user.
// Format: users/{user}
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/User"}
];
} }
// User statistics messages
message UserStats { message UserStats {
// The name of the user. option (google.api.resource) = {
string name = 1; type: "memos.api.v1/UserStats"
pattern: "users/{user}"
singular: "userStats"
plural: "userStats"
};
// The resource name of the user whose stats these are.
// Format: users/{user}
string name = 1 [(google.api.field_behavior) = IDENTIFIER];
// The timestamps when the memos were displayed. // The timestamps when the memos were displayed.
// We should return raw data to the client, and let the client format the data with the user's timezone.
repeated google.protobuf.Timestamp memo_display_timestamps = 2; repeated google.protobuf.Timestamp memo_display_timestamps = 2;
// The stats of memo types. // The stats of memo types.
MemoTypeStats memo_type_stats = 3; MemoTypeStats memo_type_stats = 3;
// The count of tags. // The count of tags.
// Format: "tag1": 1, "tag2": 2
map<string, int32> tag_count = 4; map<string, int32> tag_count = 4;
// The pinned memos of the user. // The pinned memos of the user.
repeated string pinned_memos = 5; repeated string pinned_memos = 5;
// Total memo count.
int32 total_memo_count = 6; int32 total_memo_count = 6;
// Memo type statistics.
message MemoTypeStats { message MemoTypeStats {
int32 link_count = 1; int32 link_count = 1;
int32 code_count = 2; int32 code_count = 2;
@ -198,67 +333,146 @@ message UserStats {
} }
} }
message ListAllUserStatsRequest {}
message ListAllUserStatsResponse {
repeated UserStats user_stats = 1;
}
message GetUserStatsRequest { message GetUserStatsRequest {
// The name of the user. // Required. The resource name of the user.
string name = 1; // Format: users/{user}
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/User"}
];
} }
// User settings message
message UserSetting { message UserSetting {
// The name of the user. option (google.api.resource) = {
string name = 1; type: "memos.api.v1/UserSetting"
pattern: "users/{user}"
singular: "userSetting"
plural: "userSettings"
};
// The resource name of the user whose setting this is.
// Format: users/{user}
string name = 1 [(google.api.field_behavior) = IDENTIFIER];
// The preferred locale of the user. // The preferred locale of the user.
string locale = 2; string locale = 2 [(google.api.field_behavior) = OPTIONAL];
// The preferred appearance of the user. // The preferred appearance of the user.
string appearance = 3; string appearance = 3 [(google.api.field_behavior) = OPTIONAL];
// The default visibility of the memo. // The default visibility of the memo.
string memo_visibility = 4; string memo_visibility = 4 [(google.api.field_behavior) = OPTIONAL];
} }
message GetUserSettingRequest { message GetUserSettingRequest {
// The name of the user. // Required. The resource name of the user.
string name = 1; // Format: users/{user}
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/User"}
];
} }
message UpdateUserSettingRequest { message UpdateUserSettingRequest {
// Required. The user setting to update.
UserSetting setting = 1 [(google.api.field_behavior) = REQUIRED]; UserSetting setting = 1 [(google.api.field_behavior) = REQUIRED];
google.protobuf.FieldMask update_mask = 2; // Required. The list of fields to update.
google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED];
} }
// User access token message
message UserAccessToken { message UserAccessToken {
string access_token = 1; option (google.api.resource) = {
string description = 2; type: "memos.api.v1/UserAccessToken"
google.protobuf.Timestamp issued_at = 3; pattern: "users/{user}/accessTokens/{access_token}"
google.protobuf.Timestamp expires_at = 4; singular: "userAccessToken"
plural: "userAccessTokens"
};
// The resource name of the access token.
// Format: users/{user}/accessTokens/{access_token}
string name = 1 [(google.api.field_behavior) = IDENTIFIER];
// Output only. The access token value.
string access_token = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
// The description of the access token.
string description = 3 [(google.api.field_behavior) = OPTIONAL];
// Output only. The issued timestamp.
google.protobuf.Timestamp issued_at = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
// Optional. The expiration timestamp.
google.protobuf.Timestamp expires_at = 5 [(google.api.field_behavior) = OPTIONAL];
} }
message ListUserAccessTokensRequest { message ListUserAccessTokensRequest {
// The name of the user. // Required. The parent resource whose access tokens will be listed.
string name = 1; // Format: users/{user}
string parent = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/User"}
];
// Optional. The maximum number of access tokens to return.
int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];
// Optional. A page token for pagination.
string page_token = 3 [(google.api.field_behavior) = OPTIONAL];
} }
message ListUserAccessTokensResponse { message ListUserAccessTokensResponse {
// The list of access tokens.
repeated UserAccessToken access_tokens = 1; repeated UserAccessToken access_tokens = 1;
// A token for the next page of results.
string next_page_token = 2;
// The total count of access tokens.
int32 total_size = 3;
} }
message CreateUserAccessTokenRequest { message CreateUserAccessTokenRequest {
// The name of the user. // Required. The parent resource where this access token will be created.
string name = 1; // Format: users/{user}
string parent = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/User"}
];
string description = 2; // Required. The access token to create.
UserAccessToken access_token = 2 [(google.api.field_behavior) = REQUIRED];
optional google.protobuf.Timestamp expires_at = 3; // Optional. The access token ID to use.
string access_token_id = 3 [(google.api.field_behavior) = OPTIONAL];
} }
message DeleteUserAccessTokenRequest { message DeleteUserAccessTokenRequest {
// The name of the user. // Required. The resource name of the access token to delete.
string name = 1; // Format: users/{user}/accessTokens/{access_token}
// access_token is the access token to delete. string name = 1 [
string access_token = 2; (google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = {type: "memos.api.v1/UserAccessToken"}
];
}
message ListAllUserStatsRequest {
// Optional. The maximum number of user stats to return.
int32 page_size = 1 [(google.api.field_behavior) = OPTIONAL];
// Optional. A page token for pagination.
string page_token = 2 [(google.api.field_behavior) = OPTIONAL];
}
message ListAllUserStatsResponse {
// The list of user statistics.
repeated UserStats user_stats = 1;
// A token for the next page of results.
string next_page_token = 2;
// The total count of user statistics.
int32 total_size = 3;
} }

File diff suppressed because it is too large Load Diff

@ -35,100 +35,44 @@ var (
_ = metadata.Join _ = metadata.Join
) )
func request_UserService_ListUsers_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var filter_UserService_ListUsers_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
var (
protoReq ListUsersRequest
metadata runtime.ServerMetadata
)
io.Copy(io.Discard, req.Body)
msg, err := client.ListUsers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_UserService_ListUsers_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { func request_UserService_ListUsers_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var ( var (
protoReq ListUsersRequest protoReq ListUsersRequest
metadata runtime.ServerMetadata metadata runtime.ServerMetadata
) )
msg, err := server.ListUsers(ctx, &protoReq)
return msg, metadata, err
}
func request_UserService_GetUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetUserRequest
metadata runtime.ServerMetadata
err error
)
io.Copy(io.Discard, req.Body)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := client.GetUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_UserService_GetUser_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetUserRequest
metadata runtime.ServerMetadata
err error
)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := server.GetUser(ctx, &protoReq)
return msg, metadata, err
}
var filter_UserService_GetUserByUsername_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
func request_UserService_GetUserByUsername_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetUserByUsernameRequest
metadata runtime.ServerMetadata
)
io.Copy(io.Discard, req.Body) io.Copy(io.Discard, req.Body)
if err := req.ParseForm(); err != nil { if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_GetUserByUsername_0); err != nil { if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_ListUsers_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
msg, err := client.GetUserByUsername(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) msg, err := client.ListUsers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err return msg, metadata, err
} }
func local_request_UserService_GetUserByUsername_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { func local_request_UserService_ListUsers_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var ( var (
protoReq GetUserByUsernameRequest protoReq ListUsersRequest
metadata runtime.ServerMetadata metadata runtime.ServerMetadata
) )
if err := req.ParseForm(); err != nil { if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_GetUserByUsername_0); err != nil { if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_ListUsers_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
msg, err := server.GetUserByUsername(ctx, &protoReq) msg, err := server.ListUsers(ctx, &protoReq)
return msg, metadata, err return msg, metadata, err
} }
var filter_UserService_GetUserAvatarBinary_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} var filter_UserService_GetUser_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
func request_UserService_GetUserAvatarBinary_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { func request_UserService_GetUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var ( var (
protoReq GetUserAvatarBinaryRequest protoReq GetUserRequest
metadata runtime.ServerMetadata metadata runtime.ServerMetadata
err error err error
) )
@ -144,16 +88,16 @@ func request_UserService_GetUserAvatarBinary_0(ctx context.Context, marshaler ru
if err := req.ParseForm(); err != nil { if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_GetUserAvatarBinary_0); err != nil { if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_GetUser_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
msg, err := client.GetUserAvatarBinary(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) msg, err := client.GetUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err return msg, metadata, err
} }
func local_request_UserService_GetUserAvatarBinary_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { func local_request_UserService_GetUser_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var ( var (
protoReq GetUserAvatarBinaryRequest protoReq GetUserRequest
metadata runtime.ServerMetadata metadata runtime.ServerMetadata
err error err error
) )
@ -168,13 +112,15 @@ func local_request_UserService_GetUserAvatarBinary_0(ctx context.Context, marsha
if err := req.ParseForm(); err != nil { if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_GetUserAvatarBinary_0); err != nil { if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_GetUser_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
msg, err := server.GetUserAvatarBinary(ctx, &protoReq) msg, err := server.GetUser(ctx, &protoReq)
return msg, metadata, err return msg, metadata, err
} }
var filter_UserService_CreateUser_0 = &utilities.DoubleArray{Encoding: map[string]int{"user": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
func request_UserService_CreateUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { func request_UserService_CreateUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var ( var (
protoReq CreateUserRequest protoReq CreateUserRequest
@ -183,6 +129,12 @@ func request_UserService_CreateUser_0(ctx context.Context, marshaler runtime.Mar
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.User); err != nil && !errors.Is(err, io.EOF) { if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.User); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_CreateUser_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.CreateUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) msg, err := client.CreateUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err return msg, metadata, err
} }
@ -195,6 +147,12 @@ func local_request_UserService_CreateUser_0(ctx context.Context, marshaler runti
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.User); err != nil && !errors.Is(err, io.EOF) { if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.User); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_CreateUser_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.CreateUser(ctx, &protoReq) msg, err := server.CreateUser(ctx, &protoReq)
return msg, metadata, err return msg, metadata, err
} }
@ -277,6 +235,8 @@ func local_request_UserService_UpdateUser_0(ctx context.Context, marshaler runti
return msg, metadata, err return msg, metadata, err
} }
var filter_UserService_DeleteUser_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
func request_UserService_DeleteUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { func request_UserService_DeleteUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var ( var (
protoReq DeleteUserRequest protoReq DeleteUserRequest
@ -292,6 +252,12 @@ func request_UserService_DeleteUser_0(ctx context.Context, marshaler runtime.Mar
if err != nil { if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
} }
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_DeleteUser_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.DeleteUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) msg, err := client.DeleteUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err return msg, metadata, err
} }
@ -310,16 +276,100 @@ func local_request_UserService_DeleteUser_0(ctx context.Context, marshaler runti
if err != nil { if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
} }
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_DeleteUser_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.DeleteUser(ctx, &protoReq) msg, err := server.DeleteUser(ctx, &protoReq)
return msg, metadata, err return msg, metadata, err
} }
var filter_UserService_SearchUsers_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
func request_UserService_SearchUsers_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq SearchUsersRequest
metadata runtime.ServerMetadata
)
io.Copy(io.Discard, req.Body)
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_SearchUsers_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.SearchUsers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_UserService_SearchUsers_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq SearchUsersRequest
metadata runtime.ServerMetadata
)
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_SearchUsers_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.SearchUsers(ctx, &protoReq)
return msg, metadata, err
}
func request_UserService_GetUserAvatar_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetUserAvatarRequest
metadata runtime.ServerMetadata
err error
)
io.Copy(io.Discard, req.Body)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := client.GetUserAvatar(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_UserService_GetUserAvatar_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq GetUserAvatarRequest
metadata runtime.ServerMetadata
err error
)
val, ok := pathParams["name"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
}
protoReq.Name, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
}
msg, err := server.GetUserAvatar(ctx, &protoReq)
return msg, metadata, err
}
var filter_UserService_ListAllUserStats_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
func request_UserService_ListAllUserStats_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { func request_UserService_ListAllUserStats_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var ( var (
protoReq ListAllUserStatsRequest protoReq ListAllUserStatsRequest
metadata runtime.ServerMetadata metadata runtime.ServerMetadata
) )
io.Copy(io.Discard, req.Body) io.Copy(io.Discard, req.Body)
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_ListAllUserStats_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ListAllUserStats(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) msg, err := client.ListAllUserStats(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err return msg, metadata, err
} }
@ -329,6 +379,12 @@ func local_request_UserService_ListAllUserStats_0(ctx context.Context, marshaler
protoReq ListAllUserStatsRequest protoReq ListAllUserStatsRequest
metadata runtime.ServerMetadata metadata runtime.ServerMetadata
) )
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_ListAllUserStats_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.ListAllUserStats(ctx, &protoReq) msg, err := server.ListAllUserStats(ctx, &protoReq)
return msg, metadata, err return msg, metadata, err
} }
@ -485,6 +541,8 @@ func local_request_UserService_UpdateUserSetting_0(ctx context.Context, marshale
return msg, metadata, err return msg, metadata, err
} }
var filter_UserService_ListUserAccessTokens_0 = &utilities.DoubleArray{Encoding: map[string]int{"parent": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
func request_UserService_ListUserAccessTokens_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { func request_UserService_ListUserAccessTokens_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var ( var (
protoReq ListUserAccessTokensRequest protoReq ListUserAccessTokensRequest
@ -492,13 +550,19 @@ func request_UserService_ListUserAccessTokens_0(ctx context.Context, marshaler r
err error err error
) )
io.Copy(io.Discard, req.Body) io.Copy(io.Discard, req.Body)
val, ok := pathParams["name"] val, ok := pathParams["parent"]
if !ok { if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "parent")
} }
protoReq.Name, err = runtime.String(val) protoReq.Parent, err = runtime.String(val)
if err != nil { if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "parent", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_ListUserAccessTokens_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
msg, err := client.ListUserAccessTokens(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) msg, err := client.ListUserAccessTokens(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err return msg, metadata, err
@ -510,34 +574,48 @@ func local_request_UserService_ListUserAccessTokens_0(ctx context.Context, marsh
metadata runtime.ServerMetadata metadata runtime.ServerMetadata
err error err error
) )
val, ok := pathParams["name"] val, ok := pathParams["parent"]
if !ok { if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "parent")
} }
protoReq.Name, err = runtime.String(val) protoReq.Parent, err = runtime.String(val)
if err != nil { if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "parent", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_ListUserAccessTokens_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
msg, err := server.ListUserAccessTokens(ctx, &protoReq) msg, err := server.ListUserAccessTokens(ctx, &protoReq)
return msg, metadata, err return msg, metadata, err
} }
var filter_UserService_CreateUserAccessToken_0 = &utilities.DoubleArray{Encoding: map[string]int{"access_token": 0, "parent": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}}
func request_UserService_CreateUserAccessToken_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { func request_UserService_CreateUserAccessToken_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var ( var (
protoReq CreateUserAccessTokenRequest protoReq CreateUserAccessTokenRequest
metadata runtime.ServerMetadata metadata runtime.ServerMetadata
err error err error
) )
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.AccessToken); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
val, ok := pathParams["name"] val, ok := pathParams["parent"]
if !ok { if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "parent")
} }
protoReq.Name, err = runtime.String(val) protoReq.Parent, err = runtime.String(val)
if err != nil { if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "parent", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_CreateUserAccessToken_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
msg, err := client.CreateUserAccessToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) msg, err := client.CreateUserAccessToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err return msg, metadata, err
@ -549,16 +627,22 @@ func local_request_UserService_CreateUserAccessToken_0(ctx context.Context, mars
metadata runtime.ServerMetadata metadata runtime.ServerMetadata
err error err error
) )
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) { if err := marshaler.NewDecoder(req.Body).Decode(&protoReq.AccessToken); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
val, ok := pathParams["name"] val, ok := pathParams["parent"]
if !ok { if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "parent")
} }
protoReq.Name, err = runtime.String(val) protoReq.Parent, err = runtime.String(val)
if err != nil { if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "parent", err)
}
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_CreateUserAccessToken_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
} }
msg, err := server.CreateUserAccessToken(ctx, &protoReq) msg, err := server.CreateUserAccessToken(ctx, &protoReq)
return msg, metadata, err return msg, metadata, err
@ -579,14 +663,6 @@ func request_UserService_DeleteUserAccessToken_0(ctx context.Context, marshaler
if err != nil { if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
} }
val, ok = pathParams["access_token"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "access_token")
}
protoReq.AccessToken, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "access_token", err)
}
msg, err := client.DeleteUserAccessToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) msg, err := client.DeleteUserAccessToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err return msg, metadata, err
} }
@ -605,14 +681,6 @@ func local_request_UserService_DeleteUserAccessToken_0(ctx context.Context, mars
if err != nil { if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
} }
val, ok = pathParams["access_token"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "access_token")
}
protoReq.AccessToken, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "access_token", err)
}
msg, err := server.DeleteUserAccessToken(ctx, &protoReq) msg, err := server.DeleteUserAccessToken(ctx, &protoReq)
return msg, metadata, err return msg, metadata, err
} }
@ -663,113 +731,113 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
} }
forward_UserService_GetUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_GetUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodGet, pattern_UserService_GetUserByUsername_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodPost, pattern_UserService_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserByUsername", runtime.WithHTTPPathPattern("/api/v1/users:username")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/CreateUser", runtime.WithHTTPPathPattern("/api/v1/users"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := local_request_UserService_GetUserByUsername_0(annotatedContext, inboundMarshaler, server, req, pathParams) resp, md, err := local_request_UserService_CreateUser_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_UserService_GetUserByUsername_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_CreateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodGet, pattern_UserService_GetUserAvatarBinary_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodPatch, pattern_UserService_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserAvatarBinary", runtime.WithHTTPPathPattern("/file/{name=users/*}/avatar")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/UpdateUser", runtime.WithHTTPPathPattern("/api/v1/{user.name=users/*}"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := local_request_UserService_GetUserAvatarBinary_0(annotatedContext, inboundMarshaler, server, req, pathParams) resp, md, err := local_request_UserService_UpdateUser_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_UserService_GetUserAvatarBinary_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_UpdateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodPost, pattern_UserService_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodDelete, pattern_UserService_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/CreateUser", runtime.WithHTTPPathPattern("/api/v1/users")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/DeleteUser", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := local_request_UserService_CreateUser_0(annotatedContext, inboundMarshaler, server, req, pathParams) resp, md, err := local_request_UserService_DeleteUser_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_UserService_CreateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodPatch, pattern_UserService_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodGet, pattern_UserService_SearchUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/UpdateUser", runtime.WithHTTPPathPattern("/api/v1/{user.name=users/*}")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/SearchUsers", runtime.WithHTTPPathPattern("/api/v1/users:search"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := local_request_UserService_UpdateUser_0(annotatedContext, inboundMarshaler, server, req, pathParams) resp, md, err := local_request_UserService_SearchUsers_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_UserService_UpdateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_SearchUsers_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodDelete, pattern_UserService_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodGet, pattern_UserService_GetUserAvatar_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/DeleteUser", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserAvatar", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/avatar"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := local_request_UserService_DeleteUser_0(annotatedContext, inboundMarshaler, server, req, pathParams) resp, md, err := local_request_UserService_GetUserAvatar_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_UserService_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_GetUserAvatar_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodPost, pattern_UserService_ListAllUserStats_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodGet, pattern_UserService_ListAllUserStats_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/ListAllUserStats", runtime.WithHTTPPathPattern("/api/v1/users/-/stats")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/ListAllUserStats", runtime.WithHTTPPathPattern("/api/v1/users:stats"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -789,7 +857,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserStats", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/stats")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserStats", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}:getStats"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -809,7 +877,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserSetting", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/setting")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserSetting", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}:getSetting"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -829,7 +897,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/UpdateUserSetting", runtime.WithHTTPPathPattern("/api/v1/{setting.name=users/*/setting}")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/UpdateUserSetting", runtime.WithHTTPPathPattern("/api/v1/{setting.name=users/*}:updateSetting"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -849,7 +917,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/ListUserAccessTokens", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/access_tokens")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/ListUserAccessTokens", runtime.WithHTTPPathPattern("/api/v1/{parent=users/*}/accessTokens"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -869,7 +937,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/CreateUserAccessToken", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/access_tokens")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/CreateUserAccessToken", runtime.WithHTTPPathPattern("/api/v1/{parent=users/*}/accessTokens"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -889,7 +957,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/DeleteUserAccessToken", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/access_tokens/{access_token}")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.UserService/DeleteUserAccessToken", runtime.WithHTTPPathPattern("/api/v1/{name=users/*/accessTokens/*}"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -977,96 +1045,96 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
} }
forward_UserService_GetUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_GetUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodGet, pattern_UserService_GetUserByUsername_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodPost, pattern_UserService_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserByUsername", runtime.WithHTTPPathPattern("/api/v1/users:username")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/CreateUser", runtime.WithHTTPPathPattern("/api/v1/users"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := request_UserService_GetUserByUsername_0(annotatedContext, inboundMarshaler, client, req, pathParams) resp, md, err := request_UserService_CreateUser_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_UserService_GetUserByUsername_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_CreateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodGet, pattern_UserService_GetUserAvatarBinary_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodPatch, pattern_UserService_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserAvatarBinary", runtime.WithHTTPPathPattern("/file/{name=users/*}/avatar")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/UpdateUser", runtime.WithHTTPPathPattern("/api/v1/{user.name=users/*}"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := request_UserService_GetUserAvatarBinary_0(annotatedContext, inboundMarshaler, client, req, pathParams) resp, md, err := request_UserService_UpdateUser_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_UserService_GetUserAvatarBinary_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_UpdateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodPost, pattern_UserService_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodDelete, pattern_UserService_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/CreateUser", runtime.WithHTTPPathPattern("/api/v1/users")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/DeleteUser", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := request_UserService_CreateUser_0(annotatedContext, inboundMarshaler, client, req, pathParams) resp, md, err := request_UserService_DeleteUser_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_UserService_CreateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodPatch, pattern_UserService_UpdateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodGet, pattern_UserService_SearchUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/UpdateUser", runtime.WithHTTPPathPattern("/api/v1/{user.name=users/*}")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/SearchUsers", runtime.WithHTTPPathPattern("/api/v1/users:search"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := request_UserService_UpdateUser_0(annotatedContext, inboundMarshaler, client, req, pathParams) resp, md, err := request_UserService_SearchUsers_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_UserService_UpdateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_SearchUsers_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodDelete, pattern_UserService_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodGet, pattern_UserService_GetUserAvatar_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/DeleteUser", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserAvatar", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/avatar"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := request_UserService_DeleteUser_0(annotatedContext, inboundMarshaler, client, req, pathParams) resp, md, err := request_UserService_GetUserAvatar_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_UserService_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_UserService_GetUserAvatar_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodPost, pattern_UserService_ListAllUserStats_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodGet, pattern_UserService_ListAllUserStats_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/ListAllUserStats", runtime.WithHTTPPathPattern("/api/v1/users/-/stats")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/ListAllUserStats", runtime.WithHTTPPathPattern("/api/v1/users:stats"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -1083,7 +1151,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserStats", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/stats")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserStats", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}:getStats"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -1100,7 +1168,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserSetting", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/setting")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/GetUserSetting", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}:getSetting"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -1117,7 +1185,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/UpdateUserSetting", runtime.WithHTTPPathPattern("/api/v1/{setting.name=users/*/setting}")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/UpdateUserSetting", runtime.WithHTTPPathPattern("/api/v1/{setting.name=users/*}:updateSetting"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -1134,7 +1202,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/ListUserAccessTokens", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/access_tokens")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/ListUserAccessTokens", runtime.WithHTTPPathPattern("/api/v1/{parent=users/*}/accessTokens"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -1151,7 +1219,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/CreateUserAccessToken", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/access_tokens")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/CreateUserAccessToken", runtime.WithHTTPPathPattern("/api/v1/{parent=users/*}/accessTokens"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -1168,7 +1236,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/DeleteUserAccessToken", runtime.WithHTTPPathPattern("/api/v1/{name=users/*}/access_tokens/{access_token}")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.UserService/DeleteUserAccessToken", runtime.WithHTTPPathPattern("/api/v1/{name=users/*/accessTokens/*}"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
@ -1187,28 +1255,28 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
var ( var (
pattern_UserService_ListUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "")) pattern_UserService_ListUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, ""))
pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, "")) pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, ""))
pattern_UserService_GetUserByUsername_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "username"))
pattern_UserService_GetUserAvatarBinary_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 2, 5, 2, 2, 3}, []string{"file", "users", "name", "avatar"}, ""))
pattern_UserService_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "")) pattern_UserService_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, ""))
pattern_UserService_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "user.name"}, "")) pattern_UserService_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "user.name"}, ""))
pattern_UserService_DeleteUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, "")) pattern_UserService_DeleteUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, ""))
pattern_UserService_ListAllUserStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"api", "v1", "users", "-", "stats"}, "")) pattern_UserService_SearchUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "search"))
pattern_UserService_GetUserStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "name", "stats"}, "")) pattern_UserService_GetUserAvatar_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "name", "avatar"}, ""))
pattern_UserService_GetUserSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "name", "setting"}, "")) pattern_UserService_ListAllUserStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "stats"))
pattern_UserService_UpdateUserSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 4, 3, 5, 4}, []string{"api", "v1", "users", "setting", "setting.name"}, "")) pattern_UserService_GetUserStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, "getStats"))
pattern_UserService_ListUserAccessTokens_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "name", "access_tokens"}, "")) pattern_UserService_GetUserSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "name"}, "getSetting"))
pattern_UserService_CreateUserAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "name", "access_tokens"}, "")) pattern_UserService_UpdateUserSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v1", "users", "setting.name"}, "updateSetting"))
pattern_UserService_DeleteUserAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"api", "v1", "users", "name", "access_tokens", "access_token"}, "")) pattern_UserService_ListUserAccessTokens_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "accessTokens"}, ""))
pattern_UserService_CreateUserAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "users", "parent", "accessTokens"}, ""))
pattern_UserService_DeleteUserAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "users", "accessTokens", "name"}, ""))
) )
var ( var (
forward_UserService_ListUsers_0 = runtime.ForwardResponseMessage forward_UserService_ListUsers_0 = runtime.ForwardResponseMessage
forward_UserService_GetUser_0 = runtime.ForwardResponseMessage forward_UserService_GetUser_0 = runtime.ForwardResponseMessage
forward_UserService_GetUserByUsername_0 = runtime.ForwardResponseMessage
forward_UserService_GetUserAvatarBinary_0 = runtime.ForwardResponseMessage
forward_UserService_CreateUser_0 = runtime.ForwardResponseMessage forward_UserService_CreateUser_0 = runtime.ForwardResponseMessage
forward_UserService_UpdateUser_0 = runtime.ForwardResponseMessage forward_UserService_UpdateUser_0 = runtime.ForwardResponseMessage
forward_UserService_DeleteUser_0 = runtime.ForwardResponseMessage forward_UserService_DeleteUser_0 = runtime.ForwardResponseMessage
forward_UserService_SearchUsers_0 = runtime.ForwardResponseMessage
forward_UserService_GetUserAvatar_0 = runtime.ForwardResponseMessage
forward_UserService_ListAllUserStats_0 = runtime.ForwardResponseMessage forward_UserService_ListAllUserStats_0 = runtime.ForwardResponseMessage
forward_UserService_GetUserStats_0 = runtime.ForwardResponseMessage forward_UserService_GetUserStats_0 = runtime.ForwardResponseMessage
forward_UserService_GetUserSetting_0 = runtime.ForwardResponseMessage forward_UserService_GetUserSetting_0 = runtime.ForwardResponseMessage

@ -23,11 +23,11 @@ const _ = grpc.SupportPackageIsVersion9
const ( const (
UserService_ListUsers_FullMethodName = "/memos.api.v1.UserService/ListUsers" UserService_ListUsers_FullMethodName = "/memos.api.v1.UserService/ListUsers"
UserService_GetUser_FullMethodName = "/memos.api.v1.UserService/GetUser" UserService_GetUser_FullMethodName = "/memos.api.v1.UserService/GetUser"
UserService_GetUserByUsername_FullMethodName = "/memos.api.v1.UserService/GetUserByUsername"
UserService_GetUserAvatarBinary_FullMethodName = "/memos.api.v1.UserService/GetUserAvatarBinary"
UserService_CreateUser_FullMethodName = "/memos.api.v1.UserService/CreateUser" UserService_CreateUser_FullMethodName = "/memos.api.v1.UserService/CreateUser"
UserService_UpdateUser_FullMethodName = "/memos.api.v1.UserService/UpdateUser" UserService_UpdateUser_FullMethodName = "/memos.api.v1.UserService/UpdateUser"
UserService_DeleteUser_FullMethodName = "/memos.api.v1.UserService/DeleteUser" UserService_DeleteUser_FullMethodName = "/memos.api.v1.UserService/DeleteUser"
UserService_SearchUsers_FullMethodName = "/memos.api.v1.UserService/SearchUsers"
UserService_GetUserAvatar_FullMethodName = "/memos.api.v1.UserService/GetUserAvatar"
UserService_ListAllUserStats_FullMethodName = "/memos.api.v1.UserService/ListAllUserStats" UserService_ListAllUserStats_FullMethodName = "/memos.api.v1.UserService/ListAllUserStats"
UserService_GetUserStats_FullMethodName = "/memos.api.v1.UserService/GetUserStats" UserService_GetUserStats_FullMethodName = "/memos.api.v1.UserService/GetUserStats"
UserService_GetUserSetting_FullMethodName = "/memos.api.v1.UserService/GetUserSetting" UserService_GetUserSetting_FullMethodName = "/memos.api.v1.UserService/GetUserSetting"
@ -45,29 +45,29 @@ type UserServiceClient interface {
ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error) ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error)
// GetUser gets a user by name. // GetUser gets a user by name.
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error)
// GetUserByUsername gets a user by username.
GetUserByUsername(ctx context.Context, in *GetUserByUsernameRequest, opts ...grpc.CallOption) (*User, error)
// GetUserAvatarBinary gets the avatar of a user.
GetUserAvatarBinary(ctx context.Context, in *GetUserAvatarBinaryRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error)
// CreateUser creates a new user. // CreateUser creates a new user.
CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*User, error) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*User, error)
// UpdateUser updates a user. // UpdateUser updates a user.
UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error)
// DeleteUser deletes a user. // DeleteUser deletes a user.
DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// ListAllUserStats returns all user stats. // SearchUsers searches for users based on query.
SearchUsers(ctx context.Context, in *SearchUsersRequest, opts ...grpc.CallOption) (*SearchUsersResponse, error)
// GetUserAvatar gets the avatar of a user.
GetUserAvatar(ctx context.Context, in *GetUserAvatarRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error)
// ListAllUserStats returns statistics for all users.
ListAllUserStats(ctx context.Context, in *ListAllUserStatsRequest, opts ...grpc.CallOption) (*ListAllUserStatsResponse, error) ListAllUserStats(ctx context.Context, in *ListAllUserStatsRequest, opts ...grpc.CallOption) (*ListAllUserStatsResponse, error)
// GetUserStats returns the stats of a user. // GetUserStats returns statistics for a specific user.
GetUserStats(ctx context.Context, in *GetUserStatsRequest, opts ...grpc.CallOption) (*UserStats, error) GetUserStats(ctx context.Context, in *GetUserStatsRequest, opts ...grpc.CallOption) (*UserStats, error)
// GetUserSetting gets the setting of a user. // GetUserSetting returns the user setting.
GetUserSetting(ctx context.Context, in *GetUserSettingRequest, opts ...grpc.CallOption) (*UserSetting, error) GetUserSetting(ctx context.Context, in *GetUserSettingRequest, opts ...grpc.CallOption) (*UserSetting, error)
// UpdateUserSetting updates the setting of a user. // UpdateUserSetting updates the user setting.
UpdateUserSetting(ctx context.Context, in *UpdateUserSettingRequest, opts ...grpc.CallOption) (*UserSetting, error) UpdateUserSetting(ctx context.Context, in *UpdateUserSettingRequest, opts ...grpc.CallOption) (*UserSetting, error)
// ListUserAccessTokens returns a list of access tokens for a user. // ListUserAccessTokens returns a list of access tokens for a user.
ListUserAccessTokens(ctx context.Context, in *ListUserAccessTokensRequest, opts ...grpc.CallOption) (*ListUserAccessTokensResponse, error) ListUserAccessTokens(ctx context.Context, in *ListUserAccessTokensRequest, opts ...grpc.CallOption) (*ListUserAccessTokensResponse, error)
// CreateUserAccessToken creates a new access token for a user. // CreateUserAccessToken creates a new access token for a user.
CreateUserAccessToken(ctx context.Context, in *CreateUserAccessTokenRequest, opts ...grpc.CallOption) (*UserAccessToken, error) CreateUserAccessToken(ctx context.Context, in *CreateUserAccessTokenRequest, opts ...grpc.CallOption) (*UserAccessToken, error)
// DeleteUserAccessToken deletes an access token for a user. // DeleteUserAccessToken deletes an access token.
DeleteUserAccessToken(ctx context.Context, in *DeleteUserAccessTokenRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) DeleteUserAccessToken(ctx context.Context, in *DeleteUserAccessTokenRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
} }
@ -99,50 +99,50 @@ func (c *userServiceClient) GetUser(ctx context.Context, in *GetUserRequest, opt
return out, nil return out, nil
} }
func (c *userServiceClient) GetUserByUsername(ctx context.Context, in *GetUserByUsernameRequest, opts ...grpc.CallOption) (*User, error) { func (c *userServiceClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*User, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(User) out := new(User)
err := c.cc.Invoke(ctx, UserService_GetUserByUsername_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, UserService_CreateUser_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
func (c *userServiceClient) GetUserAvatarBinary(ctx context.Context, in *GetUserAvatarBinaryRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error) { func (c *userServiceClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(httpbody.HttpBody) out := new(User)
err := c.cc.Invoke(ctx, UserService_GetUserAvatarBinary_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, UserService_UpdateUser_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
func (c *userServiceClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*User, error) { func (c *userServiceClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(User) out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, UserService_CreateUser_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, UserService_DeleteUser_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
func (c *userServiceClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error) { func (c *userServiceClient) SearchUsers(ctx context.Context, in *SearchUsersRequest, opts ...grpc.CallOption) (*SearchUsersResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(User) out := new(SearchUsersResponse)
err := c.cc.Invoke(ctx, UserService_UpdateUser_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, UserService_SearchUsers_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
func (c *userServiceClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { func (c *userServiceClient) GetUserAvatar(ctx context.Context, in *GetUserAvatarRequest, opts ...grpc.CallOption) (*httpbody.HttpBody, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(emptypb.Empty) out := new(httpbody.HttpBody)
err := c.cc.Invoke(ctx, UserService_DeleteUser_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, UserService_GetUserAvatar_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -227,29 +227,29 @@ type UserServiceServer interface {
ListUsers(context.Context, *ListUsersRequest) (*ListUsersResponse, error) ListUsers(context.Context, *ListUsersRequest) (*ListUsersResponse, error)
// GetUser gets a user by name. // GetUser gets a user by name.
GetUser(context.Context, *GetUserRequest) (*User, error) GetUser(context.Context, *GetUserRequest) (*User, error)
// GetUserByUsername gets a user by username.
GetUserByUsername(context.Context, *GetUserByUsernameRequest) (*User, error)
// GetUserAvatarBinary gets the avatar of a user.
GetUserAvatarBinary(context.Context, *GetUserAvatarBinaryRequest) (*httpbody.HttpBody, error)
// CreateUser creates a new user. // CreateUser creates a new user.
CreateUser(context.Context, *CreateUserRequest) (*User, error) CreateUser(context.Context, *CreateUserRequest) (*User, error)
// UpdateUser updates a user. // UpdateUser updates a user.
UpdateUser(context.Context, *UpdateUserRequest) (*User, error) UpdateUser(context.Context, *UpdateUserRequest) (*User, error)
// DeleteUser deletes a user. // DeleteUser deletes a user.
DeleteUser(context.Context, *DeleteUserRequest) (*emptypb.Empty, error) DeleteUser(context.Context, *DeleteUserRequest) (*emptypb.Empty, error)
// ListAllUserStats returns all user stats. // SearchUsers searches for users based on query.
SearchUsers(context.Context, *SearchUsersRequest) (*SearchUsersResponse, error)
// GetUserAvatar gets the avatar of a user.
GetUserAvatar(context.Context, *GetUserAvatarRequest) (*httpbody.HttpBody, error)
// ListAllUserStats returns statistics for all users.
ListAllUserStats(context.Context, *ListAllUserStatsRequest) (*ListAllUserStatsResponse, error) ListAllUserStats(context.Context, *ListAllUserStatsRequest) (*ListAllUserStatsResponse, error)
// GetUserStats returns the stats of a user. // GetUserStats returns statistics for a specific user.
GetUserStats(context.Context, *GetUserStatsRequest) (*UserStats, error) GetUserStats(context.Context, *GetUserStatsRequest) (*UserStats, error)
// GetUserSetting gets the setting of a user. // GetUserSetting returns the user setting.
GetUserSetting(context.Context, *GetUserSettingRequest) (*UserSetting, error) GetUserSetting(context.Context, *GetUserSettingRequest) (*UserSetting, error)
// UpdateUserSetting updates the setting of a user. // UpdateUserSetting updates the user setting.
UpdateUserSetting(context.Context, *UpdateUserSettingRequest) (*UserSetting, error) UpdateUserSetting(context.Context, *UpdateUserSettingRequest) (*UserSetting, error)
// ListUserAccessTokens returns a list of access tokens for a user. // ListUserAccessTokens returns a list of access tokens for a user.
ListUserAccessTokens(context.Context, *ListUserAccessTokensRequest) (*ListUserAccessTokensResponse, error) ListUserAccessTokens(context.Context, *ListUserAccessTokensRequest) (*ListUserAccessTokensResponse, error)
// CreateUserAccessToken creates a new access token for a user. // CreateUserAccessToken creates a new access token for a user.
CreateUserAccessToken(context.Context, *CreateUserAccessTokenRequest) (*UserAccessToken, error) CreateUserAccessToken(context.Context, *CreateUserAccessTokenRequest) (*UserAccessToken, error)
// DeleteUserAccessToken deletes an access token for a user. // DeleteUserAccessToken deletes an access token.
DeleteUserAccessToken(context.Context, *DeleteUserAccessTokenRequest) (*emptypb.Empty, error) DeleteUserAccessToken(context.Context, *DeleteUserAccessTokenRequest) (*emptypb.Empty, error)
mustEmbedUnimplementedUserServiceServer() mustEmbedUnimplementedUserServiceServer()
} }
@ -267,12 +267,6 @@ func (UnimplementedUserServiceServer) ListUsers(context.Context, *ListUsersReque
func (UnimplementedUserServiceServer) GetUser(context.Context, *GetUserRequest) (*User, error) { func (UnimplementedUserServiceServer) GetUser(context.Context, *GetUserRequest) (*User, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented") return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented")
} }
func (UnimplementedUserServiceServer) GetUserByUsername(context.Context, *GetUserByUsernameRequest) (*User, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUserByUsername not implemented")
}
func (UnimplementedUserServiceServer) GetUserAvatarBinary(context.Context, *GetUserAvatarBinaryRequest) (*httpbody.HttpBody, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUserAvatarBinary not implemented")
}
func (UnimplementedUserServiceServer) CreateUser(context.Context, *CreateUserRequest) (*User, error) { func (UnimplementedUserServiceServer) CreateUser(context.Context, *CreateUserRequest) (*User, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateUser not implemented") return nil, status.Errorf(codes.Unimplemented, "method CreateUser not implemented")
} }
@ -282,6 +276,12 @@ func (UnimplementedUserServiceServer) UpdateUser(context.Context, *UpdateUserReq
func (UnimplementedUserServiceServer) DeleteUser(context.Context, *DeleteUserRequest) (*emptypb.Empty, error) { func (UnimplementedUserServiceServer) DeleteUser(context.Context, *DeleteUserRequest) (*emptypb.Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteUser not implemented") return nil, status.Errorf(codes.Unimplemented, "method DeleteUser not implemented")
} }
func (UnimplementedUserServiceServer) SearchUsers(context.Context, *SearchUsersRequest) (*SearchUsersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method SearchUsers not implemented")
}
func (UnimplementedUserServiceServer) GetUserAvatar(context.Context, *GetUserAvatarRequest) (*httpbody.HttpBody, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUserAvatar not implemented")
}
func (UnimplementedUserServiceServer) ListAllUserStats(context.Context, *ListAllUserStatsRequest) (*ListAllUserStatsResponse, error) { func (UnimplementedUserServiceServer) ListAllUserStats(context.Context, *ListAllUserStatsRequest) (*ListAllUserStatsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListAllUserStats not implemented") return nil, status.Errorf(codes.Unimplemented, "method ListAllUserStats not implemented")
} }
@ -360,92 +360,92 @@ func _UserService_GetUser_Handler(srv interface{}, ctx context.Context, dec func
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _UserService_GetUserByUsername_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _UserService_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserByUsernameRequest) in := new(CreateUserRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(UserServiceServer).GetUserByUsername(ctx, in) return srv.(UserServiceServer).CreateUser(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: UserService_GetUserByUsername_FullMethodName, FullMethod: UserService_CreateUser_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserServiceServer).GetUserByUsername(ctx, req.(*GetUserByUsernameRequest)) return srv.(UserServiceServer).CreateUser(ctx, req.(*CreateUserRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _UserService_GetUserAvatarBinary_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _UserService_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserAvatarBinaryRequest) in := new(UpdateUserRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(UserServiceServer).GetUserAvatarBinary(ctx, in) return srv.(UserServiceServer).UpdateUser(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: UserService_GetUserAvatarBinary_FullMethodName, FullMethod: UserService_UpdateUser_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserServiceServer).GetUserAvatarBinary(ctx, req.(*GetUserAvatarBinaryRequest)) return srv.(UserServiceServer).UpdateUser(ctx, req.(*UpdateUserRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _UserService_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _UserService_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateUserRequest) in := new(DeleteUserRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(UserServiceServer).CreateUser(ctx, in) return srv.(UserServiceServer).DeleteUser(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: UserService_CreateUser_FullMethodName, FullMethod: UserService_DeleteUser_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserServiceServer).CreateUser(ctx, req.(*CreateUserRequest)) return srv.(UserServiceServer).DeleteUser(ctx, req.(*DeleteUserRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _UserService_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _UserService_SearchUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateUserRequest) in := new(SearchUsersRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(UserServiceServer).UpdateUser(ctx, in) return srv.(UserServiceServer).SearchUsers(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: UserService_UpdateUser_FullMethodName, FullMethod: UserService_SearchUsers_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserServiceServer).UpdateUser(ctx, req.(*UpdateUserRequest)) return srv.(UserServiceServer).SearchUsers(ctx, req.(*SearchUsersRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _UserService_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _UserService_GetUserAvatar_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteUserRequest) in := new(GetUserAvatarRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(UserServiceServer).DeleteUser(ctx, in) return srv.(UserServiceServer).GetUserAvatar(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: UserService_DeleteUser_FullMethodName, FullMethod: UserService_GetUserAvatar_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserServiceServer).DeleteUser(ctx, req.(*DeleteUserRequest)) return srv.(UserServiceServer).GetUserAvatar(ctx, req.(*GetUserAvatarRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
@ -591,14 +591,6 @@ var UserService_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetUser", MethodName: "GetUser",
Handler: _UserService_GetUser_Handler, Handler: _UserService_GetUser_Handler,
}, },
{
MethodName: "GetUserByUsername",
Handler: _UserService_GetUserByUsername_Handler,
},
{
MethodName: "GetUserAvatarBinary",
Handler: _UserService_GetUserAvatarBinary_Handler,
},
{ {
MethodName: "CreateUser", MethodName: "CreateUser",
Handler: _UserService_CreateUser_Handler, Handler: _UserService_CreateUser_Handler,
@ -611,6 +603,14 @@ var UserService_ServiceDesc = grpc.ServiceDesc{
MethodName: "DeleteUser", MethodName: "DeleteUser",
Handler: _UserService_DeleteUser_Handler, Handler: _UserService_DeleteUser_Handler,
}, },
{
MethodName: "SearchUsers",
Handler: _UserService_SearchUsers_Handler,
},
{
MethodName: "GetUserAvatar",
Handler: _UserService_GetUserAvatar_Handler,
},
{ {
MethodName: "ListAllUserStats", MethodName: "ListAllUserStats",
Handler: _UserService_ListAllUserStats_Handler, Handler: _UserService_ListAllUserStats_Handler,

@ -452,6 +452,45 @@ paths:
description: An unexpected error response. description: An unexpected error response.
schema: schema:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters:
- name: pageSize
description: |-
Optional. The maximum number of users to return.
The service may return fewer than this value.
If unspecified, at most 50 users will be returned.
The maximum value is 1000; values above 1000 will be coerced to 1000.
in: query
required: false
type: integer
format: int32
- name: pageToken
description: |-
Optional. A page token, received from a previous `ListUsers` call.
Provide this to retrieve the subsequent page.
in: query
required: false
type: string
- name: filter
description: |-
Optional. Filter to apply to the list results.
Example: "state=ACTIVE" or "role=USER" or "email:@example.com"
Supported operators: =, !=, <, <=, >, >=, :
Supported fields: username, email, role, state, create_time, update_time
in: query
required: false
type: string
- name: orderBy
description: |-
Optional. The order to sort results by.
Example: "create_time desc" or "username asc"
in: query
required: false
type: string
- name: showDeleted
description: Optional. If true, show deleted users in the response.
in: query
required: false
type: boolean
tags: tags:
- UserService - UserService
post: post:
@ -468,43 +507,89 @@ paths:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: user - name: user
description: Required. The user to create.
in: body in: body
required: true required: true
schema: schema:
$ref: '#/definitions/v1User' $ref: '#/definitions/v1User'
required:
- user
- name: userId
description: |-
Optional. The user ID to use for this user.
If empty, a unique ID will be generated.
Must match the pattern [a-z0-9-]+
in: query
required: false
type: string
- name: validateOnly
description: Optional. If set, validate the request but don't actually create the user.
in: query
required: false
type: boolean
- name: requestId
description: |-
Optional. An idempotency token that can be used to ensure that multiple
requests to create a user have the same result.
in: query
required: false
type: string
tags: tags:
- UserService - UserService
/api/v1/users/-/stats: /api/v1/users:search:
post: get:
summary: ListAllUserStats returns all user stats. summary: SearchUsers searches for users based on query.
operationId: UserService_ListAllUserStats operationId: UserService_SearchUsers
responses: responses:
"200": "200":
description: A successful response. description: A successful response.
schema: schema:
$ref: '#/definitions/v1ListAllUserStatsResponse' $ref: '#/definitions/v1SearchUsersResponse'
default: default:
description: An unexpected error response. description: An unexpected error response.
schema: schema:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters:
- name: query
description: Required. The search query.
in: query
required: true
type: string
- name: pageSize
description: Optional. The maximum number of users to return.
in: query
required: false
type: integer
format: int32
- name: pageToken
description: Optional. A page token for pagination.
in: query
required: false
type: string
tags: tags:
- UserService - UserService
/api/v1/users:username: /api/v1/users:stats:
get: get:
summary: GetUserByUsername gets a user by username. summary: ListAllUserStats returns statistics for all users.
operationId: UserService_GetUserByUsername operationId: UserService_ListAllUserStats
responses: responses:
"200": "200":
description: A successful response. description: A successful response.
schema: schema:
$ref: '#/definitions/v1User' $ref: '#/definitions/v1ListAllUserStatsResponse'
default: default:
description: An unexpected error response. description: An unexpected error response.
schema: schema:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: username - name: pageSize
description: The username of the user. description: Optional. The maximum number of user stats to return.
in: query
required: false
type: integer
format: int32
- name: pageToken
description: Optional. A page token for pagination.
in: query in: query
required: false required: false
type: string type: string
@ -914,16 +999,25 @@ paths:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: name_1 - name: name_1
description: The name of the user. description: |-
Required. The resource name of the user.
Format: users/{user}
in: path in: path
required: true required: true
type: string type: string
pattern: users/[^/]+ pattern: users/[^/]+
- name: readMask
description: |-
Optional. The fields to return in the response.
If not specified, all fields are returned.
in: query
required: false
type: string
tags: tags:
- UserService - UserService
delete: delete:
summary: DeleteIdentityProvider deletes an identity provider. summary: DeleteUserAccessToken deletes an access token.
operationId: IdentityProviderService_DeleteIdentityProvider operationId: UserService_DeleteUserAccessToken
responses: responses:
"200": "200":
description: A successful response. description: A successful response.
@ -936,13 +1030,15 @@ paths:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: name_1 - name: name_1
description: The name of the identityProvider to delete. description: |-
Required. The resource name of the access token to delete.
Format: users/{user}/accessTokens/{access_token}
in: path in: path
required: true required: true
type: string type: string
pattern: identityProviders/[^/]+ pattern: users/[^/]+/accessTokens/[^/]+
tags: tags:
- IdentityProviderService - UserService
/api/v1/{name_2}: /api/v1/{name_2}:
get: get:
summary: GetIdentityProvider gets an identity provider. summary: GetIdentityProvider gets an identity provider.
@ -966,8 +1062,8 @@ paths:
tags: tags:
- IdentityProviderService - IdentityProviderService
delete: delete:
summary: DeleteInbox deletes an inbox. summary: DeleteIdentityProvider deletes an identity provider.
operationId: InboxService_DeleteInbox operationId: IdentityProviderService_DeleteIdentityProvider
responses: responses:
"200": "200":
description: A successful response. description: A successful response.
@ -980,13 +1076,13 @@ paths:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: name_2 - name: name_2
description: The name of the inbox to delete. description: The name of the identityProvider to delete.
in: path in: path
required: true required: true
type: string type: string
pattern: inboxes/[^/]+ pattern: identityProviders/[^/]+
tags: tags:
- InboxService - IdentityProviderService
/api/v1/{name_3}: /api/v1/{name_3}:
get: get:
summary: GetResource returns a resource by name. summary: GetResource returns a resource by name.
@ -1010,8 +1106,8 @@ paths:
tags: tags:
- ResourceService - ResourceService
delete: delete:
summary: DeleteResource deletes a resource by name. summary: DeleteInbox deletes an inbox.
operationId: ResourceService_DeleteResource operationId: InboxService_DeleteInbox
responses: responses:
"200": "200":
description: A successful response. description: A successful response.
@ -1024,13 +1120,13 @@ paths:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: name_3 - name: name_3
description: The name of the resource. description: The name of the inbox to delete.
in: path in: path
required: true required: true
type: string type: string
pattern: resources/[^/]+ pattern: inboxes/[^/]+
tags: tags:
- ResourceService - InboxService
/api/v1/{name_4}: /api/v1/{name_4}:
get: get:
summary: GetMemo gets a memo. summary: GetMemo gets a memo.
@ -1053,6 +1149,29 @@ paths:
pattern: memos/[^/]+ pattern: memos/[^/]+
tags: tags:
- MemoService - MemoService
delete:
summary: DeleteResource deletes a resource by name.
operationId: ResourceService_DeleteResource
responses:
"200":
description: A successful response.
schema:
type: object
properties: {}
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name_4
description: The name of the resource.
in: path
required: true
type: string
pattern: resources/[^/]+
tags:
- ResourceService
/api/v1/{name_5}:
delete: delete:
summary: DeleteMemo deletes a memo. summary: DeleteMemo deletes a memo.
operationId: MemoService_DeleteMemo operationId: MemoService_DeleteMemo
@ -1067,7 +1186,7 @@ paths:
schema: schema:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: name_4 - name: name_5
description: The name of the memo. description: The name of the memo.
in: path in: path
required: true required: true
@ -1114,87 +1233,42 @@ paths:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: name - name: name
description: The name of the user. description: |-
Required. The resource name of the user to delete.
Format: users/{user}
in: path in: path
required: true required: true
type: string type: string
pattern: users/[^/]+ pattern: users/[^/]+
- name: force
description: Optional. If set to true, the user will be deleted even if they have associated data.
in: query
required: false
type: boolean
tags: tags:
- UserService - UserService
/api/v1/{name}/access_tokens: /api/v1/{name}/avatar:
get: get:
summary: ListUserAccessTokens returns a list of access tokens for a user. summary: GetUserAvatar gets the avatar of a user.
operationId: UserService_ListUserAccessTokens operationId: UserService_GetUserAvatar
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1ListUserAccessTokensResponse'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the user.
in: path
required: true
type: string
pattern: users/[^/]+
tags:
- UserService
post:
summary: CreateUserAccessToken creates a new access token for a user.
operationId: UserService_CreateUserAccessToken
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1UserAccessToken'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the user.
in: path
required: true
type: string
pattern: users/[^/]+
- name: body
in: body
required: true
schema:
$ref: '#/definitions/UserServiceCreateUserAccessTokenBody'
tags:
- UserService
/api/v1/{name}/access_tokens/{accessToken}:
delete:
summary: DeleteUserAccessToken deletes an access token for a user.
operationId: UserService_DeleteUserAccessToken
responses: responses:
"200": "200":
description: A successful response. description: A successful response.
schema: schema:
type: object $ref: '#/definitions/apiHttpBody'
properties: {}
default: default:
description: An unexpected error response. description: An unexpected error response.
schema: schema:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: name - name: name
description: The name of the user. description: |-
Required. The resource name of the user.
Format: users/{user}
in: path in: path
required: true required: true
type: string type: string
pattern: users/[^/]+ pattern: users/[^/]+
- name: accessToken
description: access_token is the access token to delete.
in: path
required: true
type: string
tags: tags:
- UserService - UserService
/api/v1/{name}/comments: /api/v1/{name}/comments:
@ -1392,9 +1466,9 @@ paths:
$ref: '#/definitions/MemoServiceSetMemoResourcesBody' $ref: '#/definitions/MemoServiceSetMemoResourcesBody'
tags: tags:
- MemoService - MemoService
/api/v1/{name}/setting: /api/v1/{name}:getSetting:
get: get:
summary: GetUserSetting gets the setting of a user. summary: GetUserSetting returns the user setting.
operationId: UserService_GetUserSetting operationId: UserService_GetUserSetting
responses: responses:
"200": "200":
@ -1407,16 +1481,18 @@ paths:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: name - name: name
description: The name of the user. description: |-
Required. The resource name of the user.
Format: users/{user}
in: path in: path
required: true required: true
type: string type: string
pattern: users/[^/]+ pattern: users/[^/]+
tags: tags:
- UserService - UserService
/api/v1/{name}/stats: /api/v1/{name}:getStats:
get: get:
summary: GetUserStats returns the stats of a user. summary: GetUserStats returns statistics for a specific user.
operationId: UserService_GetUserStats operationId: UserService_GetUserStats
responses: responses:
"200": "200":
@ -1429,13 +1505,86 @@ paths:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: name - name: name
description: The name of the user. description: |-
Required. The resource name of the user.
Format: users/{user}
in: path in: path
required: true required: true
type: string type: string
pattern: users/[^/]+ pattern: users/[^/]+
tags: tags:
- UserService - UserService
/api/v1/{parent}/accessTokens:
get:
summary: ListUserAccessTokens returns a list of access tokens for a user.
operationId: UserService_ListUserAccessTokens
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1ListUserAccessTokensResponse'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: parent
description: |-
Required. The parent resource whose access tokens will be listed.
Format: users/{user}
in: path
required: true
type: string
pattern: users/[^/]+
- name: pageSize
description: Optional. The maximum number of access tokens to return.
in: query
required: false
type: integer
format: int32
- name: pageToken
description: Optional. A page token for pagination.
in: query
required: false
type: string
tags:
- UserService
post:
summary: CreateUserAccessToken creates a new access token for a user.
operationId: UserService_CreateUserAccessToken
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1UserAccessToken'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: parent
description: |-
Required. The parent resource where this access token will be created.
Format: users/{user}
in: path
required: true
type: string
pattern: users/[^/]+
- name: accessToken
description: Required. The access token to create.
in: body
required: true
schema:
$ref: '#/definitions/v1UserAccessToken'
required:
- accessToken
- name: accessTokenId
description: Optional. The access token ID to use.
in: query
required: false
type: string
tags:
- UserService
/api/v1/{parent}/memos: /api/v1/{parent}/memos:
get: get:
summary: ListMemos lists memos with pagination and filter. summary: ListMemos lists memos with pagination and filter.
@ -1746,9 +1895,9 @@ paths:
description: The related memo. Refer to `Memo.name`. description: The related memo. Refer to `Memo.name`.
tags: tags:
- ResourceService - ResourceService
/api/v1/{setting.name}: /api/v1/{setting.name}:updateSetting:
patch: patch:
summary: UpdateUserSetting updates the setting of a user. summary: UpdateUserSetting updates the user setting.
operationId: UserService_UpdateUserSetting operationId: UserService_UpdateUserSetting
responses: responses:
"200": "200":
@ -1761,12 +1910,15 @@ paths:
$ref: '#/definitions/googlerpcStatus' $ref: '#/definitions/googlerpcStatus'
parameters: parameters:
- name: setting.name - name: setting.name
description: The name of the user. description: |-
The resource name of the user whose setting this is.
Format: users/{user}
in: path in: path
required: true required: true
type: string type: string
pattern: users/[^/]+/setting pattern: users/[^/]+
- name: setting - name: setting
description: Required. The user setting to update.
in: body in: body
required: true required: true
schema: schema:
@ -1781,6 +1933,7 @@ paths:
memoVisibility: memoVisibility:
type: string type: string
description: The default visibility of the memo. description: The default visibility of the memo.
title: Required. The user setting to update.
required: required:
- setting - setting
tags: tags:
@ -1801,77 +1954,72 @@ paths:
parameters: parameters:
- name: user.name - name: user.name
description: |- description: |-
The name of the user. The resource name of the user.
Format: users/{id}, id is the system generated auto-incremented id. Format: users/{user}
in: path in: path
required: true required: true
type: string type: string
pattern: users/[^/]+ pattern: users/[^/]+
- name: user - name: user
description: Required. The user to update.
in: body in: body
required: true required: true
schema: schema:
type: object type: object
properties: properties:
uid:
type: string
description: Output only. The system generated unique identifier.
readOnly: true
role: role:
$ref: '#/definitions/UserRole' $ref: '#/definitions/UserRole'
description: The role of the user.
username: username:
type: string type: string
description: Required. The unique username for login.
email: email:
type: string type: string
nickname: description: Optional. The email address of the user.
displayName:
type: string type: string
description: Optional. The display name of the user.
avatarUrl: avatarUrl:
type: string type: string
description: Optional. The avatar URL of the user.
description: description:
type: string type: string
description: Optional. The description of the user.
password: password:
type: string type: string
description: Input only. The password for the user.
state: state:
$ref: '#/definitions/v1State' $ref: '#/definitions/v1State'
description: The state of the user.
createTime: createTime:
type: string type: string
format: date-time format: date-time
description: Output only. The creation timestamp.
readOnly: true readOnly: true
updateTime: updateTime:
type: string type: string
format: date-time format: date-time
description: Output only. The last update timestamp.
readOnly: true
etag:
type: string
description: Output only. The etag for this resource.
readOnly: true readOnly: true
title: Required. The user to update.
required: required:
- role
- username
- state
- user - user
tags: - name: allowMissing
- UserService description: Optional. If set to true, allows updating sensitive fields.
/file/{name}/avatar:
get:
summary: GetUserAvatarBinary gets the avatar of a user.
operationId: UserService_GetUserAvatarBinary
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/apiHttpBody'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the user.
in: path
required: true
type: string
pattern: users/[^/]+
- name: httpBody.contentType
description: The HTTP Content-Type header value specifying the content type of the body.
in: query in: query
required: false required: false
type: string type: boolean
- name: httpBody.data
description: The HTTP request/response body as raw binary.
in: query
required: false
type: string
format: byte
tags: tags:
- UserService - UserService
/file/{name}/{filename}: /file/{name}/{filename}:
@ -1959,14 +2107,13 @@ definitions:
- ADMIN - ADMIN
- USER - USER
default: ROLE_UNSPECIFIED default: ROLE_UNSPECIFIED
UserServiceCreateUserAccessTokenBody: description: |-
type: object User role enumeration.
properties:
description: - ROLE_UNSPECIFIED: Unspecified role.
type: string - HOST: Host role with full system access.
expiresAt: - ADMIN: Admin role with administrative privileges.
type: string - USER: Regular user role.
format: date-time
UserStatsMemoTypeStats: UserStatsMemoTypeStats:
type: object type: object
properties: properties:
@ -1982,6 +2129,7 @@ definitions:
undoCount: undoCount:
type: integer type: integer
format: int32 format: int32
description: Memo type statistics.
WorkspaceStorageSettingS3Config: WorkspaceStorageSettingS3Config:
type: object type: object
properties: properties:
@ -2233,7 +2381,9 @@ definitions:
properties: properties:
name: name:
type: string type: string
description: The name of the user. title: |-
The resource name of the user whose setting this is.
Format: users/{user}
locale: locale:
type: string type: string
description: The preferred locale of the user. description: The preferred locale of the user.
@ -2243,6 +2393,7 @@ definitions:
memoVisibility: memoVisibility:
type: string type: string
description: The default visibility of the memo. description: The default visibility of the memo.
title: User settings message
apiv1WorkspaceCustomProfile: apiv1WorkspaceCustomProfile:
type: object type: object
properties: properties:
@ -2715,6 +2866,14 @@ definitions:
items: items:
type: object type: object
$ref: '#/definitions/v1UserStats' $ref: '#/definitions/v1UserStats'
description: The list of user statistics.
nextPageToken:
type: string
description: A token for the next page of results.
totalSize:
type: integer
format: int32
description: The total count of user statistics.
v1ListIdentityProvidersResponse: v1ListIdentityProvidersResponse:
type: object type: object
properties: properties:
@ -2818,6 +2977,14 @@ definitions:
items: items:
type: object type: object
$ref: '#/definitions/v1UserAccessToken' $ref: '#/definitions/v1UserAccessToken'
description: The list of access tokens.
nextPageToken:
type: string
description: A token for the next page of results.
totalSize:
type: integer
format: int32
description: The total count of access tokens.
v1ListUsersResponse: v1ListUsersResponse:
type: object type: object
properties: properties:
@ -2826,6 +2993,16 @@ definitions:
items: items:
type: object type: object
$ref: '#/definitions/v1User' $ref: '#/definitions/v1User'
description: The list of users.
nextPageToken:
type: string
description: |-
A token that can be sent as `page_token` to retrieve the next page.
If this field is omitted, there are no subsequent pages.
totalSize:
type: integer
format: int32
description: The total count of users (may be approximate).
v1ListWebhooksResponse: v1ListWebhooksResponse:
type: object type: object
properties: properties:
@ -3115,6 +3292,22 @@ definitions:
redirectUri: redirectUri:
type: string type: string
description: The redirect URI. description: The redirect URI.
v1SearchUsersResponse:
type: object
properties:
users:
type: array
items:
type: object
$ref: '#/definitions/v1User'
description: The list of users matching the search query.
nextPageToken:
type: string
description: A token for the next page of results.
totalSize:
type: integer
format: int32
description: The total count of matching users.
v1SpoilerNode: v1SpoilerNode:
type: object type: object
properties: properties:
@ -3215,61 +3408,94 @@ definitions:
properties: properties:
name: name:
type: string type: string
description: |- title: |-
The name of the user. The resource name of the user.
Format: users/{id}, id is the system generated auto-incremented id. Format: users/{user}
uid:
type: string
description: Output only. The system generated unique identifier.
readOnly: true readOnly: true
role: role:
$ref: '#/definitions/UserRole' $ref: '#/definitions/UserRole'
description: The role of the user.
username: username:
type: string type: string
description: Required. The unique username for login.
email: email:
type: string type: string
nickname: description: Optional. The email address of the user.
displayName:
type: string type: string
description: Optional. The display name of the user.
avatarUrl: avatarUrl:
type: string type: string
description: Optional. The avatar URL of the user.
description: description:
type: string type: string
description: Optional. The description of the user.
password: password:
type: string type: string
description: Input only. The password for the user.
state: state:
$ref: '#/definitions/v1State' $ref: '#/definitions/v1State'
description: The state of the user.
createTime: createTime:
type: string type: string
format: date-time format: date-time
description: Output only. The creation timestamp.
readOnly: true readOnly: true
updateTime: updateTime:
type: string type: string
format: date-time format: date-time
description: Output only. The last update timestamp.
readOnly: true
etag:
type: string
description: Output only. The etag for this resource.
readOnly: true readOnly: true
required:
- role
- username
- state
v1UserAccessToken: v1UserAccessToken:
type: object type: object
properties: properties:
name:
type: string
title: |-
The resource name of the access token.
Format: users/{user}/accessTokens/{access_token}
accessToken: accessToken:
type: string type: string
description: Output only. The access token value.
readOnly: true
description: description:
type: string type: string
description: The description of the access token.
issuedAt: issuedAt:
type: string type: string
format: date-time format: date-time
description: Output only. The issued timestamp.
readOnly: true
expiresAt: expiresAt:
type: string type: string
format: date-time format: date-time
description: Optional. The expiration timestamp.
title: User access token message
v1UserStats: v1UserStats:
type: object type: object
properties: properties:
name: name:
type: string type: string
description: The name of the user. title: |-
The resource name of the user whose stats these are.
Format: users/{user}
memoDisplayTimestamps: memoDisplayTimestamps:
type: array type: array
items: items:
type: string type: string
format: date-time format: date-time
description: |- description: The timestamps when the memos were displayed.
The timestamps when the memos were displayed.
We should return raw data to the client, and let the client format the data with the user's timezone.
memoTypeStats: memoTypeStats:
$ref: '#/definitions/UserStatsMemoTypeStats' $ref: '#/definitions/UserStatsMemoTypeStats'
description: The stats of memo types. description: The stats of memo types.
@ -3278,9 +3504,7 @@ definitions:
additionalProperties: additionalProperties:
type: integer type: integer
format: int32 format: int32
title: |- description: The count of tags.
The count of tags.
Format: "tag1": 1, "tag2": 2
pinnedMemos: pinnedMemos:
type: array type: array
items: items:
@ -3289,6 +3513,8 @@ definitions:
totalMemoCount: totalMemoCount:
type: integer type: integer
format: int32 format: int32
description: Total memo count.
title: User statistics messages
v1Visibility: v1Visibility:
type: string type: string
enum: enum:

@ -12,8 +12,7 @@ var authenticationAllowlistMethods = map[string]bool{
"/memos.api.v1.AuthService/SignOut": true, "/memos.api.v1.AuthService/SignOut": true,
"/memos.api.v1.AuthService/SignUp": true, "/memos.api.v1.AuthService/SignUp": true,
"/memos.api.v1.UserService/GetUser": true, "/memos.api.v1.UserService/GetUser": true,
"/memos.api.v1.UserService/GetUserByUsername": true, "/memos.api.v1.UserService/GetUserAvatar": true,
"/memos.api.v1.UserService/GetUserAvatarBinary": true,
"/memos.api.v1.UserService/GetUserStats": true, "/memos.api.v1.UserService/GetUserStats": true,
"/memos.api.v1.UserService/ListAllUserStats": true, "/memos.api.v1.UserService/ListAllUserStats": true,
"/memos.api.v1.UserService/SearchUsers": true, "/memos.api.v1.UserService/SearchUsers": true,

@ -244,8 +244,7 @@ func (s *APIV1Service) SignOut(ctx context.Context, _ *v1pb.SignOutRequest) (*em
user, _ := s.GetCurrentUser(ctx) user, _ := s.GetCurrentUser(ctx)
if user != nil { if user != nil {
if _, err := s.DeleteUserAccessToken(ctx, &v1pb.DeleteUserAccessTokenRequest{ if _, err := s.DeleteUserAccessToken(ctx, &v1pb.DeleteUserAccessTokenRequest{
Name: fmt.Sprintf("%s%d", UserNamePrefix, user.ID), Name: fmt.Sprintf("%s%d/accessTokens/%s", UserNamePrefix, user.ID, accessToken),
AccessToken: accessToken,
}); err != nil { }); err != nil {
slog.Error("failed to delete access token", "error", err) slog.Error("failed to delete access token", "error", err)
} }

@ -2,6 +2,7 @@ package v1
import ( import (
"context" "context"
"crypto/md5"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"net/http" "net/http"
@ -40,8 +41,11 @@ func (s *APIV1Service) ListUsers(ctx context.Context, _ *v1pb.ListUsersRequest)
return nil, status.Errorf(codes.Internal, "failed to list users: %v", err) return nil, status.Errorf(codes.Internal, "failed to list users: %v", err)
} }
// TODO: Implement proper filtering, ordering, and pagination
// For now, return all users with basic structure
response := &v1pb.ListUsersResponse{ response := &v1pb.ListUsersResponse{
Users: []*v1pb.User{}, Users: []*v1pb.User{},
TotalSize: int32(len(users)),
} }
for _, user := range users { for _, user := range users {
response.Users = append(response.Users, convertUserFromStore(user)) response.Users = append(response.Users, convertUserFromStore(user))
@ -63,25 +67,50 @@ func (s *APIV1Service) GetUser(ctx context.Context, request *v1pb.GetUserRequest
if user == nil { if user == nil {
return nil, status.Errorf(codes.NotFound, "user not found") return nil, status.Errorf(codes.NotFound, "user not found")
} }
userPb := convertUserFromStore(user)
return convertUserFromStore(user), nil // TODO: Implement read_mask field filtering
// For now, return all fields
return userPb, nil
} }
func (s *APIV1Service) GetUserByUsername(ctx context.Context, request *v1pb.GetUserByUsernameRequest) (*v1pb.User, error) { func (s *APIV1Service) SearchUsers(ctx context.Context, request *v1pb.SearchUsersRequest) (*v1pb.SearchUsersResponse, error) {
user, err := s.Store.GetUser(ctx, &store.FindUser{ currentUser, err := s.GetCurrentUser(ctx)
Username: &request.Username,
})
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
} }
if user == nil { if currentUser.Role != store.RoleHost && currentUser.Role != store.RoleAdmin {
return nil, status.Errorf(codes.NotFound, "user not found") return nil, status.Errorf(codes.PermissionDenied, "permission denied")
} }
return convertUserFromStore(user), nil // Search users by username, email, or display name
users, err := s.Store.ListUsers(ctx, &store.FindUser{})
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to list users: %v", err)
}
var filteredUsers []*store.User
query := strings.ToLower(request.Query)
for _, user := range users {
if strings.Contains(strings.ToLower(user.Username), query) ||
strings.Contains(strings.ToLower(user.Email), query) ||
strings.Contains(strings.ToLower(user.Nickname), query) {
filteredUsers = append(filteredUsers, user)
}
}
response := &v1pb.SearchUsersResponse{
Users: []*v1pb.User{},
TotalSize: int32(len(filteredUsers)),
}
for _, user := range filteredUsers {
response.Users = append(response.Users, convertUserFromStore(user))
}
return response, nil
} }
func (s *APIV1Service) GetUserAvatarBinary(ctx context.Context, request *v1pb.GetUserAvatarBinaryRequest) (*httpbody.HttpBody, error) { func (s *APIV1Service) GetUserAvatar(ctx context.Context, request *v1pb.GetUserAvatarRequest) (*httpbody.HttpBody, error) {
userID, err := ExtractUserIDFromName(request.Name) userID, err := ExtractUserIDFromName(request.Name)
if err != nil { if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err) return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err)
@ -122,9 +151,24 @@ func (s *APIV1Service) CreateUser(ctx context.Context, request *v1pb.CreateUserR
if currentUser.Role != store.RoleHost { if currentUser.Role != store.RoleHost {
return nil, status.Errorf(codes.PermissionDenied, "permission denied") return nil, status.Errorf(codes.PermissionDenied, "permission denied")
} }
// TODO: Handle request_id for idempotency
// TODO: Handle user_id field if provided
if !base.UIDMatcher.MatchString(strings.ToLower(request.User.Username)) { if !base.UIDMatcher.MatchString(strings.ToLower(request.User.Username)) {
return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", request.User.Username) return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", request.User.Username)
} }
// If validate_only is true, just validate without creating
if request.ValidateOnly {
// Perform validation checks without actually creating the user
return &v1pb.User{
Username: request.User.Username,
Email: request.User.Email,
DisplayName: request.User.DisplayName,
Role: request.User.Role,
}, nil
}
passwordHash, err := bcrypt.GenerateFromPassword([]byte(request.User.Password), bcrypt.DefaultCost) passwordHash, err := bcrypt.GenerateFromPassword([]byte(request.User.Password), bcrypt.DefaultCost)
if err != nil { if err != nil {
return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to generate password hash").SetInternal(err) return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to generate password hash").SetInternal(err)
@ -134,7 +178,7 @@ func (s *APIV1Service) CreateUser(ctx context.Context, request *v1pb.CreateUserR
Username: request.User.Username, Username: request.User.Username,
Role: convertUserRoleToStore(request.User.Role), Role: convertUserRoleToStore(request.User.Role),
Email: request.User.Email, Email: request.User.Email,
Nickname: request.User.Nickname, Nickname: request.User.DisplayName,
PasswordHash: string(passwordHash), PasswordHash: string(passwordHash),
}) })
if err != nil { if err != nil {
@ -167,6 +211,11 @@ func (s *APIV1Service) UpdateUser(ctx context.Context, request *v1pb.UpdateUserR
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
} }
if user == nil { if user == nil {
// Handle allow_missing field
if request.AllowMissing {
// Could create user if missing, but for now return not found
return nil, status.Errorf(codes.NotFound, "user not found")
}
return nil, status.Errorf(codes.NotFound, "user not found") return nil, status.Errorf(codes.NotFound, "user not found")
} }
@ -188,11 +237,11 @@ func (s *APIV1Service) UpdateUser(ctx context.Context, request *v1pb.UpdateUserR
return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", request.User.Username) return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", request.User.Username)
} }
update.Username = &request.User.Username update.Username = &request.User.Username
} else if field == "nickname" { } else if field == "display_name" {
if workspaceGeneralSetting.DisallowChangeNickname { if workspaceGeneralSetting.DisallowChangeNickname {
return nil, status.Errorf(codes.PermissionDenied, "permission denied: disallow change nickname") return nil, status.Errorf(codes.PermissionDenied, "permission denied: disallow change nickname")
} }
update.Nickname = &request.User.Nickname update.Nickname = &request.User.DisplayName
} else if field == "email" { } else if field == "email" {
update.Email = &request.User.Email update.Email = &request.User.Email
} else if field == "avatar_url" { } else if field == "avatar_url" {
@ -261,25 +310,39 @@ func (s *APIV1Service) DeleteUser(ctx context.Context, request *v1pb.DeleteUserR
func getDefaultUserSetting() *v1pb.UserSetting { func getDefaultUserSetting() *v1pb.UserSetting {
return &v1pb.UserSetting{ return &v1pb.UserSetting{
Name: "", // Will be set by caller
Locale: "en", Locale: "en",
Appearance: "system", Appearance: "system",
MemoVisibility: "PRIVATE", MemoVisibility: "PRIVATE",
} }
} }
func (s *APIV1Service) GetUserSetting(ctx context.Context, _ *v1pb.GetUserSettingRequest) (*v1pb.UserSetting, error) { func (s *APIV1Service) GetUserSetting(ctx context.Context, request *v1pb.GetUserSettingRequest) (*v1pb.UserSetting, error) {
user, err := s.GetCurrentUser(ctx) userID, err := ExtractUserIDFromName(request.Name)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err)
}
currentUser, err := s.GetCurrentUser(ctx)
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err) return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
} }
// Only allow user to get their own settings
if currentUser.ID != userID {
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
}
userSettings, err := s.Store.ListUserSettings(ctx, &store.FindUserSetting{ userSettings, err := s.Store.ListUserSettings(ctx, &store.FindUserSetting{
UserID: &user.ID, UserID: &userID,
}) })
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "failed to list user settings: %v", err) return nil, status.Errorf(codes.Internal, "failed to list user settings: %v", err)
} }
userSettingMessage := getDefaultUserSetting() userSettingMessage := getDefaultUserSetting()
userSettingMessage.Name = fmt.Sprintf("users/%d/setting", userID)
for _, setting := range userSettings { for _, setting := range userSettings {
if setting.Key == storepb.UserSettingKey_LOCALE { if setting.Key == storepb.UserSettingKey_LOCALE {
userSettingMessage.Locale = setting.GetLocale() userSettingMessage.Locale = setting.GetLocale()
@ -293,11 +356,27 @@ func (s *APIV1Service) GetUserSetting(ctx context.Context, _ *v1pb.GetUserSettin
} }
func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.UpdateUserSettingRequest) (*v1pb.UserSetting, error) { func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.UpdateUserSettingRequest) (*v1pb.UserSetting, error) {
user, err := s.GetCurrentUser(ctx) // Extract user ID from the setting resource name
parts := strings.Split(request.Setting.Name, "/")
if len(parts) != 3 || parts[0] != "users" || parts[2] != "setting" {
return nil, status.Errorf(codes.InvalidArgument, "invalid setting name format: %s", request.Setting.Name)
}
userID, err := ExtractUserIDFromName(fmt.Sprintf("users/%s", parts[1]))
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err)
}
currentUser, err := s.GetCurrentUser(ctx)
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err) return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
} }
// Only allow user to update their own settings
if currentUser.ID != userID {
return nil, status.Errorf(codes.PermissionDenied, "permission denied")
}
if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 { if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 {
return nil, status.Errorf(codes.InvalidArgument, "update mask is empty") return nil, status.Errorf(codes.InvalidArgument, "update mask is empty")
} }
@ -305,7 +384,7 @@ func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.Upda
for _, field := range request.UpdateMask.Paths { for _, field := range request.UpdateMask.Paths {
if field == "locale" { if field == "locale" {
if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{ if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
UserId: user.ID, UserId: userID,
Key: storepb.UserSettingKey_LOCALE, Key: storepb.UserSettingKey_LOCALE,
Value: &storepb.UserSetting_Locale{ Value: &storepb.UserSetting_Locale{
Locale: request.Setting.Locale, Locale: request.Setting.Locale,
@ -315,7 +394,7 @@ func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.Upda
} }
} else if field == "appearance" { } else if field == "appearance" {
if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{ if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
UserId: user.ID, UserId: userID,
Key: storepb.UserSettingKey_APPEARANCE, Key: storepb.UserSettingKey_APPEARANCE,
Value: &storepb.UserSetting_Appearance{ Value: &storepb.UserSetting_Appearance{
Appearance: request.Setting.Appearance, Appearance: request.Setting.Appearance,
@ -325,7 +404,7 @@ func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.Upda
} }
} else if field == "memo_visibility" { } else if field == "memo_visibility" {
if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{ if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
UserId: user.ID, UserId: userID,
Key: storepb.UserSettingKey_MEMO_VISIBILITY, Key: storepb.UserSettingKey_MEMO_VISIBILITY,
Value: &storepb.UserSetting_MemoVisibility{ Value: &storepb.UserSetting_MemoVisibility{
MemoVisibility: request.Setting.MemoVisibility, MemoVisibility: request.Setting.MemoVisibility,
@ -338,11 +417,11 @@ func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.Upda
} }
} }
return s.GetUserSetting(ctx, &v1pb.GetUserSettingRequest{}) return s.GetUserSetting(ctx, &v1pb.GetUserSettingRequest{Name: request.Setting.Name})
} }
func (s *APIV1Service) ListUserAccessTokens(ctx context.Context, request *v1pb.ListUserAccessTokensRequest) (*v1pb.ListUserAccessTokensResponse, error) { func (s *APIV1Service) ListUserAccessTokens(ctx context.Context, request *v1pb.ListUserAccessTokensRequest) (*v1pb.ListUserAccessTokensResponse, error) {
userID, err := ExtractUserIDFromName(request.Name) userID, err := ExtractUserIDFromName(request.Parent)
if err != nil { if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err) return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err)
} }
@ -382,15 +461,16 @@ func (s *APIV1Service) ListUserAccessTokens(ctx context.Context, request *v1pb.L
continue continue
} }
userAccessToken := &v1pb.UserAccessToken{ accessTokenResponse := &v1pb.UserAccessToken{
Name: fmt.Sprintf("users/%d/accessTokens/%s", userID, userAccessToken.AccessToken),
AccessToken: userAccessToken.AccessToken, AccessToken: userAccessToken.AccessToken,
Description: userAccessToken.Description, Description: userAccessToken.Description,
IssuedAt: timestamppb.New(claims.IssuedAt.Time), IssuedAt: timestamppb.New(claims.IssuedAt.Time),
} }
if claims.ExpiresAt != nil { if claims.ExpiresAt != nil {
userAccessToken.ExpiresAt = timestamppb.New(claims.ExpiresAt.Time) accessTokenResponse.ExpiresAt = timestamppb.New(claims.ExpiresAt.Time)
} }
accessTokens = append(accessTokens, userAccessToken) accessTokens = append(accessTokens, accessTokenResponse)
} }
// Sort by issued time in descending order. // Sort by issued time in descending order.
@ -404,7 +484,7 @@ func (s *APIV1Service) ListUserAccessTokens(ctx context.Context, request *v1pb.L
} }
func (s *APIV1Service) CreateUserAccessToken(ctx context.Context, request *v1pb.CreateUserAccessTokenRequest) (*v1pb.UserAccessToken, error) { func (s *APIV1Service) CreateUserAccessToken(ctx context.Context, request *v1pb.CreateUserAccessTokenRequest) (*v1pb.UserAccessToken, error) {
userID, err := ExtractUserIDFromName(request.Name) userID, err := ExtractUserIDFromName(request.Parent)
if err != nil { if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err) return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err)
} }
@ -420,8 +500,8 @@ func (s *APIV1Service) CreateUserAccessToken(ctx context.Context, request *v1pb.
} }
expiresAt := time.Time{} expiresAt := time.Time{}
if request.ExpiresAt != nil { if request.AccessToken.ExpiresAt != nil {
expiresAt = request.ExpiresAt.AsTime() expiresAt = request.AccessToken.ExpiresAt.AsTime()
} }
accessToken, err := GenerateAccessToken(currentUser.Username, currentUser.ID, expiresAt, []byte(s.Secret)) accessToken, err := GenerateAccessToken(currentUser.Username, currentUser.ID, expiresAt, []byte(s.Secret))
@ -446,13 +526,14 @@ func (s *APIV1Service) CreateUserAccessToken(ctx context.Context, request *v1pb.
} }
// Upsert the access token to user setting store. // Upsert the access token to user setting store.
if err := s.UpsertAccessTokenToStore(ctx, currentUser, accessToken, request.Description); err != nil { if err := s.UpsertAccessTokenToStore(ctx, currentUser, accessToken, request.AccessToken.Description); err != nil {
return nil, status.Errorf(codes.Internal, "failed to upsert access token to store: %v", err) return nil, status.Errorf(codes.Internal, "failed to upsert access token to store: %v", err)
} }
userAccessToken := &v1pb.UserAccessToken{ userAccessToken := &v1pb.UserAccessToken{
Name: fmt.Sprintf("users/%d/accessTokens/%s", userID, accessToken),
AccessToken: accessToken, AccessToken: accessToken,
Description: request.Description, Description: request.AccessToken.Description,
IssuedAt: timestamppb.New(claims.IssuedAt.Time), IssuedAt: timestamppb.New(claims.IssuedAt.Time),
} }
if claims.ExpiresAt != nil { if claims.ExpiresAt != nil {
@ -462,10 +543,19 @@ func (s *APIV1Service) CreateUserAccessToken(ctx context.Context, request *v1pb.
} }
func (s *APIV1Service) DeleteUserAccessToken(ctx context.Context, request *v1pb.DeleteUserAccessTokenRequest) (*emptypb.Empty, error) { func (s *APIV1Service) DeleteUserAccessToken(ctx context.Context, request *v1pb.DeleteUserAccessTokenRequest) (*emptypb.Empty, error) {
userID, err := ExtractUserIDFromName(request.Name) // Extract user ID from the access token resource name
// Format: users/{user}/accessTokens/{access_token}
parts := strings.Split(request.Name, "/")
if len(parts) != 4 || parts[0] != "users" || parts[2] != "accessTokens" {
return nil, status.Errorf(codes.InvalidArgument, "invalid access token name format: %s", request.Name)
}
userID, err := ExtractUserIDFromName(fmt.Sprintf("users/%s", parts[1]))
if err != nil { if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err) return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err)
} }
accessTokenToDelete := parts[3]
currentUser, err := s.GetCurrentUser(ctx) currentUser, err := s.GetCurrentUser(ctx)
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err) return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
@ -483,7 +573,7 @@ func (s *APIV1Service) DeleteUserAccessToken(ctx context.Context, request *v1pb.
} }
updatedUserAccessTokens := []*storepb.AccessTokensUserSetting_AccessToken{} updatedUserAccessTokens := []*storepb.AccessTokensUserSetting_AccessToken{}
for _, userAccessToken := range userAccessTokens { for _, userAccessToken := range userAccessTokens {
if userAccessToken.AccessToken == request.AccessToken { if userAccessToken.AccessToken == accessTokenToDelete {
continue continue
} }
updatedUserAccessTokens = append(updatedUserAccessTokens, userAccessToken) updatedUserAccessTokens = append(updatedUserAccessTokens, userAccessToken)
@ -528,6 +618,11 @@ func (s *APIV1Service) UpsertAccessTokenToStore(ctx context.Context, user *store
} }
func convertUserFromStore(user *store.User) *v1pb.User { func convertUserFromStore(user *store.User) *v1pb.User {
// Generate etag based on user data
etagData := fmt.Sprintf("%d-%d-%s-%s-%s", user.ID, user.UpdatedTs, user.Username, user.Email, user.Nickname)
hash := md5.Sum([]byte(etagData))
etag := fmt.Sprintf("%x", hash)
userpb := &v1pb.User{ userpb := &v1pb.User{
Name: fmt.Sprintf("%s%d", UserNamePrefix, user.ID), Name: fmt.Sprintf("%s%d", UserNamePrefix, user.ID),
State: convertStateFromStore(user.RowStatus), State: convertStateFromStore(user.RowStatus),
@ -536,9 +631,10 @@ func convertUserFromStore(user *store.User) *v1pb.User {
Role: convertUserRoleFromStore(user.Role), Role: convertUserRoleFromStore(user.Role),
Username: user.Username, Username: user.Username,
Email: user.Email, Email: user.Email,
Nickname: user.Nickname, DisplayName: user.Nickname,
AvatarUrl: user.AvatarURL, AvatarUrl: user.AvatarURL,
Description: user.Description, Description: user.Description,
Etag: etag,
} }
// Use the avatar URL instead of raw base64 image data to reduce the response size. // Use the avatar URL instead of raw base64 image data to reduce the response size.
if user.AvatarURL != "" { if user.AvatarURL != "" {

@ -51,51 +51,28 @@ func (s *APIV1Service) ListAllUserStats(ctx context.Context, _ *v1pb.ListAllUser
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "failed to list memos: %v", err) return nil, status.Errorf(codes.Internal, "failed to list memos: %v", err)
} }
userStatsMap := map[string]*v1pb.UserStats{}
userMemoStatMap := make(map[int32]*v1pb.UserStats)
for _, memo := range memos { for _, memo := range memos {
creator := fmt.Sprintf("%s%d", UserNamePrefix, memo.CreatorID)
if _, ok := userStatsMap[creator]; !ok {
userStatsMap[creator] = &v1pb.UserStats{
Name: creator,
MemoDisplayTimestamps: []*timestamppb.Timestamp{},
MemoTypeStats: &v1pb.UserStats_MemoTypeStats{},
TagCount: map[string]int32{},
}
}
displayTs := memo.CreatedTs displayTs := memo.CreatedTs
if workspaceMemoRelatedSetting.DisplayWithUpdateTime { if workspaceMemoRelatedSetting.DisplayWithUpdateTime {
displayTs = memo.UpdatedTs displayTs = memo.UpdatedTs
} }
userStats := userStatsMap[creator] userMemoStatMap[memo.CreatorID] = &v1pb.UserStats{
userStats.MemoDisplayTimestamps = append(userStats.MemoDisplayTimestamps, timestamppb.New(time.Unix(displayTs, 0))) Name: fmt.Sprintf("users/%d/stats", memo.CreatorID),
// Handle duplicated tags.
for _, tag := range memo.Payload.Tags {
userStats.TagCount[tag]++
}
if memo.Pinned {
userStats.PinnedMemos = append(userStats.PinnedMemos, fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID))
}
if memo.Payload.Property.GetHasLink() {
userStats.MemoTypeStats.LinkCount++
} }
if memo.Payload.Property.GetHasCode() { userMemoStatMap[memo.CreatorID].MemoDisplayTimestamps = append(userMemoStatMap[memo.CreatorID].MemoDisplayTimestamps, timestamppb.New(time.Unix(displayTs, 0)))
userStats.MemoTypeStats.CodeCount++
}
if memo.Payload.Property.GetHasTaskList() {
userStats.MemoTypeStats.TodoCount++
}
if memo.Payload.Property.GetHasIncompleteTasks() {
userStats.MemoTypeStats.UndoCount++
}
userStats.TotalMemoCount++
} }
userStatsList := []*v1pb.UserStats{}
for _, userStats := range userStatsMap { userMemoStats := []*v1pb.UserStats{}
userStatsList = append(userStatsList, userStats) for _, userMemoStat := range userMemoStatMap {
userMemoStats = append(userMemoStats, userMemoStat)
} }
return &v1pb.ListAllUserStatsResponse{
UserStats: userStatsList, response := &v1pb.ListAllUserStatsResponse{
}, nil UserStats: userMemoStats,
}
return response, nil
} }
func (s *APIV1Service) GetUserStats(ctx context.Context, request *v1pb.GetUserStatsRequest) (*v1pb.UserStats, error) { func (s *APIV1Service) GetUserStats(ctx context.Context, request *v1pb.GetUserStatsRequest) (*v1pb.UserStats, error) {
@ -103,32 +80,27 @@ func (s *APIV1Service) GetUserStats(ctx context.Context, request *v1pb.GetUserSt
if err != nil { if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err) return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err)
} }
user, err := s.Store.GetUser(ctx, &store.FindUser{ID: &userID})
currentUser, err := s.GetCurrentUser(ctx)
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
} }
normalStatus := store.Normal normalStatus := store.Normal
memoFind := &store.FindMemo{ memoFind := &store.FindMemo{
CreatorID: &userID,
// Exclude comments by default. // Exclude comments by default.
ExcludeComments: true, ExcludeComments: true,
ExcludeContent: true, ExcludeContent: true,
CreatorID: &userID,
RowStatus: &normalStatus, RowStatus: &normalStatus,
} }
currentUser, err := s.GetCurrentUser(ctx) if currentUser == nil {
if err != nil { memoFind.VisibilityList = []store.Visibility{store.Public}
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) } else if currentUser.ID != userID {
} memoFind.VisibilityList = []store.Visibility{store.Public, store.Protected}
visibilities := []store.Visibility{store.Public}
if currentUser != nil {
visibilities = append(visibilities, store.Protected)
if currentUser.ID == user.ID {
visibilities = append(visibilities, store.Private)
}
} }
memoFind.VisibilityList = visibilities
memos, err := s.Store.ListMemos(ctx, memoFind) memos, err := s.Store.ListMemos(ctx, memoFind)
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "failed to list memos: %v", err) return nil, status.Errorf(codes.Internal, "failed to list memos: %v", err)
@ -138,38 +110,56 @@ func (s *APIV1Service) GetUserStats(ctx context.Context, request *v1pb.GetUserSt
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to get workspace memo related setting") return nil, errors.Wrap(err, "failed to get workspace memo related setting")
} }
userStats := &v1pb.UserStats{
Name: fmt.Sprintf("%s%d", UserNamePrefix, user.ID), displayTimestamps := []*timestamppb.Timestamp{}
MemoDisplayTimestamps: []*timestamppb.Timestamp{}, tagCount := make(map[string]int32)
MemoTypeStats: &v1pb.UserStats_MemoTypeStats{}, linkCount := int32(0)
TagCount: map[string]int32{}, codeCount := int32(0)
TotalMemoCount: int32(len(memos)), todoCount := int32(0)
} undoCount := int32(0)
pinnedMemos := []string{}
for _, memo := range memos { for _, memo := range memos {
displayTs := memo.CreatedTs displayTs := memo.CreatedTs
if workspaceMemoRelatedSetting.DisplayWithUpdateTime { if workspaceMemoRelatedSetting.DisplayWithUpdateTime {
displayTs = memo.UpdatedTs displayTs = memo.UpdatedTs
} }
userStats.MemoDisplayTimestamps = append(userStats.MemoDisplayTimestamps, timestamppb.New(time.Unix(displayTs, 0))) displayTimestamps = append(displayTimestamps, timestamppb.New(time.Unix(displayTs, 0)))
// Handle duplicated tags.
for _, tag := range memo.Payload.Tags { // Count different memo types based on content
userStats.TagCount[tag]++ if memo.Payload != nil && memo.Payload.Property != nil {
if memo.Payload.Property.HasLink {
linkCount++
}
if memo.Payload.Property.HasCode {
codeCount++
}
if memo.Payload.Property.HasTaskList {
todoCount++
}
if memo.Payload.Property.HasIncompleteTasks {
undoCount++
}
} }
if memo.Pinned { if memo.Pinned {
userStats.PinnedMemos = append(userStats.PinnedMemos, fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID)) pinnedMemos = append(pinnedMemos, fmt.Sprintf("users/%d/memos/%d", userID, memo.ID))
}
if memo.Payload.Property.GetHasLink() {
userStats.MemoTypeStats.LinkCount++
}
if memo.Payload.Property.GetHasCode() {
userStats.MemoTypeStats.CodeCount++
}
if memo.Payload.Property.GetHasTaskList() {
userStats.MemoTypeStats.TodoCount++
}
if memo.Payload.Property.GetHasIncompleteTasks() {
userStats.MemoTypeStats.UndoCount++
} }
} }
userStats := &v1pb.UserStats{
Name: fmt.Sprintf("users/%d/stats", userID),
MemoDisplayTimestamps: displayTimestamps,
TagCount: tagCount,
PinnedMemos: pinnedMemos,
TotalMemoCount: int32(len(memos)),
MemoTypeStats: &v1pb.UserStats_MemoTypeStats{
LinkCount: linkCount,
CodeCount: codeCount,
TodoCount: todoCount,
UndoCount: undoCount,
},
}
return userStats, nil return userStats, nil
} }

@ -67,7 +67,7 @@ const ChangeMemberPasswordDialog: React.FC<Props> = (props: Props) => {
<div className="max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg"> <div className="max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg">
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full"> <div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
<p> <p>
{t("setting.account-section.change-password")} ({user.nickname}) {t("setting.account-section.change-password")} ({user.displayName})
</p> </p>
<Button variant="plain" onClick={handleCloseBtnClick}> <Button variant="plain" onClick={handleCloseBtnClick}>
<XIcon className="w-5 h-auto" /> <XIcon className="w-5 h-auto" />

@ -70,9 +70,11 @@ const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
try { try {
await userServiceClient.createUserAccessToken({ await userServiceClient.createUserAccessToken({
name: currentUser.name, parent: currentUser.name,
description: state.description, accessToken: {
expiresAt: state.expiration ? new Date(Date.now() + state.expiration * 1000) : undefined, description: state.description,
expiresAt: state.expiration ? new Date(Date.now() + state.expiration * 1000) : undefined,
},
}); });
onConfirm(); onConfirm();

@ -109,7 +109,7 @@ const MemoCommentMessage = observer(({ inbox }: Props) => {
onClick={handleNavigateToMemo} onClick={handleNavigateToMemo}
> >
{t("inbox.memo-comment", { {t("inbox.memo-comment", {
user: sender?.nickname || sender?.username, user: sender?.displayName || sender?.username,
memo: relatedMemo?.name, memo: relatedMemo?.name,
interpolation: { escapeValue: false }, interpolation: { escapeValue: false },
})} })}

@ -148,7 +148,7 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
to={`/u/${encodeURIComponent(creator.username)}`} to={`/u/${encodeURIComponent(creator.username)}`}
viewTransition viewTransition
> >
{creator.nickname || creator.username} {creator.displayName || creator.username}
</Link> </Link>
<div <div
className="w-auto -mt-0.5 text-xs leading-tight text-gray-400 dark:text-gray-500 select-none cursor-pointer" className="w-auto -mt-0.5 text-xs leading-tight text-gray-400 dark:text-gray-500 select-none cursor-pointer"

@ -19,12 +19,12 @@ const stringifyUsers = (users: User[], reactionType: string): string => {
return ""; return "";
} }
if (users.length < 5) { if (users.length < 5) {
return users.map((user) => user.nickname || user.username).join(", ") + " reacted with " + reactionType.toLowerCase(); return users.map((user) => user.displayName || user.username).join(", ") + " reacted with " + reactionType.toLowerCase();
} }
return ( return (
`${users `${users
.slice(0, 4) .slice(0, 4)
.map((user) => user.nickname || user.username) .map((user) => user.displayName || user.username)
.join(", ")} and ${users.length - 4} more reacted with ` + reactionType.toLowerCase() .join(", ")} and ${users.length - 4} more reacted with ` + reactionType.toLowerCase()
); );
}; };

@ -10,8 +10,8 @@ import { useTranslate } from "@/utils/i18n";
import showCreateAccessTokenDialog from "../CreateAccessTokenDialog"; import showCreateAccessTokenDialog from "../CreateAccessTokenDialog";
import LearnMore from "../LearnMore"; import LearnMore from "../LearnMore";
const listAccessTokens = async (name: string) => { const listAccessTokens = async (parent: string) => {
const { accessTokens } = await userServiceClient.listUserAccessTokens({ name }); const { accessTokens } = await userServiceClient.listUserAccessTokens({ parent });
return accessTokens.sort((a, b) => (b.issuedAt?.getTime() ?? 0) - (a.issuedAt?.getTime() ?? 0)); return accessTokens.sort((a, b) => (b.issuedAt?.getTime() ?? 0) - (a.issuedAt?.getTime() ?? 0));
}; };
@ -36,12 +36,12 @@ const AccessTokenSection = () => {
toast.success(t("setting.access-token-section.access-token-copied-to-clipboard")); toast.success(t("setting.access-token-section.access-token-copied-to-clipboard"));
}; };
const handleDeleteAccessToken = async (accessToken: string) => { const handleDeleteAccessToken = async (userAccessToken: UserAccessToken) => {
const formatedAccessToken = getFormatedAccessToken(accessToken); const formatedAccessToken = getFormatedAccessToken(userAccessToken.accessToken);
const confirmed = window.confirm(t("setting.access-token-section.access-token-deletion", { accessToken: formatedAccessToken })); const confirmed = window.confirm(t("setting.access-token-section.access-token-deletion", { accessToken: formatedAccessToken }));
if (confirmed) { if (confirmed) {
await userServiceClient.deleteUserAccessToken({ name: currentUser.name, accessToken: accessToken }); await userServiceClient.deleteUserAccessToken({ name: userAccessToken.name });
setUserAccessTokens(userAccessTokens.filter((token) => token.accessToken !== accessToken)); setUserAccessTokens(userAccessTokens.filter((token) => token.accessToken !== userAccessToken.accessToken));
} }
}; };
@ -116,7 +116,7 @@ const AccessTokenSection = () => {
<Button <Button
variant="plain" variant="plain"
onClick={() => { onClick={() => {
handleDeleteAccessToken(userAccessToken.accessToken); handleDeleteAccessToken(userAccessToken);
}} }}
> >
<TrashIcon className="text-red-600 w-4 h-auto" /> <TrashIcon className="text-red-600 w-4 h-auto" />

@ -109,7 +109,7 @@ const MemberSection = observer(() => {
}; };
const handleArchiveUserClick = async (user: User) => { const handleArchiveUserClick = async (user: User) => {
const confirmed = window.confirm(t("setting.member-section.archive-warning", { username: user.nickname })); const confirmed = window.confirm(t("setting.member-section.archive-warning", { username: user.displayName }));
if (confirmed) { if (confirmed) {
await userServiceClient.updateUser({ await userServiceClient.updateUser({
user: { user: {
@ -134,7 +134,7 @@ const MemberSection = observer(() => {
}; };
const handleDeleteUserClick = async (user: User) => { const handleDeleteUserClick = async (user: User) => {
const confirmed = window.confirm(t("setting.member-section.delete-warning", { username: user.nickname })); const confirmed = window.confirm(t("setting.member-section.delete-warning", { username: user.displayName }));
if (confirmed) { if (confirmed) {
await userStore.deleteUser(user.name); await userStore.deleteUser(user.name);
fetchUsers(); fetchUsers();
@ -209,7 +209,7 @@ const MemberSection = observer(() => {
<span className="ml-1 italic">{user.state === State.ARCHIVED && "(Archived)"}</span> <span className="ml-1 italic">{user.state === State.ARCHIVED && "(Archived)"}</span>
</td> </td>
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">{stringifyUserRole(user.role)}</td> <td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">{stringifyUserRole(user.role)}</td>
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">{user.nickname}</td> <td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">{user.displayName}</td>
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">{user.email}</td> <td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">{user.email}</td>
<td className="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium flex justify-end"> <td className="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium flex justify-end">
{currentUser?.name === user.name ? ( {currentUser?.name === user.name ? (

@ -19,7 +19,7 @@ const MyAccountSection = () => {
<UserAvatar className="mr-2 shrink-0 w-10 h-10" avatarUrl={user.avatarUrl} /> <UserAvatar className="mr-2 shrink-0 w-10 h-10" avatarUrl={user.avatarUrl} />
<div className="max-w-[calc(100%-3rem)] flex flex-col justify-center items-start"> <div className="max-w-[calc(100%-3rem)] flex flex-col justify-center items-start">
<p className="w-full"> <p className="w-full">
<span className="text-xl leading-tight font-medium">{user.nickname}</span> <span className="text-xl leading-tight font-medium">{user.displayName}</span>
<span className="ml-1 text-base leading-tight text-gray-500 dark:text-gray-400">({user.username})</span> <span className="ml-1 text-base leading-tight text-gray-500 dark:text-gray-400">({user.username})</span>
</p> </p>
<p className="w-4/5 leading-tight text-sm truncate">{user.description}</p> <p className="w-4/5 leading-tight text-sm truncate">{user.description}</p>

@ -16,7 +16,7 @@ type Props = DialogProps;
interface State { interface State {
avatarUrl: string; avatarUrl: string;
username: string; username: string;
nickname: string; displayName: string;
email: string; email: string;
description: string; description: string;
} }
@ -27,7 +27,7 @@ const UpdateAccountDialog = ({ destroy }: Props) => {
const [state, setState] = useState<State>({ const [state, setState] = useState<State>({
avatarUrl: currentUser.avatarUrl, avatarUrl: currentUser.avatarUrl,
username: currentUser.username, username: currentUser.username,
nickname: currentUser.nickname, displayName: currentUser.displayName,
email: currentUser.email, email: currentUser.email,
description: currentUser.description, description: currentUser.description,
}); });
@ -66,9 +66,9 @@ const UpdateAccountDialog = ({ destroy }: Props) => {
} }
}; };
const handleNicknameChanged = (e: React.ChangeEvent<HTMLInputElement>) => { const handleDisplayNameChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
setPartialState({ setPartialState({
nickname: e.target.value as string, displayName: e.target.value as string,
}); });
}; };
@ -107,8 +107,8 @@ const UpdateAccountDialog = ({ destroy }: Props) => {
if (!isEqual(currentUser.username, state.username)) { if (!isEqual(currentUser.username, state.username)) {
updateMask.push("username"); updateMask.push("username");
} }
if (!isEqual(currentUser.nickname, state.nickname)) { if (!isEqual(currentUser.displayName, state.displayName)) {
updateMask.push("nickname"); updateMask.push("display_name");
} }
if (!isEqual(currentUser.email, state.email)) { if (!isEqual(currentUser.email, state.email)) {
updateMask.push("email"); updateMask.push("email");
@ -123,7 +123,7 @@ const UpdateAccountDialog = ({ destroy }: Props) => {
UserPb.fromPartial({ UserPb.fromPartial({
name: currentUser.name, name: currentUser.name,
username: state.username, username: state.username,
nickname: state.nickname, displayName: state.displayName,
email: state.email, email: state.email,
avatarUrl: state.avatarUrl, avatarUrl: state.avatarUrl,
description: state.description, description: state.description,
@ -180,8 +180,8 @@ const UpdateAccountDialog = ({ destroy }: Props) => {
</p> </p>
<Input <Input
className="w-full" className="w-full"
value={state.nickname} value={state.displayName}
onChange={handleNicknameChanged} onChange={handleDisplayNameChanged}
disabled={workspaceGeneralSetting.disallowChangeNickname} disabled={workspaceGeneralSetting.disallowChangeNickname}
/> />
<p className="text-sm"> <p className="text-sm">

@ -40,7 +40,7 @@ const UserBanner = (props: Props) => {
)} )}
{!collapsed && ( {!collapsed && (
<span className="ml-2 text-lg font-medium text-slate-800 dark:text-gray-300 grow truncate"> <span className="ml-2 text-lg font-medium text-slate-800 dark:text-gray-300 grow truncate">
{currentUser.nickname || currentUser.username} {currentUser.displayName || currentUser.username}
</span> </span>
)} )}
</div> </div>

@ -90,7 +90,7 @@ const UserProfile = observer(() => {
<UserAvatar className="w-16! h-16! drop-shadow rounded-3xl" avatarUrl={user?.avatarUrl} /> <UserAvatar className="w-16! h-16! drop-shadow rounded-3xl" avatarUrl={user?.avatarUrl} />
<div className="mt-2 w-auto max-w-[calc(100%-6rem)] flex flex-col justify-center items-start"> <div className="mt-2 w-auto max-w-[calc(100%-6rem)] flex flex-col justify-center items-start">
<p className="w-full text-3xl text-black leading-tight font-medium opacity-80 dark:text-gray-200 truncate"> <p className="w-full text-3xl text-black leading-tight font-medium opacity-80 dark:text-gray-200 truncate">
{user.nickname || user.username} {user.displayName || user.username}
</p> </p>
<p className="w-full text-gray-500 leading-snug dark:text-gray-400 whitespace-pre-wrap truncate line-clamp-6"> <p className="w-full text-gray-500 leading-snug dark:text-gray-400 whitespace-pre-wrap truncate line-clamp-6">
{user.description} {user.description}

@ -71,9 +71,15 @@ const userStore = (() => {
return userMap[name]; return userMap[name];
} }
} }
const user = await userServiceClient.getUserByUsername({ // Use search instead of the deprecated getUserByUsername
username, const { users } = await userServiceClient.searchUsers({
query: username,
pageSize: 10,
}); });
const user = users.find((u) => u.username === username);
if (!user) {
throw new Error(`User with username ${username} not found`);
}
state.setPartial({ state.setPartial({
userMapByName: { userMapByName: {
...userMap, ...userMap,
@ -122,8 +128,16 @@ const userStore = (() => {
}; };
const updateUserSetting = async (userSetting: Partial<UserSetting>, updateMask: string[]) => { const updateUserSetting = async (userSetting: Partial<UserSetting>, updateMask: string[]) => {
if (!state.currentUser) {
throw new Error("No current user");
}
// Ensure the setting has the proper resource name
const settingWithName = {
...userSetting,
name: `${state.currentUser}/setting`,
};
const updatedUserSetting = await userServiceClient.updateUserSetting({ const updatedUserSetting = await userServiceClient.updateUserSetting({
setting: userSetting, setting: settingWithName,
updateMask: updateMask, updateMask: updateMask,
}); });
state.setPartial({ state.setPartial({
@ -181,6 +195,7 @@ const userStore = (() => {
} }
state.setPartial({ state.setPartial({
userStatsByName: { userStatsByName: {
...state.userStatsByName,
...userStatsByName, ...userStatsByName,
}, },
}); });
@ -210,7 +225,7 @@ const userStore = (() => {
export const initialUserStore = async () => { export const initialUserStore = async () => {
try { try {
const currentUser = await authServiceClient.getAuthStatus({}); const currentUser = await authServiceClient.getAuthStatus({});
const userSetting = await userServiceClient.getUserSetting({}); const userSetting = await userServiceClient.getUserSetting({ name: currentUser.name });
userStore.state.setPartial({ userStore.state.setPartial({
currentUser: currentUser.name, currentUser: currentUser.name,
userSetting: UserSetting.fromPartial({ userSetting: UserSetting.fromPartial({

File diff suppressed because it is too large Load Diff

@ -0,0 +1,501 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v2.6.1
// protoc unknown
// source: google/api/resource.proto
/* eslint-disable */
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
export const protobufPackage = "google.api";
/**
* A simple descriptor of a resource type.
*
* ResourceDescriptor annotates a resource message (either by means of a
* protobuf annotation or use in the service config), and associates the
* resource's schema, the resource type, and the pattern of the resource name.
*
* Example:
*
* message Topic {
* // Indicates this message defines a resource schema.
* // Declares the resource type in the format of {service}/{kind}.
* // For Kubernetes resources, the format is {api group}/{kind}.
* option (google.api.resource) = {
* type: "pubsub.googleapis.com/Topic"
* pattern: "projects/{project}/topics/{topic}"
* };
* }
*
* The ResourceDescriptor Yaml config will look like:
*
* resources:
* - type: "pubsub.googleapis.com/Topic"
* pattern: "projects/{project}/topics/{topic}"
*
* Sometimes, resources have multiple patterns, typically because they can
* live under multiple parents.
*
* Example:
*
* message LogEntry {
* option (google.api.resource) = {
* type: "logging.googleapis.com/LogEntry"
* pattern: "projects/{project}/logs/{log}"
* pattern: "folders/{folder}/logs/{log}"
* pattern: "organizations/{organization}/logs/{log}"
* pattern: "billingAccounts/{billing_account}/logs/{log}"
* };
* }
*
* The ResourceDescriptor Yaml config will look like:
*
* resources:
* - type: 'logging.googleapis.com/LogEntry'
* pattern: "projects/{project}/logs/{log}"
* pattern: "folders/{folder}/logs/{log}"
* pattern: "organizations/{organization}/logs/{log}"
* pattern: "billingAccounts/{billing_account}/logs/{log}"
*/
export interface ResourceDescriptor {
/**
* The resource type. It must be in the format of
* {service_name}/{resource_type_kind}. The `resource_type_kind` must be
* singular and must not include version numbers.
*
* Example: `storage.googleapis.com/Bucket`
*
* The value of the resource_type_kind must follow the regular expression
* /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and
* should use PascalCase (UpperCamelCase). The maximum number of
* characters allowed for the `resource_type_kind` is 100.
*/
type: string;
/**
* Optional. The relative resource name pattern associated with this resource
* type. The DNS prefix of the full resource name shouldn't be specified here.
*
* The path pattern must follow the syntax, which aligns with HTTP binding
* syntax:
*
* Template = Segment { "/" Segment } ;
* Segment = LITERAL | Variable ;
* Variable = "{" LITERAL "}" ;
*
* Examples:
*
* - "projects/{project}/topics/{topic}"
* - "projects/{project}/knowledgeBases/{knowledge_base}"
*
* The components in braces correspond to the IDs for each resource in the
* hierarchy. It is expected that, if multiple patterns are provided,
* the same component name (e.g. "project") refers to IDs of the same
* type of resource.
*/
pattern: string[];
/**
* Optional. The field on the resource that designates the resource name
* field. If omitted, this is assumed to be "name".
*/
nameField: string;
/**
* Optional. The historical or future-looking state of the resource pattern.
*
* Example:
*
* // The InspectTemplate message originally only supported resource
* // names with organization, and project was added later.
* message InspectTemplate {
* option (google.api.resource) = {
* type: "dlp.googleapis.com/InspectTemplate"
* pattern:
* "organizations/{organization}/inspectTemplates/{inspect_template}"
* pattern: "projects/{project}/inspectTemplates/{inspect_template}"
* history: ORIGINALLY_SINGLE_PATTERN
* };
* }
*/
history: ResourceDescriptor_History;
/**
* The plural name used in the resource name and permission names, such as
* 'projects' for the resource name of 'projects/{project}' and the permission
* name of 'cloudresourcemanager.googleapis.com/projects.get'. One exception
* to this is for Nested Collections that have stuttering names, as defined
* in [AIP-122](https://google.aip.dev/122#nested-collections), where the
* collection ID in the resource name pattern does not necessarily directly
* match the `plural` value.
*
* It is the same concept of the `plural` field in k8s CRD spec
* https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/
*
* Note: The plural form is required even for singleton resources. See
* https://aip.dev/156
*/
plural: string;
/**
* The same concept of the `singular` field in k8s CRD spec
* https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/
* Such as "project" for the `resourcemanager.googleapis.com/Project` type.
*/
singular: string;
/**
* Style flag(s) for this resource.
* These indicate that a resource is expected to conform to a given
* style. See the specific style flags for additional information.
*/
style: ResourceDescriptor_Style[];
}
/**
* A description of the historical or future-looking state of the
* resource pattern.
*/
export enum ResourceDescriptor_History {
/** HISTORY_UNSPECIFIED - The "unset" value. */
HISTORY_UNSPECIFIED = "HISTORY_UNSPECIFIED",
/**
* ORIGINALLY_SINGLE_PATTERN - The resource originally had one pattern and launched as such, and
* additional patterns were added later.
*/
ORIGINALLY_SINGLE_PATTERN = "ORIGINALLY_SINGLE_PATTERN",
/**
* FUTURE_MULTI_PATTERN - The resource has one pattern, but the API owner expects to add more
* later. (This is the inverse of ORIGINALLY_SINGLE_PATTERN, and prevents
* that from being necessary once there are multiple patterns.)
*/
FUTURE_MULTI_PATTERN = "FUTURE_MULTI_PATTERN",
UNRECOGNIZED = "UNRECOGNIZED",
}
export function resourceDescriptor_HistoryFromJSON(object: any): ResourceDescriptor_History {
switch (object) {
case 0:
case "HISTORY_UNSPECIFIED":
return ResourceDescriptor_History.HISTORY_UNSPECIFIED;
case 1:
case "ORIGINALLY_SINGLE_PATTERN":
return ResourceDescriptor_History.ORIGINALLY_SINGLE_PATTERN;
case 2:
case "FUTURE_MULTI_PATTERN":
return ResourceDescriptor_History.FUTURE_MULTI_PATTERN;
case -1:
case "UNRECOGNIZED":
default:
return ResourceDescriptor_History.UNRECOGNIZED;
}
}
export function resourceDescriptor_HistoryToNumber(object: ResourceDescriptor_History): number {
switch (object) {
case ResourceDescriptor_History.HISTORY_UNSPECIFIED:
return 0;
case ResourceDescriptor_History.ORIGINALLY_SINGLE_PATTERN:
return 1;
case ResourceDescriptor_History.FUTURE_MULTI_PATTERN:
return 2;
case ResourceDescriptor_History.UNRECOGNIZED:
default:
return -1;
}
}
/** A flag representing a specific style that a resource claims to conform to. */
export enum ResourceDescriptor_Style {
/** STYLE_UNSPECIFIED - The unspecified value. Do not use. */
STYLE_UNSPECIFIED = "STYLE_UNSPECIFIED",
/**
* DECLARATIVE_FRIENDLY - This resource is intended to be "declarative-friendly".
*
* Declarative-friendly resources must be more strictly consistent, and
* setting this to true communicates to tools that this resource should
* adhere to declarative-friendly expectations.
*
* Note: This is used by the API linter (linter.aip.dev) to enable
* additional checks.
*/
DECLARATIVE_FRIENDLY = "DECLARATIVE_FRIENDLY",
UNRECOGNIZED = "UNRECOGNIZED",
}
export function resourceDescriptor_StyleFromJSON(object: any): ResourceDescriptor_Style {
switch (object) {
case 0:
case "STYLE_UNSPECIFIED":
return ResourceDescriptor_Style.STYLE_UNSPECIFIED;
case 1:
case "DECLARATIVE_FRIENDLY":
return ResourceDescriptor_Style.DECLARATIVE_FRIENDLY;
case -1:
case "UNRECOGNIZED":
default:
return ResourceDescriptor_Style.UNRECOGNIZED;
}
}
export function resourceDescriptor_StyleToNumber(object: ResourceDescriptor_Style): number {
switch (object) {
case ResourceDescriptor_Style.STYLE_UNSPECIFIED:
return 0;
case ResourceDescriptor_Style.DECLARATIVE_FRIENDLY:
return 1;
case ResourceDescriptor_Style.UNRECOGNIZED:
default:
return -1;
}
}
/**
* Defines a proto annotation that describes a string field that refers to
* an API resource.
*/
export interface ResourceReference {
/**
* The resource type that the annotated field references.
*
* Example:
*
* message Subscription {
* string topic = 2 [(google.api.resource_reference) = {
* type: "pubsub.googleapis.com/Topic"
* }];
* }
*
* Occasionally, a field may reference an arbitrary resource. In this case,
* APIs use the special value * in their resource reference.
*
* Example:
*
* message GetIamPolicyRequest {
* string resource = 2 [(google.api.resource_reference) = {
* type: "*"
* }];
* }
*/
type: string;
/**
* The resource type of a child collection that the annotated field
* references. This is useful for annotating the `parent` field that
* doesn't have a fixed resource type.
*
* Example:
*
* message ListLogEntriesRequest {
* string parent = 1 [(google.api.resource_reference) = {
* child_type: "logging.googleapis.com/LogEntry"
* };
* }
*/
childType: string;
}
function createBaseResourceDescriptor(): ResourceDescriptor {
return {
type: "",
pattern: [],
nameField: "",
history: ResourceDescriptor_History.HISTORY_UNSPECIFIED,
plural: "",
singular: "",
style: [],
};
}
export const ResourceDescriptor: MessageFns<ResourceDescriptor> = {
encode(message: ResourceDescriptor, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.type !== "") {
writer.uint32(10).string(message.type);
}
for (const v of message.pattern) {
writer.uint32(18).string(v!);
}
if (message.nameField !== "") {
writer.uint32(26).string(message.nameField);
}
if (message.history !== ResourceDescriptor_History.HISTORY_UNSPECIFIED) {
writer.uint32(32).int32(resourceDescriptor_HistoryToNumber(message.history));
}
if (message.plural !== "") {
writer.uint32(42).string(message.plural);
}
if (message.singular !== "") {
writer.uint32(50).string(message.singular);
}
writer.uint32(82).fork();
for (const v of message.style) {
writer.int32(resourceDescriptor_StyleToNumber(v));
}
writer.join();
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): ResourceDescriptor {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseResourceDescriptor();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 10) {
break;
}
message.type = reader.string();
continue;
}
case 2: {
if (tag !== 18) {
break;
}
message.pattern.push(reader.string());
continue;
}
case 3: {
if (tag !== 26) {
break;
}
message.nameField = reader.string();
continue;
}
case 4: {
if (tag !== 32) {
break;
}
message.history = resourceDescriptor_HistoryFromJSON(reader.int32());
continue;
}
case 5: {
if (tag !== 42) {
break;
}
message.plural = reader.string();
continue;
}
case 6: {
if (tag !== 50) {
break;
}
message.singular = reader.string();
continue;
}
case 10: {
if (tag === 80) {
message.style.push(resourceDescriptor_StyleFromJSON(reader.int32()));
continue;
}
if (tag === 82) {
const end2 = reader.uint32() + reader.pos;
while (reader.pos < end2) {
message.style.push(resourceDescriptor_StyleFromJSON(reader.int32()));
}
continue;
}
break;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
create(base?: DeepPartial<ResourceDescriptor>): ResourceDescriptor {
return ResourceDescriptor.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<ResourceDescriptor>): ResourceDescriptor {
const message = createBaseResourceDescriptor();
message.type = object.type ?? "";
message.pattern = object.pattern?.map((e) => e) || [];
message.nameField = object.nameField ?? "";
message.history = object.history ?? ResourceDescriptor_History.HISTORY_UNSPECIFIED;
message.plural = object.plural ?? "";
message.singular = object.singular ?? "";
message.style = object.style?.map((e) => e) || [];
return message;
},
};
function createBaseResourceReference(): ResourceReference {
return { type: "", childType: "" };
}
export const ResourceReference: MessageFns<ResourceReference> = {
encode(message: ResourceReference, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
if (message.type !== "") {
writer.uint32(10).string(message.type);
}
if (message.childType !== "") {
writer.uint32(18).string(message.childType);
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): ResourceReference {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseResourceReference();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1: {
if (tag !== 10) {
break;
}
message.type = reader.string();
continue;
}
case 2: {
if (tag !== 18) {
break;
}
message.childType = reader.string();
continue;
}
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
create(base?: DeepPartial<ResourceReference>): ResourceReference {
return ResourceReference.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<ResourceReference>): ResourceReference {
const message = createBaseResourceReference();
message.type = object.type ?? "";
message.childType = object.childType ?? "";
return message;
},
};
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
export interface MessageFns<T> {
encode(message: T, writer?: BinaryWriter): BinaryWriter;
decode(input: BinaryReader | Uint8Array, length?: number): T;
create(base?: DeepPartial<T>): T;
fromPartial(object: DeepPartial<T>): T;
}
Loading…
Cancel
Save