Skip to content

Commit 0981ec3

Browse files
zeripath6543lunnytechknowlogick
authored
Add Option to synchronize Admin & Restricted states from OIDC/OAuth2 along with Setting Scopes (#16766)
* Add setting to OAuth handlers to override local 2FA settings This PR adds a setting to OAuth and OpenID login sources to allow the source to override local 2FA requirements. Fix #13939 Signed-off-by: Andrew Thornton <[email protected]> * Fix regression from #16544 Signed-off-by: Andrew Thornton <[email protected]> * Add scopes settings Signed-off-by: Andrew Thornton <[email protected]> * fix trace logging in auth_openid Signed-off-by: Andrew Thornton <[email protected]> * add required claim options Signed-off-by: Andrew Thornton <[email protected]> * Move UpdateExternalUser to externalaccount Signed-off-by: Andrew Thornton <[email protected]> * Allow OAuth2/OIDC to set Admin/Restricted status Signed-off-by: Andrew Thornton <[email protected]> * Allow use of the same group claim name for the prohibit login value Signed-off-by: Andrew Thornton <[email protected]> * fixup! Move UpdateExternalUser to externalaccount * as per wxiaoguang Signed-off-by: Andrew Thornton <[email protected]> * add label back in Signed-off-by: Andrew Thornton <[email protected]> * adjust localisation Signed-off-by: Andrew Thornton <[email protected]> * placate lint Signed-off-by: Andrew Thornton <[email protected]> Co-authored-by: 6543 <[email protected]> Co-authored-by: Lunny Xiao <[email protected]> Co-authored-by: techknowlogick <[email protected]>
1 parent b4782e2 commit 0981ec3

File tree

17 files changed

+344
-88
lines changed

17 files changed

+344
-88
lines changed

cmd/admin.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,36 @@ var (
299299
Name: "skip-local-2fa",
300300
Usage: "Set to true to skip local 2fa for users authenticated by this source",
301301
},
302+
cli.StringSliceFlag{
303+
Name: "scopes",
304+
Value: nil,
305+
Usage: "Scopes to request when to authenticate against this OAuth2 source",
306+
},
307+
cli.StringFlag{
308+
Name: "required-claim-name",
309+
Value: "",
310+
Usage: "Claim name that has to be set to allow users to login with this source",
311+
},
312+
cli.StringFlag{
313+
Name: "required-claim-value",
314+
Value: "",
315+
Usage: "Claim value that has to be set to allow users to login with this source",
316+
},
317+
cli.StringFlag{
318+
Name: "group-claim-name",
319+
Value: "",
320+
Usage: "Claim name providing group names for this source",
321+
},
322+
cli.StringFlag{
323+
Name: "admin-group",
324+
Value: "",
325+
Usage: "Group Claim value for administrator users",
326+
},
327+
cli.StringFlag{
328+
Name: "restricted-group",
329+
Value: "",
330+
Usage: "Group Claim value for restricted users",
331+
},
302332
}
303333

304334
microcmdAuthUpdateOauth = cli.Command{
@@ -649,6 +679,12 @@ func parseOAuth2Config(c *cli.Context) *oauth2.Source {
649679
CustomURLMapping: customURLMapping,
650680
IconURL: c.String("icon-url"),
651681
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
682+
Scopes: c.StringSlice("scopes"),
683+
RequiredClaimName: c.String("required-claim-name"),
684+
RequiredClaimValue: c.String("required-claim-value"),
685+
GroupClaimName: c.String("group-claim-name"),
686+
AdminGroup: c.String("admin-group"),
687+
RestrictedGroup: c.String("restricted-group"),
652688
}
653689
}
654690

@@ -711,6 +747,28 @@ func runUpdateOauth(c *cli.Context) error {
711747
oAuth2Config.IconURL = c.String("icon-url")
712748
}
713749

750+
if c.IsSet("scopes") {
751+
oAuth2Config.Scopes = c.StringSlice("scopes")
752+
}
753+
754+
if c.IsSet("required-claim-name") {
755+
oAuth2Config.RequiredClaimName = c.String("required-claim-name")
756+
757+
}
758+
if c.IsSet("required-claim-value") {
759+
oAuth2Config.RequiredClaimValue = c.String("required-claim-value")
760+
}
761+
762+
if c.IsSet("group-claim-name") {
763+
oAuth2Config.GroupClaimName = c.String("group-claim-name")
764+
}
765+
if c.IsSet("admin-group") {
766+
oAuth2Config.AdminGroup = c.String("admin-group")
767+
}
768+
if c.IsSet("restricted-group") {
769+
oAuth2Config.RestrictedGroup = c.String("restricted-group")
770+
}
771+
714772
// update custom URL mapping
715773
var customURLMapping = &oauth2.CustomURLMapping{}
716774

docs/content/doc/usage/command-line.en-us.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ Admin operations:
129129
- `--custom-profile-url`: Use a custom Profile URL (option for GitLab/GitHub).
130130
- `--custom-email-url`: Use a custom Email URL (option for GitHub).
131131
- `--icon-url`: Custom icon URL for OAuth2 login source.
132+
- `--override-local-2fa`: Allow source to override local 2fa. (Optional)
133+
- `--scopes`: Addtional scopes to request for this OAuth2 source. (Optional)
134+
- `--required-claim-name`: Claim name that has to be set to allow users to login with this source. (Optional)
135+
- `--required-claim-value`: Claim value that has to be set to allow users to login with this source. (Optional)
136+
- `--group-claim-name`: Claim name providing group names for this source. (Optional)
137+
- `--admin-group`: Group Claim value for administrator users. (Optional)
138+
- `--restricted-group`: Group Claim value for restricted users. (Optional)
132139
- Examples:
133140
- `gitea admin auth add-oauth --name external-github --provider github --key OBTAIN_FROM_SOURCE --secret OBTAIN_FROM_SOURCE`
134141
- `update-oauth`:
@@ -145,6 +152,13 @@ Admin operations:
145152
- `--custom-profile-url`: Use a custom Profile URL (option for GitLab/GitHub).
146153
- `--custom-email-url`: Use a custom Email URL (option for GitHub).
147154
- `--icon-url`: Custom icon URL for OAuth2 login source.
155+
- `--override-local-2fa`: Allow source to override local 2fa. (Optional)
156+
- `--scopes`: Addtional scopes to request for this OAuth2 source.
157+
- `--required-claim-name`: Claim name that has to be set to allow users to login with this source. (Optional)
158+
- `--required-claim-value`: Claim value that has to be set to allow users to login with this source. (Optional)
159+
- `--group-claim-name`: Claim name providing group names for this source. (Optional)
160+
- `--admin-group`: Group Claim value for administrator users. (Optional)
161+
- `--restricted-group`: Group Claim value for restricted users. (Optional)
148162
- Examples:
149163
- `gitea admin auth update-oauth --id 1 --name external-github-updated`
150164
- `add-ldap`: Add new LDAP (via Bind DN) authentication source

models/user/external_login_user.go

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ import (
1010
"time"
1111

1212
"code.gitea.io/gitea/models/db"
13-
"code.gitea.io/gitea/models/login"
1413

15-
"github.com/markbates/goth"
1614
"xorm.io/builder"
1715
)
1816

@@ -139,42 +137,18 @@ func GetUserIDByExternalUserID(provider, userID string) (int64, error) {
139137
return id, nil
140138
}
141139

142-
// UpdateExternalUser updates external user's information
143-
func UpdateExternalUser(user *User, gothUser goth.User) error {
144-
loginSource, err := login.GetActiveOAuth2LoginSourceByName(gothUser.Provider)
145-
if err != nil {
146-
return err
147-
}
148-
externalLoginUser := &ExternalLoginUser{
149-
ExternalID: gothUser.UserID,
150-
UserID: user.ID,
151-
LoginSourceID: loginSource.ID,
152-
RawData: gothUser.RawData,
153-
Provider: gothUser.Provider,
154-
Email: gothUser.Email,
155-
Name: gothUser.Name,
156-
FirstName: gothUser.FirstName,
157-
LastName: gothUser.LastName,
158-
NickName: gothUser.NickName,
159-
Description: gothUser.Description,
160-
AvatarURL: gothUser.AvatarURL,
161-
Location: gothUser.Location,
162-
AccessToken: gothUser.AccessToken,
163-
AccessTokenSecret: gothUser.AccessTokenSecret,
164-
RefreshToken: gothUser.RefreshToken,
165-
ExpiresAt: gothUser.ExpiresAt,
166-
}
167-
168-
has, err := db.GetEngine(db.DefaultContext).Where("external_id=? AND login_source_id=?", gothUser.UserID, loginSource.ID).
140+
// UpdateExternalUserByExternalID updates an external user's information
141+
func UpdateExternalUserByExternalID(external *ExternalLoginUser) error {
142+
has, err := db.GetEngine(db.DefaultContext).Where("external_id=? AND login_source_id=?", external.ExternalID, external.LoginSourceID).
169143
NoAutoCondition().
170-
Exist(externalLoginUser)
144+
Exist(external)
171145
if err != nil {
172146
return err
173147
} else if !has {
174-
return ErrExternalLoginUserNotExist{user.ID, loginSource.ID}
148+
return ErrExternalLoginUserNotExist{external.UserID, external.LoginSourceID}
175149
}
176150

177-
_, err = db.GetEngine(db.DefaultContext).Where("external_id=? AND login_source_id=?", gothUser.UserID, loginSource.ID).AllCols().Update(externalLoginUser)
151+
_, err = db.GetEngine(db.DefaultContext).Where("external_id=? AND login_source_id=?", external.ExternalID, external.LoginSourceID).AllCols().Update(external)
178152
return err
179153
}
180154

modules/templates/helper.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ func NewFuncMap() []template.FuncMap {
377377
"MermaidMaxSourceCharacters": func() int {
378378
return setting.MermaidMaxSourceCharacters
379379
},
380+
"Join": strings.Join,
380381
"QueryEscape": url.QueryEscape,
381382
}}
382383
}

options/locale/locale_en-US.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2521,6 +2521,11 @@ auths.oauth2_emailURL = Email URL
25212521
auths.skip_local_two_fa = Skip local 2FA
25222522
auths.skip_local_two_fa_helper = Leaving unset means local users with 2FA set will still have to pass 2FA to log on
25232523
auths.oauth2_tenant = Tenant
2524+
auths.oauth2_scopes = Additional Scopes
2525+
auths.oauth2_required_claim_name = Required Claim Name
2526+
auths.oauth2_required_claim_name_helper = Set this name to restrict login from this source to users with a claim with this name
2527+
auths.oauth2_required_claim_value = Required Claim Value
2528+
auths.oauth2_required_claim_value_helper = Set this value to restrict login from this source to users with a claim with this name and value
25242529
auths.enable_auto_register = Enable Auto Registration
25252530
auths.sspi_auto_create_users = Automatically create users
25262531
auths.sspi_auto_create_users_helper = Allow SSPI auth method to automatically create new accounts for users that login for the first time

routers/web/admin/auths.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"net/url"
1212
"regexp"
1313
"strconv"
14+
"strings"
1415

1516
"code.gitea.io/gitea/models/login"
1617
"code.gitea.io/gitea/modules/auth/pam"
@@ -187,6 +188,9 @@ func parseOAuth2Config(form forms.AuthenticationForm) *oauth2.Source {
187188
OpenIDConnectAutoDiscoveryURL: form.OpenIDConnectAutoDiscoveryURL,
188189
CustomURLMapping: customURLMapping,
189190
IconURL: form.Oauth2IconURL,
191+
Scopes: strings.Split(form.Oauth2Scopes, ","),
192+
RequiredClaimName: form.Oauth2RequiredClaimName,
193+
RequiredClaimValue: form.Oauth2RequiredClaimValue,
190194
SkipLocalTwoFA: form.SkipLocalTwoFA,
191195
}
192196
}
@@ -329,8 +333,8 @@ func EditAuthSource(ctx *context.Context) {
329333
break
330334
}
331335
}
332-
333336
}
337+
334338
ctx.HTML(http.StatusOK, tplAuthEdit)
335339
}
336340

0 commit comments

Comments
 (0)