Possibility to configure an OpenID Connect provider on the instance level WIP (#128).

This commit is contained in:
John Livingston
2024-04-16 11:43:38 +02:00
parent 514cc1d159
commit e646ebfd69
8 changed files with 108 additions and 24 deletions

View File

@ -79,7 +79,11 @@ async function getConverseJSParams (
const oidc = ExternalAuthOIDC.singleton()
// TODO:
const externalAuthOIDC = await oidc.isOk() ? undefined : undefined
const externalAuthOIDC = await oidc.isOk()
? {
buttonLabel: oidc.getButtonLabel() ?? '???'
}
: undefined
return {
peertubeVideoOriginalUrl: roomInfos.video?.url,

View File

@ -16,13 +16,20 @@ export async function diagExternalAuthCustomOIDC (test: string, _options: Regist
return result
}
const errors = await oidc.check()
if (errors.length) {
result.messages.push('Discovery URL: ' + (oidc.getDiscoveryUrl() ?? 'undefined'))
const oidcErrors = await oidc.check()
if (oidcErrors.length) {
result.messages.push({
level: 'error',
message: 'The ExternalAuthOIDC singleton got some errors:'
})
result.messages.push(...errors)
for (const oidcError of oidcErrors) {
result.messages.push({
level: 'error',
message: oidcError
})
}
return result
}
} catch (err) {
@ -33,6 +40,18 @@ export async function diagExternalAuthCustomOIDC (test: string, _options: Regist
return result
}
const oidc = ExternalAuthOIDC.singleton()
const issuer = await oidc.loadIssuer()
if (issuer) {
result.messages.push('Discovery URL loaded: ' + JSON.stringify(issuer.metadata))
} else {
result.messages.push({
level: 'error',
message: 'Failed to load the Discovery URL.'
})
return result
}
result.ok = true
result.messages.push('Configuration OK.')
return result

View File

@ -14,6 +14,7 @@ class ExternalAuthOIDC {
private readonly clientId: string | undefined
private readonly clientSecret: string | undefined
private ok: boolean | undefined
private issuer: Issuer | undefined | null
protected readonly logger: {
debug: (s: string) => void
info: (s: string) => void
@ -54,6 +55,22 @@ class ExternalAuthOIDC {
return !this.enabled
}
/**
* Get the button
* @returns Button label
*/
getButtonLabel (): string | undefined {
return this.buttonLabel
}
/**
* Get the discovery URL
* @returns discoveryURL
*/
getDiscoveryUrl (): string | undefined {
return this.discoveryUrl
}
/**
* Indicates if the OIDC provider is correctly configured.
* @param force If true, all checks will be forced again.
@ -78,43 +95,52 @@ class ExternalAuthOIDC {
}
const errors: string[] = []
if (this.buttonLabel === undefined) {
if ((this.buttonLabel ?? '') === '') {
errors.push('Missing button label')
}
if (this.discoveryUrl === undefined) {
if ((this.discoveryUrl ?? '') === '') {
errors.push('Missing discovery url')
} else {
try {
const uri = new URL(this.discoveryUrl)
const uri = new URL(this.discoveryUrl ?? 'wrong url')
this.logger.debug('OIDC Discovery url is valid: ' + uri.toString())
} catch (err) {
errors.push('Invalid discovery url')
}
}
if (this.clientId === undefined) {
if ((this.clientId ?? '') === '') {
errors.push('Missing client id')
}
if (this.clientSecret === undefined) {
if ((this.clientSecret ?? '') === '') {
errors.push('Missing client secret')
}
if (errors.length === 0) {
// Now we can try to use the discover service
try {
const issuer = await Issuer.discover(this.discoveryUrl as string)
this.logger.debug(`Discovered issuer, metadata are: ${JSON.stringify(issuer.metadata)}`)
} catch (err) {
this.logger.error(err as string)
errors.push(`Discovery URL non working: ${err as string}`)
}
}
if (errors.length) {
this.logger.error('OIDC is not ok: ' + JSON.stringify(errors))
}
return errors
}
/**
* Ensure the issuer is loaded.
* @returns the issuer if enabled
*/
async loadIssuer (): Promise<Issuer | null> {
// this.issuer === null means we already tried, but it failed.
if (this.issuer !== undefined) { return this.issuer }
if (!await this.isOk()) { return null }
try {
this.issuer = await Issuer.discover(this.discoveryUrl as string)
this.logger.debug(`Discovered issuer, metadata are: ${JSON.stringify(this.issuer.metadata)}`)
} catch (err) {
this.logger.error(err as string)
this.issuer = null
}
return this.issuer
}
/**
* frees the singleton
*/
@ -143,6 +169,7 @@ class ExternalAuthOIDC {
settings['external-auth-custom-oidc-client-id'] as string | undefined,
settings['external-auth-custom-oidc-client-secret'] as string | undefined
)
return singleton
}