mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	Finish log in user
This commit is contained in:
		@@ -16,7 +16,7 @@ Please see [Wiki](https://github.com/gogits/gogs/wiki) for project design.
 | 
				
			|||||||
### Dependencies
 | 
					### Dependencies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- [Go Programming Language](http://golang.org): Main develop language.
 | 
					- [Go Programming Language](http://golang.org): Main develop language.
 | 
				
			||||||
- [libgit2](http://libgit2.github.com/): Git data manipulation.
 | 
					- [libgit2](http://libgit2.github.com/)(cgo): Git data manipulation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Acknowledgments
 | 
					## Acknowledgments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,4 +24,4 @@ Please see [Wiki](https://github.com/gogits/gogs/wiki) for project design.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Contributors
 | 
					## Contributors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This project was launched by [Unknown](https://github.com/Unknwon) and [lunny](https://github.com/lunny). See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors.
 | 
					This project was launched by [Unknown](https://github.com/Unknwon), [lunny](https://github.com/lunny) and [fuxiaohei](https://github.com/fuxiaohei). See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors.
 | 
				
			||||||
							
								
								
									
										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.0306"
 | 
					const APP_VER = "0.0.1.0306"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	runtime.GOMAXPROCS(runtime.NumCPU())
 | 
						runtime.GOMAXPROCS(runtime.NumCPU())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -192,7 +192,7 @@ func GetUserById(id int64) (*User, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// LoginUserPlain validates user by raw user name and password.
 | 
					// LoginUserPlain validates user by raw user name and password.
 | 
				
			||||||
func LoginUserPlain(name, passwd string) (*User, error) {
 | 
					func LoginUserPlain(name, passwd string) (*User, error) {
 | 
				
			||||||
	user := User{Name: name, Passwd: passwd}
 | 
						user := User{LowerName: strings.ToLower(name), Passwd: passwd}
 | 
				
			||||||
	if err := user.EncodePasswd(); err != nil {
 | 
						if err := user.EncodePasswd(); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,7 @@ type RegisterForm struct {
 | 
				
			|||||||
	RetypePasswd string `form:"retypepasswd"`
 | 
						RetypePasswd string `form:"retypepasswd"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *RegisterForm) Name(field string) string {
 | 
					func (f *RegisterForm) Name(field string) string {
 | 
				
			||||||
	names := map[string]string{
 | 
						names := map[string]string{
 | 
				
			||||||
		"UserName":     "Username",
 | 
							"UserName":     "Username",
 | 
				
			||||||
		"Email":        "E-mail address",
 | 
							"Email":        "E-mail address",
 | 
				
			||||||
@@ -38,6 +38,57 @@ func (r *RegisterForm) Name(field string) string {
 | 
				
			|||||||
	return names[field]
 | 
						return names[field]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (f *RegisterForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) {
 | 
				
			||||||
 | 
						if req.Method == "GET" || errors.Count() == 0 {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
 | 
				
			||||||
 | 
						data["HasError"] = true
 | 
				
			||||||
 | 
						AssignForm(f, data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(errors.Overall) > 0 {
 | 
				
			||||||
 | 
							for _, err := range errors.Overall {
 | 
				
			||||||
 | 
								log.Error("RegisterForm.Validate: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						validate(errors, data, f)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type LogInForm struct {
 | 
				
			||||||
 | 
						UserName string `form:"username" binding:"Required;AlphaDash;MinSize(5);MaxSize(30)"`
 | 
				
			||||||
 | 
						Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (f *LogInForm) Name(field string) string {
 | 
				
			||||||
 | 
						names := map[string]string{
 | 
				
			||||||
 | 
							"UserName": "Username",
 | 
				
			||||||
 | 
							"Password": "Password",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return names[field]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (f *LogInForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) {
 | 
				
			||||||
 | 
						if req.Method == "GET" || errors.Count() == 0 {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
 | 
				
			||||||
 | 
						data["HasError"] = true
 | 
				
			||||||
 | 
						AssignForm(f, data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(errors.Overall) > 0 {
 | 
				
			||||||
 | 
							for _, err := range errors.Overall {
 | 
				
			||||||
 | 
								log.Error("LogInForm.Validate: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						validate(errors, data, f)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getMinMaxSize(field reflect.StructField) string {
 | 
					func getMinMaxSize(field reflect.StructField) string {
 | 
				
			||||||
	for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
 | 
						for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
 | 
				
			||||||
		if strings.HasPrefix(rule, "MinSize(") || strings.HasPrefix(rule, "MaxSize(") {
 | 
							if strings.HasPrefix(rule, "MinSize(") || strings.HasPrefix(rule, "MaxSize(") {
 | 
				
			||||||
@@ -86,25 +137,6 @@ func validate(errors *binding.Errors, data base.TmplData, form Form) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *RegisterForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) {
 | 
					 | 
				
			||||||
	if req.Method == "GET" || errors.Count() == 0 {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
 | 
					 | 
				
			||||||
	data["HasError"] = true
 | 
					 | 
				
			||||||
	AssignForm(r, data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if len(errors.Overall) > 0 {
 | 
					 | 
				
			||||||
		for _, err := range errors.Overall {
 | 
					 | 
				
			||||||
			log.Error("RegisterForm.Validate: %v", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	validate(errors, data, r)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AssignForm assign form values back to the template data.
 | 
					// AssignForm assign form values back to the template data.
 | 
				
			||||||
func AssignForm(form interface{}, data base.TmplData) {
 | 
					func AssignForm(form interface{}, data base.TmplData) {
 | 
				
			||||||
	typ := reflect.TypeOf(form)
 | 
						typ := reflect.TypeOf(form)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -79,36 +79,45 @@ func SignedInUser(session sessions.Session) *models.User {
 | 
				
			|||||||
	return user
 | 
						return user
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func SignIn(req *http.Request, r render.Render, session sessions.Session) {
 | 
					func SignIn(form auth.LogInForm, data base.TmplData, req *http.Request, r render.Render, session sessions.Session) {
 | 
				
			||||||
	// if logged, do not show login page
 | 
						// if logged, do not show login page
 | 
				
			||||||
	if IsSignedIn(session) {
 | 
						if IsSignedIn(session) {
 | 
				
			||||||
		r.Redirect("/")
 | 
							r.Redirect("/")
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var (
 | 
					
 | 
				
			||||||
		errString string
 | 
						data["Title"] = "Log In"
 | 
				
			||||||
		account   string
 | 
					
 | 
				
			||||||
	)
 | 
						if req.Method == "GET" {
 | 
				
			||||||
	// if post, do login action
 | 
							r.HTML(200, "user/signin", data)
 | 
				
			||||||
	if req.Method == "POST" {
 | 
							return
 | 
				
			||||||
		account = req.FormValue("account")
 | 
						}
 | 
				
			||||||
		user, err := models.LoginUserPlain(account, req.FormValue("passwd"))
 | 
					
 | 
				
			||||||
		if err == nil {
 | 
						if hasErr, ok := data["HasError"]; ok && hasErr.(bool) {
 | 
				
			||||||
 | 
							r.HTML(200, "user/signin", data)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						user, err := models.LoginUserPlain(form.UserName, form.Password)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if err.Error() == models.ErrUserNotExist.Error() {
 | 
				
			||||||
 | 
								data["HasError"] = true
 | 
				
			||||||
 | 
								data["ErrorMsg"] = "Username or password is not correct"
 | 
				
			||||||
 | 
								auth.AssignForm(form, data)
 | 
				
			||||||
 | 
								r.HTML(200, "user/signin", data)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							data["ErrorMsg"] = err
 | 
				
			||||||
 | 
							log.Error("user.SignIn: %v", data)
 | 
				
			||||||
 | 
							r.HTML(500, "base/error", nil)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// login success
 | 
						// login success
 | 
				
			||||||
	session.Set("userId", user.Id)
 | 
						session.Set("userId", user.Id)
 | 
				
			||||||
	session.Set("userName", user.Name)
 | 
						session.Set("userName", user.Name)
 | 
				
			||||||
	r.Redirect("/")
 | 
						r.Redirect("/")
 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// login fail
 | 
					 | 
				
			||||||
		errString = fmt.Sprintf("%v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// if get or error post, show login page
 | 
					 | 
				
			||||||
	r.HTML(200, "user/signin", map[string]interface{}{
 | 
					 | 
				
			||||||
		"Title":   "Log In",
 | 
					 | 
				
			||||||
		"Error":   errString,
 | 
					 | 
				
			||||||
		"Account": account,
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func SignUp(form auth.RegisterForm, data base.TmplData, req *http.Request, r render.Render) {
 | 
					func SignUp(form auth.RegisterForm, data base.TmplData, req *http.Request, r render.Render) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,33 +2,35 @@
 | 
				
			|||||||
{{template "base/navbar" .}}
 | 
					{{template "base/navbar" .}}
 | 
				
			||||||
<div class="container" id="gogs-body">
 | 
					<div class="container" id="gogs-body">
 | 
				
			||||||
    <form action="/user/login" method="post" class="form-horizontal gogs-card" id="gogs-login-card">
 | 
					    <form action="/user/login" method="post" class="form-horizontal gogs-card" id="gogs-login-card">
 | 
				
			||||||
        <h3>Log in</h3>{{if .Error}}
 | 
					        <h3>Log in</h3>
 | 
				
			||||||
        <div class="form-group">
 | 
					        <div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div>
 | 
				
			||||||
            <div class="col-md-6 col-md-offset-3 alert alert-danger text-center"><strong>{{.Error}}</strong></div>
 | 
					        <div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}">
 | 
				
			||||||
        </div>{{end}}
 | 
					            <label class="col-md-4 control-label">Username: </label>
 | 
				
			||||||
        <div class="form-group">
 | 
					 | 
				
			||||||
            <label class="col-md-4 control-label">Username or Email: </label>
 | 
					 | 
				
			||||||
            <div class="col-md-6">
 | 
					            <div class="col-md-6">
 | 
				
			||||||
                <input name="account" class="form-control" placeholder="Type your username or e-mail address" value="{{.Account}}" required="required">
 | 
					                <input name="username" class="form-control" placeholder="Type your username" value="{{.username}}" required="required">
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="form-group">
 | 
					
 | 
				
			||||||
 | 
					        <div class="form-group {{if .Err_Password}}has-error has-feedback{{end}}">
 | 
				
			||||||
            <label class="col-md-4 control-label">Password: </label>
 | 
					            <label class="col-md-4 control-label">Password: </label>
 | 
				
			||||||
            <div class="col-md-6">
 | 
					            <div class="col-md-6">
 | 
				
			||||||
                <input name="passwd" type="password" class="form-control" placeholder="Type your password" required="required">
 | 
					                <input name="passwd" type="password" class="form-control" placeholder="Type your password" required="required">
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="form-group">
 | 
					        <div class="form-group">
 | 
				
			||||||
            <div class="col-md-offset-4 col-md-6">
 | 
					            <div class="col-md-offset-4 col-md-6">
 | 
				
			||||||
                <button type="submit" class="btn btn-lg btn-primary">Log In</button>
 | 
					                <button type="submit" class="btn btn-lg btn-primary">Log In</button>
 | 
				
			||||||
                <a href="/forget-password/">Forgot your password?</a>
 | 
					                <a href="/forget-password/">Forgot your password?</a>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="form-group">
 | 
					        <div class="form-group">
 | 
				
			||||||
            <div class="col-md-offset-4 col-md-6">
 | 
					            <div class="col-md-offset-4 col-md-6">
 | 
				
			||||||
                <a href="/user/sign_up">Need an account? Sign up free.</a>
 | 
					                <a href="/user/sign_up">Need an account? Sign up now.</a>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="form-group text-center" id="gogs-social-login">
 | 
					        <div class="form-group text-center" id="gogs-social-login">
 | 
				
			||||||
            <a class="btn btn-default btn-lg">Social Login</a>
 | 
					            <a class="btn btn-default btn-lg">Social Login</a>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,12 +4,13 @@
 | 
				
			|||||||
	<form action="/user/sign_up" method="post" class="form-horizontal gogs-card" id="gogs-login-card">
 | 
						<form action="/user/sign_up" method="post" class="form-horizontal gogs-card" id="gogs-login-card">
 | 
				
			||||||
        <h3>Sign Up</h3>
 | 
					        <h3>Sign Up</h3>
 | 
				
			||||||
	    <div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div>
 | 
						    <div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div>
 | 
				
			||||||
		<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}}" required="required" title="Username must contain at least has 5 characters">
 | 
									<input name="username" class="form-control" placeholder="Type your username" value="{{.username}}" required="required" title="Username must contain at least has 5 characters">
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}">
 | 
							<div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}">
 | 
				
			||||||
			<label class="col-md-4 control-label">Email: </label>
 | 
								<label class="col-md-4 control-label">Email: </label>
 | 
				
			||||||
			<div class="col-md-6">
 | 
								<div class="col-md-6">
 | 
				
			||||||
@@ -23,17 +24,20 @@
 | 
				
			|||||||
				<input name="passwd" type="password" class="form-control" placeholder="Type your password" required="required" title="Password must contain at least has 6 characters">
 | 
									<input name="passwd" type="password" class="form-control" placeholder="Type your password" required="required" title="Password must contain at least has 6 characters">
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<div class="form-group {{if .Err_RetypePasswd}}has-error has-feedback{{end}}">
 | 
							<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 name="re-passwd" type="password" class="form-control" placeholder="Re-type your password" required="required" title="Re-type Password must be same to Password">
 | 
									<input name="re-passwd" type="password" class="form-control" placeholder="Re-type your password" required="required" title="Re-type Password must be same to Password">
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<div class="form-group">
 | 
							<div class="form-group">
 | 
				
			||||||
		    <div class="col-md-offset-4 col-md-6">
 | 
							    <div class="col-md-offset-4 col-md-6">
 | 
				
			||||||
		    	<button type="submit" class="btn btn-lg btn-primary">Create an account</button>
 | 
							    	<button type="submit" class="btn btn-lg btn-primary">Create an account</button>
 | 
				
			||||||
		    </div>
 | 
							    </div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
 | 
							
 | 
				
			||||||
	    <div class="form-group">
 | 
						    <div class="form-group">
 | 
				
			||||||
            <div class="col-md-offset-4 col-md-6">
 | 
					            <div class="col-md-offset-4 col-md-6">
 | 
				
			||||||
                <a href="/user/login">Already have an account? Sign in now!</a>
 | 
					                <a href="/user/login">Already have an account? Sign in now!</a>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								web.go
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								web.go
									
									
									
									
									
								
							@@ -58,8 +58,7 @@ func runWeb(*cli.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Routers.
 | 
						// Routers.
 | 
				
			||||||
	m.Get("/", routers.Home)
 | 
						m.Get("/", routers.Home)
 | 
				
			||||||
	m.Any("/user/login", user.SignIn)
 | 
						m.Any("/user/login", binding.BindIgnErr(auth.LogInForm{}), user.SignIn)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	m.Any("/user/sign_up", binding.BindIgnErr(auth.RegisterForm{}), user.SignUp)
 | 
						m.Any("/user/sign_up", binding.BindIgnErr(auth.RegisterForm{}), user.SignUp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m.Get("/user/profile", user.Profile) // should be /username
 | 
						m.Get("/user/profile", user.Profile) // should be /username
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user