support user features restrictions

This commit is contained in:
MaysWind
2024-11-10 01:44:58 +08:00
parent b8253b6dcc
commit 1f159bf826
11 changed files with 289 additions and 0 deletions
+8
View File
@@ -147,6 +147,10 @@ func (a *DataManagementsApi) ClearDataHandler(c *core.WebContext) (any, *errs.Er
return nil, errs.ErrUserPasswordWrong
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_CLEAR_ALL_DATA) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
err = a.templates.DeleteAllTemplates(c, uid)
if err != nil {
@@ -204,6 +208,10 @@ func (a *DataManagementsApi) getExportedFileContent(c *core.WebContext, fileType
return nil, "", errs.ErrUserNotFound
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_EXPORT_TRANSACTION) {
return nil, "", errs.ErrNotPermittedToPerformThisAction
}
accounts, err := a.accounts.GetAllAccountsByUid(c, uid)
if err != nil {
+8
View File
@@ -56,6 +56,10 @@ func (a *ForgetPasswordsApi) UserForgetPasswordRequestHandler(c *core.WebContext
return nil, errs.ErrUserIsDisabled
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_FORGET_PASSWORD) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
if a.CurrentConfig().ForgetPasswordRequireVerifyEmail && !user.EmailVerified {
log.Warnf(c, "[forget_passwords.UserForgetPasswordRequestHandler] user \"uid:%d\" has not verified email", user.Uid)
return nil, errs.ErrEmailIsNotVerified
@@ -109,6 +113,10 @@ func (a *ForgetPasswordsApi) UserResetPasswordHandler(c *core.WebContext) (any,
return nil, errs.ErrUserIsDisabled
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_FORGET_PASSWORD) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
if a.CurrentConfig().ForgetPasswordRequireVerifyEmail && !user.EmailVerified {
log.Warnf(c, "[forget_passwords.UserResetPasswordHandler] user \"uid:%d\" has not verified email", user.Uid)
return nil, errs.ErrEmailIsNotVerified
+34
View File
@@ -135,6 +135,22 @@ func (a *TokensApi) TokenRevokeHandler(c *core.WebContext) (any, *errs.Error) {
return nil, errs.ErrInvalidTokenId
}
if utils.Int64ToString(tokenRecord.UserTokenId) != c.GetTokenClaims().UserTokenId || tokenRecord.CreatedUnixTime != c.GetTokenClaims().IssuedAt {
user, err := a.users.GetUserById(c, uid)
if err != nil {
if !errs.IsCustomError(err) {
log.Errorf(c, "[token.TokenRevokeHandler] failed to get user, because %s", err.Error())
}
return nil, errs.ErrUserNotFound
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_REVOKE_OTHER_SESSION) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
}
err = a.tokens.DeleteToken(c, tokenRecord)
if err != nil {
@@ -170,6 +186,24 @@ func (a *TokensApi) TokenRevokeAllHandler(c *core.WebContext) (any, *errs.Error)
tokens = append(tokens[:currentTokenIndex], tokens[currentTokenIndex+1:]...)
if len(tokens) < 1 {
return nil, errs.ErrTokenRecordNotFound
}
user, err := a.users.GetUserById(c, uid)
if err != nil {
if !errs.IsCustomError(err) {
log.Errorf(c, "[token.TokenRevokeAllHandler] failed to get user, because %s", err.Error())
}
return nil, errs.ErrUserNotFound
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_REVOKE_OTHER_SESSION) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
err = a.tokens.DeleteTokens(c, uid, tokens)
if err != nil {
+8
View File
@@ -1077,6 +1077,10 @@ func (a *TransactionsApi) TransactionParseImportFileHandler(c *core.WebContext)
return nil, errs.ErrUserNotFound
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_IMPORT_TRANSACTION) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
accounts, err := a.accounts.GetAllAccountsByUid(c, user.Uid)
if err != nil {
@@ -1201,6 +1205,10 @@ func (a *TransactionsApi) TransactionImportHandler(c *core.WebContext) (any, *er
return nil, errs.ErrUserNotFound
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_IMPORT_TRANSACTION) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
newTransactions := make([]*models.Transaction, len(transactionImportReq.Transactions))
for i := 0; i < len(transactionImportReq.Transactions); i++ {
+12
View File
@@ -81,6 +81,10 @@ func (a *TwoFactorAuthorizationsApi) TwoFactorEnableRequestHandler(c *core.WebCo
return nil, errs.ErrUserNotFound
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_ENABLE_2FA) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
key, err := a.twoFactorAuthorizations.GenerateTwoFactorSecret(c, user)
if err != nil {
@@ -141,6 +145,10 @@ func (a *TwoFactorAuthorizationsApi) TwoFactorEnableConfirmHandler(c *core.WebCo
return nil, errs.ErrUserNotFound
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_ENABLE_2FA) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
twoFactorSetting := &models.TwoFactor{
Uid: uid,
Secret: confirmReq.Secret,
@@ -229,6 +237,10 @@ func (a *TwoFactorAuthorizationsApi) TwoFactorDisableHandler(c *core.WebContext)
return nil, errs.ErrUserNotFound
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_DISABLE_2FA) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
if !a.users.IsPasswordEqualsUserPassword(disableReq.Password, user) {
return nil, errs.ErrUserPasswordWrong
}
+37
View File
@@ -251,6 +251,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
userUpdateReq.Email = strings.TrimSpace(userUpdateReq.Email)
userUpdateReq.Nickname = strings.TrimSpace(userUpdateReq.Nickname)
modifyProfileBasicInfo := false
anythingUpdate := false
userNew := &models.User{
Uid: user.Uid,
@@ -258,12 +259,20 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
}
if userUpdateReq.Email != "" && userUpdateReq.Email != user.Email {
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_UPDATE_EMAIL) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
user.Email = userUpdateReq.Email
userNew.Email = userUpdateReq.Email
anythingUpdate = true
}
if userUpdateReq.Password != "" {
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_UPDATE_PASSWORD) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
if !a.users.IsPasswordEqualsUserPassword(userUpdateReq.OldPassword, user) {
return nil, errs.ErrUserPasswordWrong
}
@@ -277,6 +286,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
if userUpdateReq.Nickname != "" && userUpdateReq.Nickname != user.Nickname {
user.Nickname = userUpdateReq.Nickname
userNew.Nickname = userUpdateReq.Nickname
modifyProfileBasicInfo = true
anythingUpdate = true
}
@@ -299,12 +309,14 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
user.DefaultAccountId = userUpdateReq.DefaultAccountId
userNew.DefaultAccountId = userUpdateReq.DefaultAccountId
modifyProfileBasicInfo = true
anythingUpdate = true
}
if userUpdateReq.TransactionEditScope != nil && *userUpdateReq.TransactionEditScope != user.TransactionEditScope {
user.TransactionEditScope = *userUpdateReq.TransactionEditScope
userNew.TransactionEditScope = *userUpdateReq.TransactionEditScope
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.TransactionEditScope = models.TRANSACTION_EDIT_SCOPE_INVALID
@@ -316,18 +328,21 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
user.Language = userUpdateReq.Language
userNew.Language = userUpdateReq.Language
modifyUserLanguage = true
modifyProfileBasicInfo = true
anythingUpdate = true
}
if userUpdateReq.DefaultCurrency != "" && userUpdateReq.DefaultCurrency != user.DefaultCurrency {
user.DefaultCurrency = userUpdateReq.DefaultCurrency
userNew.DefaultCurrency = userUpdateReq.DefaultCurrency
modifyProfileBasicInfo = true
anythingUpdate = true
}
if userUpdateReq.FirstDayOfWeek != nil && *userUpdateReq.FirstDayOfWeek != user.FirstDayOfWeek {
user.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek
userNew.FirstDayOfWeek = *userUpdateReq.FirstDayOfWeek
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.FirstDayOfWeek = core.WEEKDAY_INVALID
@@ -336,6 +351,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
if userUpdateReq.LongDateFormat != nil && *userUpdateReq.LongDateFormat != user.LongDateFormat {
user.LongDateFormat = *userUpdateReq.LongDateFormat
userNew.LongDateFormat = *userUpdateReq.LongDateFormat
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.LongDateFormat = core.LONG_DATE_FORMAT_INVALID
@@ -344,6 +360,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
if userUpdateReq.ShortDateFormat != nil && *userUpdateReq.ShortDateFormat != user.ShortDateFormat {
user.ShortDateFormat = *userUpdateReq.ShortDateFormat
userNew.ShortDateFormat = *userUpdateReq.ShortDateFormat
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.ShortDateFormat = core.SHORT_DATE_FORMAT_INVALID
@@ -352,6 +369,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
if userUpdateReq.LongTimeFormat != nil && *userUpdateReq.LongTimeFormat != user.LongTimeFormat {
user.LongTimeFormat = *userUpdateReq.LongTimeFormat
userNew.LongTimeFormat = *userUpdateReq.LongTimeFormat
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.LongTimeFormat = core.LONG_TIME_FORMAT_INVALID
@@ -360,6 +378,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
if userUpdateReq.ShortTimeFormat != nil && *userUpdateReq.ShortTimeFormat != user.ShortTimeFormat {
user.ShortTimeFormat = *userUpdateReq.ShortTimeFormat
userNew.ShortTimeFormat = *userUpdateReq.ShortTimeFormat
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.ShortTimeFormat = core.SHORT_TIME_FORMAT_INVALID
@@ -368,6 +387,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
if userUpdateReq.DecimalSeparator != nil && *userUpdateReq.DecimalSeparator != user.DecimalSeparator {
user.DecimalSeparator = *userUpdateReq.DecimalSeparator
userNew.DecimalSeparator = *userUpdateReq.DecimalSeparator
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.DecimalSeparator = core.DECIMAL_SEPARATOR_INVALID
@@ -376,6 +396,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
if userUpdateReq.DigitGroupingSymbol != nil && *userUpdateReq.DigitGroupingSymbol != user.DigitGroupingSymbol {
user.DigitGroupingSymbol = *userUpdateReq.DigitGroupingSymbol
userNew.DigitGroupingSymbol = *userUpdateReq.DigitGroupingSymbol
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.DigitGroupingSymbol = core.DIGIT_GROUPING_SYMBOL_INVALID
@@ -384,6 +405,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
if userUpdateReq.DigitGrouping != nil && *userUpdateReq.DigitGrouping != user.DigitGrouping {
user.DigitGrouping = *userUpdateReq.DigitGrouping
userNew.DigitGrouping = *userUpdateReq.DigitGrouping
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.DigitGrouping = core.DIGIT_GROUPING_TYPE_INVALID
@@ -392,6 +414,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
if userUpdateReq.CurrencyDisplayType != nil && *userUpdateReq.CurrencyDisplayType != user.CurrencyDisplayType {
user.CurrencyDisplayType = *userUpdateReq.CurrencyDisplayType
userNew.CurrencyDisplayType = *userUpdateReq.CurrencyDisplayType
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.CurrencyDisplayType = core.CURRENCY_DISPLAY_TYPE_INVALID
@@ -400,6 +423,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
if userUpdateReq.ExpenseAmountColor != nil && *userUpdateReq.ExpenseAmountColor != user.ExpenseAmountColor {
user.ExpenseAmountColor = *userUpdateReq.ExpenseAmountColor
userNew.ExpenseAmountColor = *userUpdateReq.ExpenseAmountColor
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.ExpenseAmountColor = models.AMOUNT_COLOR_TYPE_INVALID
@@ -408,11 +432,16 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
if userUpdateReq.IncomeAmountColor != nil && *userUpdateReq.IncomeAmountColor != user.IncomeAmountColor {
user.IncomeAmountColor = *userUpdateReq.IncomeAmountColor
userNew.IncomeAmountColor = *userUpdateReq.IncomeAmountColor
modifyProfileBasicInfo = true
anythingUpdate = true
} else {
userNew.IncomeAmountColor = models.AMOUNT_COLOR_TYPE_INVALID
}
if modifyProfileBasicInfo && user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_UPDATE_PROFILE_BASIC_INFO) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
if modifyUserLanguage || userNew.DecimalSeparator != core.DECIMAL_SEPARATOR_INVALID || userNew.DigitGroupingSymbol != core.DIGIT_GROUPING_SYMBOL_INVALID {
decimalSeparator := userNew.DecimalSeparator
digitGroupingSymbol := userNew.DigitGroupingSymbol
@@ -525,6 +554,10 @@ func (a *UsersApi) UserUpdateAvatarHandler(c *core.WebContext) (any, *errs.Error
return nil, errs.ErrUserNotFound
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_UPDATE_AVATAR) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
form, err := c.MultipartForm()
if err != nil {
@@ -588,6 +621,10 @@ func (a *UsersApi) UserRemoveAvatarHandler(c *core.WebContext) (any, *errs.Error
return nil, errs.ErrUserNotFound
}
if user.FeatureRestriction.Contains(models.USER_FEATURE_RESTRICTION_TYPE_UPDATE_AVATAR) {
return nil, errs.ErrNotPermittedToPerformThisAction
}
if user.CustomAvatarType == "" {
return nil, errs.ErrNothingWillBeUpdated
}
+1
View File
@@ -37,4 +37,5 @@ var (
ErrUserAvatarNotSet = NewNormalError(NormalSubcategoryUser, 28, http.StatusNotFound, "user avatar not set")
ErrUserAvatarExtensionInvalid = NewNormalError(NormalSubcategoryUser, 29, http.StatusNotFound, "user avatar file extension invalid")
ErrExceedMaxUserAvatarFileSize = NewNormalError(NormalSubcategoryUser, 30, http.StatusBadRequest, "exceed the maximum size of user avatar file")
ErrNotPermittedToPerformThisAction = NewNormalError(NormalSubcategoryUser, 31, http.StatusBadRequest, "not permitted to perform this action")
)
+90
View File
@@ -2,6 +2,7 @@ package models
import (
"fmt"
"strings"
"time"
"github.com/mayswind/ezbookkeeping/pkg/core"
@@ -80,6 +81,94 @@ func (s AmountColorType) String() string {
}
}
// UserFeatureRestrictions represents all the restrictions of user features
type UserFeatureRestrictions int64
// Add returns a new feature restrictions with the specified feature
func (r UserFeatureRestrictions) Add(featureRestrictionType UserFeatureRestrictionType) UserFeatureRestrictions {
typeValue := int64(1 << (featureRestrictionType - 1))
return UserFeatureRestrictions(int64(r) | typeValue)
}
// Remove returns a new feature restrictions without the specified feature
func (r UserFeatureRestrictions) Remove(featureRestrictionType UserFeatureRestrictionType) UserFeatureRestrictions {
typeValue := int64(1 << (featureRestrictionType - 1))
return UserFeatureRestrictions(int64(r) & (^typeValue))
}
// Contains returns whether contains the specified feature
func (r UserFeatureRestrictions) Contains(featureRestrictionType UserFeatureRestrictionType) bool {
typeValue := int64(1 << (featureRestrictionType - 1))
return int64(r)&typeValue == typeValue
}
// String returns a textual representation of all the restrictions of user features
func (r UserFeatureRestrictions) String() string {
builder := strings.Builder{}
for restrictionType := USER_FEATURE_RESTRICTION_TYPE_UPDATE_PASSWORD; restrictionType <= USER_FEATURE_RESTRICTION_TYPE_CLEAR_ALL_DATA; restrictionType++ {
if !r.Contains(restrictionType) {
continue
}
if builder.Len() > 0 {
builder.WriteRune(',')
}
builder.WriteString(restrictionType.String())
}
return builder.String()
}
// UserFeatureRestrictionType represents the restriction type of user features
type UserFeatureRestrictionType int64
// User Feature Restriction Type
const (
USER_FEATURE_RESTRICTION_TYPE_UPDATE_PASSWORD UserFeatureRestrictionType = 1
USER_FEATURE_RESTRICTION_TYPE_UPDATE_EMAIL UserFeatureRestrictionType = 2
USER_FEATURE_RESTRICTION_TYPE_UPDATE_PROFILE_BASIC_INFO UserFeatureRestrictionType = 3
USER_FEATURE_RESTRICTION_TYPE_UPDATE_AVATAR UserFeatureRestrictionType = 4
USER_FEATURE_RESTRICTION_TYPE_REVOKE_OTHER_SESSION UserFeatureRestrictionType = 5
USER_FEATURE_RESTRICTION_TYPE_ENABLE_2FA UserFeatureRestrictionType = 6
USER_FEATURE_RESTRICTION_TYPE_DISABLE_2FA UserFeatureRestrictionType = 7
USER_FEATURE_RESTRICTION_TYPE_FORGET_PASSWORD UserFeatureRestrictionType = 8
USER_FEATURE_RESTRICTION_TYPE_IMPORT_TRANSACTION UserFeatureRestrictionType = 9
USER_FEATURE_RESTRICTION_TYPE_EXPORT_TRANSACTION UserFeatureRestrictionType = 10
USER_FEATURE_RESTRICTION_TYPE_CLEAR_ALL_DATA UserFeatureRestrictionType = 11
)
// String returns a textual representation of the restriction type of user features
func (t UserFeatureRestrictionType) String() string {
switch t {
case USER_FEATURE_RESTRICTION_TYPE_UPDATE_PASSWORD:
return "Update Password"
case USER_FEATURE_RESTRICTION_TYPE_UPDATE_EMAIL:
return "Update Email"
case USER_FEATURE_RESTRICTION_TYPE_UPDATE_PROFILE_BASIC_INFO:
return "Update Profile Basic Info"
case USER_FEATURE_RESTRICTION_TYPE_UPDATE_AVATAR:
return "Update Avatar"
case USER_FEATURE_RESTRICTION_TYPE_REVOKE_OTHER_SESSION:
return "Logout Other Session"
case USER_FEATURE_RESTRICTION_TYPE_ENABLE_2FA:
return "Enable Two-Factor Authentication"
case USER_FEATURE_RESTRICTION_TYPE_DISABLE_2FA:
return "Disable Enable Two-Factor Authentication"
case USER_FEATURE_RESTRICTION_TYPE_FORGET_PASSWORD:
return "Forget Password"
case USER_FEATURE_RESTRICTION_TYPE_IMPORT_TRANSACTION:
return "Import Transactions"
case USER_FEATURE_RESTRICTION_TYPE_EXPORT_TRANSACTION:
return "Export Transactions"
case USER_FEATURE_RESTRICTION_TYPE_CLEAR_ALL_DATA:
return "Clear All Data"
default:
return fmt.Sprintf("Invalid(%d)", int(t))
}
}
// User represents user data stored in database
type User struct {
Uid int64 `xorm:"PK"`
@@ -104,6 +193,7 @@ type User struct {
CurrencyDisplayType core.CurrencyDisplayType `xorm:"TINYINT"`
ExpenseAmountColor AmountColorType `xorm:"TINYINT"`
IncomeAmountColor AmountColorType `xorm:"TINYINT"`
FeatureRestriction UserFeatureRestrictions
Disabled bool
Deleted bool `xorm:"NOT NULL"`
EmailVerified bool `xorm:"NOT NULL"`
+89
View File
@@ -10,6 +10,95 @@ import (
"github.com/mayswind/ezbookkeeping/pkg/utils"
)
func TestUserFeatureRestrictionsAdd(t *testing.T) {
var featureRestrictions UserFeatureRestrictions
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_PASSWORD)
expectedValue := UserFeatureRestrictions(1)
assert.Equal(t, expectedValue, featureRestrictions)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_EMAIL)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_PROFILE_BASIC_INFO)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_AVATAR)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_REVOKE_OTHER_SESSION)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_ENABLE_2FA)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_DISABLE_2FA)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_FORGET_PASSWORD)
expectedValue = UserFeatureRestrictions(255)
assert.Equal(t, expectedValue, featureRestrictions)
}
func TestUserFeatureRestrictionsRemove(t *testing.T) {
var featureRestrictions UserFeatureRestrictions
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_PASSWORD)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_EMAIL)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_PROFILE_BASIC_INFO)
featureRestrictions = featureRestrictions.Remove(USER_FEATURE_RESTRICTION_TYPE_UPDATE_EMAIL)
featureRestrictions = featureRestrictions.Remove(USER_FEATURE_RESTRICTION_TYPE_UPDATE_PROFILE_BASIC_INFO)
featureRestrictions = featureRestrictions.Remove(USER_FEATURE_RESTRICTION_TYPE_UPDATE_AVATAR)
featureRestrictions = featureRestrictions.Remove(USER_FEATURE_RESTRICTION_TYPE_REVOKE_OTHER_SESSION)
expectedValue := UserFeatureRestrictions(1)
assert.Equal(t, expectedValue, featureRestrictions)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_AVATAR)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_REVOKE_OTHER_SESSION)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_ENABLE_2FA)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_DISABLE_2FA)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_FORGET_PASSWORD)
featureRestrictions = featureRestrictions.Remove(USER_FEATURE_RESTRICTION_TYPE_ENABLE_2FA)
featureRestrictions = featureRestrictions.Remove(USER_FEATURE_RESTRICTION_TYPE_DISABLE_2FA)
expectedValue = UserFeatureRestrictions(153)
assert.Equal(t, expectedValue, featureRestrictions)
}
func TestUserFeatureRestrictionsContains(t *testing.T) {
var featureRestrictions UserFeatureRestrictions
assert.False(t, featureRestrictions.Contains(USER_FEATURE_RESTRICTION_TYPE_UPDATE_PASSWORD))
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_PASSWORD)
assert.True(t, featureRestrictions.Contains(USER_FEATURE_RESTRICTION_TYPE_UPDATE_PASSWORD))
assert.False(t, featureRestrictions.Contains(USER_FEATURE_RESTRICTION_TYPE_UPDATE_PROFILE_BASIC_INFO))
}
func TestUserFeatureRestrictionsString(t *testing.T) {
var featureRestrictions UserFeatureRestrictions
expectedValue := ""
actualValue := featureRestrictions.String()
assert.Equal(t, expectedValue, actualValue)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_PASSWORD)
expectedValue = "Update Password"
actualValue = featureRestrictions.String()
assert.Equal(t, expectedValue, actualValue)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_FORGET_PASSWORD)
expectedValue = "Update Password,Forget Password"
actualValue = featureRestrictions.String()
assert.Equal(t, expectedValue, actualValue)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_EMAIL)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_PROFILE_BASIC_INFO)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_UPDATE_AVATAR)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_REVOKE_OTHER_SESSION)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_ENABLE_2FA)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_DISABLE_2FA)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_IMPORT_TRANSACTION)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_EXPORT_TRANSACTION)
featureRestrictions = featureRestrictions.Add(USER_FEATURE_RESTRICTION_TYPE_CLEAR_ALL_DATA)
expectedValue = "Update Password," +
"Update Email," +
"Update Profile Basic Info," +
"Update Avatar," +
"Logout Other Session," +
"Enable Two-Factor Authentication," +
"Disable Enable Two-Factor Authentication," +
"Forget Password," +
"Import Transactions," +
"Export Transactions," +
"Clear All Data"
actualValue = featureRestrictions.String()
assert.Equal(t, expectedValue, actualValue)
}
func TestUserCanEditTransactionByTransactionTime_ScopeIsNone(t *testing.T) {
user := &User{
TransactionEditScope: TRANSACTION_EDIT_SCOPE_NONE,
+1
View File
@@ -1023,6 +1023,7 @@
"user avatar not set": "User avatar is not set",
"user avatar file extension invalid": "User avatar file extension is invalid",
"exceed the maximum size of user avatar file": "The uploaded user avatar exceeds the maximum allowed file size",
"not permitted to perform this action": "You are not permitted to perform this action",
"unauthorized access": "Unauthorized access",
"current token is invalid": "Current token is invalid",
"current token is expired": "Current token is expired",
+1
View File
@@ -1023,6 +1023,7 @@
"user avatar not set": "用户没有设置头像",
"user avatar file extension invalid": "用户头像文件扩展名无效",
"exceed the maximum size of user avatar file": "上传的用户头像超出了允许的最大文件大小",
"not permitted to perform this action": "您不能执行该操作",
"unauthorized access": "未授权的登录",
"current token is invalid": "当前认证令牌无效",
"current token is expired": "当前认证令牌已过期",