Merge "feat: support web SSO login"
This commit is contained in:
commit
f560965348
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Support SSO login via OpenID connect.
|
||||||
|
|
||||||
|
1. If Web SSO login is successfully configured on the back-end, you can
|
||||||
|
select a login mode on the login page based on the configuration. The
|
||||||
|
default login mode is Keystone authentication. If you select the Web SSO
|
||||||
|
login mode, click Login button will switch to the Web SSO configuration page.
|
||||||
|
|
||||||
|
2. If SSO is not configured on the back-end, the front-end will directly
|
||||||
|
display the user + password login mode (Keystone authentication). You do
|
||||||
|
not need to select the login mode.
|
@ -126,6 +126,9 @@ export class SkylineClient extends Base {
|
|||||||
name: 'queryRange',
|
name: 'queryRange',
|
||||||
key: 'query_range',
|
key: 'query_range',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'sso',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,13 +65,23 @@ export default class index extends Component {
|
|||||||
const { formItems } = this.props;
|
const { formItems } = this.props;
|
||||||
// eslint-disable-next-line no-shadow
|
// eslint-disable-next-line no-shadow
|
||||||
return formItems.map((it, index) => {
|
return formItems.map((it, index) => {
|
||||||
const { name, hidden, dependencies = [], className, onChange } = it;
|
const {
|
||||||
|
name,
|
||||||
|
hidden,
|
||||||
|
dependencies = [],
|
||||||
|
className,
|
||||||
|
onChange,
|
||||||
|
extra,
|
||||||
|
label,
|
||||||
|
} = it;
|
||||||
const options = {
|
const options = {
|
||||||
name,
|
name,
|
||||||
rules: this.getFormItemRules(it),
|
rules: this.getFormItemRules(it),
|
||||||
hidden,
|
hidden,
|
||||||
dependencies,
|
dependencies,
|
||||||
className,
|
className,
|
||||||
|
extra,
|
||||||
|
label,
|
||||||
};
|
};
|
||||||
if (onChange) {
|
if (onChange) {
|
||||||
options.onChange = onChange;
|
options.onChange = onChange;
|
||||||
|
@ -1131,6 +1131,7 @@
|
|||||||
"If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.": "If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.",
|
"If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.": "If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.",
|
||||||
"If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).": "If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).",
|
"If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).": "If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).",
|
||||||
"If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project": "If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project",
|
"If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project": "If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project",
|
||||||
|
"If you are not sure which authentication method to use, please contact your administrator.": "If you are not sure which authentication method to use, please contact your administrator.",
|
||||||
"If you choose a port which subnet is different from the subnet of LB, please ensure connectivity between the two.": "If you choose a port which subnet is different from the subnet of LB, please ensure connectivity between the two.",
|
"If you choose a port which subnet is different from the subnet of LB, please ensure connectivity between the two.": "If you choose a port which subnet is different from the subnet of LB, please ensure connectivity between the two.",
|
||||||
"If you do not fill in parameters such as cpus, memory_mb, local_gb, cpu_arch, etc., you can automatically inject the configuration and Mac address of the physical machine by performing the \"Auto Inspect\" operation.": "If you do not fill in parameters such as cpus, memory_mb, local_gb, cpu_arch, etc., you can automatically inject the configuration and Mac address of the physical machine by performing the \"Auto Inspect\" operation.",
|
"If you do not fill in parameters such as cpus, memory_mb, local_gb, cpu_arch, etc., you can automatically inject the configuration and Mac address of the physical machine by performing the \"Auto Inspect\" operation.": "If you do not fill in parameters such as cpus, memory_mb, local_gb, cpu_arch, etc., you can automatically inject the configuration and Mac address of the physical machine by performing the \"Auto Inspect\" operation.",
|
||||||
"If you still want to keep the disk data, it is recommended that you create a snapshot for the disk before deleting.": "If you still want to keep the disk data, it is recommended that you create a snapshot for the disk before deleting.",
|
"If you still want to keep the disk data, it is recommended that you create a snapshot for the disk before deleting.": "If you still want to keep the disk data, it is recommended that you create a snapshot for the disk before deleting.",
|
||||||
@ -1304,6 +1305,7 @@
|
|||||||
"Keypair": "Keypair",
|
"Keypair": "Keypair",
|
||||||
"Keypair Detail": "Keypair Detail",
|
"Keypair Detail": "Keypair Detail",
|
||||||
"Keypair Info": "Keypair Info",
|
"Keypair Info": "Keypair Info",
|
||||||
|
"Keystone Credentials": "Keystone Credentials",
|
||||||
"Keystone token is expired.": "token has expired, please check whether the server time is correct and confirm whether the token is valid",
|
"Keystone token is expired.": "token has expired, please check whether the server time is correct and confirm whether the token is valid",
|
||||||
"Kill": "Kill",
|
"Kill": "Kill",
|
||||||
"Kill Container": "Kill Container",
|
"Kill Container": "Kill Container",
|
||||||
@ -1613,6 +1615,7 @@
|
|||||||
"Only a MAC address or an OpenFlow based datapath_id of the switch are accepted in this field": "Only a MAC address or an OpenFlow based datapath_id of the switch are accepted in this field",
|
"Only a MAC address or an OpenFlow based datapath_id of the switch are accepted in this field": "Only a MAC address or an OpenFlow based datapath_id of the switch are accepted in this field",
|
||||||
"Only subnets that are already connected to the router can be selected.": "Only subnets that are already connected to the router can be selected.",
|
"Only subnets that are already connected to the router can be selected.": "Only subnets that are already connected to the router can be selected.",
|
||||||
"Open External Gateway": "Open External Gateway",
|
"Open External Gateway": "Open External Gateway",
|
||||||
|
"OpenID Connect": "OpenID Connect",
|
||||||
"OpenStack Services": "OpenStack Services",
|
"OpenStack Services": "OpenStack Services",
|
||||||
"Operating Status": "Operating Status",
|
"Operating Status": "Operating Status",
|
||||||
"Operating System": "Operating System",
|
"Operating System": "Operating System",
|
||||||
@ -1756,6 +1759,7 @@
|
|||||||
"Please select availability zone": "Please select availability zone",
|
"Please select availability zone": "Please select availability zone",
|
||||||
"Please select item!": "Please select item!",
|
"Please select item!": "Please select item!",
|
||||||
"Please select key": "Please select key",
|
"Please select key": "Please select key",
|
||||||
|
"Please select login type!": "Please select login type!",
|
||||||
"Please select policy": "Please select policy",
|
"Please select policy": "Please select policy",
|
||||||
"Please select source": "Please select source",
|
"Please select source": "Please select source",
|
||||||
"Please select type": "Please select type",
|
"Please select type": "Please select type",
|
||||||
@ -2037,6 +2041,7 @@
|
|||||||
"Select User Group": "Select User Group",
|
"Select User Group": "Select User Group",
|
||||||
"Select Volume Snapshot": "Select Volume Snapshot",
|
"Select Volume Snapshot": "Select Volume Snapshot",
|
||||||
"Select a domain": "Select a domain",
|
"Select a domain": "Select a domain",
|
||||||
|
"Select a login type": "Select a login type",
|
||||||
"Select a region": "Select a region",
|
"Select a region": "Select a region",
|
||||||
"Selected": "Selected",
|
"Selected": "Selected",
|
||||||
"Selected Members": "Selected Members",
|
"Selected Members": "Selected Members",
|
||||||
|
@ -1131,6 +1131,7 @@
|
|||||||
"If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.": "如果云硬盘容量较大,修改云硬盘类型可能需要花费几个小时,请您谨慎操作。",
|
"If the capacity of the disk is large,the type modify operation may takes several hours. Please be cautious.": "如果云硬盘容量较大,修改云硬盘类型可能需要花费几个小时,请您谨慎操作。",
|
||||||
"If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).": "若快照关联的云硬盘修改过云硬盘类型,请手动修改此选项;若快照关联的云硬盘保持云硬盘类型不变,请忽略此选项(不需要做变更)。",
|
"If the volume associated with the snapshot has changed the volume type, please modify this option manually; if the volume associated with the snapshot keeps the volume type unchanged, please ignore this option. (no need to change).": "若快照关联的云硬盘修改过云硬盘类型,请手动修改此选项;若快照关联的云硬盘保持云硬盘类型不变,请忽略此选项(不需要做变更)。",
|
||||||
"If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project": "您未被授权访问任何项目,或您参与中的项目已被删除或禁用,可联系平台管理员重新分配项目",
|
"If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project": "您未被授权访问任何项目,或您参与中的项目已被删除或禁用,可联系平台管理员重新分配项目",
|
||||||
|
"If you are not sure which authentication method to use, please contact your administrator.": "如果您不确定使用哪种认证方式,请联系管理员。",
|
||||||
"If you choose a port which subnet is different from the subnet of LB, please ensure connectivity between the two.": "如果你选择了和LB子网不同的网卡,请确保两者的连通性。",
|
"If you choose a port which subnet is different from the subnet of LB, please ensure connectivity between the two.": "如果你选择了和LB子网不同的网卡,请确保两者的连通性。",
|
||||||
"If you do not fill in parameters such as cpus, memory_mb, local_gb, cpu_arch, etc., you can automatically inject the configuration and Mac address of the physical machine by performing the \"Auto Inspect\" operation.": "如不填写cpus、memory_mb、local_gb、cpu_arch等参数,您可以通过执行“自动检测”操作来自动注入物理机的配置和 Mac 地址。",
|
"If you do not fill in parameters such as cpus, memory_mb, local_gb, cpu_arch, etc., you can automatically inject the configuration and Mac address of the physical machine by performing the \"Auto Inspect\" operation.": "如不填写cpus、memory_mb、local_gb、cpu_arch等参数,您可以通过执行“自动检测”操作来自动注入物理机的配置和 Mac 地址。",
|
||||||
"If you still want to keep the disk data, it is recommended that you create a snapshot for the disk before deleting.": "如果您仍想保留云硬盘数据,建议您在删除之前为云硬盘创建快照。",
|
"If you still want to keep the disk data, it is recommended that you create a snapshot for the disk before deleting.": "如果您仍想保留云硬盘数据,建议您在删除之前为云硬盘创建快照。",
|
||||||
@ -1304,6 +1305,7 @@
|
|||||||
"Keypair": "SSH密钥对",
|
"Keypair": "SSH密钥对",
|
||||||
"Keypair Detail": "密钥详情",
|
"Keypair Detail": "密钥详情",
|
||||||
"Keypair Info": "密钥信息",
|
"Keypair Info": "密钥信息",
|
||||||
|
"Keystone Credentials": "Keystone认证",
|
||||||
"Keystone token is expired.": "token已过期,请检查服务器时间是否正确,确认token是否有效",
|
"Keystone token is expired.": "token已过期,请检查服务器时间是否正确,确认token是否有效",
|
||||||
"Kill": "终止",
|
"Kill": "终止",
|
||||||
"Kill Container": "终止容器",
|
"Kill Container": "终止容器",
|
||||||
@ -1613,6 +1615,7 @@
|
|||||||
"Only a MAC address or an OpenFlow based datapath_id of the switch are accepted in this field": "只可填写交换机的Mac地址或者交换机基于openflow的数据路径ID",
|
"Only a MAC address or an OpenFlow based datapath_id of the switch are accepted in this field": "只可填写交换机的Mac地址或者交换机基于openflow的数据路径ID",
|
||||||
"Only subnets that are already connected to the router can be selected.": "仅可选择已经连接过路由器的子网。",
|
"Only subnets that are already connected to the router can be selected.": "仅可选择已经连接过路由器的子网。",
|
||||||
"Open External Gateway": "开启公网网关",
|
"Open External Gateway": "开启公网网关",
|
||||||
|
"OpenID Connect": "OpenID连接",
|
||||||
"OpenStack Services": "OpenStack服务",
|
"OpenStack Services": "OpenStack服务",
|
||||||
"Operating Status": "操作状态",
|
"Operating Status": "操作状态",
|
||||||
"Operating System": "操作系统",
|
"Operating System": "操作系统",
|
||||||
@ -1756,6 +1759,7 @@
|
|||||||
"Please select availability zone": "请选择可用域",
|
"Please select availability zone": "请选择可用域",
|
||||||
"Please select item!": "请选择一个条目!",
|
"Please select item!": "请选择一个条目!",
|
||||||
"Please select key": "请选择一个键",
|
"Please select key": "请选择一个键",
|
||||||
|
"Please select login type!": "请选择登录方式!",
|
||||||
"Please select policy": "请选择一个策略",
|
"Please select policy": "请选择一个策略",
|
||||||
"Please select source": "请选择源",
|
"Please select source": "请选择源",
|
||||||
"Please select type": "请选择类型",
|
"Please select type": "请选择类型",
|
||||||
@ -2037,6 +2041,7 @@
|
|||||||
"Select User Group": "选择用户组",
|
"Select User Group": "选择用户组",
|
||||||
"Select Volume Snapshot": "选择云硬盘快照",
|
"Select Volume Snapshot": "选择云硬盘快照",
|
||||||
"Select a domain": "请选择Domain",
|
"Select a domain": "请选择Domain",
|
||||||
|
"Select a login type": "请选择登录方式",
|
||||||
"Select a region": "请选择Region",
|
"Select a region": "请选择Region",
|
||||||
"Selected": "已选",
|
"Selected": "已选",
|
||||||
"Selected Members": "已选择成员",
|
"Selected Members": "已选择成员",
|
||||||
|
@ -31,12 +31,14 @@ export class Login extends Component {
|
|||||||
error: false,
|
error: false,
|
||||||
message: '',
|
message: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
|
loginTypeOption: this.passwordOption,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.getDomains();
|
this.getDomains();
|
||||||
this.getRegions();
|
this.getRegions();
|
||||||
|
this.getSSO();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDomains() {
|
async getDomains() {
|
||||||
@ -49,6 +51,14 @@ export class Login extends Component {
|
|||||||
this.updateDefaultValue();
|
this.updateDefaultValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getSSO() {
|
||||||
|
try {
|
||||||
|
this.store.fetchSSO();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get rootStore() {
|
get rootStore() {
|
||||||
return this.props.rootStore;
|
return this.props.rootStore;
|
||||||
}
|
}
|
||||||
@ -89,8 +99,67 @@ export class Login extends Component {
|
|||||||
return '/base/overview';
|
return '/base/overview';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get enableSSO() {
|
||||||
|
const { sso: { enable_sso = false } = {} } = this.store;
|
||||||
|
return enable_sso;
|
||||||
|
}
|
||||||
|
|
||||||
|
get ssoProtocols() {
|
||||||
|
return {
|
||||||
|
openid: t('OpenID Connect'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get SSOOptions() {
|
||||||
|
if (!this.enableSSO) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const { sso: { protocols = [] } = {} } = this.store;
|
||||||
|
return protocols.map((it) => {
|
||||||
|
const { protocol, url } = it;
|
||||||
|
return {
|
||||||
|
label: this.ssoProtocols[protocol] || protocol,
|
||||||
|
value: url,
|
||||||
|
...it,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get passwordOption() {
|
||||||
|
return {
|
||||||
|
label: t('Keystone Credentials'),
|
||||||
|
value: 'password',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get loginTypeOptions() {
|
||||||
|
if (!this.enableSSO) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return [this.passwordOption, ...this.SSOOptions];
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoginTypeChange = (value, option) => {
|
||||||
|
this.setState({ loginTypeOption: option });
|
||||||
|
};
|
||||||
|
|
||||||
|
get currentLoginType() {
|
||||||
|
const { loginTypeOption: { value } = {} } = this.state;
|
||||||
|
if (value === 'password') {
|
||||||
|
return 'password';
|
||||||
|
}
|
||||||
|
return 'sso';
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentSSOLink() {
|
||||||
|
const { loginTypeOption: { value } = {} } = this.state;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
get defaultValue() {
|
get defaultValue() {
|
||||||
const data = {};
|
const data = {
|
||||||
|
loginType: 'password',
|
||||||
|
};
|
||||||
if (this.regions.length === 1) {
|
if (this.regions.length === 1) {
|
||||||
data.region = this.regions[0].value;
|
data.region = this.regions[0].value;
|
||||||
}
|
}
|
||||||
@ -107,84 +176,150 @@ export class Login extends Component {
|
|||||||
block: true,
|
block: true,
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
};
|
};
|
||||||
return [
|
const loginType = this.currentLoginType;
|
||||||
{
|
const errorItem = {
|
||||||
name: 'error',
|
name: 'error',
|
||||||
hidden: !error,
|
hidden: !error,
|
||||||
render: () => (
|
render: () => (
|
||||||
<div className={styles['login-error']}>
|
<div className={styles['login-error']}>
|
||||||
<InfoCircleFilled />
|
<InfoCircleFilled />
|
||||||
{this.getErrorMessage()}
|
{this.getErrorMessage()}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
};
|
||||||
{
|
const regionItem = {
|
||||||
name: 'region',
|
name: 'region',
|
||||||
required: true,
|
required: true,
|
||||||
message: t('Please select your Region!'),
|
message: t('Please select your Region!'),
|
||||||
render: () => (
|
render: () => (
|
||||||
<Select placeholder={t('Select a region')} options={this.regions} />
|
<Select placeholder={t('Select a region')} options={this.regions} />
|
||||||
),
|
),
|
||||||
},
|
};
|
||||||
{
|
const domainItem = {
|
||||||
name: 'domain',
|
name: 'domain',
|
||||||
required: true,
|
required: true,
|
||||||
message: t('Please select your Domain!'),
|
message: t('Please select your Domain!'),
|
||||||
render: () => (
|
render: () => (
|
||||||
<Select placeholder={t('Select a domain')} options={this.domains} />
|
<Select placeholder={t('Select a domain')} options={this.domains} />
|
||||||
),
|
),
|
||||||
},
|
};
|
||||||
{
|
const usernameItem = {
|
||||||
name: 'username',
|
name: 'username',
|
||||||
required: true,
|
required: true,
|
||||||
message: t('Please input your Username!'),
|
message: t('Please input your Username!'),
|
||||||
render: () => <Input placeholder={t('Username')} />,
|
render: () => <Input placeholder={t('Username')} />,
|
||||||
},
|
};
|
||||||
{
|
const passwordItem = {
|
||||||
name: 'password',
|
name: 'password',
|
||||||
required: true,
|
required: true,
|
||||||
message: t('Please input your Password!'),
|
message: t('Please input your Password!'),
|
||||||
render: () => <Input.Password placeholder={t('Password')} />,
|
render: () => <Input.Password placeholder={t('Password')} />,
|
||||||
},
|
};
|
||||||
{
|
const extraItem = {
|
||||||
name: 'extra',
|
name: 'extra',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
render: () => (
|
render: () => (
|
||||||
<Row gutter={8}>
|
<Row gutter={8}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Link to="password">{t('Forgot your password?')}</Link>
|
<Link to="password">{t('Forgot your password?')}</Link>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Link to="register" className={styles.register}>
|
<Link to="register" className={styles.register}>
|
||||||
{t('Sign up')}
|
{t('Sign up')}
|
||||||
</Link>
|
</Link>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
),
|
),
|
||||||
},
|
};
|
||||||
{
|
const submitItem = {
|
||||||
name: 'submit',
|
name: 'submit',
|
||||||
render: () => (
|
render: () => (
|
||||||
<Row gutter={8}>
|
<Row gutter={8}>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Button
|
<Button
|
||||||
loading={loading}
|
loading={loading}
|
||||||
type="primary"
|
type="primary"
|
||||||
htmlType="submit"
|
htmlType="submit"
|
||||||
className="login-form-button"
|
className="login-form-button"
|
||||||
>
|
>
|
||||||
{t('Log in')}
|
{t('Log in')}
|
||||||
</Button>
|
</Button>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
),
|
),
|
||||||
},
|
};
|
||||||
|
const namePasswordItems = [
|
||||||
|
errorItem,
|
||||||
|
regionItem,
|
||||||
|
domainItem,
|
||||||
|
usernameItem,
|
||||||
|
passwordItem,
|
||||||
|
extraItem,
|
||||||
];
|
];
|
||||||
|
const typeItem = {
|
||||||
|
name: 'loginType',
|
||||||
|
required: true,
|
||||||
|
message: t('Please select login type!'),
|
||||||
|
extra: t(
|
||||||
|
'If you are not sure which authentication method to use, please contact your administrator.'
|
||||||
|
),
|
||||||
|
render: () => (
|
||||||
|
<Select
|
||||||
|
placeholder={t('Select a login type')}
|
||||||
|
options={this.loginTypeOptions}
|
||||||
|
onChange={this.onLoginTypeChange}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
if (this.enableSSO) {
|
||||||
|
if (loginType === 'password') {
|
||||||
|
return [typeItem, ...namePasswordItems, submitItem];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [typeItem, submitItem];
|
||||||
|
}
|
||||||
|
return [...namePasswordItems, submitItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserId = (str) => str.split(':')[1].trim().split('.')[0];
|
getUserId = (str) => str.split(':')[1].trim().split('.')[0];
|
||||||
|
|
||||||
|
onLoginFailed = (error, values) => {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
const {
|
||||||
|
data: { detail = '' },
|
||||||
|
} = error.response;
|
||||||
|
const message = detail || '';
|
||||||
|
if (
|
||||||
|
message.includes(
|
||||||
|
'The password is expired and needs to be changed for user'
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
this.dealWithChangePassword(message, values);
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
error: true,
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onLoginSuccess = () => {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
error: false,
|
||||||
|
});
|
||||||
|
if (this.rootStore.user && !isEmpty(this.rootStore.user)) {
|
||||||
|
this.rootStore.routing.push(this.nextPage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
onFinish = (values) => {
|
onFinish = (values) => {
|
||||||
|
if (this.currentLoginType === 'sso') {
|
||||||
|
document.location.href = this.currentSSOLink;
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: true,
|
loading: true,
|
||||||
message: '',
|
message: '',
|
||||||
@ -194,40 +329,10 @@ export class Login extends Component {
|
|||||||
const body = { domain, password, region, username };
|
const body = { domain, password, region, username };
|
||||||
this.rootStore.login(body).then(
|
this.rootStore.login(body).then(
|
||||||
() => {
|
() => {
|
||||||
this.setState({
|
this.onLoginSuccess();
|
||||||
loading: false,
|
|
||||||
error: false,
|
|
||||||
});
|
|
||||||
if (this.rootStore.user && !isEmpty(this.rootStore.user)) {
|
|
||||||
this.rootStore.routing.push(this.nextPage);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
this.setState({
|
this.onLoginFailed(error, values);
|
||||||
loading: false,
|
|
||||||
});
|
|
||||||
const {
|
|
||||||
data: { detail },
|
|
||||||
} = error.response;
|
|
||||||
if (
|
|
||||||
detail.includes(
|
|
||||||
'The password is expired and needs to be changed for user'
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
const userId = this.getUserId(detail);
|
|
||||||
const data = {
|
|
||||||
region: values.region,
|
|
||||||
oldPassword: values.password,
|
|
||||||
userId,
|
|
||||||
};
|
|
||||||
this.rootStore.setPasswordInfo(data);
|
|
||||||
this.rootStore.routing.push('/auth/change-password');
|
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
error: true,
|
|
||||||
message: detail,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -252,6 +357,17 @@ export class Login extends Component {
|
|||||||
return t('Username or password is incorrect');
|
return t('Username or password is incorrect');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dealWithChangePassword = (detail, values) => {
|
||||||
|
const userId = this.getUserId(detail);
|
||||||
|
const data = {
|
||||||
|
region: values.region,
|
||||||
|
oldPassword: values.password,
|
||||||
|
userId,
|
||||||
|
};
|
||||||
|
this.rootStore.setPasswordInfo(data);
|
||||||
|
this.rootStore.routing.push('/auth/change-password');
|
||||||
|
};
|
||||||
|
|
||||||
updateDefaultValue = () => {
|
updateDefaultValue = () => {
|
||||||
this.formRef.current.resetFields();
|
this.formRef.current.resetFields();
|
||||||
if (this.formRef.current && this.formRef.current.resetFields) {
|
if (this.formRef.current && this.formRef.current.resetFields) {
|
||||||
|
@ -23,6 +23,9 @@ export class SkylineStore extends Base {
|
|||||||
@observable
|
@observable
|
||||||
regions = [];
|
regions = [];
|
||||||
|
|
||||||
|
@observable
|
||||||
|
sso = {};
|
||||||
|
|
||||||
get client() {
|
get client() {
|
||||||
return client.skyline.contrib;
|
return client.skyline.contrib;
|
||||||
}
|
}
|
||||||
@ -38,6 +41,12 @@ export class SkylineStore extends Base {
|
|||||||
const result = await this.client.regions();
|
const result = await this.client.regions();
|
||||||
this.regions = result;
|
this.regions = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async fetchSSO() {
|
||||||
|
const result = await client.skyline.sso.list();
|
||||||
|
this.sso = result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const globalSkylineStore = new SkylineStore();
|
const globalSkylineStore = new SkylineStore();
|
||||||
|
Loading…
Reference in New Issue
Block a user