forked from casdoor/casdoor
Fix: Shared Application Does Not Allow Login for Users Across All Linked Organizations
When using a shared application, users from organizations that have set the shared app as their default application are now able to log in. Changes: - Add GetUserOrganizationForSharedApp() to resolve actual user org for shared apps - Fix CheckLoginPermission() to allow users from orgs linked to the shared app - Update Login() controller to resolve user org before user lookup for all methods" Co-authored-by: hsluoyz <3787410+hsluoyz@users.noreply.github.com> Agent-Logs-Url: https://github.com/casdoor/casdoor/sessions/4c4a727f-2dca-4e1c-9265-1cb7763d1378
This commit is contained in:
@@ -535,14 +535,6 @@ func (c *ApiController) Login() {
|
||||
if authForm.Username != "" {
|
||||
var user *object.User
|
||||
if authForm.SigninMethod == "Face ID" {
|
||||
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
|
||||
}
|
||||
|
||||
var application *object.Application
|
||||
application, err = object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
|
||||
if err != nil {
|
||||
@@ -555,6 +547,20 @@ func (c *ApiController) Login() {
|
||||
return
|
||||
}
|
||||
|
||||
authForm.Organization, err = object.GetUserOrganizationForSharedApp(application, authForm.Organization, authForm.Username)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if !application.IsFaceIdEnabled() {
|
||||
c.ResponseError(c.T("auth:The login method: login with face is not enabled for the application"))
|
||||
return
|
||||
@@ -582,14 +588,6 @@ func (c *ApiController) Login() {
|
||||
}
|
||||
}
|
||||
} else if authForm.Password == "" {
|
||||
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
|
||||
}
|
||||
|
||||
var application *object.Application
|
||||
application, err = object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
|
||||
if err != nil {
|
||||
@@ -602,6 +600,20 @@ func (c *ApiController) Login() {
|
||||
return
|
||||
}
|
||||
|
||||
authForm.Organization, err = object.GetUserOrganizationForSharedApp(application, authForm.Organization, authForm.Username)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
verificationCodeType := object.GetVerifyType(authForm.Username)
|
||||
if verificationCodeType == object.VerifyTypeEmail && !application.IsCodeSigninViaEmailEnabled() {
|
||||
c.ResponseError(c.T("auth:The login method: login with email is not enabled for the application"))
|
||||
@@ -719,6 +731,11 @@ func (c *ApiController) Login() {
|
||||
} else {
|
||||
isPasswordWithLdapEnabled = false
|
||||
}
|
||||
authForm.Organization, err = object.GetUserOrganizationForSharedApp(application, authForm.Organization, authForm.Username)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
user, err = object.CheckUserPassword(authForm.Organization, authForm.Username, password, c.GetAcceptLanguage(), enableCaptcha, isSigninViaLdap, isPasswordWithLdapEnabled)
|
||||
}
|
||||
|
||||
|
||||
@@ -587,6 +587,17 @@ func CheckLoginPermission(userId string, application *Application) (bool, error)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// For shared applications, allow users from organizations that have this app as their default application
|
||||
if application.IsShared && owner != application.Organization {
|
||||
userOrg, err := getOrganization("admin", owner)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if userOrg != nil && userOrg.DefaultApplication == application.Name {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
permissions, err := GetPermissions(application.Organization)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
||||
@@ -103,6 +103,47 @@ func GetUserByFields(organization string, field string) (*User, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// GetUserOrganizationForSharedApp resolves the actual organization of a user when logging in via a shared application.
|
||||
// If the user is not found in the specified organization and the application is shared,
|
||||
// it searches in all organizations that have this app as their default application.
|
||||
// Returns the resolved organization name.
|
||||
func GetUserOrganizationForSharedApp(application *Application, organization string, username string) (string, error) {
|
||||
if application == nil || !application.IsShared {
|
||||
return organization, nil
|
||||
}
|
||||
|
||||
// Check if user exists in the specified organization first
|
||||
user, err := GetUserByFields(organization, username)
|
||||
if err != nil {
|
||||
return organization, err
|
||||
}
|
||||
if user != nil {
|
||||
return organization, nil
|
||||
}
|
||||
|
||||
// User not found in the default org, search in organizations that have this shared app as their default
|
||||
organizations := []*Organization{}
|
||||
err = ormer.Engine.Where("default_application=?", application.Name).Find(&organizations)
|
||||
if err != nil {
|
||||
return organization, err
|
||||
}
|
||||
|
||||
for _, org := range organizations {
|
||||
if org.Name == organization {
|
||||
continue // Already checked
|
||||
}
|
||||
user, err = GetUserByFields(org.Name, username)
|
||||
if err != nil {
|
||||
return organization, err
|
||||
}
|
||||
if user != nil {
|
||||
return org.Name, nil
|
||||
}
|
||||
}
|
||||
|
||||
return organization, nil
|
||||
}
|
||||
|
||||
func SetUserField(user *User, field string, value string) (bool, error) {
|
||||
bean := make(map[string]interface{})
|
||||
if field == "password" {
|
||||
|
||||
Reference in New Issue
Block a user