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:
parent
538a26d56f
commit
f5fa22a499
7 changed files with 83 additions and 9 deletions
|
@ -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 a new issue