fix: sso optimization (#1159)

* fix: update submodules

* fix: improve code
This commit is contained in:
chenos 2022-11-30 01:00:45 +08:00 committed by GitHub
parent 37b4151da1
commit 205fafcd4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 103 additions and 70 deletions

View File

@ -1,9 +1,9 @@
import React, { useEffect, useState, useRef } from 'react';
import { Button, Space } from 'antd';
import { LoginOutlined } from '@ant-design/icons';
import { useMemoizedFn } from 'ahooks';
import { css } from '@emotion/css';
import { useAPIClient, useRedirect } from '@nocobase/client';
import { useAPIClient, useRedirect, useRequest } from '@nocobase/client';
import { useMemoizedFn } from 'ahooks';
import { Button, Space } from 'antd';
import React, { useEffect, useState } from 'react';
export interface OIDCProvider {
clientId: string;
@ -12,26 +12,14 @@ export interface OIDCProvider {
}
export const OIDCList = () => {
const [list, setList] = useState<OIDCProvider[]>([]);
const [windowHandler, setWindowHandler] = useState<Window | undefined>();
const api = useAPIClient();
const redirect = useRedirect();
const getOidcList = async () => {
const { data: pluginsRes } = await api.request({
url: 'app:getPlugins',
});
if (!(pluginsRes.data as string[]).includes('oidc')) return;
const { data: providersRes } = await api.request({
url: 'oidcProviders:list',
params: {
filter: {
enabled: true,
},
},
});
setList(providersRes.data);
};
const { data, loading } = useRequest({
resource: 'oidc',
action: 'getEnabledProviders',
});
/**
*
@ -80,10 +68,6 @@ export const OIDCList = () => {
};
}, [windowHandler]);
useEffect(() => {
getOidcList();
}, []);
return (
<Space
direction="vertical"
@ -91,9 +75,9 @@ export const OIDCList = () => {
display: flex;
`}
>
{list.map((item) => (
{data?.data?.map?.((item) => (
<Button shape="round" block key={item.clientId} icon={<LoginOutlined />} onClick={() => handleOpen(item)}>
OIDC: {item.title}
{item.buttonTitle}
</Button>
))}
</Space>

View File

@ -1,13 +1,13 @@
import { useTranslation } from 'react-i18next';
import { i18n } from '@nocobase/client';
import { useTranslation } from 'react-i18next';
import zhCN from './zh-CN';
import enUS from './en-US';
import jaJP from './ja-JP';
import ruRU from './ru-RU';
import trTR from './tr-TR';
import zhCN from './zh-CN';
export const NAMESPACE = 'workflow';
export const NAMESPACE = 'oidc';
i18n.addResources('zh-CN', NAMESPACE, zhCN);
i18n.addResources('en-US', NAMESPACE, enUS);

View File

@ -4,6 +4,7 @@ export default {
Actions: '操作',
Delete: '删除',
Edit: '编辑',
'Button title': '登录按钮标题',
'OIDC manager': 'OIDC 管理',
'OIDC Providers': 'OIDC 身份提供者',
'Provider name': '名称',

View File

@ -1,5 +1,4 @@
import { ISchema } from '@formily/react';
import { uid } from '@formily/shared';
import { useActionContext, useRequest } from '@nocobase/client';
import { IDTOKEN_SIGN_ALG } from '../../server/shared/types';
@ -17,6 +16,17 @@ const collection = {
required: true,
} as ISchema,
},
{
type: 'string',
name: 'buttonTitle',
interface: 'input',
uiSchema: {
title: '{{t("Button title")}}',
type: 'string',
'x-component': 'Input',
required: true,
} as ISchema,
},
{
type: 'string',
name: 'clientId',
@ -169,6 +179,10 @@ export const formProperties = {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
buttonTitle: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
clientId: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',

View File

@ -0,0 +1,12 @@
import { Context } from '@nocobase/actions';
export const getEnabledProviders = async (ctx: Context, next) => {
const repository = ctx.db.getRepository('oidcProviders');
ctx.body = await repository.find({
filter: {
enabled: true,
},
fields: ['buttonTitle', 'clientId'],
});
return next();
};

View File

@ -10,6 +10,10 @@ export default {
type: 'string',
name: 'title',
},
{
name: 'buttonTitle',
type: 'string',
},
{
comment: '客户端id',
type: 'string',

View File

@ -1,10 +1,10 @@
import UsersPlugin from '@nocobase/plugin-users';
import { InstallOptions, Plugin } from '@nocobase/server';
import { resolve } from 'path';
import { generators } from 'openid-client';
import { oidc } from './authenticators/oidc';
import { resolve } from 'path';
import { getAuthUrl } from './actions/getAuthUrl';
import { getEnabledProviders } from './actions/getEnabledProviders';
import { redirect } from './actions/redirect';
import { oidc } from './authenticators/oidc';
export class OidcPlugin extends Plugin {
#OIDC_NONCE = null;
@ -20,7 +20,7 @@ export class OidcPlugin extends Plugin {
});
// 获取 User 插件
const userPlugin = this.app.getPlugin('users') as UsersPlugin;
const userPlugin = this.app.getPlugin<any>('users');
// 注册 OIDC 验证器
userPlugin.authenticators.register('oidc', oidc);
@ -31,6 +31,7 @@ export class OidcPlugin extends Plugin {
actions: {
getAuthUrl,
redirect,
getEnabledProviders,
},
});
@ -46,7 +47,7 @@ export class OidcPlugin extends Plugin {
});
// 开放访问权限
this.app.acl.allow('oidcProviders', '*');
this.app.acl.allow('oidcProviders', '*', 'allowConfigure');
this.app.acl.allow('oidc', '*');
}

View File

@ -1,8 +1,8 @@
import React, { useEffect, useState, useRef } from 'react';
import { Button, Space } from 'antd';
import { LoginOutlined } from '@ant-design/icons';
import { css } from '@emotion/css';
import { useAPIClient, useRedirect } from '@nocobase/client';
import { useAPIClient, useRedirect, useRequest } from '@nocobase/client';
import { Button, Space } from 'antd';
import React, { useEffect, useState } from 'react';
export interface SAMLProvider {
title: string;
@ -11,26 +11,14 @@ export interface SAMLProvider {
}
export const SAMLList = () => {
const [list, setList] = useState<SAMLProvider[]>([]);
const [windowHandler, setWindowHandler] = useState<Window | undefined>();
const api = useAPIClient();
const redirect = useRedirect();
const getSamlList = async () => {
const { data: pluginsRes } = await api.request({
url: 'app:getPlugins',
});
if (!(pluginsRes.data as string[]).includes('saml')) return;
const { data: providersRes } = await api.request({
url: 'samlProviders:list',
params: {
filter: {
enabled: true,
},
},
});
setList(providersRes.data);
};
const { data, loading } = useRequest({
resource: 'saml',
action: 'getEnabledProviders',
});
/**
*
@ -79,10 +67,6 @@ export const SAMLList = () => {
};
}, [windowHandler]);
useEffect(() => {
getSamlList();
}, []);
return (
<Space
direction="vertical"
@ -90,9 +74,9 @@ export const SAMLList = () => {
display: flex;
`}
>
{list.map((item) => (
{data?.data?.map?.((item) => (
<Button shape="round" block key={item.clientId} icon={<LoginOutlined />} onClick={() => handleOpen(item)}>
SAML: {item.title}
{item.buttonTitle}
</Button>
))}
</Space>

View File

@ -1,13 +1,13 @@
import { useTranslation } from 'react-i18next';
import { i18n } from '@nocobase/client';
import { useTranslation } from 'react-i18next';
import zhCN from './zh-CN';
import enUS from './en-US';
import jaJP from './ja-JP';
import ruRU from './ru-RU';
import trTR from './tr-TR';
import zhCN from './zh-CN';
export const NAMESPACE = 'workflow';
export const NAMESPACE = 'saml';
i18n.addResources('zh-CN', NAMESPACE, zhCN);
i18n.addResources('en-US', NAMESPACE, enUS);

View File

@ -6,6 +6,7 @@ export default {
Actions: '操作',
Title: '身份提供者名称',
Enable: '启用',
'Button title': '登录按钮标题',
'SAML manager': 'SAML 管理',
'SAML Providers': 'SAML 身份提供者',
'Redirect url': '重定向地址',

View File

@ -15,6 +15,17 @@ const collection = {
required: true,
} as ISchema,
},
{
type: 'string',
name: 'buttonTitle',
interface: 'input',
uiSchema: {
title: '{{t("Button title")}}',
type: 'string',
'x-component': 'Input',
required: true,
} as ISchema,
},
{
type: 'string',
name: 'clientId',
@ -98,6 +109,10 @@ export const formProperties = {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
buttonTitle: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
clientId: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',

View File

@ -0,0 +1,12 @@
import { Context } from '@nocobase/actions';
export const getEnabledProviders = async (ctx: Context, next) => {
const repository = ctx.db.getRepository('samlProviders');
ctx.body = await repository.find({
filter: {
enabled: true,
},
fields: ['buttonTitle', 'clientId'],
});
return next();
};

View File

@ -9,6 +9,10 @@ export default {
type: 'string',
name: 'title',
},
{
type: 'string',
name: 'buttonTitle',
},
{
comment: '客户端id',
type: 'string',

View File

@ -1,10 +1,10 @@
import UsersPlugin from 'packages/plugins/users/src/server';
import { InstallOptions, Plugin } from '@nocobase/server';
import { resolve } from 'path';
import { saml } from './authenticators/saml';
import { redirect } from './actions/redirect';
import { metadata } from './actions/metadata';
import { getAuthUrl } from './actions/getAuthUrl';
import { getEnabledProviders } from './actions/getEnabledProviders';
import { metadata } from './actions/metadata';
import { redirect } from './actions/redirect';
import { saml } from './authenticators/saml';
export class SAMLPlugin extends Plugin {
afterAdd() {}
@ -18,7 +18,7 @@ export class SAMLPlugin extends Plugin {
});
// 获取 User 插件
const userPlugin = this.app.getPlugin('users') as UsersPlugin;
const userPlugin = this.app.getPlugin<any>('users');
// 注册 SAML 验证器
userPlugin.authenticators.register('saml', saml);
@ -30,11 +30,12 @@ export class SAMLPlugin extends Plugin {
redirect,
metadata,
getAuthUrl,
getEnabledProviders,
},
});
// 开放访问权限
this.app.acl.allow('samlProviders', '*');
this.app.acl.allow('samlProviders', '*', 'allowConfigure');
this.app.acl.allow('saml', '*');
}

@ -1 +1 @@
Subproject commit 5a5fba41ae1cecaf3b073fcb610e9dc68dad0b85
Subproject commit cf44c47ff9b5ef41e8becde3f1c8b5b1c2af6cda