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/field_behavior.proto";
import "google/api/httpbody.proto";
import "google/api/resource.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
@ -18,21 +19,13 @@ service UserService {
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) {
option (google.api.http) = {get: "/api/v1/users"};
}
// GetUser gets a user by name.
rpc GetUser(GetUserRequest) returns (User) {
option (google.api.http) = {get: "/api/v1/{name=users/*}"};
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.
rpc CreateUser(CreateUserRequest) returns (User) {
option (google.api.http) = {
@ -41,6 +34,7 @@ service UserService {
};
option (google.api.method_signature) = "user";
}
// UpdateUser updates a user.
rpc UpdateUser(UpdateUserRequest) returns (User) {
option (google.api.http) = {
@ -49,147 +43,288 @@ service UserService {
};
option (google.api.method_signature) = "user,update_mask";
}
// DeleteUser deletes a user.
rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {delete: "/api/v1/{name=users/*}"};
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) {
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) {
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";
}
// GetUserSetting gets the setting of a user.
// GetUserSetting returns the user setting.
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";
}
// UpdateUserSetting updates the setting of a user.
// UpdateUserSetting updates the user setting.
rpc UpdateUserSetting(UpdateUserSettingRequest) returns (UserSetting) {
option (google.api.http) = {
patch: "/api/v1/{setting.name=users/*/setting}"
patch: "/api/v1/{setting.name=users/*}:updateSetting"
body: "setting"
};
option (google.api.method_signature) = "setting,update_mask";
}
// ListUserAccessTokens returns a list of access tokens for a user.
rpc ListUserAccessTokens(ListUserAccessTokensRequest) returns (ListUserAccessTokensResponse) {
option (google.api.http) = {get: "/api/v1/{name=users/*}/access_tokens"};
option (google.api.method_signature) = "name";
option (google.api.http) = {get: "/api/v1/{parent=users/*}/accessTokens"};
option (google.api.method_signature) = "parent";
}
// CreateUserAccessToken creates a new access token for a user.
rpc CreateUserAccessToken(CreateUserAccessTokenRequest) returns (UserAccessToken) {
option (google.api.http) = {
post: "/api/v1/{name=users/*}/access_tokens"
body: "*"
post: "/api/v1/{parent=users/*}/accessTokens"
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) {
option (google.api.http) = {delete: "/api/v1/{name=users/*}/access_tokens/{access_token}"};
option (google.api.method_signature) = "name,access_token";
option (google.api.http) = {delete: "/api/v1/{name=users/*/accessTokens/*}"};
option (google.api.method_signature) = "name";
}
}
message User {
// The name of the user.
// Format: users/{id}, id is the system generated auto-incremented id.
string name = 1 [
(google.api.field_behavior) = OUTPUT_ONLY,
(google.api.field_behavior) = IDENTIFIER
];
option (google.api.resource) = {
type: "memos.api.v1/User"
pattern: "users/{user}"
name_field: "name"
singular: "user"
plural: "users"
};
enum Role {
ROLE_UNSPECIFIED = 0;
HOST = 1;
ADMIN = 2;
USER = 3;
}
Role role = 3;
// The resource name of the user.
// Format: users/{user}
string name = 1 [(google.api.field_behavior) = IDENTIFIER];
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];
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];
// Output only. The last update timestamp.
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 {
// The list of users.
repeated User users = 1;
}
message GetUserRequest {
// The name of the user.
string name = 1;
}
// A token that can be sent as `page_token` to retrieve the next page.
// If this field is omitted, there are no subsequent pages.
string next_page_token = 2;
message GetUserByUsernameRequest {
// The username of the user.
string username = 1;
// The total count of users (may be approximate).
int32 total_size = 3;
}
message GetUserAvatarBinaryRequest {
// The name of the user.
string name = 1;
message GetUserRequest {
// 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"}
];
// The raw HTTP body is bound to this field.
google.api.HttpBody http_body = 2;
// Optional. The fields to return in the response.
// If not specified, all fields are returned.
google.protobuf.FieldMask read_mask = 2 [(google.api.field_behavior) = OPTIONAL];
}
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 {
// Required. The user to update.
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 {
// The name of the user.
string name = 1;
// Required. The resource name of the user to delete.
// 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 {
// The name of the user.
string name = 1;
option (google.api.resource) = {
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.
// 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;
// The stats of memo types.
MemoTypeStats memo_type_stats = 3;
// The count of tags.
// Format: "tag1": 1, "tag2": 2
map<string, int32> tag_count = 4;
// The pinned memos of the user.
repeated string pinned_memos = 5;
// Total memo count.
int32 total_memo_count = 6;
// Memo type statistics.
message MemoTypeStats {
int32 link_count = 1;
int32 code_count = 2;
@ -198,67 +333,146 @@ message UserStats {
}
}
message ListAllUserStatsRequest {}
message ListAllUserStatsResponse {
repeated UserStats user_stats = 1;
}
message GetUserStatsRequest {
// The name of the user.
string name = 1;
// 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 settings message
message UserSetting {
// The name of the user.
string name = 1;
option (google.api.resource) = {
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.
string locale = 2;
string locale = 2 [(google.api.field_behavior) = OPTIONAL];
// The preferred appearance of the user.
string appearance = 3;
string appearance = 3 [(google.api.field_behavior) = OPTIONAL];
// The default visibility of the memo.
string memo_visibility = 4;
string memo_visibility = 4 [(google.api.field_behavior) = OPTIONAL];
}
message GetUserSettingRequest {
// The name of the user.
string name = 1;
// 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"}
];
}
message UpdateUserSettingRequest {
// Required. The user setting to update.
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 {
string access_token = 1;
string description = 2;
google.protobuf.Timestamp issued_at = 3;
google.protobuf.Timestamp expires_at = 4;
option (google.api.resource) = {
type: "memos.api.v1/UserAccessToken"
pattern: "users/{user}/accessTokens/{access_token}"
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 {
// The name of the user.
string name = 1;
// Required. The parent resource whose access tokens will be listed.
// 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 {
// The list of access tokens.
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 {
// The name of the user.
string name = 1;
// Required. The parent resource where this access token will be created.
// 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 {
// The name of the user.
string name = 1;
// access_token is the access token to delete.
string access_token = 2;
// Required. The resource name of the access token to delete.
// Format: users/{user}/accessTokens/{access_token}
string name = 1 [
(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
)
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 (
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
}
var filter_UserService_ListUsers_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
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 (
protoReq ListUsersRequest
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)
if err := req.ParseForm(); err != nil {
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)
}
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
}
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 (
protoReq GetUserByUsernameRequest
protoReq ListUsersRequest
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_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)
}
msg, err := server.GetUserByUsername(ctx, &protoReq)
msg, err := server.ListUsers(ctx, &protoReq)
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 (
protoReq GetUserAvatarBinaryRequest
protoReq GetUserRequest
metadata runtime.ServerMetadata
err error
)
@ -144,16 +88,16 @@ func request_UserService_GetUserAvatarBinary_0(ctx context.Context, marshaler ru
if err := req.ParseForm(); err != nil {
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)
}
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
}
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 (
protoReq GetUserAvatarBinaryRequest
protoReq GetUserRequest
metadata runtime.ServerMetadata
err error
)
@ -168,13 +112,15 @@ func local_request_UserService_GetUserAvatarBinary_0(ctx context.Context, marsha
if err := req.ParseForm(); err != nil {
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)
}
msg, err := server.GetUserAvatarBinary(ctx, &protoReq)
msg, err := server.GetUser(ctx, &protoReq)
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) {
var (
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) {
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))
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) {
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)
return msg, metadata, err
}
@ -277,6 +235,8 @@ func local_request_UserService_UpdateUser_0(ctx context.Context, marshaler runti
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) {
var (
protoReq DeleteUserRequest
@ -292,6 +252,12 @@ func request_UserService_DeleteUser_0(ctx context.Context, marshaler runtime.Mar
if err != nil {
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))
return msg, metadata, err
}
@ -310,16 +276,100 @@ func local_request_UserService_DeleteUser_0(ctx context.Context, marshaler runti
if err != nil {
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)
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) {
var (
protoReq ListAllUserStatsRequest
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_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))
return msg, metadata, err
}
@ -329,6 +379,12 @@ func local_request_UserService_ListAllUserStats_0(ctx context.Context, marshaler
protoReq ListAllUserStatsRequest
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)
return msg, metadata, err
}
@ -485,6 +541,8 @@ func local_request_UserService_UpdateUserSetting_0(ctx context.Context, marshale
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) {
var (
protoReq ListUserAccessTokensRequest
@ -492,13 +550,19 @@ func request_UserService_ListUserAccessTokens_0(ctx context.Context, marshaler r
err error
)
io.Copy(io.Discard, req.Body)
val, ok := pathParams["name"]
val, ok := pathParams["parent"]
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 {
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))
return msg, metadata, err
@ -510,34 +574,48 @@ func local_request_UserService_ListUserAccessTokens_0(ctx context.Context, marsh
metadata runtime.ServerMetadata
err error
)
val, ok := pathParams["name"]
val, ok := pathParams["parent"]
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 {
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)
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) {
var (
protoReq CreateUserAccessTokenRequest
metadata runtime.ServerMetadata
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)
}
val, ok := pathParams["name"]
val, ok := pathParams["parent"]
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 {
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))
return msg, metadata, err
@ -549,16 +627,22 @@ func local_request_UserService_CreateUserAccessToken_0(ctx context.Context, mars
metadata runtime.ServerMetadata
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)
}
val, ok := pathParams["name"]
val, ok := pathParams["parent"]
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 {
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)
return msg, metadata, err
@ -579,14 +663,6 @@ func request_UserService_DeleteUserAccessToken_0(ctx context.Context, marshaler
if err != nil {
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))
return msg, metadata, err
}
@ -605,14 +681,6 @@ func local_request_UserService_DeleteUserAccessToken_0(ctx context.Context, mars
if err != nil {
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)
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()...)
})
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())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
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())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
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())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
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())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
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())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
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())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
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())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
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())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
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())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
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())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
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())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -789,7 +857,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -809,7 +877,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -829,7 +897,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -849,7 +917,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -869,7 +937,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -889,7 +957,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
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()...)
})
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())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
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)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
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())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
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)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
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())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
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)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
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())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
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)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
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())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
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)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
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())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -1083,7 +1151,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -1100,7 +1168,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -1117,7 +1185,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -1134,7 +1202,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -1151,7 +1219,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -1168,7 +1236,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
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 {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
@ -1187,28 +1255,28 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
var (
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_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_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_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_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_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_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_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_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_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_SearchUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "search"))
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_ListAllUserStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "users"}, "stats"))
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_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_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_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 (
forward_UserService_ListUsers_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_UpdateUser_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_GetUserStats_0 = runtime.ForwardResponseMessage
forward_UserService_GetUserSetting_0 = runtime.ForwardResponseMessage

@ -23,11 +23,11 @@ const _ = grpc.SupportPackageIsVersion9
const (
UserService_ListUsers_FullMethodName = "/memos.api.v1.UserService/ListUsers"
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_UpdateUser_FullMethodName = "/memos.api.v1.UserService/UpdateUser"
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_GetUserStats_FullMethodName = "/memos.api.v1.UserService/GetUserStats"
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)
// GetUser gets a user by name.
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(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*User, error)
// UpdateUser updates a user.
UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*User, error)
// DeleteUser deletes a user.
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)
// 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)
// GetUserSetting gets the setting of a user.
// GetUserSetting returns the user setting.
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)
// ListUserAccessTokens returns a list of access tokens for a user.
ListUserAccessTokens(ctx context.Context, in *ListUserAccessTokensRequest, opts ...grpc.CallOption) (*ListUserAccessTokensResponse, error)
// CreateUserAccessToken creates a new access token for a user.
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)
}
@ -99,50 +99,50 @@ func (c *userServiceClient) GetUser(ctx context.Context, in *GetUserRequest, opt
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...)
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 {
return nil, err
}
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...)
out := new(httpbody.HttpBody)
err := c.cc.Invoke(ctx, UserService_GetUserAvatarBinary_FullMethodName, in, out, cOpts...)
out := new(User)
err := c.cc.Invoke(ctx, UserService_UpdateUser_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
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...)
out := new(User)
err := c.cc.Invoke(ctx, UserService_CreateUser_FullMethodName, in, out, cOpts...)
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, UserService_DeleteUser_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
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...)
out := new(User)
err := c.cc.Invoke(ctx, UserService_UpdateUser_FullMethodName, in, out, cOpts...)
out := new(SearchUsersResponse)
err := c.cc.Invoke(ctx, UserService_SearchUsers_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
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...)
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, UserService_DeleteUser_FullMethodName, in, out, cOpts...)
out := new(httpbody.HttpBody)
err := c.cc.Invoke(ctx, UserService_GetUserAvatar_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
@ -227,29 +227,29 @@ type UserServiceServer interface {
ListUsers(context.Context, *ListUsersRequest) (*ListUsersResponse, error)
// GetUser gets a user by name.
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(context.Context, *CreateUserRequest) (*User, error)
// UpdateUser updates a user.
UpdateUser(context.Context, *UpdateUserRequest) (*User, error)
// DeleteUser deletes a user.
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)
// GetUserStats returns the stats of a user.
// GetUserStats returns statistics for a specific user.
GetUserStats(context.Context, *GetUserStatsRequest) (*UserStats, error)
// GetUserSetting gets the setting of a user.
// GetUserSetting returns the user setting.
GetUserSetting(context.Context, *GetUserSettingRequest) (*UserSetting, error)
// UpdateUserSetting updates the setting of a user.
// UpdateUserSetting updates the user setting.
UpdateUserSetting(context.Context, *UpdateUserSettingRequest) (*UserSetting, error)
// ListUserAccessTokens returns a list of access tokens for a user.
ListUserAccessTokens(context.Context, *ListUserAccessTokensRequest) (*ListUserAccessTokensResponse, error)
// CreateUserAccessToken creates a new access token for a user.
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)
mustEmbedUnimplementedUserServiceServer()
}
@ -267,12 +267,6 @@ func (UnimplementedUserServiceServer) ListUsers(context.Context, *ListUsersReque
func (UnimplementedUserServiceServer) GetUser(context.Context, *GetUserRequest) (*User, error) {
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) {
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) {
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) {
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)
}
func _UserService_GetUserByUsername_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserByUsernameRequest)
func _UserService_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserServiceServer).GetUserByUsername(ctx, in)
return srv.(UserServiceServer).CreateUser(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserService_GetUserByUsername_FullMethodName,
FullMethod: UserService_CreateUser_FullMethodName,
}
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)
}
func _UserService_GetUserAvatarBinary_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserAvatarBinaryRequest)
func _UserService_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserServiceServer).GetUserAvatarBinary(ctx, in)
return srv.(UserServiceServer).UpdateUser(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserService_GetUserAvatarBinary_FullMethodName,
FullMethod: UserService_UpdateUser_FullMethodName,
}
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)
}
func _UserService_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateUserRequest)
func _UserService_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserServiceServer).CreateUser(ctx, in)
return srv.(UserServiceServer).DeleteUser(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserService_CreateUser_FullMethodName,
FullMethod: UserService_DeleteUser_FullMethodName,
}
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)
}
func _UserService_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpdateUserRequest)
func _UserService_SearchUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SearchUsersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserServiceServer).UpdateUser(ctx, in)
return srv.(UserServiceServer).SearchUsers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserService_UpdateUser_FullMethodName,
FullMethod: UserService_SearchUsers_FullMethodName,
}
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)
}
func _UserService_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteUserRequest)
func _UserService_GetUserAvatar_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserAvatarRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserServiceServer).DeleteUser(ctx, in)
return srv.(UserServiceServer).GetUserAvatar(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserService_DeleteUser_FullMethodName,
FullMethod: UserService_GetUserAvatar_FullMethodName,
}
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)
}
@ -591,14 +591,6 @@ var UserService_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetUser",
Handler: _UserService_GetUser_Handler,
},
{
MethodName: "GetUserByUsername",
Handler: _UserService_GetUserByUsername_Handler,
},
{
MethodName: "GetUserAvatarBinary",
Handler: _UserService_GetUserAvatarBinary_Handler,
},
{
MethodName: "CreateUser",
Handler: _UserService_CreateUser_Handler,
@ -611,6 +603,14 @@ var UserService_ServiceDesc = grpc.ServiceDesc{
MethodName: "DeleteUser",
Handler: _UserService_DeleteUser_Handler,
},
{
MethodName: "SearchUsers",
Handler: _UserService_SearchUsers_Handler,
},
{
MethodName: "GetUserAvatar",
Handler: _UserService_GetUserAvatar_Handler,
},
{
MethodName: "ListAllUserStats",
Handler: _UserService_ListAllUserStats_Handler,

@ -452,6 +452,45 @@ paths:
description: An unexpected error response.
schema:
$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:
- UserService
post:
@ -468,43 +507,89 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: user
description: Required. The user to create.
in: body
required: true
schema:
$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:
- UserService
/api/v1/users/-/stats:
post:
summary: ListAllUserStats returns all user stats.
operationId: UserService_ListAllUserStats
/api/v1/users:search:
get:
summary: SearchUsers searches for users based on query.
operationId: UserService_SearchUsers
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1ListAllUserStatsResponse'
$ref: '#/definitions/v1SearchUsersResponse'
default:
description: An unexpected error response.
schema:
$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:
- UserService
/api/v1/users:username:
/api/v1/users:stats:
get:
summary: GetUserByUsername gets a user by username.
operationId: UserService_GetUserByUsername
summary: ListAllUserStats returns statistics for all users.
operationId: UserService_ListAllUserStats
responses:
"200":
description: A successful response.
schema:
$ref: '#/definitions/v1User'
$ref: '#/definitions/v1ListAllUserStatsResponse'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: username
description: The username of the user.
- name: pageSize
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
required: false
type: string
@ -914,16 +999,25 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name_1
description: The name of the user.
description: |-
Required. The resource name of the user.
Format: users/{user}
in: path
required: true
type: string
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:
- UserService
delete:
summary: DeleteIdentityProvider deletes an identity provider.
operationId: IdentityProviderService_DeleteIdentityProvider
summary: DeleteUserAccessToken deletes an access token.
operationId: UserService_DeleteUserAccessToken
responses:
"200":
description: A successful response.
@ -936,13 +1030,15 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- 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
required: true
type: string
pattern: identityProviders/[^/]+
pattern: users/[^/]+/accessTokens/[^/]+
tags:
- IdentityProviderService
- UserService
/api/v1/{name_2}:
get:
summary: GetIdentityProvider gets an identity provider.
@ -966,8 +1062,8 @@ paths:
tags:
- IdentityProviderService
delete:
summary: DeleteInbox deletes an inbox.
operationId: InboxService_DeleteInbox
summary: DeleteIdentityProvider deletes an identity provider.
operationId: IdentityProviderService_DeleteIdentityProvider
responses:
"200":
description: A successful response.
@ -980,13 +1076,13 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name_2
description: The name of the inbox to delete.
description: The name of the identityProvider to delete.
in: path
required: true
type: string
pattern: inboxes/[^/]+
pattern: identityProviders/[^/]+
tags:
- InboxService
- IdentityProviderService
/api/v1/{name_3}:
get:
summary: GetResource returns a resource by name.
@ -1010,8 +1106,8 @@ paths:
tags:
- ResourceService
delete:
summary: DeleteResource deletes a resource by name.
operationId: ResourceService_DeleteResource
summary: DeleteInbox deletes an inbox.
operationId: InboxService_DeleteInbox
responses:
"200":
description: A successful response.
@ -1024,13 +1120,13 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name_3
description: The name of the resource.
description: The name of the inbox to delete.
in: path
required: true
type: string
pattern: resources/[^/]+
pattern: inboxes/[^/]+
tags:
- ResourceService
- InboxService
/api/v1/{name_4}:
get:
summary: GetMemo gets a memo.
@ -1053,6 +1149,29 @@ paths:
pattern: memos/[^/]+
tags:
- 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:
summary: DeleteMemo deletes a memo.
operationId: MemoService_DeleteMemo
@ -1067,7 +1186,7 @@ paths:
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name_4
- name: name_5
description: The name of the memo.
in: path
required: true
@ -1114,87 +1233,42 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the user.
description: |-
Required. The resource name of the user to delete.
Format: users/{user}
in: path
required: true
type: string
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:
- UserService
/api/v1/{name}/access_tokens:
/api/v1/{name}/avatar:
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: 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
summary: GetUserAvatar gets the avatar of a user.
operationId: UserService_GetUserAvatar
responses:
"200":
description: A successful response.
schema:
type: object
properties: {}
$ref: '#/definitions/apiHttpBody'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the user.
description: |-
Required. The resource name of the user.
Format: users/{user}
in: path
required: true
type: string
pattern: users/[^/]+
- name: accessToken
description: access_token is the access token to delete.
in: path
required: true
type: string
tags:
- UserService
/api/v1/{name}/comments:
@ -1392,9 +1466,9 @@ paths:
$ref: '#/definitions/MemoServiceSetMemoResourcesBody'
tags:
- MemoService
/api/v1/{name}/setting:
/api/v1/{name}:getSetting:
get:
summary: GetUserSetting gets the setting of a user.
summary: GetUserSetting returns the user setting.
operationId: UserService_GetUserSetting
responses:
"200":
@ -1407,16 +1481,18 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the user.
description: |-
Required. The resource name of the user.
Format: users/{user}
in: path
required: true
type: string
pattern: users/[^/]+
tags:
- UserService
/api/v1/{name}/stats:
/api/v1/{name}:getStats:
get:
summary: GetUserStats returns the stats of a user.
summary: GetUserStats returns statistics for a specific user.
operationId: UserService_GetUserStats
responses:
"200":
@ -1429,13 +1505,86 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- name: name
description: The name of the user.
description: |-
Required. The resource name of the user.
Format: users/{user}
in: path
required: true
type: string
pattern: users/[^/]+
tags:
- 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:
get:
summary: ListMemos lists memos with pagination and filter.
@ -1746,9 +1895,9 @@ paths:
description: The related memo. Refer to `Memo.name`.
tags:
- ResourceService
/api/v1/{setting.name}:
/api/v1/{setting.name}:updateSetting:
patch:
summary: UpdateUserSetting updates the setting of a user.
summary: UpdateUserSetting updates the user setting.
operationId: UserService_UpdateUserSetting
responses:
"200":
@ -1761,12 +1910,15 @@ paths:
$ref: '#/definitions/googlerpcStatus'
parameters:
- 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
required: true
type: string
pattern: users/[^/]+/setting
pattern: users/[^/]+
- name: setting
description: Required. The user setting to update.
in: body
required: true
schema:
@ -1781,6 +1933,7 @@ paths:
memoVisibility:
type: string
description: The default visibility of the memo.
title: Required. The user setting to update.
required:
- setting
tags:
@ -1801,77 +1954,72 @@ paths:
parameters:
- name: user.name
description: |-
The name of the user.
Format: users/{id}, id is the system generated auto-incremented id.
The resource name of the user.
Format: users/{user}
in: path
required: true
type: string
pattern: users/[^/]+
- name: user
description: Required. The user to update.
in: body
required: true
schema:
type: object
properties:
uid:
type: string
description: Output only. The system generated unique identifier.
readOnly: true
role:
$ref: '#/definitions/UserRole'
description: The role of the user.
username:
type: string
description: Required. The unique username for login.
email:
type: string
nickname:
description: Optional. The email address of the user.
displayName:
type: string
description: Optional. The display name of the user.
avatarUrl:
type: string
description: Optional. The avatar URL of the user.
description:
type: string
description: Optional. The description of the user.
password:
type: string
description: Input only. The password for the user.
state:
$ref: '#/definitions/v1State'
description: The state of the user.
createTime:
type: string
format: date-time
description: Output only. The creation timestamp.
readOnly: true
updateTime:
type: string
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
title: Required. The user to update.
required:
- role
- username
- state
- user
tags:
- UserService
/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.
- name: allowMissing
description: Optional. If set to true, allows updating sensitive fields.
in: query
required: false
type: string
- name: httpBody.data
description: The HTTP request/response body as raw binary.
in: query
required: false
type: string
format: byte
type: boolean
tags:
- UserService
/file/{name}/{filename}:
@ -1959,14 +2107,13 @@ definitions:
- ADMIN
- USER
default: ROLE_UNSPECIFIED
UserServiceCreateUserAccessTokenBody:
type: object
properties:
description:
type: string
expiresAt:
type: string
format: date-time
description: |-
User role enumeration.
- ROLE_UNSPECIFIED: Unspecified role.
- HOST: Host role with full system access.
- ADMIN: Admin role with administrative privileges.
- USER: Regular user role.
UserStatsMemoTypeStats:
type: object
properties:
@ -1982,6 +2129,7 @@ definitions:
undoCount:
type: integer
format: int32
description: Memo type statistics.
WorkspaceStorageSettingS3Config:
type: object
properties:
@ -2233,7 +2381,9 @@ definitions:
properties:
name:
type: string
description: The name of the user.
title: |-
The resource name of the user whose setting this is.
Format: users/{user}
locale:
type: string
description: The preferred locale of the user.
@ -2243,6 +2393,7 @@ definitions:
memoVisibility:
type: string
description: The default visibility of the memo.
title: User settings message
apiv1WorkspaceCustomProfile:
type: object
properties:
@ -2715,6 +2866,14 @@ definitions:
items:
type: object
$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:
type: object
properties:
@ -2818,6 +2977,14 @@ definitions:
items:
type: object
$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:
type: object
properties:
@ -2826,6 +2993,16 @@ definitions:
items:
type: object
$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:
type: object
properties:
@ -3115,6 +3292,22 @@ definitions:
redirectUri:
type: string
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:
type: object
properties:
@ -3215,61 +3408,94 @@ definitions:
properties:
name:
type: string
description: |-
The name of the user.
Format: users/{id}, id is the system generated auto-incremented id.
title: |-
The resource name of the user.
Format: users/{user}
uid:
type: string
description: Output only. The system generated unique identifier.
readOnly: true
role:
$ref: '#/definitions/UserRole'
description: The role of the user.
username:
type: string
description: Required. The unique username for login.
email:
type: string
nickname:
description: Optional. The email address of the user.
displayName:
type: string
description: Optional. The display name of the user.
avatarUrl:
type: string
description: Optional. The avatar URL of the user.
description:
type: string
description: Optional. The description of the user.
password:
type: string
description: Input only. The password for the user.
state:
$ref: '#/definitions/v1State'
description: The state of the user.
createTime:
type: string
format: date-time
description: Output only. The creation timestamp.
readOnly: true
updateTime:
type: string
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
required:
- role
- username
- state
v1UserAccessToken:
type: object
properties:
name:
type: string
title: |-
The resource name of the access token.
Format: users/{user}/accessTokens/{access_token}
accessToken:
type: string
description: Output only. The access token value.
readOnly: true
description:
type: string
description: The description of the access token.
issuedAt:
type: string
format: date-time
description: Output only. The issued timestamp.
readOnly: true
expiresAt:
type: string
format: date-time
description: Optional. The expiration timestamp.
title: User access token message
v1UserStats:
type: object
properties:
name:
type: string
description: The name of the user.
title: |-
The resource name of the user whose stats these are.
Format: users/{user}
memoDisplayTimestamps:
type: array
items:
type: string
format: date-time
description: |-
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.
description: The timestamps when the memos were displayed.
memoTypeStats:
$ref: '#/definitions/UserStatsMemoTypeStats'
description: The stats of memo types.
@ -3278,9 +3504,7 @@ definitions:
additionalProperties:
type: integer
format: int32
title: |-
The count of tags.
Format: "tag1": 1, "tag2": 2
description: The count of tags.
pinnedMemos:
type: array
items:
@ -3289,6 +3513,8 @@ definitions:
totalMemoCount:
type: integer
format: int32
description: Total memo count.
title: User statistics messages
v1Visibility:
type: string
enum:

@ -12,8 +12,7 @@ var authenticationAllowlistMethods = map[string]bool{
"/memos.api.v1.AuthService/SignOut": true,
"/memos.api.v1.AuthService/SignUp": true,
"/memos.api.v1.UserService/GetUser": true,
"/memos.api.v1.UserService/GetUserByUsername": true,
"/memos.api.v1.UserService/GetUserAvatarBinary": true,
"/memos.api.v1.UserService/GetUserAvatar": true,
"/memos.api.v1.UserService/GetUserStats": true,
"/memos.api.v1.UserService/ListAllUserStats": 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)
if user != nil {
if _, err := s.DeleteUserAccessToken(ctx, &v1pb.DeleteUserAccessTokenRequest{
Name: fmt.Sprintf("%s%d", UserNamePrefix, user.ID),
AccessToken: accessToken,
Name: fmt.Sprintf("%s%d/accessTokens/%s", UserNamePrefix, user.ID, accessToken),
}); err != nil {
slog.Error("failed to delete access token", "error", err)
}

@ -2,6 +2,7 @@ package v1
import (
"context"
"crypto/md5"
"encoding/base64"
"fmt"
"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)
}
// TODO: Implement proper filtering, ordering, and pagination
// For now, return all users with basic structure
response := &v1pb.ListUsersResponse{
Users: []*v1pb.User{},
Users: []*v1pb.User{},
TotalSize: int32(len(users)),
}
for _, user := range users {
response.Users = append(response.Users, convertUserFromStore(user))
@ -63,25 +67,50 @@ func (s *APIV1Service) GetUser(ctx context.Context, request *v1pb.GetUserRequest
if user == nil {
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) {
user, err := s.Store.GetUser(ctx, &store.FindUser{
Username: &request.Username,
})
func (s *APIV1Service) SearchUsers(ctx context.Context, request *v1pb.SearchUsersRequest) (*v1pb.SearchUsersResponse, error) {
currentUser, err := s.GetCurrentUser(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
}
if user == nil {
return nil, status.Errorf(codes.NotFound, "user not found")
if currentUser.Role != store.RoleHost && currentUser.Role != store.RoleAdmin {
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)
if err != nil {
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 {
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)) {
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)
if err != nil {
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,
Role: convertUserRoleToStore(request.User.Role),
Email: request.User.Email,
Nickname: request.User.Nickname,
Nickname: request.User.DisplayName,
PasswordHash: string(passwordHash),
})
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)
}
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")
}
@ -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)
}
update.Username = &request.User.Username
} else if field == "nickname" {
} else if field == "display_name" {
if workspaceGeneralSetting.DisallowChangeNickname {
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" {
update.Email = &request.User.Email
} else if field == "avatar_url" {
@ -261,25 +310,39 @@ func (s *APIV1Service) DeleteUser(ctx context.Context, request *v1pb.DeleteUserR
func getDefaultUserSetting() *v1pb.UserSetting {
return &v1pb.UserSetting{
Name: "", // Will be set by caller
Locale: "en",
Appearance: "system",
MemoVisibility: "PRIVATE",
}
}
func (s *APIV1Service) GetUserSetting(ctx context.Context, _ *v1pb.GetUserSettingRequest) (*v1pb.UserSetting, error) {
user, err := s.GetCurrentUser(ctx)
func (s *APIV1Service) GetUserSetting(ctx context.Context, request *v1pb.GetUserSettingRequest) (*v1pb.UserSetting, error) {
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 {
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{
UserID: &user.ID,
UserID: &userID,
})
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to list user settings: %v", err)
}
userSettingMessage := getDefaultUserSetting()
userSettingMessage.Name = fmt.Sprintf("users/%d/setting", userID)
for _, setting := range userSettings {
if setting.Key == storepb.UserSettingKey_LOCALE {
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) {
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 {
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 {
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 {
if field == "locale" {
if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
UserId: user.ID,
UserId: userID,
Key: storepb.UserSettingKey_LOCALE,
Value: &storepb.UserSetting_Locale{
Locale: request.Setting.Locale,
@ -315,7 +394,7 @@ func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.Upda
}
} else if field == "appearance" {
if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
UserId: user.ID,
UserId: userID,
Key: storepb.UserSettingKey_APPEARANCE,
Value: &storepb.UserSetting_Appearance{
Appearance: request.Setting.Appearance,
@ -325,7 +404,7 @@ func (s *APIV1Service) UpdateUserSetting(ctx context.Context, request *v1pb.Upda
}
} else if field == "memo_visibility" {
if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
UserId: user.ID,
UserId: userID,
Key: storepb.UserSettingKey_MEMO_VISIBILITY,
Value: &storepb.UserSetting_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) {
userID, err := ExtractUserIDFromName(request.Name)
userID, err := ExtractUserIDFromName(request.Parent)
if err != nil {
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
}
userAccessToken := &v1pb.UserAccessToken{
accessTokenResponse := &v1pb.UserAccessToken{
Name: fmt.Sprintf("users/%d/accessTokens/%s", userID, userAccessToken.AccessToken),
AccessToken: userAccessToken.AccessToken,
Description: userAccessToken.Description,
IssuedAt: timestamppb.New(claims.IssuedAt.Time),
}
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.
@ -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) {
userID, err := ExtractUserIDFromName(request.Name)
userID, err := ExtractUserIDFromName(request.Parent)
if err != nil {
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{}
if request.ExpiresAt != nil {
expiresAt = request.ExpiresAt.AsTime()
if request.AccessToken.ExpiresAt != nil {
expiresAt = request.AccessToken.ExpiresAt.AsTime()
}
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.
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)
}
userAccessToken := &v1pb.UserAccessToken{
Name: fmt.Sprintf("users/%d/accessTokens/%s", userID, accessToken),
AccessToken: accessToken,
Description: request.Description,
Description: request.AccessToken.Description,
IssuedAt: timestamppb.New(claims.IssuedAt.Time),
}
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) {
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 {
return nil, status.Errorf(codes.InvalidArgument, "invalid user name: %v", err)
}
accessTokenToDelete := parts[3]
currentUser, err := s.GetCurrentUser(ctx)
if err != nil {
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{}
for _, userAccessToken := range userAccessTokens {
if userAccessToken.AccessToken == request.AccessToken {
if userAccessToken.AccessToken == accessTokenToDelete {
continue
}
updatedUserAccessTokens = append(updatedUserAccessTokens, userAccessToken)
@ -528,6 +618,11 @@ func (s *APIV1Service) UpsertAccessTokenToStore(ctx context.Context, user *store
}
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{
Name: fmt.Sprintf("%s%d", UserNamePrefix, user.ID),
State: convertStateFromStore(user.RowStatus),
@ -536,9 +631,10 @@ func convertUserFromStore(user *store.User) *v1pb.User {
Role: convertUserRoleFromStore(user.Role),
Username: user.Username,
Email: user.Email,
Nickname: user.Nickname,
DisplayName: user.Nickname,
AvatarUrl: user.AvatarURL,
Description: user.Description,
Etag: etag,
}
// Use the avatar URL instead of raw base64 image data to reduce the response size.
if user.AvatarURL != "" {

@ -51,51 +51,28 @@ func (s *APIV1Service) ListAllUserStats(ctx context.Context, _ *v1pb.ListAllUser
if err != nil {
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 {
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
if workspaceMemoRelatedSetting.DisplayWithUpdateTime {
displayTs = memo.UpdatedTs
}
userStats := userStatsMap[creator]
userStats.MemoDisplayTimestamps = append(userStats.MemoDisplayTimestamps, timestamppb.New(time.Unix(displayTs, 0)))
// 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++
userMemoStatMap[memo.CreatorID] = &v1pb.UserStats{
Name: fmt.Sprintf("users/%d/stats", memo.CreatorID),
}
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.TotalMemoCount++
userMemoStatMap[memo.CreatorID].MemoDisplayTimestamps = append(userMemoStatMap[memo.CreatorID].MemoDisplayTimestamps, timestamppb.New(time.Unix(displayTs, 0)))
}
userStatsList := []*v1pb.UserStats{}
for _, userStats := range userStatsMap {
userStatsList = append(userStatsList, userStats)
userMemoStats := []*v1pb.UserStats{}
for _, userMemoStat := range userMemoStatMap {
userMemoStats = append(userMemoStats, userMemoStat)
}
return &v1pb.ListAllUserStatsResponse{
UserStats: userStatsList,
}, nil
response := &v1pb.ListAllUserStatsResponse{
UserStats: userMemoStats,
}
return response, nil
}
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 {
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 {
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
}
normalStatus := store.Normal
memoFind := &store.FindMemo{
CreatorID: &userID,
// Exclude comments by default.
ExcludeComments: true,
ExcludeContent: true,
CreatorID: &userID,
RowStatus: &normalStatus,
}
currentUser, err := s.GetCurrentUser(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
}
visibilities := []store.Visibility{store.Public}
if currentUser != nil {
visibilities = append(visibilities, store.Protected)
if currentUser.ID == user.ID {
visibilities = append(visibilities, store.Private)
}
if currentUser == nil {
memoFind.VisibilityList = []store.Visibility{store.Public}
} else if currentUser.ID != userID {
memoFind.VisibilityList = []store.Visibility{store.Public, store.Protected}
}
memoFind.VisibilityList = visibilities
memos, err := s.Store.ListMemos(ctx, memoFind)
if err != nil {
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 {
return nil, errors.Wrap(err, "failed to get workspace memo related setting")
}
userStats := &v1pb.UserStats{
Name: fmt.Sprintf("%s%d", UserNamePrefix, user.ID),
MemoDisplayTimestamps: []*timestamppb.Timestamp{},
MemoTypeStats: &v1pb.UserStats_MemoTypeStats{},
TagCount: map[string]int32{},
TotalMemoCount: int32(len(memos)),
}
displayTimestamps := []*timestamppb.Timestamp{}
tagCount := make(map[string]int32)
linkCount := int32(0)
codeCount := int32(0)
todoCount := int32(0)
undoCount := int32(0)
pinnedMemos := []string{}
for _, memo := range memos {
displayTs := memo.CreatedTs
if workspaceMemoRelatedSetting.DisplayWithUpdateTime {
displayTs = memo.UpdatedTs
}
userStats.MemoDisplayTimestamps = append(userStats.MemoDisplayTimestamps, timestamppb.New(time.Unix(displayTs, 0)))
// Handle duplicated tags.
for _, tag := range memo.Payload.Tags {
userStats.TagCount[tag]++
displayTimestamps = append(displayTimestamps, timestamppb.New(time.Unix(displayTs, 0)))
// Count different memo types based on content
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 {
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() {
userStats.MemoTypeStats.CodeCount++
}
if memo.Payload.Property.GetHasTaskList() {
userStats.MemoTypeStats.TodoCount++
}
if memo.Payload.Property.GetHasIncompleteTasks() {
userStats.MemoTypeStats.UndoCount++
pinnedMemos = append(pinnedMemos, fmt.Sprintf("users/%d/memos/%d", userID, memo.ID))
}
}
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
}

@ -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="flex flex-row justify-between items-center mb-4 gap-2 w-full">
<p>
{t("setting.account-section.change-password")} ({user.nickname})
{t("setting.account-section.change-password")} ({user.displayName})
</p>
<Button variant="plain" onClick={handleCloseBtnClick}>
<XIcon className="w-5 h-auto" />

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

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

@ -148,7 +148,7 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
to={`/u/${encodeURIComponent(creator.username)}`}
viewTransition
>
{creator.nickname || creator.username}
{creator.displayName || creator.username}
</Link>
<div
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 "";
}
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 (
`${users
.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()
);
};

@ -10,8 +10,8 @@ import { useTranslate } from "@/utils/i18n";
import showCreateAccessTokenDialog from "../CreateAccessTokenDialog";
import LearnMore from "../LearnMore";
const listAccessTokens = async (name: string) => {
const { accessTokens } = await userServiceClient.listUserAccessTokens({ name });
const listAccessTokens = async (parent: string) => {
const { accessTokens } = await userServiceClient.listUserAccessTokens({ parent });
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"));
};
const handleDeleteAccessToken = async (accessToken: string) => {
const formatedAccessToken = getFormatedAccessToken(accessToken);
const handleDeleteAccessToken = async (userAccessToken: UserAccessToken) => {
const formatedAccessToken = getFormatedAccessToken(userAccessToken.accessToken);
const confirmed = window.confirm(t("setting.access-token-section.access-token-deletion", { accessToken: formatedAccessToken }));
if (confirmed) {
await userServiceClient.deleteUserAccessToken({ name: currentUser.name, accessToken: accessToken });
setUserAccessTokens(userAccessTokens.filter((token) => token.accessToken !== accessToken));
await userServiceClient.deleteUserAccessToken({ name: userAccessToken.name });
setUserAccessTokens(userAccessTokens.filter((token) => token.accessToken !== userAccessToken.accessToken));
}
};
@ -116,7 +116,7 @@ const AccessTokenSection = () => {
<Button
variant="plain"
onClick={() => {
handleDeleteAccessToken(userAccessToken.accessToken);
handleDeleteAccessToken(userAccessToken);
}}
>
<TrashIcon className="text-red-600 w-4 h-auto" />

@ -109,7 +109,7 @@ const MemberSection = observer(() => {
};
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) {
await userServiceClient.updateUser({
user: {
@ -134,7 +134,7 @@ const MemberSection = observer(() => {
};
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) {
await userStore.deleteUser(user.name);
fetchUsers();
@ -209,7 +209,7 @@ const MemberSection = observer(() => {
<span className="ml-1 italic">{user.state === State.ARCHIVED && "(Archived)"}</span>
</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="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium flex justify-end">
{currentUser?.name === user.name ? (

@ -19,7 +19,7 @@ const MyAccountSection = () => {
<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">
<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>
</p>
<p className="w-4/5 leading-tight text-sm truncate">{user.description}</p>

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

@ -40,7 +40,7 @@ const UserBanner = (props: Props) => {
)}
{!collapsed && (
<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>
)}
</div>

@ -90,7 +90,7 @@ const UserProfile = observer(() => {
<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">
<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 className="w-full text-gray-500 leading-snug dark:text-gray-400 whitespace-pre-wrap truncate line-clamp-6">
{user.description}

@ -71,9 +71,15 @@ const userStore = (() => {
return userMap[name];
}
}
const user = await userServiceClient.getUserByUsername({
username,
// Use search instead of the deprecated getUserByUsername
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({
userMapByName: {
...userMap,
@ -122,8 +128,16 @@ const userStore = (() => {
};
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({
setting: userSetting,
setting: settingWithName,
updateMask: updateMask,
});
state.setPartial({
@ -181,6 +195,7 @@ const userStore = (() => {
}
state.setPartial({
userStatsByName: {
...state.userStatsByName,
...userStatsByName,
},
});
@ -210,7 +225,7 @@ const userStore = (() => {
export const initialUserStore = async () => {
try {
const currentUser = await authServiceClient.getAuthStatus({});
const userSetting = await userServiceClient.getUserSetting({});
const userSetting = await userServiceClient.getUserSetting({ name: currentUser.name });
userStore.state.setPartial({
currentUser: currentUser.name,
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