1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-28 09:24:24 +01:00

(wip) saml sso

This commit is contained in:
Du Peng 2024-01-19 13:55:32 +01:00
parent 73566d4cd9
commit f58da357b7
10 changed files with 226 additions and 13 deletions

View File

@ -105,6 +105,13 @@ class API::AuthProvidersController < API::APIController
auth_provider_mappings_attributes: [:id, :local_model, :local_field, :api_field, :api_endpoint, :api_data_type,
:_destroy, { transformation: [:type, :format, :true_value, :false_value,
{ mapping: %i[from to] }] }])
elsif params['auth_provider']['providable_type'] == SamlProvider.name
params.require(:auth_provider)
.permit(:id, :name, :providable_type,
providable_attributes: [:id, :sp_entity_id, :idp_sso_service_url],
auth_provider_mappings_attributes: [:id, :local_model, :local_field, :api_field, :api_endpoint, :api_data_type,
:_destroy, { transformation: [:type, :format, :true_value, :false_value,
{ mapping: %i[from to] }] }])
end
end
end

View File

@ -20,6 +20,7 @@ import { FabButton } from '../base/fab-button';
import AuthProviderAPI from '../../api/auth-provider';
import { OpenidConnectForm } from './openid-connect-form';
import { DatabaseForm } from './database-form';
import { SamlForm } from './saml-form';
declare const Application: IApplication;
@ -27,7 +28,8 @@ declare const Application: IApplication;
const METHODS = {
DatabaseProvider: 'local_database',
OAuth2Provider: 'oauth2',
OpenIdConnectProvider: 'openid_connect'
OpenIdConnectProvider: 'openid_connect',
SamlProvider: 'saml'
};
interface ProviderFormProps {
@ -116,6 +118,7 @@ export const ProviderForm: React.FC<ProviderFormProps> = ({ action, provider, on
currentFormValues={output.providable_attributes as OpenIdConnectProvider}
formState={formState}
setValue={setValue} />}
{providableType === 'SamlProvider' && <SamlForm register={register} strategyName={strategyName} formState={formState} />}
{providableType && providableType !== 'DatabaseProvider' && <DataMappingForm register={register}
control={control}
formState={formState}

View File

@ -0,0 +1,45 @@
import { FormInput } from '../form/form-input';
import { UseFormRegister, FormState } from 'react-hook-form';
import { FieldValues } from 'react-hook-form/dist/types/fields';
import { useTranslation } from 'react-i18next';
import { FabOutputCopy } from '../base/fab-output-copy';
import ValidationLib from '../../lib/validation';
interface SamlFormProps<TFieldValues> {
register: UseFormRegister<TFieldValues>,
formState: FormState<TFieldValues>,
strategyName?: string,
}
/**
* Partial form to fill the OAuth2 settings for a new/existing authentication provider.
*/
export const SamlForm = <TFieldValues extends FieldValues>({ register, strategyName, formState }: SamlFormProps<TFieldValues>) => {
const { t } = useTranslation('admin');
/**
* Build the callback URL, based on the strategy name.
*/
const buildCallbackUrl = (): string => {
return `${window.location.origin}/users/auth/${strategyName}/callback`;
};
return (
<div className="saml-form">
<hr/>
<FabOutputCopy text={buildCallbackUrl()} label={t('app.admin.authentication.saml_form.authorization_callback_url')} />
<FormInput id="providable_attributes.sp_entity_id"
register={register}
placeholder="https://sso.example.net..."
label={t('app.admin.authentication.saml_form.sp_entity_id')}
rules={{ required: true }}
formState={formState} />
<FormInput id="providable_attributes.idp_sso_service_url"
register={register}
placeholder="/saml/auth..."
label={t('app.admin.authentication.saml_form.idp_sso_service_url')}
rules={{ required: true, pattern: ValidationLib.urlRegex }}
formState={formState} />
</div>
);
};

View File

@ -1,4 +1,4 @@
export type ProvidableType = 'DatabaseProvider' | 'OAuth2Provider' | 'OpenIdConnectProvider';
export type ProvidableType = 'DatabaseProvider' | 'OAuth2Provider' | 'OpenIdConnectProvider' | 'SamlProvider';
export interface AuthenticationProvider {
id?: number,
@ -7,7 +7,7 @@ export interface AuthenticationProvider {
providable_type: ProvidableType,
strategy_name: string
auth_provider_mappings_attributes: Array<AuthenticationProviderMapping>,
providable_attributes?: OAuth2Provider | OpenIdConnectProvider
providable_attributes?: OAuth2Provider | OpenIdConnectProvider | SamlProvider
}
export type mappingType = 'string' | 'text' | 'date' | 'integer' | 'boolean';
@ -65,6 +65,12 @@ export interface OpenIdConnectProvider {
extra_authorize_parameters?: string,
}
export interface SamlProvider {
id?: string,
sp_entity_id: string,
idp_sso_service_url: string
}
export interface MappingFields {
user: Array<[string, mappingType]>,
profile: Array<[string, mappingType]>

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
# SAML Provider is a special type of AuthProvider which provides authentication through an external SSO server using
# the SAML protocol.
class SamlProvider < ApplicationRecord
has_one :auth_provider, as: :providable, dependent: :destroy
validates :sp_entity_id, presence: true
validates :idp_sso_service_url, presence: true
end

View File

@ -19,3 +19,9 @@ if @provider.providable_type == OpenIdConnectProvider.name
json.extra_authorize_params @provider.providable[:extra_authorize_params].to_json
end
end
if @provider.providable_type == SamlProvider.name
json.providable_attributes do
json.extract! @provider.providable, :id, :sp_entity_id, :idp_sso_service_url
end
end

View File

@ -244,6 +244,13 @@ Devise.setup do |config|
active_provider.oidc_config.merge(
strategy_class: OmniAuth::Strategies::SsoOpenidConnectProvider
)
when 'SamlProvider'
require_relative '../../lib/omni_auth/saml'
config.omniauth active_provider.strategy_name.to_sym,
active_provider.providable.sp_entity_id,
active_provider.providable.idp_sso_service_url,
strategy_class: OmniAuth::Strategies::SsoSamlProvider
end
end

View File

@ -0,0 +1,10 @@
class CreateSamlProviders < ActiveRecord::Migration[7.0]
def change
create_table :saml_providers do |t|
t.string :sp_entity_id
t.string :idp_sso_service_url
t.timestamps
end
end
end

View File

@ -9,6 +9,13 @@ SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
--
-- Name: public; Type: SCHEMA; Schema: -; Owner: -
--
-- *not* creating schema, since initdb creates it
--
-- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: -
--
@ -2235,6 +2242,41 @@ CREATE SEQUENCE public.payment_gateway_objects_id_seq
ALTER SEQUENCE public.payment_gateway_objects_id_seq OWNED BY public.payment_gateway_objects.id;
--
-- Name: payment_infos; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.payment_infos (
id bigint NOT NULL,
data jsonb,
state character varying,
payment_for character varying,
service character varying,
statistic_profile_id bigint,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
);
--
-- Name: payment_infos_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.payment_infos_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: payment_infos_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.payment_infos_id_seq OWNED BY public.payment_infos.id;
--
-- Name: payment_schedule_items; Type: TABLE; Schema: public; Owner: -
--
@ -3224,6 +3266,38 @@ CREATE SEQUENCE public.roles_id_seq
ALTER SEQUENCE public.roles_id_seq OWNED BY public.roles.id;
--
-- Name: saml_providers; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.saml_providers (
id bigint NOT NULL,
sp_entity_id character varying,
idp_sso_service_url character varying,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
);
--
-- Name: saml_providers_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.saml_providers_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: saml_providers_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.saml_providers_id_seq OWNED BY public.saml_providers.id;
--
-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -
--
@ -4316,8 +4390,8 @@ CREATE TABLE public.users (
is_allow_newsletter boolean,
current_sign_in_ip inet,
last_sign_in_ip inet,
mapped_from_sso character varying,
validated_at timestamp without time zone,
mapped_from_sso character varying,
supporting_documents_reminder_sent_at timestamp(6) without time zone
);
@ -4870,6 +4944,13 @@ ALTER TABLE ONLY public.organizations ALTER COLUMN id SET DEFAULT nextval('publi
ALTER TABLE ONLY public.payment_gateway_objects ALTER COLUMN id SET DEFAULT nextval('public.payment_gateway_objects_id_seq'::regclass);
--
-- Name: payment_infos id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.payment_infos ALTER COLUMN id SET DEFAULT nextval('public.payment_infos_id_seq'::regclass);
--
-- Name: payment_schedule_items id; Type: DEFAULT; Schema: public; Owner: -
--
@ -5066,6 +5147,13 @@ ALTER TABLE ONLY public.reservations ALTER COLUMN id SET DEFAULT nextval('public
ALTER TABLE ONLY public.roles ALTER COLUMN id SET DEFAULT nextval('public.roles_id_seq'::regclass);
--
-- Name: saml_providers id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.saml_providers ALTER COLUMN id SET DEFAULT nextval('public.saml_providers_id_seq'::regclass);
--
-- Name: settings id; Type: DEFAULT; Schema: public; Owner: -
--
@ -5799,6 +5887,14 @@ ALTER TABLE ONLY public.payment_gateway_objects
ADD CONSTRAINT payment_gateway_objects_pkey PRIMARY KEY (id);
--
-- Name: payment_infos payment_infos_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.payment_infos
ADD CONSTRAINT payment_infos_pkey PRIMARY KEY (id);
--
-- Name: payment_schedule_items payment_schedule_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@ -6023,6 +6119,14 @@ ALTER TABLE ONLY public.roles
ADD CONSTRAINT roles_pkey PRIMARY KEY (id);
--
-- Name: saml_providers saml_providers_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.saml_providers
ADD CONSTRAINT saml_providers_pkey PRIMARY KEY (id);
--
-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@ -7004,6 +7108,13 @@ CREATE INDEX index_payment_gateway_objects_on_item_type_and_item_id ON public.pa
CREATE INDEX index_payment_gateway_objects_on_payment_gateway_object_id ON public.payment_gateway_objects USING btree (payment_gateway_object_id);
--
-- Name: index_payment_infos_on_statistic_profile_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_payment_infos_on_statistic_profile_id ON public.payment_infos USING btree (statistic_profile_id);
--
-- Name: index_payment_schedule_items_on_invoice_id; Type: INDEX; Schema: public; Owner: -
--
@ -7795,14 +7906,6 @@ CREATE INDEX proof_of_identity_type_id_and_proof_of_identity_refusal_id ON publi
CREATE UNIQUE INDEX unique_not_null_external_id ON public.invoicing_profiles USING btree (external_id) WHERE (external_id IS NOT NULL);
--
-- Name: accounting_periods accounting_periods_del_protect; Type: RULE; Schema: public; Owner: -
--
CREATE RULE accounting_periods_del_protect AS
ON DELETE TO public.accounting_periods DO INSTEAD NOTHING;
--
-- Name: accounting_periods accounting_periods_upd_protect; Type: RULE; Schema: public; Owner: -
--
@ -7836,6 +7939,14 @@ ALTER TABLE ONLY public.payment_schedules
ADD CONSTRAINT fk_rails_00308dc223 FOREIGN KEY (wallet_transaction_id) REFERENCES public.wallet_transactions(id);
--
-- Name: payment_infos fk_rails_0308366a58; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.payment_infos
ADD CONSTRAINT fk_rails_0308366a58 FOREIGN KEY (statistic_profile_id) REFERENCES public.statistic_profiles(id);
--
-- Name: cart_item_event_reservation_booking_users fk_rails_0964335a37; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -9182,8 +9293,10 @@ INSERT INTO "schema_migrations" (version) VALUES
('20230328094808'),
('20230328094809'),
('20230331132506'),
('20230509121907'),
('20230509161557'),
('20230510141305'),
('20230511080650'),
('20230511081018'),
('20230524080448'),
('20230524083558'),
@ -9199,11 +9312,13 @@ INSERT INTO "schema_migrations" (version) VALUES
('20230720085857'),
('20230728072726'),
('20230728090257'),
('20230825101952'),
('20230828073428'),
('20230831103208'),
('20230901090637'),
('20230907124230'),
('20231103093436'),
('20231108094433');
('20231108094433'),
('20240116163703');

3
lib/omni_auth/saml.rb Normal file
View File

@ -0,0 +1,3 @@
# frozen_string_literal: true
require_relative 'strategies/saml_provider'