Password Complexity Checks (#6230)
Add password complexity checks. The default settings require a lowercase, uppercase, number and a special character within passwords. Co-Authored-By: T-M-A <maxim.tkachenko@gmail.com> Co-Authored-By: Lanre Adelowo <adelowomailbox@gmail.com> Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> Co-Authored-By: Lauris BH <lauris@nix.lv>
This commit is contained in:
parent
f9aba9ba0f
commit
db657192d0
11 changed files with 207 additions and 37 deletions
|
@ -12,6 +12,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/password"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/routers"
|
||||
"code.gitea.io/gitea/services/mailer"
|
||||
|
@ -94,7 +95,10 @@ func NewUserPost(ctx *context.Context, form auth.AdminCreateUserForm) {
|
|||
u.LoginName = form.LoginName
|
||||
}
|
||||
}
|
||||
|
||||
if !password.IsComplexEnough(form.Password) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.password_complexity"), tplUserNew, &form)
|
||||
return
|
||||
}
|
||||
if err := models.CreateUser(u); err != nil {
|
||||
switch {
|
||||
case models.IsErrUserAlreadyExist(err):
|
||||
|
@ -201,6 +205,10 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) {
|
|||
ctx.ServerError("UpdateUser", err)
|
||||
return
|
||||
}
|
||||
if !password.IsComplexEnough(form.Password) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.password_complexity"), tplUserEdit, &form)
|
||||
return
|
||||
}
|
||||
u.HashPassword(form.Password)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
package admin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/password"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/routers/api/v1/convert"
|
||||
"code.gitea.io/gitea/routers/api/v1/user"
|
||||
|
@ -73,7 +76,11 @@ func CreateUser(ctx *context.APIContext, form api.CreateUserOption) {
|
|||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
if !password.IsComplexEnough(form.Password) {
|
||||
err := errors.New("PasswordComplexity")
|
||||
ctx.Error(400, "PasswordComplexity", err)
|
||||
return
|
||||
}
|
||||
if err := models.CreateUser(u); err != nil {
|
||||
if models.IsErrUserAlreadyExist(err) ||
|
||||
models.IsErrEmailAlreadyUsed(err) ||
|
||||
|
@ -131,6 +138,11 @@ func EditUser(ctx *context.APIContext, form api.EditUserOption) {
|
|||
}
|
||||
|
||||
if len(form.Password) > 0 {
|
||||
if !password.IsComplexEnough(form.Password) {
|
||||
err := errors.New("PasswordComplexity")
|
||||
ctx.Error(400, "PasswordComplexity", err)
|
||||
return
|
||||
}
|
||||
var err error
|
||||
if u.Salt, err = models.GetUserSalt(); err != nil {
|
||||
ctx.Error(500, "UpdateUser", err)
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/password"
|
||||
"code.gitea.io/gitea/modules/recaptcha"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
@ -1334,6 +1335,11 @@ func ResetPasswdPost(ctx *context.Context) {
|
|||
ctx.Data["Err_Password"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("auth.password_too_short", setting.MinPasswordLength), tplResetPassword, nil)
|
||||
return
|
||||
} else if !password.IsComplexEnough(passwd) {
|
||||
ctx.Data["IsResetForm"] = true
|
||||
ctx.Data["Err_Password"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("form.password_complexity"), tplResetPassword, nil)
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
|
@ -1364,7 +1370,6 @@ func ResetPasswdPost(ctx *context.Context) {
|
|||
func MustChangePassword(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
|
||||
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/settings/change_password"
|
||||
|
||||
ctx.HTML(200, tplMustChangePassword)
|
||||
}
|
||||
|
||||
|
@ -1372,16 +1377,12 @@ func MustChangePassword(ctx *context.Context) {
|
|||
// account was created by an admin
|
||||
func MustChangePasswordPost(ctx *context.Context, cpt *captcha.Captcha, form auth.MustChangePasswordForm) {
|
||||
ctx.Data["Title"] = ctx.Tr("auth.must_change_password")
|
||||
|
||||
ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/settings/change_password"
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.HTML(200, tplMustChangePassword)
|
||||
return
|
||||
}
|
||||
|
||||
u := ctx.User
|
||||
|
||||
// Make sure only requests for users who are eligible to change their password via
|
||||
// this method passes through
|
||||
if !u.MustChangePassword {
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/password"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/services/mailer"
|
||||
|
@ -52,6 +53,8 @@ func AccountPost(ctx *context.Context, form auth.ChangePasswordForm) {
|
|||
ctx.Flash.Error(ctx.Tr("settings.password_incorrect"))
|
||||
} else if form.Password != form.Retype {
|
||||
ctx.Flash.Error(ctx.Tr("form.password_not_match"))
|
||||
} else if !password.IsComplexEnough(form.Password) {
|
||||
ctx.Flash.Error(ctx.Tr("settings.password_complexity"))
|
||||
} else {
|
||||
var err error
|
||||
if ctx.User.Salt, err = models.GetUserSalt(); err != nil {
|
||||
|
|
|
@ -19,36 +19,77 @@ import (
|
|||
func TestChangePassword(t *testing.T) {
|
||||
oldPassword := "password"
|
||||
setting.MinPasswordLength = 6
|
||||
setting.PasswordComplexity = map[string]string{
|
||||
"lower": "[a-z]+",
|
||||
"upper": "[A-Z]+",
|
||||
"digit": "[0-9]+",
|
||||
"spec": "[-_]+",
|
||||
}
|
||||
var pcLUN = map[string]string{
|
||||
"lower": "[a-z]+",
|
||||
"upper": "[A-Z]+",
|
||||
"digit": "[0-9]+",
|
||||
}
|
||||
var pcLU = map[string]string{
|
||||
"lower": "[a-z]+",
|
||||
"upper": "[A-Z]+",
|
||||
}
|
||||
|
||||
for _, req := range []struct {
|
||||
OldPassword string
|
||||
NewPassword string
|
||||
Retype string
|
||||
Message string
|
||||
OldPassword string
|
||||
NewPassword string
|
||||
Retype string
|
||||
Message string
|
||||
PasswordComplexity map[string]string
|
||||
}{
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "123456",
|
||||
Retype: "123456",
|
||||
Message: "",
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "Qwerty123456-",
|
||||
Retype: "Qwerty123456-",
|
||||
Message: "",
|
||||
PasswordComplexity: setting.PasswordComplexity,
|
||||
},
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "12345",
|
||||
Retype: "12345",
|
||||
Message: "auth.password_too_short",
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "12345",
|
||||
Retype: "12345",
|
||||
Message: "auth.password_too_short",
|
||||
PasswordComplexity: setting.PasswordComplexity,
|
||||
},
|
||||
{
|
||||
OldPassword: "12334",
|
||||
NewPassword: "123456",
|
||||
Retype: "123456",
|
||||
Message: "settings.password_incorrect",
|
||||
OldPassword: "12334",
|
||||
NewPassword: "123456",
|
||||
Retype: "123456",
|
||||
Message: "settings.password_incorrect",
|
||||
PasswordComplexity: setting.PasswordComplexity,
|
||||
},
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "123456",
|
||||
Retype: "12345",
|
||||
Message: "form.password_not_match",
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "123456",
|
||||
Retype: "12345",
|
||||
Message: "form.password_not_match",
|
||||
PasswordComplexity: setting.PasswordComplexity,
|
||||
},
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "Qwerty",
|
||||
Retype: "Qwerty",
|
||||
Message: "settings.password_complexity",
|
||||
PasswordComplexity: setting.PasswordComplexity,
|
||||
},
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "Qwerty",
|
||||
Retype: "Qwerty",
|
||||
Message: "settings.password_complexity",
|
||||
PasswordComplexity: pcLUN,
|
||||
},
|
||||
{
|
||||
OldPassword: oldPassword,
|
||||
NewPassword: "QWERTY",
|
||||
Retype: "QWERTY",
|
||||
Message: "settings.password_complexity",
|
||||
PasswordComplexity: pcLU,
|
||||
},
|
||||
} {
|
||||
models.PrepareTestEnv(t)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue