user_setting.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package store
  2. import (
  3. "context"
  4. "github.com/pkg/errors"
  5. "google.golang.org/protobuf/encoding/protojson"
  6. storepb "github.com/usememos/memos/proto/gen/store"
  7. )
  8. type UserSetting struct {
  9. UserID int32
  10. Key storepb.UserSettingKey
  11. Value string
  12. }
  13. type FindUserSetting struct {
  14. UserID *int32
  15. Key storepb.UserSettingKey
  16. }
  17. func (s *Store) UpsertUserSetting(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) {
  18. userSettingRaw, err := convertUserSettingToRaw(upsert)
  19. if err != nil {
  20. return nil, err
  21. }
  22. userSettingRaw, err = s.driver.UpsertUserSetting(ctx, userSettingRaw)
  23. if err != nil {
  24. return nil, err
  25. }
  26. userSetting, err := convertUserSettingFromRaw(userSettingRaw)
  27. if err != nil {
  28. return nil, err
  29. }
  30. if userSetting == nil {
  31. return nil, errors.New("unexpected nil user setting")
  32. }
  33. s.userSettingCache.Store(getUserSettingCacheKey(userSetting.UserId, userSetting.Key.String()), userSetting)
  34. return userSetting, nil
  35. }
  36. func (s *Store) ListUserSettings(ctx context.Context, find *FindUserSetting) ([]*storepb.UserSetting, error) {
  37. userSettingRawList, err := s.driver.ListUserSettings(ctx, find)
  38. if err != nil {
  39. return nil, err
  40. }
  41. userSettings := []*storepb.UserSetting{}
  42. for _, userSettingRaw := range userSettingRawList {
  43. userSetting, err := convertUserSettingFromRaw(userSettingRaw)
  44. if err != nil {
  45. return nil, err
  46. }
  47. if userSetting == nil {
  48. continue
  49. }
  50. s.userSettingCache.Store(getUserSettingCacheKey(userSetting.UserId, userSetting.Key.String()), userSetting)
  51. userSettings = append(userSettings, userSetting)
  52. }
  53. return userSettings, nil
  54. }
  55. func (s *Store) GetUserSetting(ctx context.Context, find *FindUserSetting) (*storepb.UserSetting, error) {
  56. if find.UserID != nil {
  57. if cache, ok := s.userSettingCache.Load(getUserSettingCacheKey(*find.UserID, find.Key.String())); ok {
  58. userSetting, ok := cache.(*storepb.UserSetting)
  59. if ok {
  60. return userSetting, nil
  61. }
  62. }
  63. }
  64. list, err := s.ListUserSettings(ctx, find)
  65. if err != nil {
  66. return nil, err
  67. }
  68. if len(list) == 0 {
  69. return nil, nil
  70. }
  71. if len(list) > 1 {
  72. return nil, errors.Errorf("expected 1 user setting, but got %d", len(list))
  73. }
  74. userSetting := list[0]
  75. s.userSettingCache.Store(getUserSettingCacheKey(userSetting.UserId, userSetting.Key.String()), userSetting)
  76. return userSetting, nil
  77. }
  78. // GetUserAccessTokens returns the access tokens of the user.
  79. func (s *Store) GetUserAccessTokens(ctx context.Context, userID int32) ([]*storepb.AccessTokensUserSetting_AccessToken, error) {
  80. userSetting, err := s.GetUserSetting(ctx, &FindUserSetting{
  81. UserID: &userID,
  82. Key: storepb.UserSettingKey_ACCESS_TOKENS,
  83. })
  84. if err != nil {
  85. return nil, err
  86. }
  87. if userSetting == nil {
  88. return []*storepb.AccessTokensUserSetting_AccessToken{}, nil
  89. }
  90. accessTokensUserSetting := userSetting.GetAccessTokens()
  91. return accessTokensUserSetting.AccessTokens, nil
  92. }
  93. // RemoveUserAccessToken remove the access token of the user.
  94. func (s *Store) RemoveUserAccessToken(ctx context.Context, userID int32, token string) error {
  95. oldAccessTokens, err := s.GetUserAccessTokens(ctx, userID)
  96. if err != nil {
  97. return err
  98. }
  99. newAccessTokens := make([]*storepb.AccessTokensUserSetting_AccessToken, 0, len(oldAccessTokens))
  100. for _, t := range oldAccessTokens {
  101. if token != t.AccessToken {
  102. newAccessTokens = append(newAccessTokens, t)
  103. }
  104. }
  105. _, err = s.UpsertUserSetting(ctx, &storepb.UserSetting{
  106. UserId: userID,
  107. Key: storepb.UserSettingKey_ACCESS_TOKENS,
  108. Value: &storepb.UserSetting_AccessTokens{
  109. AccessTokens: &storepb.AccessTokensUserSetting{
  110. AccessTokens: newAccessTokens,
  111. },
  112. },
  113. })
  114. return err
  115. }
  116. func convertUserSettingFromRaw(raw *UserSetting) (*storepb.UserSetting, error) {
  117. userSetting := &storepb.UserSetting{
  118. UserId: raw.UserID,
  119. Key: raw.Key,
  120. }
  121. switch raw.Key {
  122. case storepb.UserSettingKey_ACCESS_TOKENS:
  123. accessTokensUserSetting := &storepb.AccessTokensUserSetting{}
  124. if err := protojsonUnmarshaler.Unmarshal([]byte(raw.Value), accessTokensUserSetting); err != nil {
  125. return nil, err
  126. }
  127. userSetting.Value = &storepb.UserSetting_AccessTokens{AccessTokens: accessTokensUserSetting}
  128. case storepb.UserSettingKey_LOCALE:
  129. userSetting.Value = &storepb.UserSetting_Locale{Locale: raw.Value}
  130. case storepb.UserSettingKey_APPEARANCE:
  131. userSetting.Value = &storepb.UserSetting_Appearance{Appearance: raw.Value}
  132. case storepb.UserSettingKey_MEMO_VISIBILITY:
  133. userSetting.Value = &storepb.UserSetting_MemoVisibility{MemoVisibility: raw.Value}
  134. default:
  135. return nil, nil
  136. }
  137. return userSetting, nil
  138. }
  139. func convertUserSettingToRaw(userSetting *storepb.UserSetting) (*UserSetting, error) {
  140. raw := &UserSetting{
  141. UserID: userSetting.UserId,
  142. Key: userSetting.Key,
  143. }
  144. switch userSetting.Key {
  145. case storepb.UserSettingKey_ACCESS_TOKENS:
  146. accessTokensUserSetting := userSetting.GetAccessTokens()
  147. value, err := protojson.Marshal(accessTokensUserSetting)
  148. if err != nil {
  149. return nil, err
  150. }
  151. raw.Value = string(value)
  152. case storepb.UserSettingKey_LOCALE:
  153. raw.Value = userSetting.GetLocale()
  154. case storepb.UserSettingKey_APPEARANCE:
  155. raw.Value = userSetting.GetAppearance()
  156. case storepb.UserSettingKey_MEMO_VISIBILITY:
  157. raw.Value = userSetting.GetMemoVisibility()
  158. default:
  159. return nil, errors.Errorf("unsupported user setting key: %v", userSetting.Key)
  160. }
  161. return raw, nil
  162. }