mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-20 14:54:15 +01:00
(bug) use arrays for OIDC scopes in front and DB.
Send the scope as a string separated with spaces to the OIDC provider.
This commit is contained in:
parent
78f7cdcb8c
commit
2172c102c9
@ -10,6 +10,7 @@ import { OpenIdConnectProvider } from '../../models/authentication-provider';
|
||||
import SsoClient from '../../api/external/sso';
|
||||
import { FieldPathValue } from 'react-hook-form/dist/types/path';
|
||||
import { FormMultiSelect } from '../form/form-multi-select';
|
||||
import { difference } from 'lodash';
|
||||
|
||||
interface OpenidConnectFormProps<TFieldValues, TContext extends object> {
|
||||
register: UseFormRegister<TFieldValues>,
|
||||
@ -60,6 +61,21 @@ export const OpenidConnectForm = <TFieldValues extends FieldValues, TContext ext
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the list of scopes that are available for the current configuration.
|
||||
* The resulting list is provided through the callback parameter.
|
||||
*/
|
||||
const loadScopes = (inputValue: string, callback: (options: Array<{ value: string, label: string }>) => void): void => {
|
||||
const current = currentFormValues.scope || [];
|
||||
if (scopesAvailable) {
|
||||
// add custom scopes to the list of available scopes
|
||||
const unlisted = difference(current, scopesAvailable);
|
||||
callback(scopesAvailable.concat(unlisted).map(scope => ({ value: scope, label: scope })));
|
||||
} else {
|
||||
current.map(scope => ({ value: scope, label: scope }));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback that check for the existence of the .well-known/openid-configuration endpoint, for the given issuer.
|
||||
* This callback is triggered when the user changes the issuer field.
|
||||
@ -102,18 +118,12 @@ export const OpenidConnectForm = <TFieldValues extends FieldValues, TContext ext
|
||||
]}
|
||||
valueDefault={'basic'}
|
||||
control={control} />
|
||||
{!scopesAvailable && <FormInput id="providable_attributes.scope"
|
||||
register={register}
|
||||
label={t('app.admin.authentication.openid_connect_form.scope')}
|
||||
placeholder="openid profile email"
|
||||
tooltip={<HtmlTranslate trKey="app.admin.authentication.openid_connect_form.scope_help_html" />} />}
|
||||
{scopesAvailable && <FormMultiSelect id="providable_attributes.scope"
|
||||
label={t('app.admin.authentication.openid_connect_form.scope')}
|
||||
tooltip={<HtmlTranslate trKey="app.admin.authentication.openid_connect_form.scope_help_html" />}
|
||||
options={scopesAvailable.map((scope) => ({ value: scope, label: scope }))}
|
||||
delimiter={' '}
|
||||
creatable
|
||||
control={control} />}
|
||||
<FormMultiSelect id="providable_attributes.scope"
|
||||
label={t('app.admin.authentication.openid_connect_form.scope')}
|
||||
tooltip={<HtmlTranslate trKey="app.admin.authentication.openid_connect_form.scope_help_html" />}
|
||||
loadOptions={loadScopes}
|
||||
creatable
|
||||
control={control} />
|
||||
<FormSelect id="providable_attributes.prompt"
|
||||
label={t('app.admin.authentication.openid_connect_form.prompt')}
|
||||
tooltip={<HtmlTranslate trKey="app.admin.authentication.openid_connect_form.prompt_help_html" />}
|
||||
|
@ -16,7 +16,6 @@ interface CommonProps<TFieldValues, TContext extends object, TOptionValue> exten
|
||||
onChange?: (values: Array<TOptionValue>) => void,
|
||||
placeholder?: string,
|
||||
creatable?: boolean,
|
||||
delimiter?: string
|
||||
}
|
||||
|
||||
// we should provide either an array of options or a function that returns a promise, but not both
|
||||
@ -36,7 +35,7 @@ type selectOption<TOptionValue> = { value: TOptionValue, label: string, select?:
|
||||
* This component is a wrapper around react-select to use with react-hook-form.
|
||||
* It is a multi-select component.
|
||||
*/
|
||||
export const FormMultiSelect = <TFieldValues extends FieldValues, TContext extends object, TOptionValue>({ id, label, tooltip, className, control, placeholder, options, valuesDefault, error, rules, disabled, onChange, formState, warning, loadOptions, creatable, delimiter }: FormSelectProps<TFieldValues, TContext, TOptionValue>) => {
|
||||
export const FormMultiSelect = <TFieldValues extends FieldValues, TContext extends object, TOptionValue>({ id, label, tooltip, className, control, placeholder, options, valuesDefault, error, rules, disabled, onChange, formState, warning, loadOptions, creatable }: FormSelectProps<TFieldValues, TContext, TOptionValue>) => {
|
||||
const { t } = useTranslation('shared');
|
||||
|
||||
const [isDisabled, setIsDisabled] = React.useState<boolean>(false);
|
||||
@ -121,7 +120,6 @@ export const FormMultiSelect = <TFieldValues extends FieldValues, TContext exten
|
||||
className: 'rs',
|
||||
ref,
|
||||
value: getCurrentValues(value),
|
||||
delimiter,
|
||||
placeholder,
|
||||
isDisabled,
|
||||
isMulti: true,
|
||||
|
@ -47,7 +47,7 @@ export interface OpenIdConnectProvider {
|
||||
issuer: string,
|
||||
discovery: boolean,
|
||||
client_auth_method?: 'basic' | 'jwks',
|
||||
scope?: string,
|
||||
scope?: Array<string>,
|
||||
prompt?: 'none' | 'login' | 'consent' | 'select_account',
|
||||
send_scope_to_token_endpoint?: string,
|
||||
client__identifier: string,
|
||||
|
@ -17,6 +17,10 @@ class OpenIdConnectProvider < ApplicationRecord
|
||||
validates :prompt, inclusion: { in: %w[none login consent select_account], allow_nil: true }
|
||||
validates :client_auth_method, inclusion: { in: %w[basic jwks] }
|
||||
|
||||
def scope
|
||||
self[:scope].join(' ')
|
||||
end
|
||||
|
||||
def config
|
||||
OpenIdConnectProvider.columns.map(&:name).filter { |n| !n.start_with?('client__') && n != 'profile_url' }.map do |n|
|
||||
[n, send(n)]
|
||||
|
9
db/migrate/20220531160223_change_oidc_scope_to_array.rb
Normal file
9
db/migrate/20220531160223_change_oidc_scope_to_array.rb
Normal file
@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Previously, the OpenID Connect scope was a string, scopes were separated by commas.
|
||||
# To be more fron-end friendly, we now use an array.
|
||||
class ChangeOidcScopeToArray < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
change_column :open_id_connect_providers, :scope, "varchar[] USING (string_to_array(scope, ','))"
|
||||
end
|
||||
end
|
@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2022_05_17_140916) do
|
||||
ActiveRecord::Schema.define(version: 2022_05_31_160223) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "fuzzystrmatch"
|
||||
@ -415,7 +415,7 @@ ActiveRecord::Schema.define(version: 2022_05_17_140916) do
|
||||
t.string "issuer"
|
||||
t.boolean "discovery"
|
||||
t.string "client_auth_method"
|
||||
t.string "scope"
|
||||
t.string "scope", array: true
|
||||
t.string "response_type"
|
||||
t.string "response_mode"
|
||||
t.string "display"
|
||||
|
Loading…
x
Reference in New Issue
Block a user