diff options
Diffstat (limited to 'routers/web/auth/auth.go')
-rw-r--r-- | routers/web/auth/auth.go | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 3fe1d5970e..94f75f69ff 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -76,6 +76,10 @@ func autoSignIn(ctx *context.Context) (bool, error) { } return false, nil } + userHasTwoFactorAuth, err := auth.HasTwoFactorOrWebAuthn(ctx, u.ID) + if err != nil { + return false, fmt.Errorf("HasTwoFactorOrWebAuthn: %w", err) + } isSucceed = true @@ -87,9 +91,9 @@ func autoSignIn(ctx *context.Context) (bool, error) { ctx.SetSiteCookie(setting.CookieRememberName, nt.ID+":"+token, setting.LogInRememberDays*timeutil.Day) if err := updateSession(ctx, nil, map[string]any{ - // Set session IDs - "uid": u.ID, - "uname": u.Name, + session.KeyUID: u.ID, + session.KeyUname: u.Name, + session.KeyUserHasTwoFactorAuth: userHasTwoFactorAuth, }); err != nil { return false, fmt.Errorf("unable to updateSession: %w", err) } @@ -169,6 +173,7 @@ func prepareSignInPageData(ctx *context.Context) { ctx.Data["PageIsLogin"] = true ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx) ctx.Data["EnablePasswordSignInForm"] = setting.Service.EnablePasswordSignInForm + ctx.Data["EnablePasskeyAuth"] = setting.Service.EnablePasskeyAuth if setting.Service.EnableCaptcha && setting.Service.RequireCaptchaForLogin { context.SetCaptchaData(ctx) @@ -191,7 +196,7 @@ func SignIn(ctx *context.Context) { // SignInPost response for sign in request func SignInPost(ctx *context.Context) { if !setting.Service.EnablePasswordSignInForm { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -238,9 +243,8 @@ func SignInPost(ctx *context.Context) { } // Now handle 2FA: - // First of all if the source can skip local two fa we're done - if skipper, ok := source.Cfg.(auth_service.LocalTwoFASkipper); ok && skipper.IsSkipLocalTwoFA() { + if source.TwoFactorShouldSkip() { handleSignIn(ctx, u, form.Remember) return } @@ -261,7 +265,7 @@ func SignInPost(ctx *context.Context) { } if !hasTOTPtwofa && !hasWebAuthnTwofa { - // No two factor auth configured we can sign in the user + // No two-factor auth configured we can sign in the user handleSignIn(ctx, u, form.Remember) return } @@ -310,8 +314,14 @@ func handleSignInFull(ctx *context.Context, u *user_model.User, remember, obeyRe ctx.SetSiteCookie(setting.CookieRememberName, nt.ID+":"+token, setting.LogInRememberDays*timeutil.Day) } + userHasTwoFactorAuth, err := auth.HasTwoFactorOrWebAuthn(ctx, u.ID) + if err != nil { + ctx.ServerError("HasTwoFactorOrWebAuthn", err) + return setting.AppSubURL + "/" + } + if err := updateSession(ctx, []string{ - // Delete the openid, 2fa and linkaccount data + // Delete the openid, 2fa and link_account data "openid_verified_uri", "openid_signin_remember", "openid_determined_email", @@ -320,8 +330,9 @@ func handleSignInFull(ctx *context.Context, u *user_model.User, remember, obeyRe "twofaRemember", "linkAccount", }, map[string]any{ - "uid": u.ID, - "uname": u.Name, + session.KeyUID: u.ID, + session.KeyUname: u.Name, + session.KeyUserHasTwoFactorAuth: userHasTwoFactorAuth, }); err != nil { ctx.ServerError("RegenerateSession", err) return setting.AppSubURL + "/" @@ -410,9 +421,11 @@ func SignOut(ctx *context.Context) { // SignUp render the register page func SignUp(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("sign_up") - ctx.Data["SignUpLink"] = setting.AppSubURL + "/user/sign_up" + hasUsers, _ := user_model.HasUsers(ctx) + ctx.Data["IsFirstTimeRegistration"] = !hasUsers.HasAnyUser + oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, optional.Some(true)) if err != nil { ctx.ServerError("UserSignUp", err) @@ -455,7 +468,7 @@ func SignUpPost(ctx *context.Context) { // Permission denied if DisableRegistration or AllowOnlyExternalRegistration options are true if setting.Service.DisableRegistration || setting.Service.AllowOnlyExternalRegistration { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -533,7 +546,8 @@ func createUserInContext(ctx *context.Context, tpl templates.TplName, form any, } if err := user_model.CreateUser(ctx, u, meta, overwrites); err != nil { if allowLink && (user_model.IsErrUserAlreadyExist(err) || user_model.IsErrEmailAlreadyUsed(err)) { - if setting.OAuth2Client.AccountLinking == setting.OAuth2AccountLinkingAuto { + switch setting.OAuth2Client.AccountLinking { + case setting.OAuth2AccountLinkingAuto: var user *user_model.User user = &user_model.User{Name: u.Name} hasUser, err := user_model.GetUser(ctx, user) @@ -549,7 +563,7 @@ func createUserInContext(ctx *context.Context, tpl templates.TplName, form any, // TODO: probably we should respect 'remember' user's choice... linkAccount(ctx, user, *gothUser, true) return false // user is already created here, all redirects are handled - } else if setting.OAuth2Client.AccountLinking == setting.OAuth2AccountLinkingLogin { + case setting.OAuth2AccountLinkingLogin: showLinkingLogin(ctx, *gothUser) return false // user will be created only after linking login } @@ -598,10 +612,16 @@ func createUserInContext(ctx *context.Context, tpl templates.TplName, form any, // sends a confirmation email if required. func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.User) (ok bool) { // Auto-set admin for the only user. - if user_model.CountUsers(ctx, nil) == 1 { + hasUsers, err := user_model.HasUsers(ctx) + if err != nil { + ctx.ServerError("HasUsers", err) + return false + } + if hasUsers.HasOnlyOneUser { + // the only user is the one just created, will set it as admin opts := &user_service.UpdateOptions{ IsActive: optional.Some(true), - IsAdmin: optional.Some(true), + IsAdmin: user_service.UpdateOptionFieldFromValue(true), SetLastLogin: true, } if err := user_service.UpdateUser(ctx, u, opts); err != nil { @@ -766,7 +786,7 @@ func handleAccountActivation(ctx *context.Context, user *user_model.User) { } if err := user_model.UpdateUserCols(ctx, user, "is_active", "rands"); err != nil { if user_model.IsErrUserNotExist(err) { - ctx.NotFound("UpdateUserCols", err) + ctx.NotFound(err) } else { ctx.ServerError("UpdateUser", err) } |