feat: read admin group from OIDC token claim (#445)

This commit is contained in:
Johannes Kirchner 2025-04-02 13:38:11 +02:00 committed by GitHub
parent 7907c7bc1e
commit 8cfaceb303
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 59 additions and 7 deletions

View File

@ -106,6 +106,10 @@ oidc.client-key:
oidc.secret:
# Discovery endpoint of the OpenID provider. Generally something like http://auth.example.com/.well-known/openid-configuration
oidc.discovery-url:
# The name of the claim containing the groups
oidc.group-claim-name:
# The name of the group that should receive admin rights
oidc.admin-group:
# Instance name
# Set your own custom name to be displayed instead of 'Opengist'

View File

@ -76,4 +76,19 @@ Opengist can be configured to use OAuth to authenticate users, with GitHub, Gite
# Discovery endpoint of the OpenID provider. Generally something like http://auth.example.com/.well-known/openid-configuration
OG_OIDC_DISCOVERY_URL=http://auth.example.com/.well-known/openid-configuration
```
### OIDC Admin Group
OpenGist supports automatic admin privilege assignment based on OIDC group claims. To configure this feature:
```yaml
oidc.group-claim-name: groups # Name of the claim containing the groups
oidc.admin-group: admin-group-name # Name of the group that should receive admin rights
```
```shell
OG_OIDC_GROUP_CLAIM_NAME=groups
OG_OIDC_ADMIN_GROUP=admin-group-name
```
The `group-claim-name` must match the name of the claim in your JWT token that contains the groups.
Users who are members of the configured `admin-group` will automatically receive admin privileges in OpenGist. These privileges are synchronized on every login.

View File

@ -70,10 +70,12 @@ type config struct {
GiteaUrl string `yaml:"gitea.url" env:"OG_GITEA_URL"`
GiteaName string `yaml:"gitea.name" env:"OG_GITEA_NAME"`
OIDCProviderName string `yaml:"oidc.provider-name" env:"OG_OIDC_PROVIDER_NAME"`
OIDCClientKey string `yaml:"oidc.client-key" env:"OG_OIDC_CLIENT_KEY"`
OIDCSecret string `yaml:"oidc.secret" env:"OG_OIDC_SECRET"`
OIDCDiscoveryUrl string `yaml:"oidc.discovery-url" env:"OG_OIDC_DISCOVERY_URL"`
OIDCProviderName string `yaml:"oidc.provider-name" env:"OG_OIDC_PROVIDER_NAME"`
OIDCClientKey string `yaml:"oidc.client-key" env:"OG_OIDC_CLIENT_KEY"`
OIDCSecret string `yaml:"oidc.secret" env:"OG_OIDC_SECRET"`
OIDCDiscoveryUrl string `yaml:"oidc.discovery-url" env:"OG_OIDC_DISCOVERY_URL"`
OIDCGroupClaimName string `yaml:"oidc.group-claim-name" env:"OG_OIDC_GROUP_CLAIM_NAME"`
OIDCAdminGroup string `yaml:"oidc.admin-group" env:"OG_OIDC_ADMIN_GROUP"`
MetricsEnabled bool `yaml:"metrics.enabled" env:"OG_METRICS_ENABLED"`

View File

@ -4,6 +4,9 @@ import (
"crypto/md5"
"errors"
"fmt"
"slices"
"strings"
"github.com/rs/zerolog/log"
"github.com/thomiceli/opengist/internal/auth/oauth"
"github.com/thomiceli/opengist/internal/config"
@ -12,7 +15,6 @@ import (
"golang.org/x/text/cases"
"golang.org/x/text/language"
"gorm.io/gorm"
"strings"
)
func Oauth(ctx *context.Context) error {
@ -110,7 +112,8 @@ func OauthCallback(ctx *context.Context) error {
return ctx.ErrorRes(500, "Cannot create user", err)
}
if userDB.ID == 1 {
// if oidc admin group is not configured set first user as admin
if config.C.OIDCAdminGroup == "" && userDB.ID == 1 {
if err = userDB.SetAdmin(); err != nil {
return ctx.ErrorRes(500, "Cannot set user admin", err)
}
@ -136,6 +139,32 @@ func OauthCallback(ctx *context.Context) error {
}
}
// update is admin status from oidc group
if config.C.OIDCAdminGroup != "" {
groupClaimName := config.C.OIDCGroupClaimName
if groupClaimName == "" {
log.Error().Msg("No OIDC group claim name configured")
} else if groups, ok := user.RawData[groupClaimName].([]interface{}); ok {
var groupNames []string
for _, group := range groups {
if groupName, ok := group.(string); ok {
groupNames = append(groupNames, groupName)
}
}
isOIDCAdmin := slices.Contains(groupNames, config.C.OIDCAdminGroup)
log.Debug().Bool("isOIDCAdmin", isOIDCAdmin).Str("user", user.Name).Msg("User is in admin group")
if userDB.IsAdmin != isOIDCAdmin {
userDB.IsAdmin = isOIDCAdmin
if err = userDB.Update(); err != nil {
return ctx.ErrorRes(500, "Cannot set user admin", err)
}
}
} else {
log.Error().Msg("No groups found in user data")
}
}
sess := ctx.GetSession()
sess.Values["user"] = userDB.ID
ctx.SaveSession(sess)

View File

@ -69,6 +69,8 @@
<dt>OIDC client Key</dt><dd>{{ if .c.OIDCClientKey }}&#60;defined&#62;{{ end }}</dd>
<dt>OIDC Secret</dt><dd>{{ if .c.OIDCSecret }}&#60;defined&#62;{{ end }}</dd>
<dt>OIDC Discovery URL</dt><dd>{{ if .c.OIDCDiscoveryUrl }}&#60;defined&#62;{{ end }}</dd>
<dt>OIDC Group Claim Name</dt><dd>{{ .c.OIDCGroupClaimName }}</dd>
<dt>OIDC Admin Group</dt><dd>{{ .c.OIDCAdminGroup }}</dd>
</dl>
</div>
<div>