mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Fix prohibit login check on authorization (#6106)
* fix bug prohibit login not applied on dashboard * fix tests * fix bug user status leak * fix typo * return after render
This commit is contained in:
		| @@ -112,7 +112,7 @@ func TestCreateReleasePaging(t *testing.T) { | |||||||
|  |  | ||||||
| 	checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.12", i18n.Tr("en", "repo.release.draft"), 10) | 	checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.12", i18n.Tr("en", "repo.release.draft"), 10) | ||||||
|  |  | ||||||
| 	// Check that user3 does not see draft and still see 10 latest releases | 	// Check that user4 does not see draft and still see 10 latest releases | ||||||
| 	session2 := loginUser(t, "user3") | 	session2 := loginUser(t, "user4") | ||||||
| 	checkLatestReleaseAndCount(t, session2, "/user2/repo1", "v0.0.11", i18n.Tr("en", "repo.release.stable"), 10) | 	checkLatestReleaseAndCount(t, session2, "/user2/repo1", "v0.0.11", i18n.Tr("en", "repo.release.stable"), 10) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -104,7 +104,7 @@ func TestViewRepoWithSymlinks(t *testing.T) { | |||||||
| func TestViewAsRepoAdmin(t *testing.T) { | func TestViewAsRepoAdmin(t *testing.T) { | ||||||
| 	for user, expectedNoDescription := range map[string]bool{ | 	for user, expectedNoDescription := range map[string]bool{ | ||||||
| 		"user2": true, | 		"user2": true, | ||||||
| 		"user3": false, | 		"user4": false, | ||||||
| 	} { | 	} { | ||||||
| 		prepareTestEnv(t) | 		prepareTestEnv(t) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -90,6 +90,38 @@ func (err ErrUserNotExist) Error() string { | |||||||
| 	return fmt.Sprintf("user does not exist [uid: %d, name: %s, keyid: %d]", err.UID, err.Name, err.KeyID) | 	return fmt.Sprintf("user does not exist [uid: %d, name: %s, keyid: %d]", err.UID, err.Name, err.KeyID) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ErrUserProhibitLogin represents a "ErrUserProhibitLogin" kind of error. | ||||||
|  | type ErrUserProhibitLogin struct { | ||||||
|  | 	UID  int64 | ||||||
|  | 	Name string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsErrUserProhibitLogin checks if an error is a ErrUserProhibitLogin | ||||||
|  | func IsErrUserProhibitLogin(err error) bool { | ||||||
|  | 	_, ok := err.(ErrUserProhibitLogin) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (err ErrUserProhibitLogin) Error() string { | ||||||
|  | 	return fmt.Sprintf("user is not allowed login [uid: %d, name: %s]", err.UID, err.Name) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ErrUserInactive represents a "ErrUserInactive" kind of error. | ||||||
|  | type ErrUserInactive struct { | ||||||
|  | 	UID  int64 | ||||||
|  | 	Name string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsErrUserInactive checks if an error is a ErrUserInactive | ||||||
|  | func IsErrUserInactive(err error) bool { | ||||||
|  | 	_, ok := err.(ErrUserInactive) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (err ErrUserInactive) Error() string { | ||||||
|  | 	return fmt.Sprintf("user is inactive [uid: %d, name: %s]", err.UID, err.Name) | ||||||
|  | } | ||||||
|  |  | ||||||
| // ErrEmailAlreadyUsed represents a "EmailAlreadyUsed" kind of error. | // ErrEmailAlreadyUsed represents a "EmailAlreadyUsed" kind of error. | ||||||
| type ErrEmailAlreadyUsed struct { | type ErrEmailAlreadyUsed struct { | ||||||
| 	Email string | 	Email string | ||||||
|   | |||||||
| @@ -600,16 +600,29 @@ func ExternalUserLogin(user *User, login, password string, source *LoginSource, | |||||||
| 		return nil, ErrLoginSourceNotActived | 		return nil, ErrLoginSourceNotActived | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	var err error | ||||||
| 	switch source.Type { | 	switch source.Type { | ||||||
| 	case LoginLDAP, LoginDLDAP: | 	case LoginLDAP, LoginDLDAP: | ||||||
| 		return LoginViaLDAP(user, login, password, source, autoRegister) | 		user, err = LoginViaLDAP(user, login, password, source, autoRegister) | ||||||
| 	case LoginSMTP: | 	case LoginSMTP: | ||||||
| 		return LoginViaSMTP(user, login, password, source.ID, source.Cfg.(*SMTPConfig), autoRegister) | 		user, err = LoginViaSMTP(user, login, password, source.ID, source.Cfg.(*SMTPConfig), autoRegister) | ||||||
| 	case LoginPAM: | 	case LoginPAM: | ||||||
| 		return LoginViaPAM(user, login, password, source.ID, source.Cfg.(*PAMConfig), autoRegister) | 		user, err = LoginViaPAM(user, login, password, source.ID, source.Cfg.(*PAMConfig), autoRegister) | ||||||
|  | 	default: | ||||||
|  | 		return nil, ErrUnsupportedLoginType | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil, ErrUnsupportedLoginType | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !user.IsActive { | ||||||
|  | 		return nil, ErrUserInactive{user.ID, user.Name} | ||||||
|  | 	} else if user.ProhibitLogin { | ||||||
|  | 		return nil, ErrUserProhibitLogin{user.ID, user.Name} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return user, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // UserSignIn validates user name and password. | // UserSignIn validates user name and password. | ||||||
| @@ -645,6 +658,12 @@ func UserSignIn(username, password string) (*User, error) { | |||||||
| 		switch user.LoginType { | 		switch user.LoginType { | ||||||
| 		case LoginNoType, LoginPlain, LoginOAuth2: | 		case LoginNoType, LoginPlain, LoginOAuth2: | ||||||
| 			if user.IsPasswordSet() && user.ValidatePassword(password) { | 			if user.IsPasswordSet() && user.ValidatePassword(password) { | ||||||
|  | 				if !user.IsActive { | ||||||
|  | 					return nil, ErrUserInactive{user.ID, user.Name} | ||||||
|  | 				} else if user.ProhibitLogin { | ||||||
|  | 					return nil, ErrUserProhibitLogin{user.ID, user.Name} | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 				return user, nil | 				return user, nil | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"net/url" | 	"net/url" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/modules/auth" | 	"code.gitea.io/gitea/modules/auth" | ||||||
|  | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"github.com/go-macaron/csrf" | 	"github.com/go-macaron/csrf" | ||||||
| 	macaron "gopkg.in/macaron.v1" | 	macaron "gopkg.in/macaron.v1" | ||||||
| @@ -32,8 +33,12 @@ func Toggle(options *ToggleOptions) macaron.Handler { | |||||||
|  |  | ||||||
| 		// Check prohibit login users. | 		// Check prohibit login users. | ||||||
| 		if ctx.IsSigned { | 		if ctx.IsSigned { | ||||||
|  | 			if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { | ||||||
| 			if ctx.User.ProhibitLogin { | 				ctx.Data["Title"] = ctx.Tr("auth.active_your_account") | ||||||
|  | 				ctx.HTML(200, "user/auth/activate") | ||||||
|  | 				return | ||||||
|  | 			} else if !ctx.User.IsActive || ctx.User.ProhibitLogin { | ||||||
|  | 				log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr()) | ||||||
| 				ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") | 				ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") | ||||||
| 				ctx.HTML(200, "user/auth/prohibit_login") | 				ctx.HTML(200, "user/auth/prohibit_login") | ||||||
| 				return | 				return | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
|  | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/search" | 	"code.gitea.io/gitea/modules/search" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| @@ -39,6 +40,10 @@ func Home(ctx *context.Context) { | |||||||
| 		if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { | 		if !ctx.User.IsActive && setting.Service.RegisterEmailConfirm { | ||||||
| 			ctx.Data["Title"] = ctx.Tr("auth.active_your_account") | 			ctx.Data["Title"] = ctx.Tr("auth.active_your_account") | ||||||
| 			ctx.HTML(200, user.TplActivate) | 			ctx.HTML(200, user.TplActivate) | ||||||
|  | 		} else if !ctx.User.IsActive || ctx.User.ProhibitLogin { | ||||||
|  | 			log.Info("Failed authentication attempt for %s from %s", ctx.User.Name, ctx.RemoteAddr()) | ||||||
|  | 			ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") | ||||||
|  | 			ctx.HTML(200, "user/auth/prohibit_login") | ||||||
| 		} else { | 		} else { | ||||||
| 			user.Dashboard(ctx) | 			user.Dashboard(ctx) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -161,6 +161,19 @@ func SignInPost(ctx *context.Context, form auth.SignInForm) { | |||||||
| 		} else if models.IsErrEmailAlreadyUsed(err) { | 		} else if models.IsErrEmailAlreadyUsed(err) { | ||||||
| 			ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSignIn, &form) | 			ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSignIn, &form) | ||||||
| 			log.Info("Failed authentication attempt for %s from %s", form.UserName, ctx.RemoteAddr()) | 			log.Info("Failed authentication attempt for %s from %s", form.UserName, ctx.RemoteAddr()) | ||||||
|  | 		} else if models.IsErrUserProhibitLogin(err) { | ||||||
|  | 			log.Info("Failed authentication attempt for %s from %s", form.UserName, ctx.RemoteAddr()) | ||||||
|  | 			ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") | ||||||
|  | 			ctx.HTML(200, "user/auth/prohibit_login") | ||||||
|  | 		} else if models.IsErrUserInactive(err) { | ||||||
|  | 			if setting.Service.RegisterEmailConfirm { | ||||||
|  | 				ctx.Data["Title"] = ctx.Tr("auth.active_your_account") | ||||||
|  | 				ctx.HTML(200, TplActivate) | ||||||
|  | 			} else { | ||||||
|  | 				log.Info("Failed authentication attempt for %s from %s", form.UserName, ctx.RemoteAddr()) | ||||||
|  | 				ctx.Data["Title"] = ctx.Tr("auth.prohibit_login") | ||||||
|  | 				ctx.HTML(200, "user/auth/prohibit_login") | ||||||
|  | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			ctx.ServerError("UserSignIn", err) | 			ctx.ServerError("UserSignIn", err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user