Skip to content

Commit 4d2b734

Browse files
committed
updated with oidc fixes
1 parent a1522eb commit 4d2b734

File tree

7 files changed

+61
-23
lines changed

7 files changed

+61
-23
lines changed

CHANGELOG.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ All notable changes to this project will be documented in this file. For commit
44

55
## v0.7.8-beta
66

7+
Note: if using oidc, please update from 0.7.7 to resolve invalid_grant issue. Also - oidc no longer creates users automatically by default -- must be enabled.
78

89
**New Features**:
9-
-
10-
11-
**Notes**:
12-
-
10+
- More oidc user creation options https://github.com/gtsteffaniak/filebrowser/issues/685
11+
- `auth.methods.oidc.createUser` must be true to automatically create user, defaults to false.
12+
- `auth.methods.oidc.adminGroup` allows using oidc provider group name to enable admin user creation.
1313

1414
**BugFixes**:
1515
- fix save editor info sometimes saves wrong file. https://github.com/gtsteffaniak/filebrowser/issues/701

backend/common/settings/auth.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ type OidcConfig struct {
6060
UserIdentifier string `json:"userIdentifier"` // the user identifier to use for authentication. Default is "username", can be "email" or "username", or "phone"
6161
DisableVerifyTLS bool `json:"disableVerifyTLS"` // disable TLS verification for the OIDC provider. This is insecure and should only be used for testing.
6262
LogoutRedirectUrl string `json:"logoutRedirectUrl"` // if provider logout url is provided, filebrowser will also redirect to logout url. Custom logout query params are respected.
63+
CreateUser bool `json:"createUser"` // create user if not exists
64+
AdminGroup string `json:"adminGroup"` // if set, users in this group will be granted admin privileges.
6365
Provider *oidc.Provider `json:"-"` // OIDC provider
6466
Verifier *oidc.IDTokenVerifier `json:"-"` // OIDC verifier
6567
}

backend/http/oidc.go

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"crypto/tls"
55
"fmt"
66
"net/http"
7+
"slices"
78
"strings"
89
"time"
910

@@ -18,11 +19,12 @@ import (
1819

1920
// userInfo struct to hold user claims from either UserInfo or ID token
2021
type userInfo struct {
21-
Name string `json:"name"`
22-
PreferredUsername string `json:"preferred_username"`
23-
Email string `json:"email"`
24-
Sub string `json:"sub"`
25-
Phone string `json:"phone_number"`
22+
Name string `json:"name"`
23+
PreferredUsername string `json:"preferred_username"`
24+
Email string `json:"email"`
25+
Sub string `json:"sub"`
26+
Phone string `json:"phone_number"`
27+
Groups []string `json:"groups"`
2628
}
2729

2830
// oidcCallbackHandler handles the OIDC callback after the user authenticates with the provider.
@@ -174,9 +176,16 @@ func oidcCallbackHandler(w http.ResponseWriter, r *http.Request, d *requestConte
174176
logger.Error("No valid username found in ID token or UserInfo response.")
175177
return http.StatusInternalServerError, fmt.Errorf("no valid username found in ID token or UserInfo response from claims")
176178
}
179+
isAdmin := false // Default to non-admin user
180+
if config.Auth.Methods.OidcAuth.AdminGroup != "" {
181+
if slices.Contains(userdata.Groups, config.Auth.Methods.OidcAuth.AdminGroup) {
182+
isAdmin = true // User is in the admin group, grant admin privileges
183+
logger.Debugf("User %s is in admin group %s, granting admin privileges.", loginUsername, config.Auth.Methods.OidcAuth.AdminGroup)
184+
}
185+
}
177186
// Proceed to log the user in with the OIDC data
178187
// userdata struct now contains info from either verified ID token or UserInfo endpoint
179-
return loginWithOidcUser(w, r, loginUsername)
188+
return loginWithOidcUser(w, r, loginUsername, isAdmin)
180189
}
181190

182191
// oidcLoginHandler redirects the user to the OIDC provider's authorization endpoint.
@@ -213,25 +222,28 @@ func oidcLoginHandler(w http.ResponseWriter, r *http.Request, d *requestContext)
213222
// loginWithOidcUser extracts the username from the user claims (userInfo)
214223
// based on the configured UserIdentifier and logs the user into the application.
215224
// It creates a new user if one doesn't exist.
216-
func loginWithOidcUser(w http.ResponseWriter, r *http.Request, username string) (int, error) {
217-
logger.Debugf("Successfully authenticated OIDC username: %s", username)
225+
func loginWithOidcUser(w http.ResponseWriter, r *http.Request, username string, isAdmin bool) (int, error) {
226+
logger.Debugf("Successfully authenticated OIDC username: %s isAdmin: %v", username, isAdmin)
218227
// Retrieve the user from the store and store it in the context
219228
user, err := store.Users.Get(username)
220229
if err != nil {
221230
if err.Error() != "the resource does not exist" {
222231
return http.StatusInternalServerError, err
223232
}
224-
225-
err = storage.CreateUser(users.User{
226-
LoginMethod: users.LoginMethodOidc,
227-
Username: username,
228-
}, false)
229-
if err != nil {
230-
return http.StatusInternalServerError, err
231-
}
232-
user, err = store.Users.Get(username)
233-
if err != nil {
234-
return http.StatusInternalServerError, err
233+
if config.Auth.Methods.OidcAuth.CreateUser {
234+
err = storage.CreateUser(users.User{
235+
LoginMethod: users.LoginMethodOidc,
236+
Username: username,
237+
}, isAdmin)
238+
if err != nil {
239+
return http.StatusInternalServerError, err
240+
}
241+
user, err = store.Users.Get(username)
242+
if err != nil {
243+
return http.StatusInternalServerError, err
244+
}
245+
} else {
246+
return http.StatusForbidden, fmt.Errorf("user %s does not exist and createUser is disabled. Your admin needs to create your user before you can access this application", username)
235247
}
236248
}
237249
if user.LoginMethod != users.LoginMethodOidc {

backend/swagger/docs/docs.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1910,6 +1910,10 @@ const docTemplate = `{
19101910
"settings.OidcConfig": {
19111911
"type": "object",
19121912
"properties": {
1913+
"adminGroup": {
1914+
"description": "if set, users in this group will be granted admin privileges.",
1915+
"type": "string"
1916+
},
19131917
"clientId": {
19141918
"description": "client id of the OIDC application",
19151919
"type": "string"
@@ -1918,6 +1922,10 @@ const docTemplate = `{
19181922
"description": "client secret of the OIDC application",
19191923
"type": "string"
19201924
},
1925+
"createUser": {
1926+
"description": "create user if not exists",
1927+
"type": "boolean"
1928+
},
19211929
"disableVerifyTLS": {
19221930
"description": "disable TLS verification for the OIDC provider. This is insecure and should only be used for testing.",
19231931
"type": "boolean"

backend/swagger/docs/swagger.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,10 @@
18991899
"settings.OidcConfig": {
19001900
"type": "object",
19011901
"properties": {
1902+
"adminGroup": {
1903+
"description": "if set, users in this group will be granted admin privileges.",
1904+
"type": "string"
1905+
},
19021906
"clientId": {
19031907
"description": "client id of the OIDC application",
19041908
"type": "string"
@@ -1907,6 +1911,10 @@
19071911
"description": "client secret of the OIDC application",
19081912
"type": "string"
19091913
},
1914+
"createUser": {
1915+
"description": "create user if not exists",
1916+
"type": "boolean"
1917+
},
19101918
"disableVerifyTLS": {
19111919
"description": "disable TLS verification for the OIDC provider. This is insecure and should only be used for testing.",
19121920
"type": "boolean"

backend/swagger/docs/swagger.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,18 @@ definitions:
209209
type: object
210210
settings.OidcConfig:
211211
properties:
212+
adminGroup:
213+
description: if set, users in this group will be granted admin privileges.
214+
type: string
212215
clientId:
213216
description: client id of the OIDC application
214217
type: string
215218
clientSecret:
216219
description: client secret of the OIDC application
217220
type: string
221+
createUser:
222+
description: create user if not exists
223+
type: boolean
218224
disableVerifyTLS:
219225
description: disable TLS verification for the OIDC provider. This is insecure
220226
and should only be used for testing.

frontend/public/config.generated.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ auth:
6969
userIdentifier: "" # the user identifier to use for authentication. Default is "username", can be "email" or "username", or "phone"
7070
disableVerifyTLS: false # disable TLS verification for the OIDC provider. This is insecure and should only be used for testing.
7171
logoutRedirectUrl: "" # if provider logout url is provided, filebrowser will also redirect to logout url. Custom logout query params are respected.
72+
createUser: false # create user if not exists
73+
adminGroup: "" # if set, users in this group will be granted admin privileges.
7274
key: "" # the key used to sign the JWT tokens. If not set, a random key will be generated.
7375
adminUsername: admin # the username of the admin user. If not set, the default is "admin".
7476
adminPassword: admin # the password of the admin user. If not set, the default is "admin".

0 commit comments

Comments
 (0)