-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
75 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug | ||
# Copyright: (c) <[email protected]> | ||
# Released under the AGPL-3.0 License. | ||
from apps.setting.utils import AppSetting | ||
import requests | ||
|
||
push_server = 'https://push.spug.cc' | ||
|
@@ -24,3 +25,21 @@ def get_contacts(token): | |
return res['data'] | ||
except Exception: | ||
return [] | ||
|
||
|
||
def send_login_code(token, user, code): | ||
url = f'{push_server}/spug/message/' | ||
data = { | ||
'token': token, | ||
'targets': [user], | ||
'source': 'mfa', | ||
'dataset': { | ||
'code': code | ||
} | ||
} | ||
res = requests.post(url, json=data, timeout=15) | ||
if res.status_code != 200: | ||
raise Exception(f'status code: {res.status_code}') | ||
res = res.json() | ||
if res.get('error'): | ||
raise Exception(res['error']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,18 +3,24 @@ | |
* Copyright (c) <[email protected]> | ||
* Released under the AGPL-3.0 License. | ||
*/ | ||
import React, { useState } from 'react'; | ||
import { Link } from 'react-router-dom'; | ||
import { observer } from 'mobx-react'; | ||
import { Modal, Form, Select, Input, message } from 'antd'; | ||
import http from 'libs/http'; | ||
import React, {useState, useEffect} from 'react'; | ||
import {Link} from 'react-router-dom'; | ||
import {observer} from 'mobx-react'; | ||
import {Modal, Form, Select, Input, message} from 'antd'; | ||
import {http, includes} from 'libs'; | ||
import store from './store'; | ||
import rStore from '../role/store'; | ||
|
||
|
||
export default observer(function () { | ||
const [form] = Form.useForm(); | ||
const [loading, setLoading] = useState(false); | ||
const [contacts, setContacts] = useState([]) | ||
|
||
useEffect(() => { | ||
http.get('/api/alarm/contact/?only_push=1') | ||
.then(res => setContacts(res)) | ||
}, []); | ||
|
||
function handleSubmit() { | ||
setLoading(true); | ||
|
@@ -44,11 +50,13 @@ export default observer(function () { | |
<Form.Item required name="nickname" label="姓名"> | ||
<Input placeholder="请输入姓名"/> | ||
</Form.Item> | ||
<Form.Item required hidden={store.record.id} name="password" label="密码" extra="至少8位包含数字、小写和大写字母。"> | ||
<Form.Item required hidden={store.record.id} name="password" label="密码" | ||
extra="至少8位包含数字、小写和大写字母。"> | ||
<Input.Password placeholder="请输入密码"/> | ||
</Form.Item> | ||
<Form.Item hidden={store.record.is_supper} label="角色" style={{marginBottom: 0}}> | ||
<Form.Item name="role_ids" style={{display: 'inline-block', width: '80%'}} extra="权限最大化原则,组合多个角色权限。"> | ||
<Form.Item name="role_ids" style={{display: 'inline-block', width: '80%'}} | ||
extra="权限最大化原则,组合多个角色权限。"> | ||
<Select mode="multiple" placeholder="请选择"> | ||
{rStore.records.map(item => ( | ||
<Select.Option value={item.id} key={item.id}>{item.name}</Select.Option> | ||
|
@@ -61,13 +69,17 @@ export default observer(function () { | |
</Form.Item> | ||
<Form.Item | ||
name="wx_token" | ||
label="微信Token" | ||
label="推送标识" | ||
extra={( | ||
<span> | ||
如果启用了MFA(两步验证)则该项为必填。 | ||
<a target="_blank" rel="noopener noreferrer" href="https://spug.cc/docs/wx-token/">什么是微信Token?</a> | ||
</span>)}> | ||
<Input placeholder="请输入微信Token"/> | ||
<Select showSearch filterOption={(i, o) => includes(o.children, i)} placeholder="请选择绑定推送标识"> | ||
{contacts.map(item => ( | ||
<Select.Option value={item.id} key={item.id}>{item.name}</Select.Option> | ||
))} | ||
</Select> | ||
</Form.Item> | ||
</Form> | ||
</Modal> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,17 +3,14 @@ | |
* Copyright (c) <[email protected]> | ||
* Released under the AGPL-3.0 License. | ||
*/ | ||
import React, { useState, useEffect } from 'react'; | ||
import { observer } from 'mobx-react'; | ||
import { Form, Switch, Input, Space, message, Button } from 'antd'; | ||
import React, {useState, useEffect} from 'react'; | ||
import {observer} from 'mobx-react'; | ||
import {Form, Switch, Input, Space, Spin, message, Button} from 'antd'; | ||
import styles from './index.module.css'; | ||
import http from 'libs/http'; | ||
import store from './store'; | ||
|
||
export default observer(function () { | ||
const [verify_ip, setVerifyIP] = useState(store.settings.verify_ip); | ||
const [bind_ip, setBindIP] = useState(store.settings.bind_ip); | ||
const [mfa, setMFA] = useState(store.settings.MFA || {}); | ||
const [code, setCode] = useState(); | ||
const [visible, setVisible] = useState(false); | ||
const [counter, setCounter] = useState(0); | ||
|
@@ -29,25 +26,25 @@ export default observer(function () { | |
}, [counter]) | ||
|
||
function handleChangeVerifyIP(v) { | ||
setVerifyIP(v); | ||
store.isFetching = true; | ||
http.post('/api/setting/', {data: [{key: 'verify_ip', value: v}]}) | ||
.then(() => { | ||
message.success('设置成功'); | ||
store.fetchSettings() | ||
}) | ||
}, () => store.isFetching = false) | ||
} | ||
|
||
function handleChangeBindIP(v) { | ||
setBindIP(v); | ||
store.isFetching = true; | ||
http.post('/api/setting/', {data: [{key: 'bind_ip', value: v}]}) | ||
.then(() => { | ||
message.success('设置成功'); | ||
store.fetchSettings() | ||
}) | ||
}, () => store.isFetching = false) | ||
} | ||
|
||
function handleChangeMFA(v) { | ||
if (v && !store.settings.spug_key) return message.error('开启MFA认证需要先在基本设置中配置调用凭据'); | ||
if (v && !store.settings.spug_push_key) return message.error('开启MFA认证需要先在推送服务设置中绑定推送助手账户'); | ||
v ? setVisible(true) : handleMFAModify(false) | ||
} | ||
|
||
|
@@ -62,16 +59,16 @@ export default observer(function () { | |
setLoading2(true) | ||
http.post('/api/setting/mfa/', {enable: v, code}) | ||
.then(() => { | ||
setMFA({enable: v}); | ||
setVisible(false); | ||
message.success('设置成功'); | ||
store.fetchSettings() | ||
}) | ||
.finally(() => setLoading2(false)) | ||
} | ||
|
||
const {verify_ip, bind_ip, MFA} = store.settings; | ||
return ( | ||
<React.Fragment> | ||
<Spin spinning={store.isFetching}> | ||
<div className={styles.title}>安全设置</div> | ||
<Form layout="vertical" style={{maxWidth: 500}}> | ||
<Form.Item | ||
|
@@ -98,8 +95,9 @@ export default observer(function () { | |
label="登录MFA(两步)认证" | ||
style={{marginTop: 24}} | ||
extra={visible ? '输入验证码,通过验证后开启。' : | ||
<span>建议开启,登录时额外使用验证码进行身份验证。开启前至少要确保管理员账户配置了微信Token(账户管理/编辑),开启后未配置微信Token的账户将无法登录,<a | ||
target="_blank" rel="noopener noreferrer" href="https://spug.cc/docs/wx-token/">什么是微信Token?</a></span>}> | ||
<span>建议开启,登录时额外使用验证码进行身份验证。开启前至少要确保管理员账户配置了推送标识(账户管理/编辑),开启后未配置的账户将无法登录,<a | ||
target="_blank" rel="noopener noreferrer" | ||
href="https://spug.cc/docs/wx-token/">什么是微信Token?</a></span>}> | ||
{visible ? ( | ||
<div style={{display: 'flex', width: 490}}> | ||
<Form.Item noStyle extra="验证通过后开启MFA(两步验证)。"> | ||
|
@@ -120,10 +118,10 @@ export default observer(function () { | |
checkedChildren="开启" | ||
unCheckedChildren="关闭" | ||
onChange={handleChangeMFA} | ||
checked={mfa.enable}/> | ||
checked={MFA?.enable}/> | ||
)} | ||
</Form.Item> | ||
</Form> | ||
</React.Fragment> | ||
</Spin> | ||
) | ||
}) |