aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--models/login.go128
-rw-r--r--models/user.go38
-rw-r--r--modules/auth/auth.go1
-rw-r--r--modules/auth/ldap/ldap.go4
-rw-r--r--modules/auth/ldap/ldap_test.go32
-rw-r--r--routers/admin/user.go3
-rw-r--r--routers/user/user.go5
-rw-r--r--templates/admin/users/edit.tmpl7
-rw-r--r--templates/admin/users/new.tmpl7
9 files changed, 183 insertions, 42 deletions
diff --git a/models/login.go b/models/login.go
index 21e1ce686a..05ffac2c57 100644
--- a/models/login.go
+++ b/models/login.go
@@ -7,6 +7,7 @@ package models
import (
"encoding/json"
"errors"
+ "strings"
"time"
"github.com/go-xorm/core"
@@ -17,7 +18,8 @@ import (
// Login types.
const (
- LT_PLAIN = iota + 1
+ LT_NOTYPE = iota
+ LT_PLAIN
LT_LDAP
LT_SMTP
)
@@ -49,13 +51,14 @@ func (cfg *LDAPConfig) ToDB() ([]byte, error) {
}
type LoginSource struct {
- Id int64
- Type int
- Name string `xorm:"unique"`
- IsActived bool `xorm:"not null default false"`
- Cfg core.Conversion `xorm:"TEXT"`
- Created time.Time `xorm:"created"`
- Updated time.Time `xorm:"updated"`
+ Id int64
+ Type int
+ Name string `xorm:"unique"`
+ IsActived bool `xorm:"not null default false"`
+ Cfg core.Conversion `xorm:"TEXT"`
+ Created time.Time `xorm:"created"`
+ Updated time.Time `xorm:"updated"`
+ AllowAutoRegisted bool `xorm:"not null default false"`
}
func (source *LoginSource) TypeString() string {
@@ -120,3 +123,112 @@ func DelLoginSource(source *LoginSource) error {
_, err = orm.Id(source.Id).Delete(&LoginSource{})
return err
}
+
+// login a user
+func LoginUser(uname, passwd string) (*User, error) {
+ var u *User
+ var emailLogin bool
+ if strings.Contains(uname, "@") {
+ u = &User{Email: uname}
+ emailLogin = true
+ } else {
+ u = &User{LowerName: strings.ToLower(uname)}
+ }
+
+ has, err := orm.Get(u)
+ if err != nil {
+ return nil, err
+ }
+
+ // if email login, then we cannot auto register
+ if emailLogin {
+ if !has {
+ return nil, ErrUserNotExist
+ }
+ }
+ if u.LoginType == LT_NOTYPE {
+ u.LoginType = LT_PLAIN
+ }
+
+ // for plain login, user must have existed.
+ if u.LoginType == LT_PLAIN {
+ if !has {
+ return nil, ErrUserNotExist
+ }
+
+ newUser := &User{Passwd: passwd, Salt: u.Salt}
+ newUser.EncodePasswd()
+ if u.Passwd != newUser.Passwd {
+ return nil, ErrUserNotExist
+ }
+ return u, nil
+ } else {
+ if !has {
+ var sources []LoginSource
+ cond := &LoginSource{IsActived: true, AllowAutoRegisted: true}
+ err = orm.UseBool().Find(&sources, cond)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, source := range sources {
+ u, err := LoginUserLdapSource(nil, u.LoginName, passwd,
+ source.Id, source.Cfg.(*LDAPConfig), true)
+ if err == nil {
+ return u, err
+ }
+ }
+
+ return nil, ErrUserNotExist
+ }
+
+ var source LoginSource
+ hasSource, err := orm.Id(u.LoginSource).Get(&source)
+ if err != nil {
+ return nil, err
+ }
+ if !hasSource {
+ return nil, ErrLoginSourceNotExist
+ }
+
+ if !source.IsActived {
+ return nil, ErrLoginSourceNotActived
+ }
+
+ switch u.LoginType {
+ case LT_LDAP:
+ return LoginUserLdapSource(u, u.LoginName, passwd,
+ source.Id, source.Cfg.(*LDAPConfig), false)
+ case LT_SMTP:
+ }
+ return nil, ErrUnsupportedLoginType
+ }
+}
+
+// Query if name/passwd can login against the LDAP direcotry pool
+// Create a local user if success
+// Return the same LoginUserPlain semantic
+func LoginUserLdapSource(user *User, name, passwd string, sourceId int64, cfg *LDAPConfig, autoRegister bool) (*User, error) {
+ mail, logged := cfg.Ldapsource.SearchEntry(name, passwd)
+ if !logged {
+ // user not in LDAP, do nothing
+ return nil, ErrUserNotExist
+ }
+ if !autoRegister {
+ return user, nil
+ }
+
+ // fake a local user creation
+ user = &User{
+ LowerName: strings.ToLower(name),
+ Name: strings.ToLower(name),
+ LoginType: LT_LDAP,
+ LoginSource: sourceId,
+ LoginName: name,
+ IsActive: true,
+ Passwd: passwd,
+ Email: mail,
+ }
+
+ return RegisterUser(user)
+}
diff --git a/models/user.go b/models/user.go
index b2b16f1136..c5c474ee6f 100644
--- a/models/user.go
+++ b/models/user.go
@@ -27,11 +27,14 @@ const (
)
var (
- ErrUserOwnRepos = errors.New("User still have ownership of repositories")
- ErrUserAlreadyExist = errors.New("User already exist")
- ErrUserNotExist = errors.New("User does not exist")
- ErrEmailAlreadyUsed = errors.New("E-mail already used")
- ErrUserNameIllegal = errors.New("User name contains illegal characters")
+ ErrUserOwnRepos = errors.New("User still have ownership of repositories")
+ ErrUserAlreadyExist = errors.New("User already exist")
+ ErrUserNotExist = errors.New("User does not exist")
+ ErrEmailAlreadyUsed = errors.New("E-mail already used")
+ ErrUserNameIllegal = errors.New("User name contains illegal characters")
+ ErrLoginSourceNotExist = errors.New("Login source does not exist")
+ ErrLoginSourceNotActived = errors.New("Login source is not actived")
+ ErrUnsupportedLoginType = errors.New("Login source is unknow")
)
// User represents the object of individual and member of organization.
@@ -44,6 +47,7 @@ type User struct {
Passwd string `xorm:"not null"`
LoginType int
LoginSource int64 `xorm:"not null default 0"`
+ LoginName string
Type int
NumFollowers int
NumFollowings int
@@ -439,30 +443,6 @@ func SearchUserByName(key string, limit int) (us []*User, err error) {
return us, err
}
-// LoginUserPlain validates user by raw user name and password.
-func LoginUserPlain(uname, passwd string) (*User, error) {
- var u *User
- if strings.Contains(uname, "@") {
- u = &User{Email: uname}
- } else {
- u = &User{LowerName: strings.ToLower(uname)}
- }
-
- has, err := orm.Get(u)
- if err != nil {
- return nil, err
- } else if !has {
- return nil, ErrUserNotExist
- }
-
- newUser := &User{Passwd: passwd, Salt: u.Salt}
- newUser.EncodePasswd()
- if u.Passwd != newUser.Passwd {
- return nil, ErrUserNotExist
- }
- return u, nil
-}
-
// Follow is connection request for receiving user notifycation.
type Follow struct {
Id int64
diff --git a/modules/auth/auth.go b/modules/auth/auth.go
index 4587b3835b..eefb5ed6e3 100644
--- a/modules/auth/auth.go
+++ b/modules/auth/auth.go
@@ -27,6 +27,7 @@ type RegisterForm struct {
Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"`
RetypePasswd string `form:"retypepasswd"`
LoginType string `form:"logintype"`
+ LoginName string `form:"loginname"`
}
func (f *RegisterForm) Name(field string) string {
diff --git a/modules/auth/ldap/ldap.go b/modules/auth/ldap/ldap.go
index 8578e38a4d..493339cde0 100644
--- a/modules/auth/ldap/ldap.go
+++ b/modules/auth/ldap/ldap.go
@@ -42,7 +42,7 @@ func AddSource(name string, host string, port int, basedn string, attributes str
func LoginUser(name, passwd string) (a string, r bool) {
r = false
for _, ls := range Authensource {
- a, r = ls.searchEntry(name, passwd)
+ a, r = ls.SearchEntry(name, passwd)
if r {
return
}
@@ -51,7 +51,7 @@ func LoginUser(name, passwd string) (a string, r bool) {
}
// searchEntry : search an LDAP source if an entry (name, passwd) is valide and in the specific filter
-func (ls Ldapsource) searchEntry(name, passwd string) (string, bool) {
+func (ls Ldapsource) SearchEntry(name, passwd string) (string, bool) {
l, err := goldap.Dial("tcp", fmt.Sprintf("%s:%d", ls.Host, ls.Port))
if err != nil {
log.Debug("LDAP Connect error, disabled source %s", ls.Host)
diff --git a/modules/auth/ldap/ldap_test.go b/modules/auth/ldap/ldap_test.go
new file mode 100644
index 0000000000..8096573782
--- /dev/null
+++ b/modules/auth/ldap/ldap_test.go
@@ -0,0 +1,32 @@
+package ldap
+
+import (
+ "fmt"
+ "testing"
+)
+
+var ldapServer = "ldap.itd.umich.edu"
+var ldapPort = uint16(389)
+var baseDN = "dc=umich,dc=edu"
+var filter = []string{
+ "(cn=cis-fac)",
+ "(&(objectclass=rfc822mailgroup)(cn=*Computer*))",
+ "(&(objectclass=rfc822mailgroup)(cn=*Mathematics*))"}
+var attributes = []string{
+ "cn",
+ "description"}
+var msadsaformat = ""
+
+func TestLDAP(t *testing.T) {
+ AddSource("test", ldapServer, ldapPort,
+ basedn, attributes, filter,
+ msadsaformat)
+ user, err := LoginUserLdap("xiaolunwen", "")
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ fmt.Println(user)
+
+}
diff --git a/routers/admin/user.go b/routers/admin/user.go
index 0d60ee9a76..fa98bd32ea 100644
--- a/routers/admin/user.go
+++ b/routers/admin/user.go
@@ -58,7 +58,8 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) {
fields := strings.Split(form.LoginType, "-")
u.LoginType, _ = strconv.Atoi(fields[0])
u.LoginSource, _ = strconv.ParseInt(fields[1], 10, 64)
- fmt.Println(u.LoginSource)
+ u.LoginName = form.LoginName
+ fmt.Println(u.LoginType, u.LoginSource, u.LoginName)
}
var err error
diff --git a/routers/user/user.go b/routers/user/user.go
index e33353abdb..6a7d016612 100644
--- a/routers/user/user.go
+++ b/routers/user/user.go
@@ -92,7 +92,7 @@ func SignInPost(ctx *middleware.Context, form auth.LogInForm) {
var user *models.User
var err error
- if base.Service.LdapAuth {
+ /*if base.Service.LdapAuth {
user, err = models.LoginUserLdap(form.UserName, form.Password)
if err != nil {
log.Error("Fail to login through LDAP: %v", err)
@@ -101,7 +101,8 @@ func SignInPost(ctx *middleware.Context, form auth.LogInForm) {
// try local if not LDAP or it's failed
if !base.Service.LdapAuth || err != nil {
user, err = models.LoginUserPlain(form.UserName, form.Password)
- }
+ }*/
+ user, err = models.LoginUser(form.UserName, form.Password)
if err != nil {
if err == models.ErrUserNotExist {
log.Trace("%s Log in failed: %s/%s", ctx.Req.RequestURI, form.UserName, form.Password)
diff --git a/templates/admin/users/edit.tmpl b/templates/admin/users/edit.tmpl
index 1fb29234ed..4995856768 100644
--- a/templates/admin/users/edit.tmpl
+++ b/templates/admin/users/edit.tmpl
@@ -27,6 +27,13 @@
</div>
<div class="form-group">
+ <label class="col-md-3 control-label">Auth Login Name: </label>
+ <div class="col-md-7">
+ <input name="loginname" class="form-control" placeholder="Type auth login's username" value="{{.loginname}}">
+ </div>
+ </div>
+
+ <div class="form-group">
<label class="col-md-3 control-label">Username: </label>
<label class="control-label">{{.User.Name}}</label>
</div>
diff --git a/templates/admin/users/new.tmpl b/templates/admin/users/new.tmpl
index 88da16aa4e..b4843a99ca 100644
--- a/templates/admin/users/new.tmpl
+++ b/templates/admin/users/new.tmpl
@@ -24,6 +24,13 @@
</select>
</div>
</div>
+
+ <div class="form-group">
+ <label class="col-md-3 control-label">Auth Login Name: </label>
+ <div class="col-md-7">
+ <input name="loginname" class="form-control" placeholder="Type auth login's username" value="{{.loginname}}">
+ </div>
+ </div>
<div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}">
<label class="col-md-3 control-label">Username: </label>