1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-09 00:18:00 +01:00

feat: SSO auto-create users with default role (#326)

This commit is contained in:
Ivar Conradi Østhus 2021-08-23 12:16:38 +02:00 committed by GitHub
parent 45554773a4
commit b5bb516c1c
10 changed files with 166 additions and 131 deletions

View File

@ -25,6 +25,7 @@
"license": "Apache-2.0",
"scripts": {
"build": "INLINE_RUNTIME_CHUNK=false react-scripts build",
"lint": "eslint src",
"start": "react-scripts start",
"start:heroku": "UNLEASH_API=https://unleash.herokuapp.com yarn run start",
"test": "react-scripts test",

View File

@ -4,12 +4,7 @@ import { ThemeProvider } from '@material-ui/core';
import ClientApplications from '../application-edit-component';
import renderer from 'react-test-renderer';
import { MemoryRouter } from 'react-router-dom';
import {
ADMIN,
CREATE_FEATURE,
CREATE_STRATEGY,
UPDATE_APPLICATION,
} from '../../AccessProvider/permissions';
import { ADMIN } from '../../AccessProvider/permissions';
import theme from '../../../themes/main-theme';
import { createFakeStore } from '../../../accessStoreFake';

View File

@ -353,7 +353,7 @@ export const routes = [
{
path: '/admin/auth',
parent: '/admin',
title: 'Authentication',
title: 'Single Sign-On',
component: AdminAuth,
type: 'protected',
layout: 'main',

View File

@ -1,5 +1,4 @@
import React from 'react';
import { RouteComponentProps } from 'react-router';
interface IRoute {
path: string;

View File

@ -56,7 +56,7 @@ function AdminMenu({ history }) {
activeStyle={activeNavLinkStyle}
style={navLinkStyle}
>
Authentication
Single Sign-On
</NavLink>
}
></Tab>

View File

@ -0,0 +1,102 @@
import React, { ChangeEvent, Fragment } from 'react';
import { FormControl, Grid, MenuItem, Switch, TextField, Select, InputLabel, FormControlLabel } from '@material-ui/core';
interface Props {
data?: {
enabled: boolean;
autoCreate: boolean;
defaultRootRole?: string;
emailDomains?: string;
};
setValue: (name: string, value: string | boolean) => void;
}
function AutoCreateForm({ data = { enabled: false, autoCreate: false }, setValue }: Props) {
const updateAutoCreate = () => {
setValue('autoCreate', !data.autoCreate);
}
const updateDefaultRootRole = (evt: ChangeEvent<{ name?: string; value: unknown }>) => {
setValue('defaultRootRole', evt.target.value as string);
}
const updateField = (e: ChangeEvent<HTMLInputElement>) => {
setValue(e.target.name, e.target.value);
}
return (
<Fragment>
<Grid container spacing={3}>
<Grid item md={5}>
<strong>Auto-create users</strong>
<p>
Enable automatic creation of new users when signing in.
</p>
</Grid>
<Grid item md={6} style={{ padding: '20px' }}>
<FormControlLabel
control={ <Switch
onChange={updateAutoCreate}
name="enabled"
checked={data.autoCreate}
disabled={!data.enabled}
/>}
label="Auto-create users"
/>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item md={5}>
<strong>Default Root Role</strong>
<p>
Choose which root role the user should get when no explicit role mapping exists.
</p>
</Grid>
<Grid item md={6}>
<FormControl style={{minWidth: '200px'}}>
<InputLabel id="defaultRootRole-label">Default Role</InputLabel>
<Select
labelId="defaultRootRole-label"
id="defaultRootRole"
name="defaultRootRole"
disabled={!data.autoCreate}
value={data.defaultRootRole || 'Editor'}
onChange={updateDefaultRootRole}
>
{/*consider these from API or constants. */}
<MenuItem value='Viewer'>Viewer</MenuItem>
<MenuItem value='Editor'>Editor</MenuItem>
<MenuItem value='Admin'>Admin</MenuItem>
</Select>
</FormControl>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item md={5}>
<strong>Email domains</strong>
<p>
Comma separated list of email domains
that should be allowed to sign in.
</p>
</Grid>
<Grid item md={6}>
<TextField
onChange={updateField}
label="Email domains"
name="emailDomains"
disabled={!data.autoCreate}
required={!!data.autoCreate}
value={data.emailDomains || ''}
placeholder="@company.com, @anotherCompany.com"
style={{ width: '400px' }}
rows={2}
variant="outlined"
size="small"
/>
</Grid>
</Grid>
</Fragment>);
}
export default AutoCreateForm;

View File

@ -28,7 +28,7 @@ function AdminAuthPage({ authenticationType, history }) {
return (
<div>
<AdminMenu history={history} />
<PageContent headerContent="Authentication">
<PageContent headerContent="Single Sign-On">
<ConditionallyRender condition={authenticationType === 'enterprise'}
show={
<TabNav tabData={tabs} />

View File

@ -1,6 +1,6 @@
import React, { useState, useEffect, useContext } from 'react';
import PropTypes from 'prop-types';
import { Button, Grid, Switch, TextField } from '@material-ui/core';
import { Button, FormControlLabel, Grid, Switch, TextField } from '@material-ui/core';
import { Alert } from '@material-ui/lab';
import PageContent from '../../../component/common/PageContent/PageContent';
import AccessContext from '../../../contexts/AccessContext';
@ -92,13 +92,15 @@ function GoogleAuth({
</p>
</Grid>
<Grid item xs={6} style={{ padding: '20px' }}>
<Switch
<FormControlLabel
control={ <Switch
onChange={updateEnabled}
value={data.enabled}
name="enabled"
checked={data.enabled}
>
{data.enabled ? 'Enabled' : 'Disabled'}
</Switch>
/>}
label={data.enabled ? 'Enabled' : 'Disabled'}
/>
</Grid>
</Grid>
<Grid container spacing={3}>

View File

@ -1,10 +1,11 @@
import React, { useState, useEffect, useContext } from 'react';
import PropTypes from 'prop-types';
import { Button, Grid, Switch, TextField } from '@material-ui/core';
import { Button, FormControlLabel, Grid, Switch, TextField } from '@material-ui/core';
import { Alert } from '@material-ui/lab';
import PageContent from '../../../component/common/PageContent/PageContent';
import AccessContext from '../../../contexts/AccessContext';
import { ADMIN } from '../../../component/AccessProvider/permissions';
import AutoCreateForm from './AutoCreateForm/AutoCreateForm';
const initialState = {
enabled: false,
@ -39,19 +40,19 @@ function OidcAuth({ config, getOidcConfig, updateOidcConfig, unleashUrl }) {
}
const updateField = e => {
setData({
...data,
[e.target.name]: e.target.value,
});
setValue(e.target.name, e.target.value);
};
const updateEnabled = () => {
setData({ ...data, enabled: !data.enabled });
};
const updateAutoCreate = () => {
setData({ ...data, autoCreate: !data.autoCreate });
};
const setValue = (field, value) => {
setData({
...data,
[field]: value,
});
}
const onSubmit = async e => {
e.preventDefault();
@ -93,14 +94,15 @@ function OidcAuth({ config, getOidcConfig, updateOidcConfig, unleashUrl }) {
<p>Enable Open Id Connect Authentication.</p>
</Grid>
<Grid item md={6}>
<Switch
<FormControlLabel
control={ <Switch
onChange={updateEnabled}
value={data.enabled}
name="enabled"
checked={data.enabled}
>
{data.enabled ? 'Enabled' : 'Disabled'}
</Switch>
/>}
label={data.enabled ? 'Enabled' : 'Disabled'}
/>
</Grid>
</Grid>
<Grid container spacing={3}>
@ -114,6 +116,7 @@ function OidcAuth({ config, getOidcConfig, updateOidcConfig, unleashUrl }) {
label="Discover URL"
name="discoverUrl"
value={data.discoverUrl || ''}
disabled={!data.enabled}
style={{ width: '400px' }}
variant="outlined"
size="small"
@ -132,6 +135,7 @@ function OidcAuth({ config, getOidcConfig, updateOidcConfig, unleashUrl }) {
label="Client ID"
name="clientId"
value={data.clientId || ''}
disabled={!data.enabled}
style={{ width: '400px' }}
variant="outlined"
size="small"
@ -150,6 +154,7 @@ function OidcAuth({ config, getOidcConfig, updateOidcConfig, unleashUrl }) {
label="Client Secret"
name="secret"
value={data.secret || ''}
disabled={!data.enabled}
style={{ width: '400px' }}
variant="outlined"
size="small"
@ -157,46 +162,9 @@ function OidcAuth({ config, getOidcConfig, updateOidcConfig, unleashUrl }) {
/>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item md={5}>
<strong>Auto-create users</strong>
<p>
Enable automatic creation of new users when signing
in with Open ID connect.
</p>
</Grid>
<Grid item md={6} style={{ padding: '20px' }}>
<Switch
onChange={updateAutoCreate}
name="enabled"
checked={data.autoCreate}
>
Auto-create users
</Switch>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item md={5}>
<strong>Email domains</strong>
<p>
(Optional) Comma separated list of email domains
that should be allowed to sign in.
</p>
</Grid>
<Grid item md={6}>
<TextField
onChange={updateField}
label="Email domains"
name="emailDomains"
value={data.emailDomains || ''}
placeholder="@company.com, @anotherCompany.com"
style={{ width: '400px' }}
rows={2}
variant="outlined"
size="small"
/>
</Grid>
</Grid>
<AutoCreateForm data={data} setValue={setValue} />
<Grid container spacing={3}>
<Grid item md={12}>
<Button

View File

@ -1,10 +1,11 @@
import React, { useState, useEffect, useContext } from 'react';
import PropTypes from 'prop-types';
import { Button, Grid, Switch, TextField } from '@material-ui/core';
import { Button, FormControlLabel, Grid, Switch, TextField } from '@material-ui/core';
import { Alert } from '@material-ui/lab';
import PageContent from '../../../component/common/PageContent/PageContent';
import AccessContext from '../../../contexts/AccessContext';
import { ADMIN } from '../../../component/AccessProvider/permissions';
import AutoCreateForm from './AutoCreateForm/AutoCreateForm';
const initialState = {
enabled: false,
@ -38,19 +39,19 @@ function SamlAuth({ config, getSamlConfig, updateSamlConfig, unleashUrl }) {
}
const updateField = e => {
setData({
...data,
[e.target.name]: e.target.value,
});
setValue(e.target.name, e.target.value);
};
const updateEnabled = () => {
setData({ ...data, enabled: !data.enabled });
};
const updateAutoCreate = () => {
setData({ ...data, autoCreate: !data.autoCreate });
};
const setValue = (field, value) => {
setData({
...data,
[field]: value,
});
}
const onSubmit = async e => {
e.preventDefault();
@ -90,14 +91,15 @@ function SamlAuth({ config, getSamlConfig, updateSamlConfig, unleashUrl }) {
<p>Enable SAML 2.0 Authentication.</p>
</Grid>
<Grid item md={6}>
<Switch
<FormControlLabel
control={ <Switch
onChange={updateEnabled}
value={data.enabled}
name="enabled"
checked={data.enabled}
>
{data.enabled ? 'Enabled' : 'Disabled'}
</Switch>
/>}
label={data.enabled ? 'Enabled' : 'Disabled'}
/>
</Grid>
</Grid>
<Grid container spacing={3}>
@ -111,6 +113,7 @@ function SamlAuth({ config, getSamlConfig, updateSamlConfig, unleashUrl }) {
label="Entity ID"
name="entityId"
value={data.entityId || ''}
disabled={!data.enabled}
style={{ width: '400px' }}
variant="outlined"
size="small"
@ -132,6 +135,7 @@ function SamlAuth({ config, getSamlConfig, updateSamlConfig, unleashUrl }) {
label="Single Sign-On URL"
name="signOnUrl"
value={data.signOnUrl || ''}
disabled={!data.enabled}
style={{ width: '400px'}}
variant="outlined"
size="small"
@ -153,6 +157,7 @@ function SamlAuth({ config, getSamlConfig, updateSamlConfig, unleashUrl }) {
label="X.509 Certificate"
name="certificate"
value={data.certificate || ''}
disabled={!data.enabled}
style={{width: '100%'}}
InputProps={{
style: {
@ -173,7 +178,7 @@ function SamlAuth({ config, getSamlConfig, updateSamlConfig, unleashUrl }) {
<Grid item md={5}>
<strong>Single Sign-out URL</strong>
<p>
(optional) The url to redirect the user to for
(Optional) The url to redirect the user to for
signing out of the IDP.
</p>
</Grid>
@ -183,6 +188,7 @@ function SamlAuth({ config, getSamlConfig, updateSamlConfig, unleashUrl }) {
label="Single Sign-out URL"
name="signOutUrl"
value={data.signOutUrl || ''}
disabled={!data.enabled}
style={{ width: '400px'}}
variant="outlined"
size="small"
@ -203,6 +209,7 @@ function SamlAuth({ config, getSamlConfig, updateSamlConfig, unleashUrl }) {
label="X.509 Certificate"
name="spCertificate"
value={data.spCertificate || ''}
disabled={!data.enabled}
style={{width: '100%'}}
InputProps={{
style: {
@ -217,46 +224,7 @@ function SamlAuth({ config, getSamlConfig, updateSamlConfig, unleashUrl }) {
/>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item md={5}>
<strong>Auto-create users</strong>
<p>
Enable automatic creation of new users when signing
in with Saml.
</p>
</Grid>
<Grid item md={6} style={{ padding: '20px' }}>
<Switch
onChange={updateAutoCreate}
name="enabled"
checked={data.autoCreate}
>
Auto-create users
</Switch>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item md={5}>
<strong>Email domains</strong>
<p>
(Optional) Comma separated list of email domains
that should be allowed to sign in.
</p>
</Grid>
<Grid item md={6}>
<TextField
onChange={updateField}
label="Email domains"
name="emailDomains"
value={data.emailDomains || ''}
placeholder="@company.com, @anotherCompany.com"
style={{ width: '400px' }}
rows={2}
variant="outlined"
size="small"
/>
</Grid>
</Grid>
<AutoCreateForm data={data} setValue={setValue} />
<Grid container spacing={3}>
<Grid item md={5}>
<Button