mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 10:45:47 +08:00
feat: support LDAP's SetPassword (#3395)
* fix: Resolve the issue mentioned in #3392 * fix: Change checkLdapUserPassword to CheckLdapUserPassword. * fix: the issue mentioned by hsluoyz. * fix: Check if the user parameter is nil * fix: use existing i18n message
This commit is contained in:
parent
01212cd1f3
commit
b927c6d7b4
@ -475,6 +475,16 @@ func (c *ApiController) SetPassword() {
|
|||||||
|
|
||||||
userId := util.GetId(userOwner, userName)
|
userId := util.GetId(userOwner, userName)
|
||||||
|
|
||||||
|
user, err := object.GetUser(userId)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if user == nil {
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), userId))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
requestUserId := c.GetSessionUsername()
|
requestUserId := c.GetSessionUsername()
|
||||||
if requestUserId == "" && code == "" {
|
if requestUserId == "" && code == "" {
|
||||||
c.ResponseError(c.T("general:Please login first"), "Please login first")
|
c.ResponseError(c.T("general:Please login first"), "Please login first")
|
||||||
@ -518,7 +528,11 @@ func (c *ApiController) SetPassword() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if code == "" {
|
} else if code == "" {
|
||||||
err = object.CheckPassword(targetUser, oldPassword, c.GetAcceptLanguage())
|
if user.Ldap == "" {
|
||||||
|
err = object.CheckPassword(targetUser, oldPassword, c.GetAcceptLanguage())
|
||||||
|
} else {
|
||||||
|
err = object.CheckLdapUserPassword(targetUser, oldPassword, c.GetAcceptLanguage())
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
@ -563,7 +577,12 @@ func (c *ApiController) SetPassword() {
|
|||||||
targetUser.NeedUpdatePassword = false
|
targetUser.NeedUpdatePassword = false
|
||||||
targetUser.LastChangePasswordTime = util.GetCurrentTime()
|
targetUser.LastChangePasswordTime = util.GetCurrentTime()
|
||||||
|
|
||||||
_, err = object.UpdateUser(userId, targetUser, []string{"password", "need_update_password", "password_type", "last_change_password_time"}, false)
|
if user.Ldap == "" {
|
||||||
|
_, err = object.UpdateUser(userId, targetUser, []string{"password", "need_update_password", "password_type", "last_change_password_time"}, false)
|
||||||
|
} else {
|
||||||
|
err = object.ResetLdapPassword(targetUser, newPassword, c.GetAcceptLanguage())
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
|
1
go.mod
1
go.mod
@ -63,6 +63,7 @@ require (
|
|||||||
golang.org/x/crypto v0.21.0
|
golang.org/x/crypto v0.21.0
|
||||||
golang.org/x/net v0.21.0
|
golang.org/x/net v0.21.0
|
||||||
golang.org/x/oauth2 v0.17.0
|
golang.org/x/oauth2 v0.17.0
|
||||||
|
golang.org/x/text v0.14.0
|
||||||
google.golang.org/api v0.150.0
|
google.golang.org/api v0.150.0
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0
|
gopkg.in/square/go-jose.v2 v2.6.0
|
||||||
|
@ -273,7 +273,7 @@ func CheckPasswordComplexity(user *User, password string) string {
|
|||||||
return CheckPasswordComplexityByOrg(organization, password)
|
return CheckPasswordComplexityByOrg(organization, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkLdapUserPassword(user *User, password string, lang string) error {
|
func CheckLdapUserPassword(user *User, password string, lang string) error {
|
||||||
ldaps, err := GetLdaps(user.Owner)
|
ldaps, err := GetLdaps(user.Owner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -368,7 +368,7 @@ func CheckUserPassword(organization string, username string, password string, la
|
|||||||
}
|
}
|
||||||
|
|
||||||
// only for LDAP users
|
// only for LDAP users
|
||||||
err = checkLdapUserPassword(user, password, lang)
|
err = CheckLdapUserPassword(user, password, lang)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err.Error() == "user not exist" {
|
if err.Error() == "user not exist" {
|
||||||
return nil, fmt.Errorf(i18n.Translate(lang, "check:The user: %s doesn't exist in LDAP server"), username)
|
return nil, fmt.Errorf(i18n.Translate(lang, "check:The user: %s doesn't exist in LDAP server"), username)
|
||||||
|
@ -20,9 +20,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
goldap "github.com/go-ldap/ldap/v3"
|
goldap "github.com/go-ldap/ldap/v3"
|
||||||
"github.com/thanhpk/randstr"
|
"github.com/thanhpk/randstr"
|
||||||
|
"golang.org/x/text/encoding/unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LdapConn struct {
|
type LdapConn struct {
|
||||||
@ -371,6 +373,64 @@ func GetExistUuids(owner string, uuids []string) ([]string, error) {
|
|||||||
return existUuids, nil
|
return existUuids, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ResetLdapPassword(user *User, newPassword string, lang string) error {
|
||||||
|
ldaps, err := GetLdaps(user.Owner)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ldapServer := range ldaps {
|
||||||
|
conn, err := ldapServer.GetLdapConn()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
searchReq := goldap.NewSearchRequest(ldapServer.BaseDn, goldap.ScopeWholeSubtree, goldap.NeverDerefAliases,
|
||||||
|
0, 0, false, ldapServer.buildAuthFilterString(user), []string{}, nil)
|
||||||
|
|
||||||
|
searchResult, err := conn.Conn.Search(searchReq)
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(searchResult.Entries) == 0 {
|
||||||
|
conn.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(searchResult.Entries) > 1 {
|
||||||
|
conn.Close()
|
||||||
|
return fmt.Errorf(i18n.Translate(lang, "check:Multiple accounts with same uid, please check your ldap server"))
|
||||||
|
}
|
||||||
|
|
||||||
|
userDn := searchResult.Entries[0].DN
|
||||||
|
|
||||||
|
var pwdEncoded string
|
||||||
|
modifyPasswordRequest := goldap.NewModifyRequest(userDn, nil)
|
||||||
|
if conn.IsAD {
|
||||||
|
utf16 := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
|
||||||
|
pwdEncoded, err := utf16.NewEncoder().String("\"" + newPassword + "\"")
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
modifyPasswordRequest.Replace("unicodePwd", []string{pwdEncoded})
|
||||||
|
modifyPasswordRequest.Replace("userAccountControl", []string{"512"})
|
||||||
|
} else {
|
||||||
|
pwdEncoded = newPassword
|
||||||
|
modifyPasswordRequest.Replace("userPassword", []string{pwdEncoded})
|
||||||
|
}
|
||||||
|
|
||||||
|
err = conn.Conn.Modify(modifyPasswordRequest)
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ldapUser *LdapUser) buildLdapUserName(owner string) (string, error) {
|
func (ldapUser *LdapUser) buildLdapUserName(owner string) (string, error) {
|
||||||
user := User{}
|
user := User{}
|
||||||
uidWithNumber := fmt.Sprintf("%s_%s", ldapUser.Uid, ldapUser.UidNumber)
|
uidWithNumber := fmt.Sprintf("%s_%s", ldapUser.Uid, ldapUser.UidNumber)
|
||||||
|
@ -504,7 +504,7 @@ func GetPasswordToken(application *Application, username string, password string
|
|||||||
}
|
}
|
||||||
|
|
||||||
if user.Ldap != "" {
|
if user.Ldap != "" {
|
||||||
err = checkLdapUserPassword(user, password, "en")
|
err = CheckLdapUserPassword(user, password, "en")
|
||||||
} else {
|
} else {
|
||||||
err = CheckPassword(user, password, "en")
|
err = CheckPassword(user, password, "en")
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user