diff options
author | 2024-02-27 10:07:29 -0500 | |
---|---|---|
committer | 2024-02-27 16:07:29 +0100 | |
commit | 9bf448be7aa5e2468d5a6302d7c37ebad0f84176 (patch) | |
tree | c03e0079e84d8fd412cc23abc9ebb1b1118559e8 /internal/api/auth/callback.go | |
parent | [chore/docs] Various little docs updates (#2691) (diff) | |
download | gotosocial-9bf448be7aa5e2468d5a6302d7c37ebad0f84176.tar.xz |
[feature/oidc] Add support for very basic RBAC (#2642)
* Add support for very basic RBAC
* Add some small tests for allowedGroup and adminGroup
* Switch to table-driven tests
Diffstat (limited to 'internal/api/auth/callback.go')
-rw-r--r-- | internal/api/auth/callback.go | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/internal/api/auth/callback.go b/internal/api/auth/callback.go index d0fa78322..37c257229 100644 --- a/internal/api/auth/callback.go +++ b/internal/api/auth/callback.go @@ -23,6 +23,7 @@ import ( "fmt" "net" "net/http" + "slices" "strings" "github.com/gin-contrib/sessions" @@ -156,6 +157,14 @@ func (m *Module) CallbackGETHandler(c *gin.Context) { apiutil.TemplateWebPage(c, page) return } + + // Check user permissions on login + if !allowedGroup(claims.Groups) { + err := fmt.Errorf("User groups %+v do not include an allowed group", claims.Groups) + apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1) + return + } + s.Set(sessionUserID, user.ID) if err := s.Save(); err != nil { m.clearSession(s) @@ -297,6 +306,11 @@ func (m *Module) createUserFromOIDC(ctx context.Context, claims *oidc.Claims, ex return nil, gtserror.NewErrorConflict(err, help) } + if !allowedGroup(claims.Groups) { + err := fmt.Errorf("User groups %+v do not include an allowed group", claims.Groups) + return nil, gtserror.NewErrorUnauthorized(err, err.Error()) + } + // We still need to set something as a password, even // if it's not a password the user will end up using. // @@ -356,13 +370,12 @@ func (m *Module) createUserFromOIDC(ctx context.Context, claims *oidc.Claims, ex // adminGroup returns true if one of the given OIDC // groups is equal to at least one admin OIDC group. func adminGroup(groups []string) bool { - for _, ag := range config.GetOIDCAdminGroups() { - for _, g := range groups { - if strings.EqualFold(ag, g) { - // This is an admin group, - // ∴ user is an admin. - return true - } + adminGroups := config.GetOIDCAdminGroups() + for _, claimedGroup := range groups { + if slices.ContainsFunc(adminGroups, func(allowedGroup string) bool { + return strings.EqualFold(claimedGroup, allowedGroup) + }) { + return true } } @@ -370,3 +383,24 @@ func adminGroup(groups []string) bool { // ∴ user is not an admin. return false } + +// allowedGroup returns true if one of the given OIDC +// groups is equal to at least one allowed OIDC group. +func allowedGroup(groups []string) bool { + allowedGroups := config.GetOIDCAllowedGroups() + if len(allowedGroups) == 0 { + // If no groups are configured, allow access (for backwards compatibility) + return true + } + for _, claimedGroup := range groups { + if slices.ContainsFunc(allowedGroups, func(allowedGroup string) bool { + return strings.EqualFold(claimedGroup, allowedGroup) + }) { + return true + } + } + + // User is in no allowed groups, + // ∴ user is not allowed to log in + return false +} |