Add setting to OAuth handlers to skip local 2FA authentication (#16594)

This PR adds a setting to OAuth and OpenID login sources to allow the source to
skip local 2FA authentication.

Fix #13939

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
zeripath 2021-09-10 17:37:57 +01:00 committed by GitHub
parent 51578d6418
commit 9ca0e7905c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 36 additions and 8 deletions

View file

@ -574,7 +574,7 @@ func SignInOAuth(ctx *context.Context) {
user, gothUser, err := oAuth2UserLoginCallback(loginSource, ctx.Req, ctx.Resp)
if err == nil && user != nil {
// we got the user without going through the whole OAuth2 authentication flow again
handleOAuth2SignIn(ctx, user, gothUser)
handleOAuth2SignIn(ctx, loginSource, user, gothUser)
return
}
@ -660,7 +660,7 @@ func SignInOAuthCallback(ctx *context.Context) {
}
}
handleOAuth2SignIn(ctx, u, gothUser)
handleOAuth2SignIn(ctx, loginSource, u, gothUser)
}
func getUserName(gothUser *goth.User) string {
@ -702,18 +702,22 @@ func updateAvatarIfNeed(url string, u *models.User) {
}
}
func handleOAuth2SignIn(ctx *context.Context, u *models.User, gothUser goth.User) {
func handleOAuth2SignIn(ctx *context.Context, source *models.LoginSource, u *models.User, gothUser goth.User) {
updateAvatarIfNeed(gothUser.AvatarURL, u)
// If this user is enrolled in 2FA, we can't sign the user in just yet.
// Instead, redirect them to the 2FA authentication page.
_, err := models.GetTwoFactorByUID(u.ID)
if err != nil {
if !models.IsErrTwoFactorNotEnrolled(err) {
needs2FA := false
if !source.Cfg.(*oauth2.Source).SkipLocalTwoFA {
_, err := models.GetTwoFactorByUID(u.ID)
if err != nil && !models.IsErrTwoFactorNotEnrolled(err) {
ctx.ServerError("UserSignIn", err)
return
}
needs2FA = err == nil
}
// If this user is enrolled in 2FA and this source doesn't override it,
// we can't sign the user in just yet. Instead, redirect them to the 2FA authentication page.
if !needs2FA {
if err := ctx.Session.Set("uid", u.ID); err != nil {
log.Error("Error setting uid in session: %v", err)
}