diff --git a/conf/ezbookkeeping.ini b/conf/ezbookkeeping.ini index 60f63d86..06a9c515 100644 --- a/conf/ezbookkeeping.ini +++ b/conf/ezbookkeeping.ini @@ -377,6 +377,8 @@ max_user_avatar_size = 1048576 # 12: Sync Application Settings # 13: MCP (Model Context Protocol) Access # 14: Create Transactions from AI Image Recognition +# 15: OAuth 2.0 Login +# 16: Unlink Third-party Login default_feature_restrictions = [data] diff --git a/pkg/api/oauth2_authentications.go b/pkg/api/oauth2_authentications.go index 30ac651e..461acec9 100644 --- a/pkg/api/oauth2_authentications.go +++ b/pkg/api/oauth2_authentications.go @@ -265,6 +265,10 @@ func (a *OAuth2AuthenticationApi) CallbackHandler(c *core.WebContext) (string, * FeatureRestriction: a.CurrentConfig().DefaultFeatureRestrictions, } + if user.FeatureRestriction.Contains(core.USER_FEATURE_RESTRICTION_TYPE_OAUTH2_LOGIN) { + return a.redirectToFailedCallbackPage(c, errs.ErrNotPermittedToPerformThisAction) + } + err = a.users.CreateUser(c, user, true) if err != nil { @@ -294,6 +298,10 @@ func (a *OAuth2AuthenticationApi) CallbackHandler(c *core.WebContext) (string, * } } + if user.FeatureRestriction.Contains(core.USER_FEATURE_RESTRICTION_TYPE_OAUTH2_LOGIN) { + return a.redirectToFailedCallbackPage(c, errs.ErrNotPermittedToPerformThisAction) + } + if userExternalAuth == nil { tokenContext, err := json.Marshal(&models.OAuth2CallbackTokenContext{ ExternalAuthType: userExternalAuthType, diff --git a/pkg/api/user_external_auths.go b/pkg/api/user_external_auths.go index e8486771..7a6a24c2 100644 --- a/pkg/api/user_external_auths.go +++ b/pkg/api/user_external_auths.go @@ -87,6 +87,10 @@ func (a *UserExternalAuthsApi) UnlinkExternalAuthHandler(c *core.WebContext) (an return nil, errs.ErrUserPasswordWrong } + if user.FeatureRestriction.Contains(core.USER_FEATURE_RESTRICTION_TYPE_UNLINK_THIRD_PARTY_LOGIN) { + return nil, errs.ErrNotPermittedToPerformThisAction + } + externalAuthType := core.UserExternalAuthType(externalAuthLinkReq.ExternalAuthType) if !externalAuthType.IsValid() { diff --git a/pkg/core/user_feature_restriction.go b/pkg/core/user_feature_restriction.go index 1ede63db..76519d1d 100644 --- a/pkg/core/user_feature_restriction.go +++ b/pkg/core/user_feature_restriction.go @@ -90,10 +90,12 @@ const ( USER_FEATURE_RESTRICTION_TYPE_SYNC_APPLICATION_SETTINGS UserFeatureRestrictionType = 12 USER_FEATURE_RESTRICTION_TYPE_MCP_ACCESS UserFeatureRestrictionType = 13 USER_FEATURE_RESTRICTION_TYPE_CREATE_TRANSACTION_FROM_AI_IMAGE_RECOGNITION UserFeatureRestrictionType = 14 + USER_FEATURE_RESTRICTION_TYPE_OAUTH2_LOGIN UserFeatureRestrictionType = 15 + USER_FEATURE_RESTRICTION_TYPE_UNLINK_THIRD_PARTY_LOGIN UserFeatureRestrictionType = 16 ) const userFeatureRestrictionTypeMinValue UserFeatureRestrictionType = USER_FEATURE_RESTRICTION_TYPE_UPDATE_PASSWORD -const userFeatureRestrictionTypeMaxValue UserFeatureRestrictionType = USER_FEATURE_RESTRICTION_TYPE_CREATE_TRANSACTION_FROM_AI_IMAGE_RECOGNITION +const userFeatureRestrictionTypeMaxValue UserFeatureRestrictionType = USER_FEATURE_RESTRICTION_TYPE_UNLINK_THIRD_PARTY_LOGIN // String returns a textual representation of the restriction type of user features func (t UserFeatureRestrictionType) String() string { @@ -126,6 +128,10 @@ func (t UserFeatureRestrictionType) String() string { return "MCP (Model Context Protocol) Access" case USER_FEATURE_RESTRICTION_TYPE_CREATE_TRANSACTION_FROM_AI_IMAGE_RECOGNITION: return "Create Transaction from AI Image Recognition" + case USER_FEATURE_RESTRICTION_TYPE_OAUTH2_LOGIN: + return "OAuth 2.0 Login" + case USER_FEATURE_RESTRICTION_TYPE_UNLINK_THIRD_PARTY_LOGIN: + return "Unlink Third-Party Login" default: return fmt.Sprintf("Invalid(%d)", int(t)) }