feat: return most backend API errors to frontend (#1836)

* feat: return most backend API errros to frontend

Signed-off-by: yehong <239859435@qq.com>

* refactor: reduce int type change

Signed-off-by: yehong <239859435@qq.com>

* feat: return err backend in token.go

Signed-off-by: yehong <239859435@qq.com>

---------

Signed-off-by: yehong <239859435@qq.com>
This commit is contained in:
yehong
2023-05-30 15:49:39 +08:00
committed by GitHub
parent 34151c0095
commit 02e692a300
105 changed files with 3788 additions and 1734 deletions

View File

@ -93,7 +93,12 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
c.ResponseError(c.T("auth:Challenge method should be S256"))
return
}
code := object.GetOAuthCode(userId, clientId, responseType, redirectUri, scope, state, nonce, codeChallenge, c.Ctx.Request.Host, c.GetAcceptLanguage())
code, err := object.GetOAuthCode(userId, clientId, responseType, redirectUri, scope, state, nonce, codeChallenge, c.Ctx.Request.Host, c.GetAcceptLanguage())
if err != nil {
c.ResponseError(err.Error(), nil)
return
}
resp = codeToResponse(code)
if application.EnableSigninSession || application.HasPromptPage() {
@ -142,12 +147,16 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
}
if resp.Status == "ok" {
object.AddSession(&object.Session{
_, err = object.AddSession(&object.Session{
Owner: user.Owner,
Name: user.Name,
Application: application.Name,
SessionId: []string{c.Ctx.Input.CruSession.SessionID()},
})
if err != nil {
c.ResponseError(err.Error(), nil)
return
}
}
return resp
@ -171,7 +180,12 @@ func (c *ApiController) GetApplicationLogin() {
scope := c.Input().Get("scope")
state := c.Input().Get("state")
msg, application := object.CheckOAuthLogin(clientId, responseType, redirectUri, scope, state, c.GetAcceptLanguage())
msg, application, err := object.CheckOAuthLogin(clientId, responseType, redirectUri, scope, state, c.GetAcceptLanguage())
if err != nil {
c.ResponseError(err.Error())
return
}
application = object.GetMaskedApplication(application, "")
if msg != "" {
c.ResponseError(msg, application)
@ -248,7 +262,10 @@ func (c *ApiController) Login() {
var msg string
if authForm.Password == "" {
if user = object.GetUserByFields(authForm.Organization, authForm.Username); user == nil {
if user, err = object.GetUserByFields(authForm.Organization, authForm.Username); err != nil {
c.ResponseError(err.Error(), nil)
return
} else if user == nil {
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(authForm.Organization, authForm.Username)))
return
}
@ -272,9 +289,18 @@ func (c *ApiController) Login() {
}
// disable the verification code
object.DisableVerificationCode(checkDest)
err := object.DisableVerificationCode(checkDest)
if err != nil {
c.ResponseError(err.Error(), nil)
return
}
} else {
application := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
application, err := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
if err != nil {
c.ResponseError(err.Error(), nil)
return
}
if application == nil {
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), authForm.Application))
return
@ -284,7 +310,10 @@ func (c *ApiController) Login() {
return
}
var enableCaptcha bool
if enableCaptcha = object.CheckToEnableCaptcha(application, authForm.Organization, authForm.Username); enableCaptcha {
if enableCaptcha, err = object.CheckToEnableCaptcha(application, authForm.Organization, authForm.Username); err != nil {
c.ResponseError(err.Error())
return
} else if enableCaptcha {
isHuman, err := captcha.VerifyCaptchaByCaptchaType(authForm.CaptchaType, authForm.CaptchaToken, authForm.ClientSecret)
if err != nil {
c.ResponseError(err.Error())
@ -304,7 +333,12 @@ func (c *ApiController) Login() {
if msg != "" {
resp = &Response{Status: "error", Msg: msg}
} else {
application := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
application, err := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
if err != nil {
c.ResponseError(err.Error())
return
}
if application == nil {
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), authForm.Application))
return
@ -312,7 +346,11 @@ func (c *ApiController) Login() {
resp = c.HandleLoggedIn(application, user, &authForm)
organization := object.GetOrganizationByUser(user)
organization, err := object.GetOrganizationByUser(user)
if err != nil {
c.ResponseError(err.Error())
}
if user != nil && organization.HasRequiredMfa() && !user.IsMfaEnabled() {
resp.Msg = object.RequiredMfa
}
@ -325,18 +363,34 @@ func (c *ApiController) Login() {
} else if authForm.Provider != "" {
var application *object.Application
if authForm.ClientId != "" {
application = object.GetApplicationByClientId(authForm.ClientId)
application, err = object.GetApplicationByClientId(authForm.ClientId)
if err != nil {
c.ResponseError(err.Error())
return
}
} else {
application = object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
application, err = object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
if err != nil {
c.ResponseError(err.Error())
return
}
}
if application == nil {
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), authForm.Application))
return
}
organization, err := object.GetOrganization(util.GetId("admin", application.Organization))
if err != nil {
c.ResponseError(c.T(err.Error()))
}
provider, err := object.GetProvider(util.GetId("admin", authForm.Provider))
if err != nil {
c.ResponseError(err.Error())
return
}
organization := object.GetOrganization(util.GetId("admin", application.Organization))
provider := object.GetProvider(util.GetId("admin", authForm.Provider))
providerItem := application.GetProviderItem(provider.Name)
if !providerItem.IsProviderVisible() {
c.ResponseError(fmt.Sprintf(c.T("auth:The provider: %s is not enabled for the application"), provider.Name))
@ -396,9 +450,17 @@ func (c *ApiController) Login() {
if authForm.Method == "signup" {
user := &object.User{}
if provider.Category == "SAML" {
user = object.GetUser(util.GetId(application.Organization, userInfo.Id))
user, err = object.GetUser(util.GetId(application.Organization, userInfo.Id))
if err != nil {
c.ResponseError(err.Error())
return
}
} else if provider.Category == "OAuth" {
user = object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
user, err = object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
if err != nil {
c.ResponseError(err.Error())
return
}
}
if user != nil && !user.IsDeleted {
@ -419,12 +481,20 @@ func (c *ApiController) Login() {
if application.EnableLinkWithEmail {
if userInfo.Email != "" {
// Find existing user with Email
user = object.GetUserByField(application.Organization, "email", userInfo.Email)
user, err = object.GetUserByField(application.Organization, "email", userInfo.Email)
if err != nil {
c.ResponseError(err.Error())
return
}
}
if user == nil && userInfo.Phone != "" {
// Find existing user with phone number
user = object.GetUserByField(application.Organization, "phone", userInfo.Phone)
user, err = object.GetUserByField(application.Organization, "phone", userInfo.Phone)
if err != nil {
c.ResponseError(err.Error())
return
}
}
}
@ -440,7 +510,12 @@ func (c *ApiController) Login() {
}
// Handle username conflicts
tmpUser := object.GetUser(util.GetId(application.Organization, userInfo.Username))
tmpUser, err := object.GetUser(util.GetId(application.Organization, userInfo.Username))
if err != nil {
c.ResponseError(err.Error())
return
}
if tmpUser != nil {
uid, err := uuid.NewRandom()
if err != nil {
@ -453,7 +528,13 @@ func (c *ApiController) Login() {
}
properties := map[string]string{}
properties["no"] = strconv.Itoa(object.GetUserCount(application.Organization, "", "") + 2)
count, err := object.GetUserCount(application.Organization, "", "")
if err != nil {
c.ResponseError(err.Error())
return
}
properties["no"] = strconv.Itoa(int(count + 2))
initScore, err := organization.GetInitScore()
if err != nil {
c.ResponseError(fmt.Errorf(c.T("account:Get init score failed, error: %w"), err).Error())
@ -482,7 +563,12 @@ func (c *ApiController) Login() {
Properties: properties,
}
affected := object.AddUser(user)
affected, err := object.AddUser(user)
if err != nil {
c.ResponseError(err.Error())
return
}
if !affected {
c.ResponseError(fmt.Sprintf(c.T("auth:Failed to create user, user information is invalid: %s"), util.StructToJson(user)))
return
@ -490,8 +576,17 @@ func (c *ApiController) Login() {
}
// sync info from 3rd-party if possible
object.SetUserOAuthProperties(organization, user, provider.Type, userInfo)
object.LinkUserAccount(user, provider.Type, userInfo.Id)
_, err := object.SetUserOAuthProperties(organization, user, provider.Type, userInfo)
if err != nil {
c.ResponseError(err.Error())
return
}
_, err = object.LinkUserAccount(user, provider.Type, userInfo.Id)
if err != nil {
c.ResponseError(err.Error())
return
}
resp = c.HandleLoggedIn(application, user, &authForm)
@ -516,18 +611,36 @@ func (c *ApiController) Login() {
return
}
oldUser := object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
oldUser, err := object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
if err != nil {
c.ResponseError(err.Error())
return
}
if oldUser != nil {
c.ResponseError(fmt.Sprintf(c.T("auth:The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)"), provider.Type, userInfo.Username, userInfo.DisplayName, oldUser.Name, oldUser.DisplayName))
return
}
user := object.GetUser(userId)
user, err := object.GetUser(userId)
if err != nil {
c.ResponseError(err.Error())
return
}
// sync info from 3rd-party if possible
object.SetUserOAuthProperties(organization, user, provider.Type, userInfo)
_, err = object.SetUserOAuthProperties(organization, user, provider.Type, userInfo)
if err != nil {
c.ResponseError(err.Error())
return
}
isLinked, err := object.LinkUserAccount(user, provider.Type, userInfo.Id)
if err != nil {
c.ResponseError(err.Error())
return
}
isLinked := object.LinkUserAccount(user, provider.Type, userInfo.Id)
if isLinked {
resp = &Response{Status: "ok", Msg: "", Data: isLinked}
} else {
@ -536,7 +649,11 @@ func (c *ApiController) Login() {
}
} else if c.getMfaSessionData() != nil {
mfaSession := c.getMfaSessionData()
user := object.GetUser(mfaSession.UserId)
user, err := object.GetUser(mfaSession.UserId)
if err != nil {
c.ResponseError(err.Error())
return
}
if authForm.Passcode != "" {
MfaUtil := object.GetMfaUtil(authForm.MfaType, user.GetPreferMfa(false))
@ -554,7 +671,12 @@ func (c *ApiController) Login() {
}
}
application := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
application, err := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
if err != nil {
c.ResponseError(err.Error())
return
}
if application == nil {
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), authForm.Application))
return
@ -569,7 +691,12 @@ func (c *ApiController) Login() {
} else {
if c.GetSessionUsername() != "" {
// user already signed in to Casdoor, so let the user click the avatar button to do the quick sign-in
application := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
application, err := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
if err != nil {
c.ResponseError(err.Error())
return
}
if application == nil {
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), authForm.Application))
return
@ -624,8 +751,9 @@ func (c *ApiController) HandleSamlLogin() {
func (c *ApiController) HandleOfficialAccountEvent() {
respBytes, err := ioutil.ReadAll(c.Ctx.Request.Body)
if err != nil {
c.ResponseError(err.Error())
panic(err)
}
var data struct {
MsgType string `xml:"MsgType"`
Event string `xml:"Event"`
@ -633,8 +761,9 @@ func (c *ApiController) HandleOfficialAccountEvent() {
}
err = xml.Unmarshal(respBytes, &data)
if err != nil {
c.ResponseError(err.Error())
panic(err)
}
lock.Lock()
defer lock.Unlock()
if data.EventKey != "" {
@ -670,7 +799,12 @@ func (c *ApiController) GetWebhookEventType() {
func (c *ApiController) GetCaptchaStatus() {
organization := c.Input().Get("organization")
userId := c.Input().Get("user_id")
user := object.GetUserByFields(organization, userId)
user, err := object.GetUserByFields(organization, userId)
if err != nil {
c.ResponseError(err.Error())
return
}
var captchaEnabled bool
if user != nil && user.SigninWrongTimes >= object.SigninWrongTimesLimit {
captchaEnabled = true