diff --git a/spug_api/apps/app/views.py b/spug_api/apps/app/views.py
index 9fbbfe2..a5fc358 100644
--- a/spug_api/apps/app/views.py
+++ b/spug_api/apps/app/views.py
@@ -196,7 +196,12 @@ def get_versions(request, d_id):
return json_response({'branches': branches, 'tags': tags})
-@auth('deploy.app.config')
+@auth('deploy.app.config|deploy.app.edit')
def kit_key(request):
- api_key = AppSetting.get_default('api_key')
- return json_response(api_key)
+ form, error = JsonParser(
+ Argument('key', filter=lambda x: x in ('api_key', 'public_key'), help='参数错误')
+ ).parse(request.body)
+ if error is None:
+ api_key = AppSetting.get_default(form.key)
+ return json_response(api_key)
+ return json_response(error=error)
diff --git a/spug_web/src/index.less b/spug_web/src/index.less
index 69b8796..5c1cbab 100644
--- a/spug_web/src/index.less
+++ b/spug_web/src/index.less
@@ -30,4 +30,9 @@ code {
/* Common CSS style */
.none {
display: none;
+}
+
+.btn {
+ color: #2563fc;
+ cursor: pointer;
}
\ No newline at end of file
diff --git a/spug_web/src/pages/deploy/app/AutoDeploy.js b/spug_web/src/pages/deploy/app/AutoDeploy.js
index 310e4ae..c522bc4 100644
--- a/spug_web/src/pages/deploy/app/AutoDeploy.js
+++ b/spug_web/src/pages/deploy/app/AutoDeploy.js
@@ -19,7 +19,7 @@ export default observer(function AutoDeploy() {
if (store.deploy.extend === '1') {
fetchVersions()
}
- http.get('/api/app/kit/key/')
+ http.post('/api/app/kit/key/', {key: 'api_key'})
.then(res => setKey(res))
}, [])
diff --git a/spug_web/src/pages/deploy/app/Ext1Setup1.js b/spug_web/src/pages/deploy/app/Ext1Setup1.js
index 216d3f0..a88f9f7 100644
--- a/spug_web/src/pages/deploy/app/Ext1Setup1.js
+++ b/spug_web/src/pages/deploy/app/Ext1Setup1.js
@@ -7,12 +7,14 @@ import React, { useEffect, useState } from 'react';
import { observer } from 'mobx-react';
import { Link } from 'react-router-dom';
import { Switch, Form, Input, Select, Button, Radio } from 'antd';
+import Repo from './Repo';
import envStore from 'pages/config/environment/store';
import Selector from 'pages/host/Selector';
import store from './store';
export default observer(function Ext1Setup1() {
const [envs, setEnvs] = useState([]);
+ const [visible, setVisible] = useState(false);
function updateEnvs() {
const ids = store.currentRecord['deploys'].map(x => x.env_id);
@@ -63,7 +65,7 @@ export default observer(function Ext1Setup1() {
{info.host_ids.length > 0 && 已选择 {info.host_ids.length} 台}
-
+ setVisible(true)}>私有仓库?}>
info['git_repo'] = e.target.value}
placeholder="请输入Git仓库地址"/>
@@ -119,6 +121,7 @@ export default observer(function Ext1Setup1() {
selectedRowKeys={[...info.host_ids]}
onCancel={() => store.selectorVisible = false}
onOk={(_, ids) => info.host_ids = ids}/>
+ {visible && info['git_repo'] = v} onCancel={() => setVisible(false)}/>}
)
})
diff --git a/spug_web/src/pages/deploy/app/Repo.js b/spug_web/src/pages/deploy/app/Repo.js
new file mode 100644
index 0000000..d1aa037
--- /dev/null
+++ b/spug_web/src/pages/deploy/app/Repo.js
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
+ * Copyright (c)
+ * Released under the AGPL-3.0 License.
+ */
+import React, { useEffect, useState } from 'react';
+import { Modal, Form, Radio, Input, message } from 'antd';
+import { http } from 'libs';
+
+function Repo(props) {
+ const [form] = Form.useForm()
+ const [key, setKey] = useState()
+
+ useEffect(() => {
+ http.post('/api/app/kit/key/', {key: 'public_key'})
+ .then(res => setKey(res))
+ if (props.url) {
+ const fields = props.url.match(/^(https?:\/\/)(.+):(.+)@(.*)$/)
+ if (fields && fields.length === 5) {
+ form.setFieldsValue({
+ type: 'password',
+ url: fields[1] + fields[4],
+ username: decodeURIComponent(fields[2]),
+ password: decodeURIComponent(fields[3])
+ })
+ } else if (props.url.startsWith('git@')) {
+ form.setFieldsValue({type: 'key', url: props.url})
+ } else {
+ form.setFieldsValue({url: props.url})
+ }
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [])
+
+ function handleSubmit() {
+ const formData = form.getFieldsValue()
+ if (!formData.url) return message.error('请输入仓库地址')
+ let url = formData.url;
+ if (formData.type === 'password') {
+ if (!formData.username) return message.error('请输入账户')
+ if (!formData.password) return message.error('请输入密码')
+ if (formData.url.startsWith('http')) {
+ const username = encodeURIComponent(formData.username)
+ const password = encodeURIComponent(formData.password)
+ url = formData.url.replace(/^(https?:\/\/)/, `$1${username}:${password}@`)
+ } else {
+ return message.error('认证类型为账户密码,仓库地址需以http或https开头。')
+ }
+ } else if (formData.url.startsWith('http')) {
+ return message.error('输入的仓库地址以http或https开头,则认证类型需为账户密码认证。')
+ }
+ props.onOk(url)
+ props.onCancel()
+ }
+
+ function copyToClipBoard() {
+ const t = document.createElement('input');
+ t.value = key;
+ document.body.appendChild(t);
+ t.select();
+ document.execCommand('copy');
+ t.remove();
+ message.success('已复制')
+ }
+
+ return (
+
+
+
+ 账户密码
+ 密钥
+
+
+
+
+
+
+
+ {({getFieldValue}) =>
+ getFieldValue('type') === 'password' ? (
+
+
+
+
+
+
+
+
+ ) : (
+
+ 请复制该密钥,以Gitee为例可参考
+ Gitee文档
+ 进行后续配置。
+
+ )}>
+ 点击复制密钥
+
+ )
+ }
+
+
+
+ )
+}
+
+export default Repo