Skip to content

Commit

Permalink
Add Option to synchronize Admin & Restricted states from OIDC/OAuth2 …
Browse files Browse the repository at this point in the history
…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 <art27@cantab.net>

* Fix regression from #16544

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Add scopes settings

Signed-off-by: Andrew Thornton <art27@cantab.net>

* fix trace logging in auth_openid

Signed-off-by: Andrew Thornton <art27@cantab.net>

* add required claim options

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Move UpdateExternalUser to externalaccount

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Allow OAuth2/OIDC to set Admin/Restricted status

Signed-off-by: Andrew Thornton <art27@cantab.net>

* Allow use of the same group claim name for the prohibit login value

Signed-off-by: Andrew Thornton <art27@cantab.net>

* fixup! Move UpdateExternalUser to externalaccount

* as per wxiaoguang

Signed-off-by: Andrew Thornton <art27@cantab.net>

* add label back in

Signed-off-by: Andrew Thornton <art27@cantab.net>

* adjust localisation

Signed-off-by: Andrew Thornton <art27@cantab.net>

* placate lint

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
  • Loading branch information
4 people committed Dec 14, 2021
1 parent b4782e2 commit 0981ec3
Show file tree
Hide file tree
Showing 17 changed files with 344 additions and 88 deletions.
58 changes: 58 additions & 0 deletions cmd/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,36 @@ var (
Name: "skip-local-2fa",
Usage: "Set to true to skip local 2fa for users authenticated by this source",
},
cli.StringSliceFlag{
Name: "scopes",
Value: nil,
Usage: "Scopes to request when to authenticate against this OAuth2 source",
},
cli.StringFlag{
Name: "required-claim-name",
Value: "",
Usage: "Claim name that has to be set to allow users to login with this source",
},
cli.StringFlag{
Name: "required-claim-value",
Value: "",
Usage: "Claim value that has to be set to allow users to login with this source",
},
cli.StringFlag{
Name: "group-claim-name",
Value: "",
Usage: "Claim name providing group names for this source",
},
cli.StringFlag{
Name: "admin-group",
Value: "",
Usage: "Group Claim value for administrator users",
},
cli.StringFlag{
Name: "restricted-group",
Value: "",
Usage: "Group Claim value for restricted users",
},
}

microcmdAuthUpdateOauth = cli.Command{
Expand Down Expand Up @@ -649,6 +679,12 @@ func parseOAuth2Config(c *cli.Context) *oauth2.Source {
CustomURLMapping: customURLMapping,
IconURL: c.String("icon-url"),
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
Scopes: c.StringSlice("scopes"),
RequiredClaimName: c.String("required-claim-name"),
RequiredClaimValue: c.String("required-claim-value"),
GroupClaimName: c.String("group-claim-name"),
AdminGroup: c.String("admin-group"),
RestrictedGroup: c.String("restricted-group"),
}
}

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

if c.IsSet("scopes") {
oAuth2Config.Scopes = c.StringSlice("scopes")
}

if c.IsSet("required-claim-name") {
oAuth2Config.RequiredClaimName = c.String("required-claim-name")

}
if c.IsSet("required-claim-value") {
oAuth2Config.RequiredClaimValue = c.String("required-claim-value")
}

if c.IsSet("group-claim-name") {
oAuth2Config.GroupClaimName = c.String("group-claim-name")
}
if c.IsSet("admin-group") {
oAuth2Config.AdminGroup = c.String("admin-group")
}
if c.IsSet("restricted-group") {
oAuth2Config.RestrictedGroup = c.String("restricted-group")
}

// update custom URL mapping
var customURLMapping = &oauth2.CustomURLMapping{}

Expand Down
14 changes: 14 additions & 0 deletions docs/content/doc/usage/command-line.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ Admin operations:
- `--custom-profile-url`: Use a custom Profile URL (option for GitLab/GitHub).
- `--custom-email-url`: Use a custom Email URL (option for GitHub).
- `--icon-url`: Custom icon URL for OAuth2 login source.
- `--override-local-2fa`: Allow source to override local 2fa. (Optional)
- `--scopes`: Addtional scopes to request for this OAuth2 source. (Optional)
- `--required-claim-name`: Claim name that has to be set to allow users to login with this source. (Optional)
- `--required-claim-value`: Claim value that has to be set to allow users to login with this source. (Optional)
- `--group-claim-name`: Claim name providing group names for this source. (Optional)
- `--admin-group`: Group Claim value for administrator users. (Optional)
- `--restricted-group`: Group Claim value for restricted users. (Optional)
- Examples:
- `gitea admin auth add-oauth --name external-github --provider github --key OBTAIN_FROM_SOURCE --secret OBTAIN_FROM_SOURCE`
- `update-oauth`:
Expand All @@ -145,6 +152,13 @@ Admin operations:
- `--custom-profile-url`: Use a custom Profile URL (option for GitLab/GitHub).
- `--custom-email-url`: Use a custom Email URL (option for GitHub).
- `--icon-url`: Custom icon URL for OAuth2 login source.
- `--override-local-2fa`: Allow source to override local 2fa. (Optional)
- `--scopes`: Addtional scopes to request for this OAuth2 source.
- `--required-claim-name`: Claim name that has to be set to allow users to login with this source. (Optional)
- `--required-claim-value`: Claim value that has to be set to allow users to login with this source. (Optional)
- `--group-claim-name`: Claim name providing group names for this source. (Optional)
- `--admin-group`: Group Claim value for administrator users. (Optional)
- `--restricted-group`: Group Claim value for restricted users. (Optional)
- Examples:
- `gitea admin auth update-oauth --id 1 --name external-github-updated`
- `add-ldap`: Add new LDAP (via Bind DN) authentication source
Expand Down
38 changes: 6 additions & 32 deletions models/user/external_login_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import (
"time"

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/login"

"github.com/markbates/goth"
"xorm.io/builder"
)

Expand Down Expand Up @@ -139,42 +137,18 @@ func GetUserIDByExternalUserID(provider, userID string) (int64, error) {
return id, nil
}

// UpdateExternalUser updates external user's information
func UpdateExternalUser(user *User, gothUser goth.User) error {
loginSource, err := login.GetActiveOAuth2LoginSourceByName(gothUser.Provider)
if err != nil {
return err
}
externalLoginUser := &ExternalLoginUser{
ExternalID: gothUser.UserID,
UserID: user.ID,
LoginSourceID: loginSource.ID,
RawData: gothUser.RawData,
Provider: gothUser.Provider,
Email: gothUser.Email,
Name: gothUser.Name,
FirstName: gothUser.FirstName,
LastName: gothUser.LastName,
NickName: gothUser.NickName,
Description: gothUser.Description,
AvatarURL: gothUser.AvatarURL,
Location: gothUser.Location,
AccessToken: gothUser.AccessToken,
AccessTokenSecret: gothUser.AccessTokenSecret,
RefreshToken: gothUser.RefreshToken,
ExpiresAt: gothUser.ExpiresAt,
}

has, err := db.GetEngine(db.DefaultContext).Where("external_id=? AND login_source_id=?", gothUser.UserID, loginSource.ID).
// UpdateExternalUserByExternalID updates an external user's information
func UpdateExternalUserByExternalID(external *ExternalLoginUser) error {
has, err := db.GetEngine(db.DefaultContext).Where("external_id=? AND login_source_id=?", external.ExternalID, external.LoginSourceID).
NoAutoCondition().
Exist(externalLoginUser)
Exist(external)
if err != nil {
return err
} else if !has {
return ErrExternalLoginUserNotExist{user.ID, loginSource.ID}
return ErrExternalLoginUserNotExist{external.UserID, external.LoginSourceID}
}

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

Expand Down
1 change: 1 addition & 0 deletions modules/templates/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ func NewFuncMap() []template.FuncMap {
"MermaidMaxSourceCharacters": func() int {
return setting.MermaidMaxSourceCharacters
},
"Join": strings.Join,
"QueryEscape": url.QueryEscape,
}}
}
Expand Down
5 changes: 5 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2521,6 +2521,11 @@ 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.oauth2_scopes = Additional Scopes
auths.oauth2_required_claim_name = Required Claim Name
auths.oauth2_required_claim_name_helper = Set this name to restrict login from this source to users with a claim with this name
auths.oauth2_required_claim_value = Required Claim Value
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
auths.enable_auto_register = Enable Auto Registration
auths.sspi_auto_create_users = Automatically create users
auths.sspi_auto_create_users_helper = Allow SSPI auth method to automatically create new accounts for users that login for the first time
Expand Down
6 changes: 5 additions & 1 deletion routers/web/admin/auths.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/url"
"regexp"
"strconv"
"strings"

"code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/modules/auth/pam"
Expand Down Expand Up @@ -187,6 +188,9 @@ func parseOAuth2Config(form forms.AuthenticationForm) *oauth2.Source {
OpenIDConnectAutoDiscoveryURL: form.OpenIDConnectAutoDiscoveryURL,
CustomURLMapping: customURLMapping,
IconURL: form.Oauth2IconURL,
Scopes: strings.Split(form.Oauth2Scopes, ","),
RequiredClaimName: form.Oauth2RequiredClaimName,
RequiredClaimValue: form.Oauth2RequiredClaimValue,
SkipLocalTwoFA: form.SkipLocalTwoFA,
}
}
Expand Down Expand Up @@ -329,8 +333,8 @@ func EditAuthSource(ctx *context.Context) {
break
}
}

}

ctx.HTML(http.StatusOK, tplAuthEdit)
}

Expand Down
Loading

0 comments on commit 0981ec3

Please sign in to comment.