mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-31 14:31:02 +00:00 
			
		
		
		
	Finish register user
This commit is contained in:
		
					parent
					
						
							
								4b912b9ae6
							
						
					
				
			
			
				commit
				
					
						1249392c83
					
				
			
		
					 7 changed files with 78 additions and 27 deletions
				
			
		|  | @ -16,3 +16,6 @@ NAME = gogs | ||||||
| USER = root | USER = root | ||||||
| PASSWD =  | PASSWD =  | ||||||
| PASSWD_jiahua = root | PASSWD_jiahua = root | ||||||
|  | 
 | ||||||
|  | [security] | ||||||
|  | USER_PASSWD_SALT = !#@FDEWREWR&*( | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								gogs.go
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
										
									
									
									
								
							|  | @ -19,7 +19,7 @@ import ( | ||||||
| // Test that go1.1 tag above is included in builds. main.go refers to this definition. | // Test that go1.1 tag above is included in builds. main.go refers to this definition. | ||||||
| const go11tag = true | const go11tag = true | ||||||
| 
 | 
 | ||||||
| const APP_VER = "0.0.0.0305" | const APP_VER = "0.0.0.0306" | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||||
|  |  | ||||||
|  | @ -17,6 +17,12 @@ import ( | ||||||
| 	"github.com/gogits/gogs/utils" | 	"github.com/gogits/gogs/utils" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | var UserPasswdSalt string | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	UserPasswdSalt = utils.Cfg.MustValue("security", "USER_PASSWD_SALT") | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // User types. | // User types. | ||||||
| const ( | const ( | ||||||
| 	UT_INDIVIDUAL = iota + 1 | 	UT_INDIVIDUAL = iota + 1 | ||||||
|  | @ -33,9 +39,9 @@ const ( | ||||||
| type User struct { | type User struct { | ||||||
| 	Id            int64 | 	Id            int64 | ||||||
| 	LowerName     string `xorm:"unique not null"` | 	LowerName     string `xorm:"unique not null"` | ||||||
| 	Name          string `xorm:"unique not null" valid:"AlphaDash;MinSize(5);MaxSize(30)"` | 	Name          string `xorm:"unique not null"` | ||||||
| 	Email         string `xorm:"unique not null" valid:"Email"` | 	Email         string `xorm:"unique not null"` | ||||||
| 	Passwd        string `xorm:"not null" valid:"MinSize(8)"` | 	Passwd        string `xorm:"not null"` | ||||||
| 	LoginType     int | 	LoginType     int | ||||||
| 	Type          int | 	Type          int | ||||||
| 	NumFollowers  int | 	NumFollowers  int | ||||||
|  | @ -79,6 +85,7 @@ var ( | ||||||
| 	ErrUserOwnRepos     = errors.New("User still have ownership of repositories") | 	ErrUserOwnRepos     = errors.New("User still have ownership of repositories") | ||||||
| 	ErrUserAlreadyExist = errors.New("User already exist") | 	ErrUserAlreadyExist = errors.New("User already exist") | ||||||
| 	ErrUserNotExist     = errors.New("User does not exist") | 	ErrUserNotExist     = errors.New("User does not exist") | ||||||
|  | 	ErrEmailAlreadyUsed = errors.New("E-mail already used") | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // IsUserExist checks if given user name exist, | // IsUserExist checks if given user name exist, | ||||||
|  | @ -87,6 +94,10 @@ func IsUserExist(name string) (bool, error) { | ||||||
| 	return orm.Get(&User{LowerName: strings.ToLower(name)}) | 	return orm.Get(&User{LowerName: strings.ToLower(name)}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func IsEmailUsed(email string) (bool, error) { | ||||||
|  | 	return orm.Get(&User{Email: email}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // RegisterUser creates record of a new user. | // RegisterUser creates record of a new user. | ||||||
| func RegisterUser(user *User) (err error) { | func RegisterUser(user *User) (err error) { | ||||||
| 	isExist, err := IsUserExist(user.Name) | 	isExist, err := IsUserExist(user.Name) | ||||||
|  | @ -96,9 +107,18 @@ func RegisterUser(user *User) (err error) { | ||||||
| 		return ErrUserAlreadyExist | 		return ErrUserAlreadyExist | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	isExist, err = IsEmailUsed(user.Email) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} else if isExist { | ||||||
|  | 		return ErrEmailAlreadyUsed | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	user.LowerName = strings.ToLower(user.Name) | 	user.LowerName = strings.ToLower(user.Name) | ||||||
| 	user.Avatar = utils.EncodeMd5(user.Email) | 	user.Avatar = utils.EncodeMd5(user.Email) | ||||||
| 	user.EncodePasswd() | 	if err = user.EncodePasswd(); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
| 	if _, err = orm.Insert(user); err != nil { | 	if _, err = orm.Insert(user); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | @ -136,7 +156,7 @@ func DeleteUser(user *User) error { | ||||||
| 
 | 
 | ||||||
| // EncodePasswd encodes password to safe format. | // EncodePasswd encodes password to safe format. | ||||||
| func (user *User) EncodePasswd() error { | func (user *User) EncodePasswd() error { | ||||||
| 	newPasswd, err := scrypt.Key([]byte(user.Passwd), []byte("!#@FDEWREWR&*("), 16384, 8, 1, 64) | 	newPasswd, err := scrypt.Key([]byte(user.Passwd), []byte(UserPasswdSalt), 16384, 8, 1, 64) | ||||||
| 	user.Passwd = fmt.Sprintf("%x", newPasswd) | 	user.Passwd = fmt.Sprintf("%x", newPasswd) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,10 +17,25 @@ import ( | ||||||
| 	"github.com/gogits/gogs/utils/log" | 	"github.com/gogits/gogs/utils/log" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | type Form interface { | ||||||
|  | 	Name(field string) string | ||||||
|  | } | ||||||
|  | 
 | ||||||
| type RegisterForm struct { | type RegisterForm struct { | ||||||
| 	Username string `form:"username" binding:"Required;AlphaDash;MinSize(5);MaxSize(30)"` | 	UserName     string `form:"username" binding:"Required;AlphaDash;MinSize(5);MaxSize(30)"` | ||||||
| 	Email    string `form:"email" binding:"Required;Email;MaxSize(50)"` | 	Email        string `form:"email" binding:"Required;Email;MaxSize(50)"` | ||||||
| 	Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"` | 	Password     string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"` | ||||||
|  | 	RetypePasswd string `form:"retypepasswd"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *RegisterForm) Name(field string) string { | ||||||
|  | 	names := map[string]string{ | ||||||
|  | 		"UserName":     "Username", | ||||||
|  | 		"Email":        "E-mail address", | ||||||
|  | 		"Password":     "Password", | ||||||
|  | 		"RetypePasswd": "Re-type password", | ||||||
|  | 	} | ||||||
|  | 	return names[field] | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func getMinMaxSize(field reflect.StructField) string { | func getMinMaxSize(field reflect.StructField) string { | ||||||
|  | @ -32,7 +47,7 @@ func getMinMaxSize(field reflect.StructField) string { | ||||||
| 	return "" | 	return "" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func validate(errors *binding.Errors, data base.TmplData, form interface{}) { | func validate(errors *binding.Errors, data base.TmplData, form Form) { | ||||||
| 	typ := reflect.TypeOf(form) | 	typ := reflect.TypeOf(form) | ||||||
| 	val := reflect.ValueOf(form) | 	val := reflect.ValueOf(form) | ||||||
| 
 | 
 | ||||||
|  | @ -54,15 +69,15 @@ func validate(errors *binding.Errors, data base.TmplData, form interface{}) { | ||||||
| 			data["Err_"+field.Name] = true | 			data["Err_"+field.Name] = true | ||||||
| 			switch err { | 			switch err { | ||||||
| 			case binding.RequireError: | 			case binding.RequireError: | ||||||
| 				data["ErrorMsg"] = field.Name + " cannot be empty" | 				data["ErrorMsg"] = form.Name(field.Name) + " cannot be empty" | ||||||
| 			case binding.AlphaDashError: | 			case binding.AlphaDashError: | ||||||
| 				data["ErrorMsg"] = field.Name + " must be valid alpha or numeric or dash(-_) characters" | 				data["ErrorMsg"] = form.Name(field.Name) + " must be valid alpha or numeric or dash(-_) characters" | ||||||
| 			case binding.MinSizeError: | 			case binding.MinSizeError: | ||||||
| 				data["ErrorMsg"] = field.Name + " must contain at least has " + getMinMaxSize(field) + " characters" | 				data["ErrorMsg"] = form.Name(field.Name) + " must contain at least " + getMinMaxSize(field) + " characters" | ||||||
| 			case binding.MaxSizeError: | 			case binding.MaxSizeError: | ||||||
| 				data["ErrorMsg"] = field.Name + " must contain at most has " + getMinMaxSize(field) + " characters" | 				data["ErrorMsg"] = form.Name(field.Name) + " must contain at most " + getMinMaxSize(field) + " characters" | ||||||
| 			case binding.EmailError: | 			case binding.EmailError: | ||||||
| 				data["ErrorMsg"] = field.Name + " is not valid" | 				data["ErrorMsg"] = form.Name(field.Name) + " is not valid" | ||||||
| 			default: | 			default: | ||||||
| 				data["ErrorMsg"] = "Unknown error: " + err | 				data["ErrorMsg"] = "Unknown error: " + err | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -118,30 +118,43 @@ func SignUp(form auth.RegisterForm, data base.TmplData, req *http.Request, r ren | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if form.Password != form.RetypePasswd { | ||||||
|  | 		data["HasError"] = true | ||||||
|  | 		data["Err_Password"] = true | ||||||
|  | 		data["Err_RetypePasswd"] = true | ||||||
|  | 		data["ErrorMsg"] = "Password and re-type password are not same" | ||||||
|  | 		auth.AssignForm(form, data) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if hasErr, ok := data["HasError"]; ok && hasErr.(bool) { | 	if hasErr, ok := data["HasError"]; ok && hasErr.(bool) { | ||||||
| 		r.HTML(200, "user/signup", data) | 		r.HTML(200, "user/signup", data) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	//Front-end should do double check of password. |  | ||||||
| 	u := &models.User{ | 	u := &models.User{ | ||||||
| 		Name:   form.Username, | 		Name:   form.UserName, | ||||||
| 		Email:  form.Email, | 		Email:  form.Email, | ||||||
| 		Passwd: form.Password, | 		Passwd: form.Password, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err := models.RegisterUser(u); err != nil { | 	if err := models.RegisterUser(u); err != nil { | ||||||
| 		if err.Error() == models.ErrUserAlreadyExist.Error() { | 		data["HasError"] = true | ||||||
| 			data["HasError"] = true | 		auth.AssignForm(form, data) | ||||||
|  | 
 | ||||||
|  | 		switch err.Error() { | ||||||
|  | 		case models.ErrUserAlreadyExist.Error(): | ||||||
| 			data["Err_Username"] = true | 			data["Err_Username"] = true | ||||||
| 			data["ErrorMsg"] = "Username has been already taken" | 			data["ErrorMsg"] = "Username has been already taken" | ||||||
| 			auth.AssignForm(form, data) |  | ||||||
| 			r.HTML(200, "user/signup", data) | 			r.HTML(200, "user/signup", data) | ||||||
| 			return | 		case models.ErrEmailAlreadyUsed.Error(): | ||||||
|  | 			data["Err_Email"] = true | ||||||
|  | 			data["ErrorMsg"] = "E-mail address has been already used" | ||||||
|  | 			r.HTML(200, "user/signup", data) | ||||||
|  | 		default: | ||||||
|  | 			data["ErrorMsg"] = err | ||||||
|  | 			log.Error("user.SignUp: %v", data) | ||||||
|  | 			r.HTML(500, "base/error", nil) | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		log.Error("user.SignUp: %v", err) |  | ||||||
| 		r.HTML(500, "status/500", nil) |  | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| {{template "base/head" .}} | {{template "base/head" .}} | ||||||
| {{template "base/navbar" .}} | {{template "base/navbar" .}} | ||||||
| <div id="gogs-body" class="container"> | <div id="gogs-body" class="container"> | ||||||
| 	An error is occupied : {{.Error}} | 	An error is occurred : {{.ErrorMsg}} | ||||||
| </div> | </div> | ||||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||||
|  | @ -6,7 +6,7 @@ | ||||||
| 	{{if .HasError}} | 	{{if .HasError}} | ||||||
| 	<div class="alert alert-danger">{{.ErrorMsg}}</div> | 	<div class="alert alert-danger">{{.ErrorMsg}}</div> | ||||||
| 	{{end}} | 	{{end}} | ||||||
| 		<div class="form-group {{if .Err_Username}}has-error has-feedback{{end}}"> | 		<div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}"> | ||||||
| 			<label class="col-md-4 control-label">Username: </label> | 			<label class="col-md-4 control-label">Username: </label> | ||||||
| 			<div class="col-md-6"> | 			<div class="col-md-6"> | ||||||
| 				<input name="username" class="form-control" placeholder="Type your username" value="{{.username}}"> | 				<input name="username" class="form-control" placeholder="Type your username" value="{{.username}}"> | ||||||
|  | @ -25,7 +25,7 @@ | ||||||
| 				<input name="passwd" type="password" class="form-control" placeholder="Type your password"> | 				<input name="passwd" type="password" class="form-control" placeholder="Type your password"> | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
| 		<div class="form-group"> | 		<div class="form-group {{if .Err_RetypePasswd}}has-error has-feedback{{end}}"> | ||||||
| 			<label class="col-md-4 control-label">Re-type: </label> | 			<label class="col-md-4 control-label">Re-type: </label> | ||||||
| 			<div class="col-md-6"> | 			<div class="col-md-6"> | ||||||
| 				<input type="password" class="form-control" placeholder="Re-type your password"> | 				<input type="password" class="form-control" placeholder="Re-type your password"> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue