Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions _local/lookout/config-auth.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ uiConfig:
authority: "http://localhost:8180/realms/armada"
clientId: "armada-server"
scope: "openid profile email"
# Keycloak defines a "name" claim which is more human readable than the default "sub"
displayNameClaim: "name"
19 changes: 12 additions & 7 deletions internal/lookout/configuration/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,19 +162,24 @@ type AnalyticsConfig struct {
DataWrapper string `json:"dataWrapper,omitempty"`
}

type OidcConfig struct {
Authority string `json:"authority"`
ClientId string `json:"clientId"`
Scope string `json:"scope"`
LoadUserInfo *bool `json:"loadUserInfo"`
// DisplayNameClaim specifies which OIDC claim to use for the username display.
// Common values: "name", "preferred_username", "email", "given_name". Defaults to "sub".
DisplayNameClaim *string `json:"displayNameClaim,omitempty"`
}

// UIConfig must match the LookoutUiConfig TypeScript interface defined in internal/lookoutui/src/config/types.ts
type UIConfig struct {
CustomTitle string `json:"customTitle"`

// We have a separate flag here (instead of making the Oidc field optional)
// so that clients can override the server's preference.
OidcEnabled bool `json:"oidcEnabled"`
Oidc *struct {
Authority string `json:"authority"`
ClientId string `json:"clientId"`
Scope string `json:"scope"`
LoadUserInfo *bool `json:"loadUserInfo"`
} `json:"oidc,omitempty"`
OidcEnabled bool `json:"oidcEnabled"`
Oidc *OidcConfig `json:"oidc,omitempty"`

ArmadaApiBaseUrl string `json:"armadaApiBaseUrl"`
UserAnnotationPrefix string `json:"userAnnotationPrefix"`
Expand Down
1 change: 1 addition & 0 deletions internal/lookoutui/src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface OidcConfig {
clientId: string
scope: string
loadUserInfo: boolean
displayNameClaim?: string
}

export interface CommandSpec {
Expand Down
15 changes: 15 additions & 0 deletions internal/lookoutui/src/oidcAuth/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import { useCallback, useContext, useEffect, useState } from "react"

import { UserManager } from "oidc-client-ts"

import { getConfig } from "../config"

import { OidcAuthContext } from "./OidcAuthContext"
import { appendAuthorizationHeaders } from "./utils"

const config = getConfig()

export const useUserManager = (): UserManager | undefined => useContext(OidcAuthContext)?.userManager

export const useUsername = (): string | null => {
Expand All @@ -21,6 +25,17 @@ export const useUsername = (): string | null => {
return
}

if (config.oidc?.displayNameClaim) {
const displayName = user.profile[config.oidc.displayNameClaim]
if (typeof displayName === "string") {
setUsername(displayName)
return
}
// eslint-disable-next-line no-console
console.warn(
`[useUsername] displayNameClaim "${config.oidc.displayNameClaim}" not found or not a string in OIDC profile; falling back to "sub"`,
)
}
Comment thread
greptile-apps[bot] marked this conversation as resolved.
setUsername(user.profile.sub)
})()
}, [userManager])
Expand Down
Loading