mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 03:18:24 +00:00 
			
		
		
		
	Merge branch 'develop' of github.com:gogits/gogs into develop
This commit is contained in:
		| @@ -6,7 +6,9 @@ go: | |||||||
|   - 1.4 |   - 1.4 | ||||||
|   - tip |   - tip | ||||||
|  |  | ||||||
| sudo: false | before_install: | ||||||
|  |   - sudo apt-get update -qq | ||||||
|  |   - sudo apt-get install -y libpam-dev | ||||||
|  |  | ||||||
| script: go build -v | script: go build -v | ||||||
|  |  | ||||||
|   | |||||||
| @@ -102,7 +102,7 @@ func runServ(c *cli.Context) { | |||||||
|  |  | ||||||
| 	cmd := os.Getenv("SSH_ORIGINAL_COMMAND") | 	cmd := os.Getenv("SSH_ORIGINAL_COMMAND") | ||||||
| 	if cmd == "" { | 	if cmd == "" { | ||||||
| 		println("Hi", user.Name, "! You've successfully authenticated, but Gogs does not provide shell access.") | 		fmt.Printf("Hi, %s! You've successfully authenticated, but Gogs does not provide shell access.\n", user.Name) | ||||||
| 		if user.IsAdmin { | 		if user.IsAdmin { | ||||||
| 			println("If this is unexpected, please log in with password and setup Gogs under another user.") | 			println("If this is unexpected, please log in with password and setup Gogs under another user.") | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -619,6 +619,7 @@ auths.smtp_auth = SMTP Authorization Type | |||||||
| auths.smtphost = SMTP Host | auths.smtphost = SMTP Host | ||||||
| auths.smtpport = SMTP Port | auths.smtpport = SMTP Port | ||||||
| auths.enable_tls = Enable TLS Encryption | auths.enable_tls = Enable TLS Encryption | ||||||
|  | auths.pam_service_name = PAM Service Name | ||||||
| auths.enable_auto_register = Enable Auto Registration | auths.enable_auto_register = Enable Auto Registration | ||||||
| auths.tips = Tips | auths.tips = Tips | ||||||
| auths.edit = Edit Authorization Setting | auths.edit = Edit Authorization Setting | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ import ( | |||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
|  |  | ||||||
| 	"github.com/gogits/gogs/modules/auth/ldap" | 	"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/log" | ||||||
| 	"github.com/gogits/gogs/modules/uuid" | 	"github.com/gogits/gogs/modules/uuid" | ||||||
| ) | ) | ||||||
| @@ -28,6 +29,7 @@ const ( | |||||||
| 	PLAIN | 	PLAIN | ||||||
| 	LDAP | 	LDAP | ||||||
| 	SMTP | 	SMTP | ||||||
|  | 	PAM | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| @@ -39,12 +41,14 @@ var ( | |||||||
| var LoginTypes = map[LoginType]string{ | var LoginTypes = map[LoginType]string{ | ||||||
| 	LDAP: "LDAP", | 	LDAP: "LDAP", | ||||||
| 	SMTP: "SMTP", | 	SMTP: "SMTP", | ||||||
|  | 	PAM: "PAM", | ||||||
| } | } | ||||||
|  |  | ||||||
| // Ensure structs implemented interface. | // Ensure structs implemented interface. | ||||||
| var ( | var ( | ||||||
| 	_ core.Conversion = &LDAPConfig{} | 	_ core.Conversion = &LDAPConfig{} | ||||||
| 	_ core.Conversion = &SMTPConfig{} | 	_ core.Conversion = &SMTPConfig{} | ||||||
|  | 	_ core.Conversion = &PAMConfig{} | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type LDAPConfig struct { | type LDAPConfig struct { | ||||||
| @@ -74,6 +78,18 @@ func (cfg *SMTPConfig) ToDB() ([]byte, error) { | |||||||
| 	return json.Marshal(cfg) | 	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 { | type LoginSource struct { | ||||||
| 	Id                int64 | 	Id                int64 | ||||||
| 	Type              LoginType | 	Type              LoginType | ||||||
| @@ -97,6 +113,10 @@ func (source *LoginSource) SMTP() *SMTPConfig { | |||||||
| 	return source.Cfg.(*SMTPConfig) | 	return source.Cfg.(*SMTPConfig) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (source *LoginSource) PAM() *PAMConfig { | ||||||
|  | 	return source.Cfg.(*PAMConfig) | ||||||
|  | } | ||||||
|  |  | ||||||
| func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { | func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { | ||||||
| 	if colName == "type" { | 	if colName == "type" { | ||||||
| 		ty := (*val).(int64) | 		ty := (*val).(int64) | ||||||
| @@ -105,6 +125,8 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { | |||||||
| 			source.Cfg = new(LDAPConfig) | 			source.Cfg = new(LDAPConfig) | ||||||
| 		case SMTP: | 		case SMTP: | ||||||
| 			source.Cfg = new(SMTPConfig) | 			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. | 	// For plain login, user must exist to reach this line. | ||||||
| 	// Now verify password. | 	// Now verify password. | ||||||
| 	if u.LoginType == PLAIN { | 	if u.LoginType == PLAIN { | ||||||
| 		if !u.ValidtePassword(passwd) { | 		if !u.ValidatePassword(passwd) { | ||||||
| 			return nil, ErrUserNotExist | 			return nil, ErrUserNotExist | ||||||
| 		} | 		} | ||||||
| 		return u, nil | 		return u, nil | ||||||
| @@ -197,6 +219,13 @@ func UserSignIn(uname, passwd string) (*User, error) { | |||||||
| 					return u, nil | 					return u, nil | ||||||
| 				} | 				} | ||||||
| 				log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err) | 				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) | 		return LoginUserLdapSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*LDAPConfig), false) | ||||||
| 	case SMTP: | 	case SMTP: | ||||||
| 		return LoginUserSMTPSource(u, u.LoginName, passwd, source.Id, source.Cfg.(*SMTPConfig), false) | 		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 | 	return nil, ErrUnsupportedLoginType | ||||||
| } | } | ||||||
| @@ -359,3 +390,33 @@ func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTP | |||||||
| 	err := CreateUser(u) | 	err := CreateUser(u) | ||||||
| 	return u, err | 	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 | ||||||
|  | } | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ var ( | |||||||
| 	ErrRepoFileNotLoaded = errors.New("Repository file not loaded") | 	ErrRepoFileNotLoaded = errors.New("Repository file not loaded") | ||||||
| 	ErrMirrorNotExist    = errors.New("Mirror does not exist") | 	ErrMirrorNotExist    = errors.New("Mirror does not exist") | ||||||
| 	ErrInvalidReference  = errors.New("Invalid reference specified") | 	ErrInvalidReference  = errors.New("Invalid reference specified") | ||||||
|  | 	ErrNameEmpty         = errors.New("Name is empty") | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| @@ -242,10 +243,11 @@ func (repo *Repository) CloneLink() (cl CloneLink, err error) { | |||||||
| 	if err = repo.GetOwner(); err != nil { | 	if err = repo.GetOwner(); err != nil { | ||||||
| 		return cl, err | 		return cl, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if setting.SSHPort != 22 { | 	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 { | 	} 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) | 	cl.HTTPS = fmt.Sprintf("%s%s/%s.git", setting.AppUrl, repo.Owner.LowerName, repo.LowerName) | ||||||
| 	return cl, nil | 	return cl, nil | ||||||
| @@ -258,7 +260,11 @@ var ( | |||||||
|  |  | ||||||
| // IsUsableName checks if name is reserved or pattern of name is not allowed. | // IsUsableName checks if name is reserved or pattern of name is not allowed. | ||||||
| func IsUsableName(name string) error { | 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 { | 	for i := range reservedNames { | ||||||
| 		if name == reservedNames[i] { | 		if name == reservedNames[i] { | ||||||
| 			return ErrNameReserved{name} | 			return ErrNameReserved{name} | ||||||
|   | |||||||
| @@ -143,8 +143,8 @@ func (u *User) EncodePasswd() { | |||||||
| 	u.Passwd = fmt.Sprintf("%x", newPasswd) | 	u.Passwd = fmt.Sprintf("%x", newPasswd) | ||||||
| } | } | ||||||
|  |  | ||||||
| // ValidtePassword checks if given password matches the one belongs to the user. | // ValidatePassword checks if given password matches the one belongs to the user. | ||||||
| func (u *User) ValidtePassword(passwd string) bool { | func (u *User) ValidatePassword(passwd string) bool { | ||||||
| 	newUser := &User{Passwd: passwd, Salt: u.Salt} | 	newUser := &User{Passwd: passwd, Salt: u.Salt} | ||||||
| 	newUser.EncodePasswd() | 	newUser.EncodePasswd() | ||||||
| 	return u.Passwd == newUser.Passwd | 	return u.Passwd == newUser.Passwd | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ type AuthenticationForm struct { | |||||||
| 	SMTPPort          int    `form:"smtp_port"` | 	SMTPPort          int    `form:"smtp_port"` | ||||||
| 	TLS               bool   `form:"tls"` | 	TLS               bool   `form:"tls"` | ||||||
| 	AllowAutoRegister bool   `form:"allowautoregister"` | 	AllowAutoRegister bool   `form:"allowautoregister"` | ||||||
|  | 	PAMServiceName    string | ||||||
| } | } | ||||||
|  |  | ||||||
| func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								modules/auth/pam/pam.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								modules/auth/pam/pam.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | // +build !windows | ||||||
|  |  | ||||||
|  | // Copyright 2014 The Gogs Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package pam | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  |  | ||||||
|  | 	"github.com/msteinert/pam" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func PAMAuth(serviceName, userName, passwd string) error { | ||||||
|  | 	t, err := pam.StartFunc(serviceName, userName, func(s pam.Style, msg string) (string, error) { | ||||||
|  | 		switch s { | ||||||
|  | 		case pam.PromptEchoOff: | ||||||
|  | 			return passwd, nil | ||||||
|  | 		case pam.PromptEchoOn, pam.ErrorMsg, pam.TextInfo: | ||||||
|  | 			return "", nil | ||||||
|  | 		} | ||||||
|  | 		return "", errors.New("Unrecognized PAM message style") | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err = t.Authenticate(0); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								modules/auth/pam/pam_stub.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								modules/auth/pam/pam_stub.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | // +build windows | ||||||
|  |  | ||||||
|  | // Copyright 2014 The Gogs Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package pam | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func PAMAuth(serviceName, userName, passwd string) error { | ||||||
|  | 	return errors.New("PAM not supported") | ||||||
|  | } | ||||||
| @@ -139,6 +139,13 @@ func (ctx *Context) Handle(status int, title string, err error) { | |||||||
| 	ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status))) | 	ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status))) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (ctx *Context) HandleText(status int, title string) { | ||||||
|  | 	if (status / 100 == 4) || (status / 100 == 5) { | ||||||
|  | 		log.Error(4, "%s", title) | ||||||
|  | 	} | ||||||
|  | 	ctx.RenderData(status, []byte(title)) | ||||||
|  | } | ||||||
|  |  | ||||||
| func (ctx *Context) HandleAPI(status int, obj interface{}) { | func (ctx *Context) HandleAPI(status int, obj interface{}) { | ||||||
| 	var message string | 	var message string | ||||||
| 	if err, ok := obj.(error); ok { | 	if err, ok := obj.(error); ok { | ||||||
|   | |||||||
| @@ -53,6 +53,7 @@ var ( | |||||||
| 	HttpAddr, HttpPort string | 	HttpAddr, HttpPort string | ||||||
| 	DisableSSH         bool | 	DisableSSH         bool | ||||||
| 	SSHPort            int | 	SSHPort            int | ||||||
|  | 	SSHDomain          string | ||||||
| 	OfflineMode        bool | 	OfflineMode        bool | ||||||
| 	DisableRouterLog   bool | 	DisableRouterLog   bool | ||||||
| 	CertFile, KeyFile  string | 	CertFile, KeyFile  string | ||||||
| @@ -232,6 +233,7 @@ func NewConfigContext() { | |||||||
| 	HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0") | 	HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0") | ||||||
| 	HttpPort = sec.Key("HTTP_PORT").MustString("3000") | 	HttpPort = sec.Key("HTTP_PORT").MustString("3000") | ||||||
| 	DisableSSH = sec.Key("DISABLE_SSH").MustBool() | 	DisableSSH = sec.Key("DISABLE_SSH").MustBool() | ||||||
|  | 	SSHDomain = sec.Key("SSH_DOMAIN").MustString(Domain) | ||||||
| 	SSHPort = sec.Key("SSH_PORT").MustInt(22) | 	SSHPort = sec.Key("SSH_PORT").MustInt(22) | ||||||
| 	OfflineMode = sec.Key("OFFLINE_MODE").MustBool() | 	OfflineMode = sec.Key("OFFLINE_MODE").MustBool() | ||||||
| 	DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool() | 	DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool() | ||||||
|   | |||||||
| @@ -753,10 +753,17 @@ function initAdmin() { | |||||||
|         if (v == 2) { |         if (v == 2) { | ||||||
|             $('.ldap').toggleShow(); |             $('.ldap').toggleShow(); | ||||||
|             $('.smtp').toggleHide(); |             $('.smtp').toggleHide(); | ||||||
|  |             $('.pam').toggleHide(); | ||||||
|         } |         } | ||||||
|         if (v == 3) { |         if (v == 3) { | ||||||
|             $('.smtp').toggleShow(); |             $('.smtp').toggleShow(); | ||||||
|             $('.ldap').toggleHide(); |             $('.ldap').toggleHide(); | ||||||
|  |             $('.pam').toggleHide(); | ||||||
|  |         } | ||||||
|  |         if (v == 4) { | ||||||
|  |             $('.pam').toggleShow(); | ||||||
|  |             $('.smtp').toggleHide(); | ||||||
|  |             $('.ldap').toggleHide(); | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -25,6 +25,11 @@ The register and sign-in page style | |||||||
|   .form-label { |   .form-label { | ||||||
|     width: 160px; |     width: 160px; | ||||||
|   } |   } | ||||||
|  |   .chk-label { | ||||||
|  |     width: auto; | ||||||
|  |     text-align: left; | ||||||
|  |     margin-left: 176px; | ||||||
|  |   } | ||||||
|   .alert{ |   .alert{ | ||||||
|     margin:0 30px 24px 30px; |     margin:0 30px 24px 30px; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -84,6 +84,10 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||||||
| 			Port: form.SMTPPort, | 			Port: form.SMTPPort, | ||||||
| 			TLS:  form.TLS, | 			TLS:  form.TLS, | ||||||
| 		} | 		} | ||||||
|  | 	case models.PAM: | ||||||
|  | 		u = &models.PAMConfig{ | ||||||
|  | 			ServiceName: form.PAMServiceName, | ||||||
|  | 		} | ||||||
| 	default: | 	default: | ||||||
| 		ctx.Error(400) | 		ctx.Error(400) | ||||||
| 		return | 		return | ||||||
| @@ -166,6 +170,10 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||||||
| 			Port: form.SMTPPort, | 			Port: form.SMTPPort, | ||||||
| 			TLS:  form.TLS, | 			TLS:  form.TLS, | ||||||
| 		} | 		} | ||||||
|  | 	case models.PAM: | ||||||
|  | 		config = &models.PAMConfig{ | ||||||
|  | 			ServiceName: form.PAMServiceName, | ||||||
|  | 		} | ||||||
| 	default: | 	default: | ||||||
| 		ctx.Error(400) | 		ctx.Error(400) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -164,7 +164,7 @@ func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) { | |||||||
| 		} | 		} | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if !u.ValidtePassword(ctx.Query("password")) { | 	if !u.ValidatePassword(ctx.Query("password")) { | ||||||
| 		ctx.HandleAPI(422, "Username or password is not correct.") | 		ctx.HandleAPI(422, "Username or password is not correct.") | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -96,12 +96,12 @@ func Http(ctx *middleware.Context) { | |||||||
| 		// FIXME: middlewares/context.go did basic auth check already, | 		// FIXME: middlewares/context.go did basic auth check already, | ||||||
| 		// maybe could use that one. | 		// maybe could use that one. | ||||||
| 		if len(auths) != 2 || auths[0] != "Basic" { | 		if len(auths) != 2 || auths[0] != "Basic" { | ||||||
| 			ctx.Handle(401, "no basic auth and digit auth", nil) | 			ctx.HandleText(401, "no basic auth and digit auth") | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		authUsername, authPasswd, err = base.BasicAuthDecode(auths[1]) | 		authUsername, authPasswd, err = base.BasicAuthDecode(auths[1]) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Handle(401, "no basic auth and digit auth", nil) | 			ctx.HandleText(401, "no basic auth and digit auth") | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -116,7 +116,7 @@ func Http(ctx *middleware.Context) { | |||||||
| 			token, err := models.GetAccessTokenBySha(authUsername) | 			token, err := models.GetAccessTokenBySha(authUsername) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				if err == models.ErrAccessTokenNotExist { | 				if err == models.ErrAccessTokenNotExist { | ||||||
| 					ctx.Handle(401, "invalid token", nil) | 					ctx.HandleText(401, "invalid token") | ||||||
| 				} else { | 				} else { | ||||||
| 					ctx.Handle(500, "GetAccessTokenBySha", err) | 					ctx.Handle(500, "GetAccessTokenBySha", err) | ||||||
| 				} | 				} | ||||||
| @@ -138,23 +138,23 @@ func Http(ctx *middleware.Context) { | |||||||
|  |  | ||||||
| 			has, err := models.HasAccess(authUser, repo, tp) | 			has, err := models.HasAccess(authUser, repo, tp) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				ctx.Handle(401, "no basic auth and digit auth", nil) | 				ctx.HandleText(401, "no basic auth and digit auth") | ||||||
| 				return | 				return | ||||||
| 			} else if !has { | 			} else if !has { | ||||||
| 				if tp == models.ACCESS_MODE_READ { | 				if tp == models.ACCESS_MODE_READ { | ||||||
| 					has, err = models.HasAccess(authUser, repo, models.ACCESS_MODE_WRITE) | 					has, err = models.HasAccess(authUser, repo, models.ACCESS_MODE_WRITE) | ||||||
| 					if err != nil || !has { | 					if err != nil || !has { | ||||||
| 						ctx.Handle(401, "no basic auth and digit auth", nil) | 						ctx.HandleText(401, "no basic auth and digit auth") | ||||||
| 						return | 						return | ||||||
| 					} | 					} | ||||||
| 				} else { | 				} else { | ||||||
| 					ctx.Handle(401, "no basic auth and digit auth", nil) | 					ctx.HandleText(401, "no basic auth and digit auth") | ||||||
| 					return | 					return | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if !isPull && repo.IsMirror { | 			if !isPull && repo.IsMirror { | ||||||
| 				ctx.Handle(401, "can't push to mirror", nil) | 				ctx.HandleText(401, "can't push to mirror") | ||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ LOGFILE=${GOGS_HOME}/log/gogs.log | |||||||
| RETVAL=0 | RETVAL=0 | ||||||
|  |  | ||||||
| # Read configuration from /etc/sysconfig/gogs to override defaults | # Read configuration from /etc/sysconfig/gogs to override defaults | ||||||
| [ -r /etc/sysconfig/$NAME ] && ./etc/sysconfig/$NAME | [ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME | ||||||
|  |  | ||||||
| # Don't do anything if nothing is installed | # Don't do anything if nothing is installed | ||||||
| [ -x ${GOGS_PATH} ] || exit 0 | [ -x ${GOGS_PATH} ] || exit 0 | ||||||
|   | |||||||
| @@ -91,6 +91,12 @@ | |||||||
|                                     <label class="req" for="smtp_port">{{.i18n.Tr "admin.auths.smtpport"}}</label> |                                     <label class="req" for="smtp_port">{{.i18n.Tr "admin.auths.smtpport"}}</label> | ||||||
|                                     <input class="ipt ipt-large ipt-radius {{if .Err_SmtpPort}}ipt-error{{end}}" id="smtp_port" name="smtp_port" value="{{.Source.SMTP.Port}}" /> |                                     <input class="ipt ipt-large ipt-radius {{if .Err_SmtpPort}}ipt-error{{end}}" id="smtp_port" name="smtp_port" value="{{.Source.SMTP.Port}}" /> | ||||||
|                                 </div> |                                 </div> | ||||||
|  |  | ||||||
|  |                                 {{else if eq $type 4}} | ||||||
|  |                                 <div class="field"> | ||||||
|  |                                     <label class="req" for="pam_service_name">{{.i18n.Tr "admin.auths.pam_service_name"}}</label> | ||||||
|  |                                     <input class="ipt ipt-large ipt-radius {{if .Err_PAMServiceName}}ipt-error{{end}}" id="pam_service_name" name="pam_service_name" value="{{.Source.PAM.ServiceName}}" /> | ||||||
|  |                                 </div> | ||||||
|                                 {{end}} |                                 {{end}} | ||||||
|  |  | ||||||
|                                 <div class="field"> |                                 <div class="field"> | ||||||
|   | |||||||
| @@ -86,6 +86,12 @@ | |||||||
|                                         <input class="ipt ipt-large ipt-radius {{if .Err_SmtpPort}}ipt-error{{end}}" id="smtp_port" name="smtp_port" value="{{.smtp_port}}" /> |                                         <input class="ipt ipt-large ipt-radius {{if .Err_SmtpPort}}ipt-error{{end}}" id="smtp_port" name="smtp_port" value="{{.smtp_port}}" /> | ||||||
|                                     </div> |                                     </div> | ||||||
|                                 </div> |                                 </div> | ||||||
|  |                                 <div class="pam hidden"> | ||||||
|  |                                     <div class="field"> | ||||||
|  |                                         <label class="req" for="pam_service_name">{{.i18n.Tr "admin.auths.pam_service_name"}}</label> | ||||||
|  |                                         <input class="ipt ipt-large ipt-radius {{if .Err_PAMServiceName}}ipt-error{{end}}" id="pam_service_name" name="pam_service_name" value="{{.pam_service_name}}" /> | ||||||
|  |                                     </div> | ||||||
|  |                                 </div> | ||||||
|                                 <div class="field"> |                                 <div class="field"> | ||||||
|                                     <div class="smtp hidden"> |                                     <div class="smtp hidden"> | ||||||
|                                         <label></label> |                                         <label></label> | ||||||
|   | |||||||
| @@ -12,7 +12,9 @@ | |||||||
|                             <li><i class="octicon octicon-star"></i> {{.NumStars}}</li> |                             <li><i class="octicon octicon-star"></i> {{.NumStars}}</li> | ||||||
|                             <li><i class="octicon octicon-git-branch"></i> {{.NumForks}}</li> |                             <li><i class="octicon octicon-git-branch"></i> {{.NumForks}}</li> | ||||||
|                         </ul> |                         </ul> | ||||||
| 						<h2><a href="{{AppSubUrl}}/{{.Owner.Name}}/{{.Name}}">{{.Name}}</a></h2> |                         <h2> | ||||||
|  |                             <a href="{{AppSubUrl}}/{{.Owner.Name}}/{{.Name}}">{{.Owner.Name}} / {{.Name}}</a> | ||||||
|  |                         </h2> | ||||||
|                         <p class="org-repo-description">{{.Description}}</p> |                         <p class="org-repo-description">{{.Description}}</p> | ||||||
|                         <p class="org-repo-updated">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}</p> |                         <p class="org-repo-updated">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}</p> | ||||||
|                     </div> |                     </div> | ||||||
|   | |||||||
| @@ -17,8 +17,9 @@ | |||||||
|             </div> |             </div> | ||||||
|             {{if not .IsSocialLogin}} |             {{if not .IsSocialLogin}} | ||||||
|             <div class="field"> |             <div class="field"> | ||||||
|                 <span class="form-label"></span> |                 <label class="chk-label"> | ||||||
|                     <input class="ipt-chk" id="remember" name="remember" type="checkbox"/>    <strong>{{.i18n.Tr "auth.remember_me"}}</strong> |                     <input class="ipt-chk" id="remember" name="remember" type="checkbox"/>    <strong>{{.i18n.Tr "auth.remember_me"}}</strong> | ||||||
|  |                 </label> | ||||||
|             </div> |             </div> | ||||||
|             {{end}} |             {{end}} | ||||||
|             <div class="field"> |             <div class="field"> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user