diff options
author | Unknwon <u@gogs.io> | 2015-04-24 05:21:10 -0400 |
---|---|---|
committer | Unknwon <u@gogs.io> | 2015-04-24 05:21:10 -0400 |
commit | c08baee0855807d24a1b86adfcea86d0731e2a3a (patch) | |
tree | c033d0fd4a4c4104b0b6304ec9f2a26c6047ce10 /models | |
parent | 7a7c096fd09035f759168800402389457648f47e (diff) | |
parent | f92bdf875b4ccb2a8eadaa571d112ebf653986d6 (diff) |
Merge branch 'develop' of github.com:gogits/gogs into develop
Diffstat (limited to 'models')
-rw-r--r-- | models/login.go | 63 | ||||
-rw-r--r-- | models/repo.go | 12 | ||||
-rw-r--r-- | models/user.go | 4 |
3 files changed, 73 insertions, 6 deletions
diff --git a/models/login.go b/models/login.go index 916e2731..10f782be 100644 --- a/models/login.go +++ b/models/login.go @@ -17,6 +17,7 @@ import ( "github.com/go-xorm/xorm" "github.com/gogits/gogs/modules/auth/ldap" + "github.com/gogits/gogs/modules/auth/pam" "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/uuid" ) @@ -28,6 +29,7 @@ const ( PLAIN LDAP SMTP + PAM ) var ( @@ -39,12 +41,14 @@ var ( var LoginTypes = map[LoginType]string{ LDAP: "LDAP", SMTP: "SMTP", + PAM: "PAM", } // Ensure structs implemented interface. var ( _ core.Conversion = &LDAPConfig{} _ core.Conversion = &SMTPConfig{} + _ core.Conversion = &PAMConfig{} ) type LDAPConfig struct { @@ -74,6 +78,18 @@ func (cfg *SMTPConfig) ToDB() ([]byte, error) { return json.Marshal(cfg) } +type PAMConfig struct { + ServiceName string // pam service (e.g. system-auth) +} + +func (cfg *PAMConfig) FromDB(bs []byte) error { + return json.Unmarshal(bs, &cfg) +} + +func (cfg *PAMConfig) ToDB() ([]byte, error) { + return json.Marshal(cfg) +} + type LoginSource struct { Id int64 Type LoginType @@ -97,6 +113,10 @@ func (source *LoginSource) SMTP() *SMTPConfig { return source.Cfg.(*SMTPConfig) } +func (source *LoginSource) PAM() *PAMConfig { + return source.Cfg.(*PAMConfig) +} + func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { if colName == "type" { ty := (*val).(int64) @@ -105,6 +125,8 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { source.Cfg = new(LDAPConfig) case SMTP: source.Cfg = new(SMTPConfig) + case PAM: + source.Cfg = new(PAMConfig) } } } @@ -169,7 +191,7 @@ func UserSignIn(uname, passwd string) (*User, error) { // For plain login, user must exist to reach this line. // Now verify password. if u.LoginType == PLAIN { - if !u.ValidtePassword(passwd) { + if !u.ValidatePassword(passwd) { return nil, ErrUserNotExist } return u, nil @@ -197,6 +219,13 @@ func UserSignIn(uname, passwd string) (*User, error) { return u, nil } log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err) + } else if source.Type == PAM { + u, err := LoginUserPAMSource(nil, uname, passwd, + source.Id, source.Cfg.(*PAMConfig), true) + if err == nil { + return u, nil + } + log.Warn("Fail to login(%s) by PAM(%s): %v", uname, source.Name, err) } } @@ -218,6 +247,8 @@ func UserSignIn(uname, passwd string) (*User, error) { return LoginUserLdapSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*LDAPConfig), false) case SMTP: return LoginUserSMTPSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*SMTPConfig), false) + case PAM: + return LoginUserPAMSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*PAMConfig), false) } return nil, ErrUnsupportedLoginType } @@ -359,3 +390,33 @@ func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTP err := CreateUser(u) return u, err } + +// Query if name/passwd can login against PAM +// Create a local user if success +// Return the same LoginUserPlain semantic +func LoginUserPAMSource(u *User, name, passwd string, sourceId int64, cfg *PAMConfig, autoRegister bool) (*User, error) { + if err := pam.PAMAuth(cfg.ServiceName, name, passwd); err != nil { + if strings.Contains(err.Error(), "Authentication failure") { + return nil, ErrUserNotExist + } + return nil, err + } + + if !autoRegister { + return u, nil + } + + // fake a local user creation + u = &User{ + LowerName: strings.ToLower(name), + Name: strings.ToLower(name), + LoginType: PAM, + LoginSource: sourceId, + LoginName: name, + IsActive: true, + Passwd: passwd, + Email: name, + } + err := CreateUser(u) + return u, err +} diff --git a/models/repo.go b/models/repo.go index 7b47c20b..f144be5a 100644 --- a/models/repo.go +++ b/models/repo.go @@ -40,6 +40,7 @@ var ( ErrRepoFileNotLoaded = errors.New("Repository file not loaded") ErrMirrorNotExist = errors.New("Mirror does not exist") ErrInvalidReference = errors.New("Invalid reference specified") + ErrNameEmpty = errors.New("Name is empty") ) var ( @@ -242,10 +243,11 @@ func (repo *Repository) CloneLink() (cl CloneLink, err error) { if err = repo.GetOwner(); err != nil { return cl, err } + if setting.SSHPort != 22 { - cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.Domain, setting.SSHPort, repo.Owner.LowerName, repo.LowerName) + cl.SSH = fmt.Sprintf("ssh://%s@%s:%d/%s/%s.git", setting.RunUser, setting.SSHDomain, setting.SSHPort, repo.Owner.LowerName, repo.LowerName) } else { - cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.Domain, repo.Owner.LowerName, repo.LowerName) + cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", setting.RunUser, setting.SSHDomain, repo.Owner.LowerName, repo.LowerName) } cl.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, repo.Owner.LowerName, repo.LowerName) return cl, nil @@ -258,7 +260,11 @@ var ( // IsUsableName checks if name is reserved or pattern of name is not allowed. func IsUsableName(name string) error { - name = strings.ToLower(name) + name = strings.TrimSpace(strings.ToLower(name)) + if utf8.RuneCountInString(name) == 0 { + return ErrNameEmpty + } + for i := range reservedNames { if name == reservedNames[i] { return ErrNameReserved{name} diff --git a/models/user.go b/models/user.go index bf69f97a..e239ea17 100644 --- a/models/user.go +++ b/models/user.go @@ -143,8 +143,8 @@ func (u *User) EncodePasswd() { u.Passwd = fmt.Sprintf("%x", newPasswd) } -// ValidtePassword checks if given password matches the one belongs to the user. -func (u *User) ValidtePassword(passwd string) bool { +// ValidatePassword checks if given password matches the one belongs to the user. +func (u *User) ValidatePassword(passwd string) bool { newUser := &User{Passwd: passwd, Salt: u.Salt} newUser.EncodePasswd() return u.Passwd == newUser.Passwd |