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:
parent
45554773a4
commit
b5bb516c1c
@ -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",
|
||||
|
@ -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';
|
||||
|
@ -353,7 +353,7 @@ export const routes = [
|
||||
{
|
||||
path: '/admin/auth',
|
||||
parent: '/admin',
|
||||
title: 'Authentication',
|
||||
title: 'Single Sign-On',
|
||||
component: AdminAuth,
|
||||
type: 'protected',
|
||||
layout: 'main',
|
||||
|
@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import { RouteComponentProps } from 'react-router';
|
||||
|
||||
interface IRoute {
|
||||
path: string;
|
||||
|
@ -56,7 +56,7 @@ function AdminMenu({ history }) {
|
||||
activeStyle={activeNavLinkStyle}
|
||||
style={navLinkStyle}
|
||||
>
|
||||
Authentication
|
||||
Single Sign-On
|
||||
</NavLink>
|
||||
}
|
||||
></Tab>
|
||||
|
102
frontend/src/page/admin/auth/AutoCreateForm/AutoCreateForm.tsx
Normal file
102
frontend/src/page/admin/auth/AutoCreateForm/AutoCreateForm.tsx
Normal 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;
|
@ -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} />
|
||||
|
@ -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
|
||||
onChange={updateEnabled}
|
||||
name="enabled"
|
||||
checked={data.enabled}
|
||||
>
|
||||
{data.enabled ? 'Enabled' : 'Disabled'}
|
||||
</Switch>
|
||||
<FormControlLabel
|
||||
control={ <Switch
|
||||
onChange={updateEnabled}
|
||||
value={data.enabled}
|
||||
name="enabled"
|
||||
checked={data.enabled}
|
||||
/>}
|
||||
label={data.enabled ? 'Enabled' : 'Disabled'}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container spacing={3}>
|
||||
|
@ -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
|
||||
onChange={updateEnabled}
|
||||
value={data.enabled}
|
||||
name="enabled"
|
||||
checked={data.enabled}
|
||||
>
|
||||
{data.enabled ? 'Enabled' : 'Disabled'}
|
||||
</Switch>
|
||||
<FormControlLabel
|
||||
control={ <Switch
|
||||
onChange={updateEnabled}
|
||||
value={data.enabled}
|
||||
name="enabled"
|
||||
checked={data.enabled}
|
||||
/>}
|
||||
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
|
||||
|
@ -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
|
||||
onChange={updateEnabled}
|
||||
value={data.enabled}
|
||||
name="enabled"
|
||||
checked={data.enabled}
|
||||
>
|
||||
{data.enabled ? 'Enabled' : 'Disabled'}
|
||||
</Switch>
|
||||
<FormControlLabel
|
||||
control={ <Switch
|
||||
onChange={updateEnabled}
|
||||
value={data.enabled}
|
||||
name="enabled"
|
||||
checked={data.enabled}
|
||||
/>}
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user