setUserForPublicAuth sets h.user based on the authentication information in the request. Returns an error if the user can not authenticate successfully, and returns AuditFields even in the case that there is an error in the request. Uses: 1. Bearer token (OIDC JWT) if present and OIDC is enabled 2
(dbCtx *db.DatabaseContext)
| 958 | // 3. Cookie auth if present |
| 959 | // 4. Guest access if enabled |
| 960 | func (h *handler) setUserForPublicAuth(dbCtx *db.DatabaseContext) (base.AuditFields, error) { |
| 961 | var auditFields base.AuditFields |
| 962 | // If oidc enabled, check for bearer ID token |
| 963 | if dbCtx.Options.OIDCOptions != nil || len(dbCtx.LocalJWTProviders) > 0 { |
| 964 | if token := h.getBearerToken(); token != "" { |
| 965 | auditFields = base.AuditFields{base.AuditFieldAuthMethod: "bearer"} |
| 966 | var updates auth.PrincipalConfig |
| 967 | var err error |
| 968 | h.user, updates, err = dbCtx.Authenticator(h.ctx()).AuthenticateUntrustedJWT(token, dbCtx.OIDCProviders, dbCtx.LocalJWTProviders, h.getOIDCCallbackURL) |
| 969 | if h.user == nil || err != nil { |
| 970 | return auditFields, ErrInvalidLogin |
| 971 | } |
| 972 | if issuer := h.user.JWTIssuer(); issuer != "" { |
| 973 | auditFields["oidc_issuer"] = issuer |
| 974 | } |
| 975 | if changes := checkJWTIssuerStillValid(h.ctx(), dbCtx, h.user); changes != nil { |
| 976 | updates = updates.Merge(*changes) |
| 977 | } |
| 978 | _, _, err = dbCtx.UpdatePrincipal(h.ctx(), &updates, true, true) |
| 979 | if err != nil { |
| 980 | return auditFields, fmt.Errorf("failed to update OIDC user after sign-in: %w", err) |
| 981 | } |
| 982 | // TODO: could avoid this extra fetch if UpdatePrincipal returned the newly updated principal |
| 983 | if updates.Name != nil { |
| 984 | h.user, err = dbCtx.Authenticator(h.ctx()).GetUser(*updates.Name) |
| 985 | } |
| 986 | return auditFields, err |
| 987 | } |
| 988 | |
| 989 | /* |
| 990 | * If unsupported/oidc testing is enabled |
| 991 | * and this is a call on the token endpoint |
| 992 | * and the username and password match those in the oidc default provider config |
| 993 | * then authorize this request |
| 994 | */ |
| 995 | if strings.HasSuffix(h.rq.URL.Path, "/_oidc_testing/token") && dbCtx.Options.UnsupportedOptions != nil && |
| 996 | dbCtx.Options.UnsupportedOptions.OidcTestProvider != nil && dbCtx.Options.UnsupportedOptions.OidcTestProvider.Enabled { |
| 997 | if username, password := h.getBasicAuth(); username != "" && password != "" { |
| 998 | provider := dbCtx.Options.OIDCOptions.Providers.GetProviderForIssuer(h.ctx(), issuerUrlForDB(h, dbCtx.Name), testProviderAudiences) |
| 999 | if provider != nil && provider.ValidationKey != nil { |
| 1000 | if base.ValDefault(provider.ClientID, "") == username && *provider.ValidationKey == password { |
| 1001 | return base.AuditFields{base.AuditFieldAuthMethod: "basic"}, nil |
| 1002 | } |
| 1003 | } |
| 1004 | } |
| 1005 | } |
| 1006 | } |
| 1007 | |
| 1008 | // Check basic auth first |
| 1009 | if !dbCtx.Options.DisablePasswordAuthentication { |
| 1010 | if userName, password := h.getBasicAuth(); userName != "" { |
| 1011 | auditFields := base.AuditFields{base.AuditFieldAuthMethod: "basic"} |
| 1012 | var err error |
| 1013 | h.user, err = dbCtx.Authenticator(h.ctx()).AuthenticateUser(userName, password) |
| 1014 | if err != nil { |
| 1015 | return auditFields, err |
| 1016 | } |
| 1017 | if h.user == nil { |
no test coverage detected