mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	#1625 remove auto_register and makes it default
This commit is contained in:
		| @@ -61,8 +61,8 @@ The goal of this project is to make the easiest, fastest, and most painless way | |||||||
| - Gravatar and custom source support | - Gravatar and custom source support | ||||||
| - Mail service | - Mail service | ||||||
| - Administration panel | - Administration panel | ||||||
| - Supports MySQL, PostgreSQL and SQLite3 | - CI integration: [Drone](https://github.com/drone/drone) | ||||||
| - Social account login (GitHub, Google, QQ, Weibo) | - Supports MySQL, PostgreSQL, SQLite3 and [TiDB](https://github.com/pingcap/tidb) | ||||||
| - Multi-language support ([14 languages](https://crowdin.com/project/gogs)) | - Multi-language support ([14 languages](https://crowdin.com/project/gogs)) | ||||||
|  |  | ||||||
| ## System Requirements | ## System Requirements | ||||||
|   | |||||||
| @@ -28,8 +28,8 @@ Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自 | |||||||
| - 支持 Gravatar 以及自定义源 | - 支持 Gravatar 以及自定义源 | ||||||
| - 支持邮件服务 | - 支持邮件服务 | ||||||
| - 支持后台管理面板 | - 支持后台管理面板 | ||||||
| - 支持 MySQL、PostgreSQL 以及 SQLite3 数据库 | - 支持 CI 集成:[Drone](https://github.com/drone/drone) | ||||||
| - 支持社交帐号登录(GitHub、Google、QQ、微博) | - 支持 MySQL、PostgreSQL、SQLite3 和 [TiDB](https://github.com/pingcap/tidb) 数据库 | ||||||
| - 支持多语言本地化([14 种语言]([more](https://crowdin.com/project/gogs))) | - 支持多语言本地化([14 种语言]([more](https://crowdin.com/project/gogs))) | ||||||
|  |  | ||||||
| ## 系统要求 | ## 系统要求 | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ code = Code | |||||||
| [install] | [install] | ||||||
| install = Installation | install = Installation | ||||||
| title = Install Steps For First-time Run | title = Install Steps For First-time Run | ||||||
| requite_db_desc = Gogs requires MySQL, PostgreSQL or SQLite3. | requite_db_desc = Gogs requires MySQL, PostgreSQL, SQLite3 or TiDB. | ||||||
| db_title = Database Settings | db_title = Database Settings | ||||||
| db_type = Database Type | db_type = Database Type | ||||||
| host = Host | host = Host | ||||||
| @@ -64,7 +64,7 @@ db_name = Database Name | |||||||
| db_helper = Please use INNODB engine with utf8_general_ci charset for MySQL. | db_helper = Please use INNODB engine with utf8_general_ci charset for MySQL. | ||||||
| ssl_mode = SSL Mode | ssl_mode = SSL Mode | ||||||
| path = Path | path = Path | ||||||
| sqlite_helper = The file path of SQLite3 database. | sqlite_helper = The file path of SQLite3 or TiDB database. | ||||||
| err_empty_db_path = SQLite3 or TiDB database path cannot be empty. | err_empty_db_path = SQLite3 or TiDB database path cannot be empty. | ||||||
| err_invalid_tidb_name = TiDB database name does not allow characters "." and "-". | err_invalid_tidb_name = TiDB database name does not allow characters "." and "-". | ||||||
| no_admin_and_disable_registration = You cannot disable registration without creating an admin account. | no_admin_and_disable_registration = You cannot disable registration without creating an admin account. | ||||||
|   | |||||||
							
								
								
									
										179
									
								
								models/login.go
									
									
									
									
									
								
							
							
						
						
									
										179
									
								
								models/login.go
									
									
									
									
									
								
							| @@ -96,14 +96,13 @@ func (cfg *PAMConfig) ToDB() ([]byte, error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| type LoginSource struct { | type LoginSource struct { | ||||||
| 	ID                int64 `xorm:"pk autoincr"` | 	ID        int64 `xorm:"pk autoincr"` | ||||||
| 	Type              LoginType | 	Type      LoginType | ||||||
| 	Name              string          `xorm:"UNIQUE"` | 	Name      string          `xorm:"UNIQUE"` | ||||||
| 	IsActived         bool            `xorm:"NOT NULL DEFAULT false"` | 	IsActived bool            `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	Cfg               core.Conversion `xorm:"TEXT"` | 	Cfg       core.Conversion `xorm:"TEXT"` | ||||||
| 	AllowAutoRegister bool            `xorm:"NOT NULL DEFAULT false"` | 	Created   time.Time       `xorm:"CREATED"` | ||||||
| 	Created           time.Time       `xorm:"CREATED"` | 	Updated   time.Time       `xorm:"UPDATED"` | ||||||
| 	Updated           time.Time       `xorm:"UPDATED"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { | func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { | ||||||
| @@ -208,81 +207,18 @@ func DeleteSource(source *LoginSource) error { | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| // UserSignIn validates user name and password. | // .____     ________      _____ __________ | ||||||
| func UserSignIn(uname, passwd string) (*User, error) { | // |    |    \______ \    /  _  \\______   \ | ||||||
| 	var u *User | // |    |     |    |  \  /  /_\  \|     ___/ | ||||||
| 	if strings.Contains(uname, "@") { | // |    |___  |    `   \/    |    \    | | ||||||
| 		u = &User{Email: uname} | // |_______ \/_______  /\____|__  /____| | ||||||
| 	} else { | //         \/        \/         \/ | ||||||
| 		u = &User{LowerName: strings.ToLower(uname)} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	userExists, err := x.Get(u) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if userExists { |  | ||||||
| 		switch u.LoginType { |  | ||||||
| 		case NOTYPE, PLAIN: |  | ||||||
| 			if u.ValidatePassword(passwd) { |  | ||||||
| 				return u, nil |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			return nil, ErrUserNotExist{u.Id, u.Name} |  | ||||||
|  |  | ||||||
| 		default: |  | ||||||
| 			var source LoginSource |  | ||||||
| 			hasSource, err := x.Id(u.LoginSource).Get(&source) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, err |  | ||||||
| 			} else if !hasSource { |  | ||||||
| 				return nil, ErrLoginSourceNotExist |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			return ExternalUserLogin(u, u.LoginName, passwd, &source, false) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var sources []LoginSource |  | ||||||
| 	if err = x.UseBool().Find(&sources, &LoginSource{IsActived: true}); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for _, source := range sources { |  | ||||||
| 		u, err := ExternalUserLogin(nil, uname, passwd, &source, source.AllowAutoRegister) |  | ||||||
| 		if err == nil { |  | ||||||
| 			return u, nil |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		log.Warn("Failed to login '%s' via '%s': %v", uname, source.Name, err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil, ErrUserNotExist{u.Id, u.Name} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func ExternalUserLogin(u *User, name, passwd string, source *LoginSource, autoRegister bool) (*User, error) { |  | ||||||
| 	if !source.IsActived { |  | ||||||
| 		return nil, ErrLoginSourceNotActived |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	switch source.Type { |  | ||||||
| 	case LDAP, DLDAP: |  | ||||||
| 		return LoginUserLdapSource(u, name, passwd, source, autoRegister) |  | ||||||
| 	case SMTP: |  | ||||||
| 		return LoginUserSMTPSource(u, name, passwd, source.ID, source.Cfg.(*SMTPConfig), autoRegister) |  | ||||||
| 	case PAM: |  | ||||||
| 		return LoginUserPAMSource(u, name, passwd, source.ID, source.Cfg.(*PAMConfig), autoRegister) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil, ErrUnsupportedLoginType |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Query if name/passwd can login against the LDAP directory pool | // Query if name/passwd can login against the LDAP directory pool | ||||||
| // Create a local user if success | // Create a local user if success | ||||||
| // Return the same LoginUserPlain semantic | // Return the same LoginUserPlain semantic | ||||||
| // FIXME: https://github.com/gogits/gogs/issues/672 | // FIXME: https://github.com/gogits/gogs/issues/672 | ||||||
| func LoginUserLdapSource(u *User, name, passwd string, source *LoginSource, autoRegister bool) (*User, error) { | func LoginUserLDAPSource(u *User, name, passwd string, source *LoginSource, autoRegister bool) (*User, error) { | ||||||
| 	cfg := source.Cfg.(*LDAPConfig) | 	cfg := source.Cfg.(*LDAPConfig) | ||||||
| 	directBind := (source.Type == DLDAP) | 	directBind := (source.Type == DLDAP) | ||||||
| 	fn, sn, mail, admin, logged := cfg.Ldapsource.SearchEntry(name, passwd, directBind) | 	fn, sn, mail, admin, logged := cfg.Ldapsource.SearchEntry(name, passwd, directBind) | ||||||
| @@ -303,11 +239,10 @@ func LoginUserLdapSource(u *User, name, passwd string, source *LoginSource, auto | |||||||
| 	u = &User{ | 	u = &User{ | ||||||
| 		LowerName:   strings.ToLower(name), | 		LowerName:   strings.ToLower(name), | ||||||
| 		Name:        name, | 		Name:        name, | ||||||
| 		FullName:    fn + " " + sn, | 		FullName:    strings.TrimSpace(fn + " " + sn), | ||||||
| 		LoginType:   source.Type, | 		LoginType:   source.Type, | ||||||
| 		LoginSource: source.ID, | 		LoginSource: source.ID, | ||||||
| 		LoginName:   name, | 		LoginName:   name, | ||||||
| 		Passwd:      passwd, |  | ||||||
| 		Email:       mail, | 		Email:       mail, | ||||||
| 		IsAdmin:     admin, | 		IsAdmin:     admin, | ||||||
| 		IsActive:    true, | 		IsActive:    true, | ||||||
| @@ -315,6 +250,13 @@ func LoginUserLdapSource(u *User, name, passwd string, source *LoginSource, auto | |||||||
| 	return u, CreateUser(u) | 	return u, CreateUser(u) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //   _________   __________________________ | ||||||
|  | //  /   _____/  /     \__    ___/\______   \ | ||||||
|  | //  \_____  \  /  \ /  \|    |    |     ___/ | ||||||
|  | //  /        \/    Y    \    |    |    | | ||||||
|  | // /_______  /\____|__  /____|    |____| | ||||||
|  | //         \/         \/ | ||||||
|  |  | ||||||
| type loginAuth struct { | type loginAuth struct { | ||||||
| 	username, password string | 	username, password string | ||||||
| } | } | ||||||
| @@ -433,6 +375,13 @@ func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTP | |||||||
| 	return u, err | 	return u, err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // __________  _____      _____ | ||||||
|  | // \______   \/  _  \    /     \ | ||||||
|  | //  |     ___/  /_\  \  /  \ /  \ | ||||||
|  | //  |    |  /    |    \/    Y    \ | ||||||
|  | //  |____|  \____|__  /\____|__  / | ||||||
|  | //                  \/         \/ | ||||||
|  |  | ||||||
| // Query if name/passwd can login against PAM | // Query if name/passwd can login against PAM | ||||||
| // Create a local user if success | // Create a local user if success | ||||||
| // Return the same LoginUserPlain semantic | // Return the same LoginUserPlain semantic | ||||||
| @@ -462,3 +411,73 @@ func LoginUserPAMSource(u *User, name, passwd string, sourceId int64, cfg *PAMCo | |||||||
| 	err := CreateUser(u) | 	err := CreateUser(u) | ||||||
| 	return u, err | 	return u, err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func ExternalUserLogin(u *User, name, passwd string, source *LoginSource, autoRegister bool) (*User, error) { | ||||||
|  | 	if !source.IsActived { | ||||||
|  | 		return nil, ErrLoginSourceNotActived | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	switch source.Type { | ||||||
|  | 	case LDAP, DLDAP: | ||||||
|  | 		return LoginUserLDAPSource(u, name, passwd, source, autoRegister) | ||||||
|  | 	case SMTP: | ||||||
|  | 		return LoginUserSMTPSource(u, name, passwd, source.ID, source.Cfg.(*SMTPConfig), autoRegister) | ||||||
|  | 	case PAM: | ||||||
|  | 		return LoginUserPAMSource(u, name, passwd, source.ID, source.Cfg.(*PAMConfig), autoRegister) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil, ErrUnsupportedLoginType | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // UserSignIn validates user name and password. | ||||||
|  | func UserSignIn(uname, passwd string) (*User, error) { | ||||||
|  | 	var u *User | ||||||
|  | 	if strings.Contains(uname, "@") { | ||||||
|  | 		u = &User{Email: uname} | ||||||
|  | 	} else { | ||||||
|  | 		u = &User{LowerName: strings.ToLower(uname)} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	userExists, err := x.Get(u) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if userExists { | ||||||
|  | 		switch u.LoginType { | ||||||
|  | 		case NOTYPE, PLAIN: | ||||||
|  | 			if u.ValidatePassword(passwd) { | ||||||
|  | 				return u, nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return nil, ErrUserNotExist{u.Id, u.Name} | ||||||
|  |  | ||||||
|  | 		default: | ||||||
|  | 			var source LoginSource | ||||||
|  | 			hasSource, err := x.Id(u.LoginSource).Get(&source) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return nil, err | ||||||
|  | 			} else if !hasSource { | ||||||
|  | 				return nil, ErrLoginSourceNotExist | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return ExternalUserLogin(u, u.LoginName, passwd, &source, false) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var sources []LoginSource | ||||||
|  | 	if err = x.UseBool().Find(&sources, &LoginSource{IsActived: true}); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, source := range sources { | ||||||
|  | 		u, err := ExternalUserLogin(nil, uname, passwd, &source, true) | ||||||
|  | 		if err == nil { | ||||||
|  | 			return u, nil | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		log.Warn("Failed to login '%s' via '%s': %v", uname, source.Name, err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil, ErrUserNotExist{u.Id, u.Name} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -10,29 +10,28 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| type AuthenticationForm struct { | type AuthenticationForm struct { | ||||||
| 	ID                int64 | 	ID               int64 | ||||||
| 	Type              int    `binding:"Range(2,5)"` | 	Type             int    `binding:"Range(2,5)"` | ||||||
| 	Name              string `binding:"Required;MaxSize(30)"` | 	Name             string `binding:"Required;MaxSize(30)"` | ||||||
| 	Host              string | 	Host             string | ||||||
| 	Port              int | 	Port             int | ||||||
| 	BindDN            string | 	BindDN           string | ||||||
| 	BindPassword      string | 	BindPassword     string | ||||||
| 	UserBase          string | 	UserBase         string | ||||||
| 	UserDN            string `form:"user_dn"` | 	UserDN           string `form:"user_dn"` | ||||||
| 	AttributeName     string | 	AttributeName    string | ||||||
| 	AttributeSurname  string | 	AttributeSurname string | ||||||
| 	AttributeMail     string | 	AttributeMail    string | ||||||
| 	Filter            string | 	Filter           string | ||||||
| 	AdminFilter       string | 	AdminFilter      string | ||||||
| 	IsActive          bool | 	IsActive         bool | ||||||
| 	SMTPAuth          string | 	SMTPAuth         string | ||||||
| 	SMTPHost          string | 	SMTPHost         string | ||||||
| 	SMTPPort          int | 	SMTPPort         int | ||||||
| 	AllowedDomains    string | 	AllowedDomains   string | ||||||
| 	TLS               bool | 	TLS              bool | ||||||
| 	SkipVerify        bool | 	SkipVerify       bool | ||||||
| 	AllowAutoRegister bool | 	PAMServiceName   string `form:"pam_service_name"` | ||||||
| 	PAMServiceName    string `form:"pam_service_name"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *AuthenticationForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||||
|   | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -127,11 +127,10 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.CreateSource(&models.LoginSource{ | 	if err := models.CreateSource(&models.LoginSource{ | ||||||
| 		Type:              models.LoginType(form.Type), | 		Type:      models.LoginType(form.Type), | ||||||
| 		Name:              form.Name, | 		Name:      form.Name, | ||||||
| 		IsActived:         form.IsActive, | 		IsActived: form.IsActive, | ||||||
| 		AllowAutoRegister: form.AllowAutoRegister, | 		Cfg:       config, | ||||||
| 		Cfg:               config, |  | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		ctx.Handle(500, "CreateSource", err) | 		ctx.Handle(500, "CreateSource", err) | ||||||
| 		return | 		return | ||||||
| @@ -195,7 +194,6 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||||||
|  |  | ||||||
| 	source.Name = form.Name | 	source.Name = form.Name | ||||||
| 	source.IsActived = form.IsActive | 	source.IsActived = form.IsActive | ||||||
| 	source.AllowAutoRegister = form.AllowAutoRegister |  | ||||||
| 	source.Cfg = config | 	source.Cfg = config | ||||||
| 	if err := models.UpdateSource(source); err != nil { | 	if err := models.UpdateSource(source); err != nil { | ||||||
| 		ctx.Handle(500, "UpdateSource", err) | 		ctx.Handle(500, "UpdateSource", err) | ||||||
|   | |||||||
| @@ -73,6 +73,9 @@ func GlobalInit() { | |||||||
| 	if models.EnableSQLite3 { | 	if models.EnableSQLite3 { | ||||||
| 		log.Info("SQLite3 Supported") | 		log.Info("SQLite3 Supported") | ||||||
| 	} | 	} | ||||||
|  | 	if models.EnableTidb { | ||||||
|  | 		log.Info("TiDB Supported") | ||||||
|  | 	} | ||||||
| 	checkRunMode() | 	checkRunMode() | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -131,12 +131,6 @@ | |||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             {{end}} |             {{end}} | ||||||
|             <div class="inline field"> |  | ||||||
|               <div class="ui checkbox"> |  | ||||||
|                 <label><strong>{{.i18n.Tr "admin.auths.enable_auto_register"}}</strong></label> |  | ||||||
|                 <input name="allow_auto_register" type="checkbox" {{if .Source.AllowAutoRegister}}checked{{end}}> |  | ||||||
|               </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="inline field"> |             <div class="inline field"> | ||||||
|               <div class="ui checkbox"> |               <div class="ui checkbox"> | ||||||
|                 <label><strong>{{.i18n.Tr "admin.auths.activated"}}</strong></label> |                 <label><strong>{{.i18n.Tr "admin.auths.activated"}}</strong></label> | ||||||
|   | |||||||
| @@ -128,12 +128,6 @@ | |||||||
|                 <input name="skip_verify" type="checkbox" {{if .skip_verify}}checked{{end}}> |                 <input name="skip_verify" type="checkbox" {{if .skip_verify}}checked{{end}}> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <div class="inline field"> |  | ||||||
|               <div class="ui checkbox"> |  | ||||||
|                 <label><strong>{{.i18n.Tr "admin.auths.enable_auto_register"}}</strong></label> |  | ||||||
|                 <input name="allow_auto_register" type="checkbox" {{if .allow_auto_register}}checked{{end}}> |  | ||||||
|               </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="inline field"> |             <div class="inline field"> | ||||||
|               <div class="ui checkbox"> |               <div class="ui checkbox"> | ||||||
|                 <label><strong>{{.i18n.Tr "admin.auths.activated"}}</strong></label> |                 <label><strong>{{.i18n.Tr "admin.auths.activated"}}</strong></label> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user