Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 5 commits into from
Sep 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cmd/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ var (
Value: "",
Usage: "Custom icon URL for OAuth2 login source",
},
cli.BoolFlag{
Name: "skip-local-2fa",
Usage: "Set to true to skip local 2fa for users authenticated by this source",
},
}

microcmdAuthUpdateOauth = cli.Command{
Expand Down Expand Up @@ -616,6 +620,7 @@ func parseOAuth2Config(c *cli.Context) *oauth2.Source {
OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"),
CustomURLMapping: customURLMapping,
IconURL: c.String("icon-url"),
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
}
}

Expand Down
2 changes: 2 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2456,6 +2456,8 @@ auths.oauth2_tokenURL = Token URL
auths.oauth2_authURL = Authorize URL
auths.oauth2_profileURL = Profile URL
auths.oauth2_emailURL = Email URL
auths.skip_local_two_fa = Skip local 2FA
auths.skip_local_two_fa_helper = Leaving unset means local users with 2FA set will still have to pass 2FA to log on
auths.oauth2_tenant = Tenant
auths.enable_auto_register = Enable Auto Registration
auths.sspi_auto_create_users = Automatically create users
Expand Down
1 change: 1 addition & 0 deletions routers/web/admin/auths.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ func parseOAuth2Config(form forms.AuthenticationForm) *oauth2.Source {
OpenIDConnectAutoDiscoveryURL: form.OpenIDConnectAutoDiscoveryURL,
CustomURLMapping: customURLMapping,
IconURL: form.Oauth2IconURL,
SkipLocalTwoFA: form.SkipLocalTwoFA,
}
}

Expand Down
20 changes: 12 additions & 8 deletions routers/web/user/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -660,7 +660,7 @@ func SignInOAuthCallback(ctx *context.Context) {
}
}

handleOAuth2SignIn(ctx, u, gothUser)
handleOAuth2SignIn(ctx, loginSource, u, gothUser)
}

func getUserName(gothUser *goth.User) string {
Expand Down Expand Up @@ -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)
}
Expand Down
1 change: 1 addition & 0 deletions services/auth/source/oauth2/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Source struct {
OpenIDConnectAutoDiscoveryURL string
CustomURLMapping *CustomURLMapping
IconURL string
SkipLocalTwoFA bool

// reference to the loginSource
loginSource *models.LoginSource
Expand Down
1 change: 1 addition & 0 deletions services/forms/auth_form.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type AuthenticationForm struct {
Oauth2EmailURL string
Oauth2IconURL string
Oauth2Tenant string
SkipLocalTwoFA bool
SSPIAutoCreateUsers bool
SSPIAutoActivateUsers bool
SSPIStripDomainNames bool
Expand Down
7 changes: 7 additions & 0 deletions templates/admin/auth/edit.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@
<label for="open_id_connect_auto_discovery_url">{{.i18n.Tr "admin.auths.openIdConnectAutoDiscoveryURL"}}</label>
<input id="open_id_connect_auto_discovery_url" name="open_id_connect_auto_discovery_url" value="{{$cfg.OpenIDConnectAutoDiscoveryURL}}">
</div>
<div class="optional field">
<div class="ui checkbox">
<label for="skip_local_two_fa"><strong>{{.i18n.Tr "admin.auths.skip_local_two_fa"}}</strong></label>
<input id="skip_local_two_fa" name="skip_local_two_fa" type="checkbox" {{if $cfg.SkipLocalTwoFA}}checked{{end}}>
<p class="help">{{.i18n.Tr "admin.auths.skip_local_two_fa_helper"}}</p>
</div>
</div>

<div class="oauth2_use_custom_url inline field">
<div class="ui checkbox">
Expand Down
7 changes: 7 additions & 0 deletions templates/admin/auth/source/oauth.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@
<label for="open_id_connect_auto_discovery_url">{{.i18n.Tr "admin.auths.openIdConnectAutoDiscoveryURL"}}</label>
<input id="open_id_connect_auto_discovery_url" name="open_id_connect_auto_discovery_url" value="{{.open_id_connect_auto_discovery_url}}">
</div>
<div class="optional field">
<div class="ui checkbox">
<label for="skip_local_two_fa"><strong>{{.i18n.Tr "admin.auths.skip_local_two_fa"}}</strong></label>
<input id="skip_local_two_fa" name="skip_local_two_fa" type="checkbox" {{if .skip_local_two_fa}}checked{{end}}>
<p class="help">{{.i18n.Tr "admin.auths.skip_local_two_fa_helper"}}</p>
</div>
</div>

<div class="oauth2_use_custom_url inline field">
<div class="ui checkbox">
Expand Down