user_service.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. package v2
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "strings"
  7. "time"
  8. "github.com/golang-jwt/jwt/v5"
  9. "github.com/labstack/echo/v4"
  10. "github.com/pkg/errors"
  11. "golang.org/x/crypto/bcrypt"
  12. "golang.org/x/exp/slices"
  13. "google.golang.org/grpc/codes"
  14. "google.golang.org/grpc/status"
  15. "google.golang.org/protobuf/types/known/timestamppb"
  16. "github.com/usememos/memos/api/auth"
  17. "github.com/usememos/memos/internal/util"
  18. apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
  19. storepb "github.com/usememos/memos/proto/gen/store"
  20. "github.com/usememos/memos/store"
  21. )
  22. func (s *APIV2Service) ListUsers(ctx context.Context, _ *apiv2pb.ListUsersRequest) (*apiv2pb.ListUsersResponse, error) {
  23. currentUser, err := getCurrentUser(ctx, s.Store)
  24. if err != nil {
  25. return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
  26. }
  27. if currentUser.Role != store.RoleHost && currentUser.Role != store.RoleAdmin {
  28. return nil, status.Errorf(codes.PermissionDenied, "permission denied")
  29. }
  30. users, err := s.Store.ListUsers(ctx, &store.FindUser{})
  31. if err != nil {
  32. return nil, status.Errorf(codes.Internal, "failed to list users: %v", err)
  33. }
  34. response := &apiv2pb.ListUsersResponse{
  35. Users: []*apiv2pb.User{},
  36. }
  37. for _, user := range users {
  38. response.Users = append(response.Users, convertUserFromStore(user))
  39. }
  40. return response, nil
  41. }
  42. func (s *APIV2Service) GetUser(ctx context.Context, request *apiv2pb.GetUserRequest) (*apiv2pb.GetUserResponse, error) {
  43. username, err := ExtractUsernameFromName(request.Name)
  44. if err != nil {
  45. return nil, status.Errorf(codes.InvalidArgument, "name is required")
  46. }
  47. user, err := s.Store.GetUser(ctx, &store.FindUser{
  48. Username: &username,
  49. })
  50. if err != nil {
  51. return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
  52. }
  53. if user == nil {
  54. return nil, status.Errorf(codes.NotFound, "user not found")
  55. }
  56. userMessage := convertUserFromStore(user)
  57. response := &apiv2pb.GetUserResponse{
  58. User: userMessage,
  59. }
  60. return response, nil
  61. }
  62. func (s *APIV2Service) CreateUser(ctx context.Context, request *apiv2pb.CreateUserRequest) (*apiv2pb.CreateUserResponse, error) {
  63. currentUser, err := getCurrentUser(ctx, s.Store)
  64. if err != nil {
  65. return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
  66. }
  67. if currentUser.Role != store.RoleHost {
  68. return nil, status.Errorf(codes.PermissionDenied, "permission denied")
  69. }
  70. username, err := ExtractUsernameFromName(request.User.Name)
  71. if err != nil {
  72. return nil, status.Errorf(codes.InvalidArgument, "name is required")
  73. }
  74. if !util.ResourceNameMatcher.MatchString(strings.ToLower(username)) {
  75. return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", username)
  76. }
  77. passwordHash, err := bcrypt.GenerateFromPassword([]byte(request.User.Password), bcrypt.DefaultCost)
  78. if err != nil {
  79. return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to generate password hash").SetInternal(err)
  80. }
  81. user, err := s.Store.CreateUser(ctx, &store.User{
  82. Username: username,
  83. Role: convertUserRoleToStore(request.User.Role),
  84. Email: request.User.Email,
  85. Nickname: request.User.Nickname,
  86. PasswordHash: string(passwordHash),
  87. })
  88. if err != nil {
  89. return nil, status.Errorf(codes.Internal, "failed to create user: %v", err)
  90. }
  91. response := &apiv2pb.CreateUserResponse{
  92. User: convertUserFromStore(user),
  93. }
  94. return response, nil
  95. }
  96. func (s *APIV2Service) UpdateUser(ctx context.Context, request *apiv2pb.UpdateUserRequest) (*apiv2pb.UpdateUserResponse, error) {
  97. username, err := ExtractUsernameFromName(request.User.Name)
  98. if err != nil {
  99. return nil, status.Errorf(codes.InvalidArgument, "name is required")
  100. }
  101. currentUser, err := getCurrentUser(ctx, s.Store)
  102. if err != nil {
  103. return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
  104. }
  105. if currentUser.Username != username && currentUser.Role != store.RoleAdmin && currentUser.Role != store.RoleHost {
  106. return nil, status.Errorf(codes.PermissionDenied, "permission denied")
  107. }
  108. if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 {
  109. return nil, status.Errorf(codes.InvalidArgument, "update mask is empty")
  110. }
  111. user, err := s.Store.GetUser(ctx, &store.FindUser{Username: &username})
  112. if err != nil {
  113. return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
  114. }
  115. if user == nil {
  116. return nil, status.Errorf(codes.NotFound, "user not found")
  117. }
  118. currentTs := time.Now().Unix()
  119. update := &store.UpdateUser{
  120. ID: user.ID,
  121. UpdatedTs: &currentTs,
  122. }
  123. for _, field := range request.UpdateMask.Paths {
  124. if field == "username" {
  125. if !util.ResourceNameMatcher.MatchString(strings.ToLower(request.User.Username)) {
  126. return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", request.User.Username)
  127. }
  128. update.Username = &request.User.Username
  129. } else if field == "nickname" {
  130. update.Nickname = &request.User.Nickname
  131. } else if field == "email" {
  132. update.Email = &request.User.Email
  133. } else if field == "avatar_url" {
  134. update.AvatarURL = &request.User.AvatarUrl
  135. } else if field == "role" {
  136. role := convertUserRoleToStore(request.User.Role)
  137. update.Role = &role
  138. } else if field == "password" {
  139. passwordHash, err := bcrypt.GenerateFromPassword([]byte(request.User.Password), bcrypt.DefaultCost)
  140. if err != nil {
  141. return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to generate password hash").SetInternal(err)
  142. }
  143. passwordHashStr := string(passwordHash)
  144. update.PasswordHash = &passwordHashStr
  145. } else if field == "row_status" {
  146. rowStatus := convertRowStatusToStore(request.User.RowStatus)
  147. update.RowStatus = &rowStatus
  148. } else {
  149. return nil, status.Errorf(codes.InvalidArgument, "invalid update path: %s", field)
  150. }
  151. }
  152. updatedUser, err := s.Store.UpdateUser(ctx, update)
  153. if err != nil {
  154. return nil, status.Errorf(codes.Internal, "failed to update user: %v", err)
  155. }
  156. response := &apiv2pb.UpdateUserResponse{
  157. User: convertUserFromStore(updatedUser),
  158. }
  159. return response, nil
  160. }
  161. func (s *APIV2Service) DeleteUser(ctx context.Context, request *apiv2pb.DeleteUserRequest) (*apiv2pb.DeleteUserResponse, error) {
  162. username, err := ExtractUsernameFromName(request.Name)
  163. if err != nil {
  164. return nil, status.Errorf(codes.InvalidArgument, "name is required")
  165. }
  166. currentUser, err := getCurrentUser(ctx, s.Store)
  167. if err != nil {
  168. return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
  169. }
  170. if currentUser.Username != username && currentUser.Role != store.RoleAdmin && currentUser.Role != store.RoleHost {
  171. return nil, status.Errorf(codes.PermissionDenied, "permission denied")
  172. }
  173. user, err := s.Store.GetUser(ctx, &store.FindUser{Username: &username})
  174. if err != nil {
  175. return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
  176. }
  177. if user == nil {
  178. return nil, status.Errorf(codes.NotFound, "user not found")
  179. }
  180. if err := s.Store.DeleteUser(ctx, &store.DeleteUser{
  181. ID: user.ID,
  182. }); err != nil {
  183. return nil, status.Errorf(codes.Internal, "failed to delete user: %v", err)
  184. }
  185. return &apiv2pb.DeleteUserResponse{}, nil
  186. }
  187. func getDefaultUserSetting() *apiv2pb.UserSetting {
  188. return &apiv2pb.UserSetting{
  189. Locale: "en",
  190. Appearance: "system",
  191. MemoVisibility: "PRIVATE",
  192. }
  193. }
  194. func (s *APIV2Service) GetUserSetting(ctx context.Context, _ *apiv2pb.GetUserSettingRequest) (*apiv2pb.GetUserSettingResponse, error) {
  195. user, err := getCurrentUser(ctx, s.Store)
  196. if err != nil {
  197. return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
  198. }
  199. userSettings, err := s.Store.ListUserSettings(ctx, &store.FindUserSetting{
  200. UserID: &user.ID,
  201. })
  202. if err != nil {
  203. return nil, status.Errorf(codes.Internal, "failed to list user settings: %v", err)
  204. }
  205. userSettingMessage := getDefaultUserSetting()
  206. for _, setting := range userSettings {
  207. if setting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE {
  208. userSettingMessage.Locale = setting.GetLocale()
  209. } else if setting.Key == storepb.UserSettingKey_USER_SETTING_APPEARANCE {
  210. userSettingMessage.Appearance = setting.GetAppearance()
  211. } else if setting.Key == storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY {
  212. userSettingMessage.MemoVisibility = setting.GetMemoVisibility()
  213. } else if setting.Key == storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID {
  214. userSettingMessage.TelegramUserId = setting.GetTelegramUserId()
  215. }
  216. }
  217. return &apiv2pb.GetUserSettingResponse{
  218. Setting: userSettingMessage,
  219. }, nil
  220. }
  221. func (s *APIV2Service) UpdateUserSetting(ctx context.Context, request *apiv2pb.UpdateUserSettingRequest) (*apiv2pb.UpdateUserSettingResponse, error) {
  222. user, err := getCurrentUser(ctx, s.Store)
  223. if err != nil {
  224. return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
  225. }
  226. if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 {
  227. return nil, status.Errorf(codes.InvalidArgument, "update mask is empty")
  228. }
  229. for _, field := range request.UpdateMask.Paths {
  230. if field == "locale" {
  231. if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
  232. UserId: user.ID,
  233. Key: storepb.UserSettingKey_USER_SETTING_LOCALE,
  234. Value: &storepb.UserSetting_Locale{
  235. Locale: request.Setting.Locale,
  236. },
  237. }); err != nil {
  238. return nil, status.Errorf(codes.Internal, "failed to upsert user setting: %v", err)
  239. }
  240. } else if field == "appearance" {
  241. if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
  242. UserId: user.ID,
  243. Key: storepb.UserSettingKey_USER_SETTING_APPEARANCE,
  244. Value: &storepb.UserSetting_Appearance{
  245. Appearance: request.Setting.Appearance,
  246. },
  247. }); err != nil {
  248. return nil, status.Errorf(codes.Internal, "failed to upsert user setting: %v", err)
  249. }
  250. } else if field == "memo_visibility" {
  251. if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
  252. UserId: user.ID,
  253. Key: storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY,
  254. Value: &storepb.UserSetting_MemoVisibility{
  255. MemoVisibility: request.Setting.MemoVisibility,
  256. },
  257. }); err != nil {
  258. return nil, status.Errorf(codes.Internal, "failed to upsert user setting: %v", err)
  259. }
  260. } else if field == "telegram_user_id" {
  261. if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
  262. UserId: user.ID,
  263. Key: storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID,
  264. Value: &storepb.UserSetting_TelegramUserId{
  265. TelegramUserId: request.Setting.TelegramUserId,
  266. },
  267. }); err != nil {
  268. return nil, status.Errorf(codes.Internal, "failed to upsert user setting: %v", err)
  269. }
  270. } else {
  271. return nil, status.Errorf(codes.InvalidArgument, "invalid update path: %s", field)
  272. }
  273. }
  274. userSettingResponse, err := s.GetUserSetting(ctx, &apiv2pb.GetUserSettingRequest{})
  275. if err != nil {
  276. return nil, status.Errorf(codes.Internal, "failed to get user setting: %v", err)
  277. }
  278. return &apiv2pb.UpdateUserSettingResponse{
  279. Setting: userSettingResponse.Setting,
  280. }, nil
  281. }
  282. func (s *APIV2Service) ListUserAccessTokens(ctx context.Context, request *apiv2pb.ListUserAccessTokensRequest) (*apiv2pb.ListUserAccessTokensResponse, error) {
  283. user, err := getCurrentUser(ctx, s.Store)
  284. if err != nil {
  285. return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
  286. }
  287. if user == nil {
  288. return nil, status.Errorf(codes.PermissionDenied, "permission denied")
  289. }
  290. userID := user.ID
  291. username, err := ExtractUsernameFromName(request.Name)
  292. if err != nil {
  293. return nil, status.Errorf(codes.InvalidArgument, "name is required")
  294. }
  295. // List access token for other users need to be verified.
  296. if user.Username != username {
  297. // Normal users can only list their access tokens.
  298. if user.Role == store.RoleUser {
  299. return nil, status.Errorf(codes.PermissionDenied, "permission denied")
  300. }
  301. // The request user must be exist.
  302. requestUser, err := s.Store.GetUser(ctx, &store.FindUser{Username: &username})
  303. if requestUser == nil || err != nil {
  304. return nil, status.Errorf(codes.NotFound, "fail to find user %s", username)
  305. }
  306. userID = requestUser.ID
  307. }
  308. userAccessTokens, err := s.Store.GetUserAccessTokens(ctx, userID)
  309. if err != nil {
  310. return nil, status.Errorf(codes.Internal, "failed to list access tokens: %v", err)
  311. }
  312. accessTokens := []*apiv2pb.UserAccessToken{}
  313. for _, userAccessToken := range userAccessTokens {
  314. claims := &auth.ClaimsMessage{}
  315. _, err := jwt.ParseWithClaims(userAccessToken.AccessToken, claims, func(t *jwt.Token) (any, error) {
  316. if t.Method.Alg() != jwt.SigningMethodHS256.Name {
  317. return nil, errors.Errorf("unexpected access token signing method=%v, expect %v", t.Header["alg"], jwt.SigningMethodHS256)
  318. }
  319. if kid, ok := t.Header["kid"].(string); ok {
  320. if kid == "v1" {
  321. return []byte(s.Secret), nil
  322. }
  323. }
  324. return nil, errors.Errorf("unexpected access token kid=%v", t.Header["kid"])
  325. })
  326. if err != nil {
  327. // If the access token is invalid or expired, just ignore it.
  328. continue
  329. }
  330. userAccessToken := &apiv2pb.UserAccessToken{
  331. AccessToken: userAccessToken.AccessToken,
  332. Description: userAccessToken.Description,
  333. IssuedAt: timestamppb.New(claims.IssuedAt.Time),
  334. }
  335. if claims.ExpiresAt != nil {
  336. userAccessToken.ExpiresAt = timestamppb.New(claims.ExpiresAt.Time)
  337. }
  338. accessTokens = append(accessTokens, userAccessToken)
  339. }
  340. // Sort by issued time in descending order.
  341. slices.SortFunc(accessTokens, func(i, j *apiv2pb.UserAccessToken) int {
  342. return int(i.IssuedAt.Seconds - j.IssuedAt.Seconds)
  343. })
  344. response := &apiv2pb.ListUserAccessTokensResponse{
  345. AccessTokens: accessTokens,
  346. }
  347. return response, nil
  348. }
  349. func (s *APIV2Service) CreateUserAccessToken(ctx context.Context, request *apiv2pb.CreateUserAccessTokenRequest) (*apiv2pb.CreateUserAccessTokenResponse, error) {
  350. user, err := getCurrentUser(ctx, s.Store)
  351. if err != nil {
  352. return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
  353. }
  354. expiresAt := time.Time{}
  355. if request.ExpiresAt != nil {
  356. expiresAt = request.ExpiresAt.AsTime()
  357. }
  358. accessToken, err := auth.GenerateAccessToken(user.Username, user.ID, expiresAt, []byte(s.Secret))
  359. if err != nil {
  360. return nil, status.Errorf(codes.Internal, "failed to generate access token: %v", err)
  361. }
  362. claims := &auth.ClaimsMessage{}
  363. _, err = jwt.ParseWithClaims(accessToken, claims, func(t *jwt.Token) (any, error) {
  364. if t.Method.Alg() != jwt.SigningMethodHS256.Name {
  365. return nil, errors.Errorf("unexpected access token signing method=%v, expect %v", t.Header["alg"], jwt.SigningMethodHS256)
  366. }
  367. if kid, ok := t.Header["kid"].(string); ok {
  368. if kid == "v1" {
  369. return []byte(s.Secret), nil
  370. }
  371. }
  372. return nil, errors.Errorf("unexpected access token kid=%v", t.Header["kid"])
  373. })
  374. if err != nil {
  375. return nil, status.Errorf(codes.Internal, "failed to parse access token: %v", err)
  376. }
  377. // Upsert the access token to user setting store.
  378. if err := s.UpsertAccessTokenToStore(ctx, user, accessToken, request.Description); err != nil {
  379. return nil, status.Errorf(codes.Internal, "failed to upsert access token to store: %v", err)
  380. }
  381. userAccessToken := &apiv2pb.UserAccessToken{
  382. AccessToken: accessToken,
  383. Description: request.Description,
  384. IssuedAt: timestamppb.New(claims.IssuedAt.Time),
  385. }
  386. if claims.ExpiresAt != nil {
  387. userAccessToken.ExpiresAt = timestamppb.New(claims.ExpiresAt.Time)
  388. }
  389. response := &apiv2pb.CreateUserAccessTokenResponse{
  390. AccessToken: userAccessToken,
  391. }
  392. return response, nil
  393. }
  394. func (s *APIV2Service) DeleteUserAccessToken(ctx context.Context, request *apiv2pb.DeleteUserAccessTokenRequest) (*apiv2pb.DeleteUserAccessTokenResponse, error) {
  395. user, err := getCurrentUser(ctx, s.Store)
  396. if err != nil {
  397. return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err)
  398. }
  399. userAccessTokens, err := s.Store.GetUserAccessTokens(ctx, user.ID)
  400. if err != nil {
  401. return nil, status.Errorf(codes.Internal, "failed to list access tokens: %v", err)
  402. }
  403. updatedUserAccessTokens := []*storepb.AccessTokensUserSetting_AccessToken{}
  404. for _, userAccessToken := range userAccessTokens {
  405. if userAccessToken.AccessToken == request.AccessToken {
  406. continue
  407. }
  408. updatedUserAccessTokens = append(updatedUserAccessTokens, userAccessToken)
  409. }
  410. if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
  411. UserId: user.ID,
  412. Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS,
  413. Value: &storepb.UserSetting_AccessTokens{
  414. AccessTokens: &storepb.AccessTokensUserSetting{
  415. AccessTokens: updatedUserAccessTokens,
  416. },
  417. },
  418. }); err != nil {
  419. return nil, status.Errorf(codes.Internal, "failed to upsert user setting: %v", err)
  420. }
  421. return &apiv2pb.DeleteUserAccessTokenResponse{}, nil
  422. }
  423. func (s *APIV2Service) UpsertAccessTokenToStore(ctx context.Context, user *store.User, accessToken, description string) error {
  424. userAccessTokens, err := s.Store.GetUserAccessTokens(ctx, user.ID)
  425. if err != nil {
  426. return errors.Wrap(err, "failed to get user access tokens")
  427. }
  428. userAccessToken := storepb.AccessTokensUserSetting_AccessToken{
  429. AccessToken: accessToken,
  430. Description: description,
  431. }
  432. userAccessTokens = append(userAccessTokens, &userAccessToken)
  433. if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
  434. UserId: user.ID,
  435. Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS,
  436. Value: &storepb.UserSetting_AccessTokens{
  437. AccessTokens: &storepb.AccessTokensUserSetting{
  438. AccessTokens: userAccessTokens,
  439. },
  440. },
  441. }); err != nil {
  442. return errors.Wrap(err, "failed to upsert user setting")
  443. }
  444. return nil
  445. }
  446. func convertUserFromStore(user *store.User) *apiv2pb.User {
  447. return &apiv2pb.User{
  448. Name: fmt.Sprintf("%s%s", UserNamePrefix, user.Username),
  449. Id: user.ID,
  450. RowStatus: convertRowStatusFromStore(user.RowStatus),
  451. CreateTime: timestamppb.New(time.Unix(user.CreatedTs, 0)),
  452. UpdateTime: timestamppb.New(time.Unix(user.UpdatedTs, 0)),
  453. Role: convertUserRoleFromStore(user.Role),
  454. Username: user.Username,
  455. Email: user.Email,
  456. Nickname: user.Nickname,
  457. AvatarUrl: user.AvatarURL,
  458. }
  459. }
  460. func convertUserRoleFromStore(role store.Role) apiv2pb.User_Role {
  461. switch role {
  462. case store.RoleHost:
  463. return apiv2pb.User_HOST
  464. case store.RoleAdmin:
  465. return apiv2pb.User_ADMIN
  466. case store.RoleUser:
  467. return apiv2pb.User_USER
  468. default:
  469. return apiv2pb.User_ROLE_UNSPECIFIED
  470. }
  471. }
  472. func convertUserRoleToStore(role apiv2pb.User_Role) store.Role {
  473. switch role {
  474. case apiv2pb.User_HOST:
  475. return store.RoleHost
  476. case apiv2pb.User_ADMIN:
  477. return store.RoleAdmin
  478. case apiv2pb.User_USER:
  479. return store.RoleUser
  480. default:
  481. return store.RoleUser
  482. }
  483. }