109 lines
3.6 KiB
Go
109 lines
3.6 KiB
Go
package api
|
|
|
|
import (
|
|
"sort"
|
|
|
|
"github.com/mayswind/ezbookkeeping/pkg/auth/oauth2"
|
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
|
"github.com/mayswind/ezbookkeeping/pkg/log"
|
|
"github.com/mayswind/ezbookkeeping/pkg/models"
|
|
"github.com/mayswind/ezbookkeeping/pkg/services"
|
|
)
|
|
|
|
// UserExternalAuthsApi represents user external auth api
|
|
type UserExternalAuthsApi struct {
|
|
users *services.UserService
|
|
userExternalAuths *services.UserExternalAuthService
|
|
}
|
|
|
|
// Initialize a user external auth api singleton instance
|
|
var (
|
|
UserExternalAuths = &UserExternalAuthsApi{
|
|
users: services.Users,
|
|
userExternalAuths: services.UserExternalAuths,
|
|
}
|
|
)
|
|
|
|
// ExternalAuthListHanlder returns external authentications list of current user
|
|
func (a *UserExternalAuthsApi) ExternalAuthListHanlder(c *core.WebContext) (any, *errs.Error) {
|
|
uid := c.GetCurrentUid()
|
|
userExternalAuths, err := a.userExternalAuths.GetUserAllExternalAuthsByUid(c, uid)
|
|
|
|
if err != nil {
|
|
log.Errorf(c, "[user_external_auths.ExternalAuthListHanlder] failed to get all external authentications for user \"uid:%d\", because %s", uid, err.Error())
|
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
|
}
|
|
|
|
userExternalAuthResps := make(models.UserExternalAuthInfoResponsesSlice, 0, len(userExternalAuths)+1)
|
|
currentExternalAuthType := oauth2.GetExternalUserAuthType()
|
|
hasCurrentExternalAuth := false
|
|
|
|
for i := 0; i < len(userExternalAuths); i++ {
|
|
userExternalAuth := userExternalAuths[i]
|
|
|
|
if userExternalAuth.ExternalAuthType == currentExternalAuthType {
|
|
hasCurrentExternalAuth = true
|
|
}
|
|
|
|
userExternalAuthResps = append(userExternalAuthResps, userExternalAuth.ToUserExternalAuthInfoResponse())
|
|
}
|
|
|
|
if !hasCurrentExternalAuth {
|
|
userExternalAuthResps = append(userExternalAuthResps, &models.UserExternalAuthInfoResponse{
|
|
ExternalAuthCategory: currentExternalAuthType.GetCategory(),
|
|
ExternalAuthType: currentExternalAuthType,
|
|
Linked: false,
|
|
})
|
|
}
|
|
|
|
sort.Sort(userExternalAuthResps)
|
|
|
|
return userExternalAuthResps, nil
|
|
}
|
|
|
|
// UnlinkExternalAuthHandler unlinks external authentication for current user
|
|
func (a *UserExternalAuthsApi) UnlinkExternalAuthHandler(c *core.WebContext) (any, *errs.Error) {
|
|
var externalAuthLinkReq models.UserExternalAuthUnlinkRequest
|
|
err := c.ShouldBindJSON(&externalAuthLinkReq)
|
|
|
|
if err != nil {
|
|
log.Warnf(c, "[user_external_auths.UnlinkExternalAuthHandler] parse request failed, because %s", err.Error())
|
|
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
|
|
}
|
|
|
|
uid := c.GetCurrentUid()
|
|
user, err := a.users.GetUserById(c, uid)
|
|
|
|
if err != nil {
|
|
if !errs.IsCustomError(err) {
|
|
log.Warnf(c, "[user_external_auths.UnlinkExternalAuthHandler] failed to get user for user \"uid:%d\", because %s", uid, err.Error())
|
|
}
|
|
|
|
return nil, errs.ErrUserNotFound
|
|
}
|
|
|
|
if !a.users.IsPasswordEqualsUserPassword(externalAuthLinkReq.Password, user) {
|
|
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() {
|
|
return nil, errs.ErrUserExternalAuthNotFound
|
|
}
|
|
|
|
err = a.userExternalAuths.DeleteUserExternalAuth(c, uid, externalAuthType)
|
|
|
|
if err != nil {
|
|
log.Errorf(c, "[user_external_auths.UnlinkExternalAuthHandler] failed to unlink external authentication \"%s\" for user \"uid:%d\", because %s", externalAuthLinkReq.ExternalAuthType, uid, err.Error())
|
|
return nil, errs.Or(err, errs.ErrOperationFailed)
|
|
}
|
|
|
|
return true, nil
|
|
}
|