Browse Source

解决echo出现的字符丢失问题

docker-svn
witersen 3 years ago
parent
commit
ac5bb41488
  1. 374
      01.web/src/views/repositoryInfo/index.vue
  2. 11
      02.php/app/controller/Svnrep.php
  3. 44
      02.php/app/function/ipc.php
  4. 6
      02.php/app/service/Personal.php
  5. 10
      02.php/app/service/Svn.php
  6. 30
      02.php/app/service/Svngroup.php
  7. 195
      02.php/app/service/Svnrep.php
  8. 26
      02.php/app/service/Svnuser.php
  9. 33
      02.php/server/svnadmind.php

374
01.web/src/views/repositoryInfo/index.vue

@ -390,32 +390,6 @@
:title="titleModalRepHooks" :title="titleModalRepHooks"
class-name="hooks" class-name="hooks"
> >
<!-- <Form ref="formRepHooks" :model="formRepHooks" :label-width="60">
<FormItem label="类型">
<Select v-model="formRepHooks.select" :transfer="true">
<Option
v-for="item in formRepHooks.type"
:value="item.value"
:key="item.value"
>{{ item.label }}</Option
>
</Select>
</FormItem>
<FormItem label="脚本">
<Input
v-model="formRepHooks.type[formRepHooks.select].shell"
:rows="10"
show-word-limit
type="textarea"
placeholder="请输入hooks shell脚本 首行需为:#!/bin/bash 或 #!/bin/sh"
/>
</FormItem>
<FormItem>
<Button ghost type="primary" @click="EditRepHook"
>应用针对当前</Button
>
</FormItem>
</Form> -->
<Tabs type="card"> <Tabs type="card">
<TabPane label="仓库钩子"> <TabPane label="仓库钩子">
<Card :bordered="false" :dis-hover="true" class="my-modal"> <Card :bordered="false" :dis-hover="true" class="my-modal">
@ -423,80 +397,156 @@
<List> <List>
<Divider orientation="left" size="small">Commit</Divider> <Divider orientation="left" size="small">Commit</Divider>
<ListItem> <ListItem>
<ListItemMeta description="Start-commit hook" /> <ListItemMeta
description="Start-commit hook"
v-if="formRepHooks.start_commit.hasFile"
/>
<ListItemMeta title="Start-commit hook" v-else />
<template slot="action"> <template slot="action">
<li> <li>
<span>编辑</span> <span @click="ModalStudyRepHook('start_commit')"
>介绍</span
>
</li>
<li>
<span @click="ModalEditRepHook('start_commit')"
>编辑</span
>
</li> </li>
<li> <li>
<span>移除</span> <span
@click="DelRepHook(formRepHooks.start_commit.fileName)"
>移除</span
>
</li> </li>
</template> </template>
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemMeta title="Pre-commit hook" /> <ListItemMeta
description="Pre-commit hook"
v-if="formRepHooks.pre_commit.hasFile"
/>
<ListItemMeta title="Pre-commit hook" v-else />
<template slot="action"> <template slot="action">
<li> <li>
<span>编辑</span> <span @click="ModalStudyRepHook('pre_commit')">介绍</span>
</li> </li>
<li> <li>
<span>移除</span> <span @click="ModalEditRepHook('pre_commit')">编辑</span>
</li>
<li>
<span
@click="DelRepHook(formRepHooks.pre_commit.fileName)"
>移除</span
>
</li> </li>
</template> </template>
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemMeta title="Post-commit hook" /> <ListItemMeta
description="Post-commit hook"
v-if="formRepHooks.post_commit.hasFile"
/>
<ListItemMeta title="Post-commit hook" v-else />
<template slot="action"> <template slot="action">
<li> <li>
<span>编辑</span> <span @click="ModalStudyRepHook('post_commit')"
>介绍</span
>
</li> </li>
<li> <li>
<span>移除</span> <span @click="ModalEditRepHook('post_commit')">编辑</span>
</li>
<li>
<span
@click="DelRepHook(formRepHooks.post_commit.fileName)"
>移除</span
>
</li> </li>
</template> </template>
</ListItem> </ListItem>
<Divider orientation="left" size="small">Locks</Divider> <Divider orientation="left" size="small">Locks</Divider>
<ListItem> <ListItem>
<ListItemMeta title="Pre-lock hook" /> <ListItemMeta
description="Pre-lock hook"
v-if="formRepHooks.pre_lock.hasFile"
/>
<ListItemMeta title="Pre-lock hook" v-else />
<template slot="action"> <template slot="action">
<li> <li>
<span>编辑</span> <span @click="ModalStudyRepHook('pre_lock')">介绍</span>
</li> </li>
<li> <li>
<span>移除</span> <span @click="ModalEditRepHook('pre_lock')">编辑</span>
</li>
<li>
<span @click="DelRepHook(formRepHooks.pre_lock.fileName)"
>移除</span
>
</li> </li>
</template> </template>
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemMeta title="Post-lock hook" /> <ListItemMeta
description="Post-lock hook"
v-if="formRepHooks.post_lock.hasFile"
/>
<ListItemMeta title="Post-lock hook" v-else />
<template slot="action"> <template slot="action">
<li> <li>
<span>编辑</span> <span @click="ModalStudyRepHook('post_lock')">介绍</span>
</li>
<li>
<span @click="ModalEditRepHook('post_lock')">编辑</span>
</li> </li>
<li> <li>
<span>移除</span> <span @click="DelRepHook(formRepHooks.post_lock.fileName)"
>移除</span
>
</li> </li>
</template> </template>
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemMeta title="Pre-unlock hook" /> <ListItemMeta
description="Pre-unlock hook"
v-if="formRepHooks.pre_unlock.hasFile"
/>
<ListItemMeta title="Pre-unlock hook" v-else />
<template slot="action"> <template slot="action">
<li> <li>
<span>编辑</span> <span @click="ModalStudyRepHook('pre_unlock')">介绍</span>
</li> </li>
<li> <li>
<span>移除</span> <span @click="ModalEditRepHook('pre_unlock')">编辑</span>
</li>
<li>
<span
@click="DelRepHook(formRepHooks.pre_unlock.fileName)"
>移除</span
>
</li> </li>
</template> </template>
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemMeta title="Post-unlock hook" /> <ListItemMeta
description="Post-unlock hook"
v-if="formRepHooks.post_unlock.hasFile"
/>
<ListItemMeta title="Post-unlock hook" v-else />
<template slot="action"> <template slot="action">
<li> <li>
<span>编辑</span> <span @click="ModalStudyRepHook('post_unlock')"
>介绍</span
>
</li>
<li>
<span @click="ModalEditRepHook('post_unlock')">编辑</span>
</li> </li>
<li> <li>
<span>移除</span> <span
@click="DelRepHook(formRepHooks.post_unlock.fileName)"
>移除</span
>
</li> </li>
</template> </template>
</ListItem> </ListItem>
@ -504,30 +554,69 @@
>Revision property change</Divider >Revision property change</Divider
> >
<ListItem> <ListItem>
<ListItemMeta title="Pre-reversion property change hook" /> <ListItemMeta
description="Pre-reversion property change hook"
v-if="formRepHooks.pre_revprop_change.hasFile"
/>
<ListItemMeta
title="Pre-reversion property change hook"
v-else
/>
<template slot="action"> <template slot="action">
<li> <li>
<span>编辑</span> <span @click="ModalStudyRepHook('pre_revprop_change')"
>介绍</span
>
</li> </li>
<li> <li>
<span>移除</span> <span @click="ModalEditRepHook('pre_revprop_change')"
>编辑</span
>
</li>
<li>
<span
@click="
DelRepHook(formRepHooks.pre_revprop_change.fileName)
"
>移除</span
>
</li> </li>
</template> </template>
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemMeta title="Post-reversion property change hook" /> <ListItemMeta
description="Post-reversion property change hook"
v-if="formRepHooks.post_revprop_change.hasFile"
/>
<ListItemMeta
title="Post-reversion property change hook"
v-else
/>
<template slot="action"> <template slot="action">
<li> <li>
<span>编辑</span> <span @click="ModalStudyRepHook('post_revprop_change')"
>介绍</span
>
</li>
<li>
<span @click="ModalEditRepHook('post_revprop_change')"
>编辑</span
>
</li> </li>
<li> <li>
<span>移除</span> <span
@click="
DelRepHook(formRepHooks.post_revprop_change.fileName)
"
>移除</span
>
</li> </li>
</template> </template>
</ListItem> </ListItem>
</List> </List>
</Scroll> </Scroll>
</Card> </Card>
<Spin size="large" fix v-if="loadingGetRepHooks"></Spin>
</TabPane> </TabPane>
<TabPane label="常用钩子"> <TabPane label="常用钩子">
<Scroll> <Scroll>
@ -564,6 +653,38 @@
> >
</div> </div>
</Modal> </Modal>
<!-- 对话框-钩子模板内容查看 -->
<Modal v-model="modalStudyRepHook" :title="titleModalStudyRepHook">
<Input
v-model="tempSelectRepHookTmpl"
:rows="15"
show-word-limit
type="textarea"
/>
<div slot="footer">
<Button type="primary" ghost @click="modalStudyRepHook = false"
>取消</Button
>
</div>
</Modal>
<!-- 对话框-钩子内容编辑 -->
<Modal v-model="modalEditRepHook" :title="titleModalEditRepHook">
<Input
v-model="tempSelectRepHookCon"
:rows="15"
show-word-limit
type="textarea"
placeholder="具体介绍和语法可看钩子介绍"
/>
<div slot="footer">
<Button
type="primary"
@click="EditRepHook"
:loading="loadingEditRepHook"
>应用</Button
>
</div>
</Modal>
<!-- 对话框-高级 --> <!-- 对话框-高级 -->
<Modal v-model="modalRepAdvance" :title="titleModalRepAdvance"> <Modal v-model="modalRepAdvance" :title="titleModalRepAdvance">
<Tabs type="card"> <Tabs type="card">
@ -781,6 +902,10 @@ export default {
modalRepAllUser: false, modalRepAllUser: false,
//SVN //SVN
modalRepAllGroup: false, modalRepAllGroup: false,
//
modalEditRepHook: false,
//
modalStudyRepHook: false,
/** /**
* 排序数据 * 排序数据
@ -851,6 +976,10 @@ export default {
loadingImportBackup: false, loadingImportBackup: false,
// //
loadingEditRepName: false, loadingEditRepName: false,
//
loadingGetRepHooks: true,
//
loadingEditRepHook: false,
/** /**
* 临时变量 * 临时变量
@ -877,6 +1006,12 @@ export default {
currentRepPriAddUser: "", currentRepPriAddUser: "",
// //
currentRepPriAddGroup: "", currentRepPriAddGroup: "",
//
tempSelectRepHook: "",
//
tempSelectRepHookCon: "",
//
tempSelectRepHookTmpl: "",
/** /**
* 对话框标题 * 对话框标题
@ -893,6 +1028,10 @@ export default {
titleModalEditRepName: "", titleModalEditRepName: "",
// //
titleModalRepAdvance: "", titleModalRepAdvance: "",
//
titleModalEditRepHook: "",
//
titleModalStudyRepHook: "",
/** /**
* 表单 * 表单
@ -918,53 +1057,19 @@ export default {
formRepImport: {}, formRepImport: {},
// //
formRepHooks: { formRepHooks: {
select: "start-commit", start_commit: { fileName: "", hasFile: false, con: "", tmpl: "" },
type: { pre_commit: { fileName: "", hasFile: false, con: "", tmpl: "" },
"start-commit": { post_commit: { fileName: "", hasFile: false, con: "", tmpl: "" },
value: "start-commit", pre_lock: { fileName: "", hasFile: false, con: "", tmpl: "" },
label: "start-commit---事务创建前", post_lock: { fileName: "", hasFile: false, con: "", tmpl: "" },
shell: "", pre_unlock: { fileName: "", hasFile: false, con: "", tmpl: "" },
}, post_unlock: { fileName: "", hasFile: false, con: "", tmpl: "" },
"pre-commit": { pre_revprop_change: { fileName: "", hasFile: false, con: "", tmpl: "" },
value: "pre-commit", post_revprop_change: {
label: "pre-commit---事务提交前", fileName: "",
shell: "", hasFile: false,
}, con: "",
"post-commit": { tmpl: "",
value: "post-commit",
label: "post-commit---事务提交后",
shell: "",
},
"pre-lock": {
value: "pre-lock",
label: "pre-lock---锁定文件前",
shell: "",
},
"post-lock": {
value: "post-lock",
label: "post-lock---锁定文件后",
shell: "",
},
"pre-unlock": {
value: "pre-unlock",
label: "pre-unlock---解锁文件前",
shell: "",
},
"post-unlock": {
value: "post-unlock",
label: "post-unlock---解锁文件后",
shell: "",
},
"pre-revprop-change": {
value: "pre-revprop-change",
label: "pre-revprop-change---修改修订版属性前",
shell: "",
},
"post-revprop-change": {
value: "post-revprop-change",
label: "post-revprop-change---修改修订版属性后",
shell: "",
},
}, },
}, },
// //
@ -2334,39 +2439,98 @@ export default {
*/ */
GetRepHooks() { GetRepHooks() {
var that = this; var that = this;
that.loadingGetRepHooks = true;
var data = { var data = {
rep_name: that.currentRepName, rep_name: that.currentRepName,
}; };
that.$axios that.$axios
.post("/api.php?c=Svnrep&a=GetRepHooks&t=web", data) .post("/api.php?c=Svnrep&a=GetRepHooks&t=web", data)
.then(function (response) { .then(function (response) {
that.loadingGetRepHooks = false;
var result = response.data; var result = response.data;
if (result.status == 1) { if (result.status == 1) {
that.formRepHooks.type = result.data; that.formRepHooks = result.data;
} else { } else {
that.$Message.error(result.message); that.$Message.error(result.message);
} }
}) })
.catch(function (error) { .catch(function (error) {
that.loadingGetRepHooks = false;
console.log(error); console.log(error);
that.$Message.error("出错了 请联系管理员!"); that.$Message.error("出错了 请联系管理员!");
}); });
}, },
/** /**
* 修改仓库的钩子内容针对单个钩子 * 移除仓库钩子
*/ */
DelRepHook(fileName) {
var that = this;
that.loadingGetRepHooks = true;
var data = {
rep_name: that.currentRepName,
fileName: fileName,
};
that.$axios
.post("/api.php?c=Svnrep&a=DelRepHook&t=web", data)
.then(function (response) {
var result = response.data;
if (result.status == 1) {
that.$Message.success(result.message);
that.GetRepHooks();
} else {
that.loadingGetRepHooks = false;
that.$Message.error(result.message);
}
})
.catch(function (error) {
that.loadingGetRepHooks = false;
console.log(error);
that.$Message.error("出错了 请联系管理员!");
});
},
/**
* 查看钩子模板内容
*/
ModalStudyRepHook(key) {
//
this.tempSelectRepHook = this.formRepHooks[key].fileName;
//
this.tempSelectRepHookTmpl = this.formRepHooks[key].tmpl;
//
this.titleModalStudyRepHook =
"钩子信息介绍 - " + this.formRepHooks[key].fileName;
//
this.modalStudyRepHook = true;
},
/**
* 修改仓库的钩子内容
*/
ModalEditRepHook(key) {
//
this.tempSelectRepHook = this.formRepHooks[key].fileName;
//
this.tempSelectRepHookCon = this.formRepHooks[key].con;
//
this.titleModalEditRepHook =
"钩子文件编辑 - " + this.formRepHooks[key].fileName;
//
this.modalEditRepHook = true;
},
EditRepHook() { EditRepHook() {
var that = this; var that = this;
that.loadingEditRepHook = true;
var data = { var data = {
rep_name: that.currentRepName, rep_name: that.currentRepName,
type: that.formRepHooks.select, fileName: that.tempSelectRepHook,
content: that.formRepHooks.type[that.formRepHooks.select].shell, content: that.tempSelectRepHookCon,
}; };
that.$axios that.$axios
.post("/api.php?c=Svnrep&a=EditRepHook&t=web", data) .post("/api.php?c=Svnrep&a=EditRepHook&t=web", data)
.then(function (response) { .then(function (response) {
that.loadingEditRepHook = false;
var result = response.data; var result = response.data;
if (result.status == 1) { if (result.status == 1) {
that.modalEditRepHook = false;
that.$Message.success(result.message); that.$Message.success(result.message);
that.GetRepHooks(); that.GetRepHooks();
} else { } else {
@ -2374,11 +2538,11 @@ export default {
} }
}) })
.catch(function (error) { .catch(function (error) {
that.loadingEditRepHook = false;
console.log(error); console.log(error);
that.$Message.error("出错了 请联系管理员!"); that.$Message.error("出错了 请联系管理员!");
}); });
}, },
/** /**
* 高级 * 高级
*/ */

11
02.php/app/controller/Svnrep.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:05 * @Date: 2022-04-24 23:37:05
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-09 18:54:31 * @LastEditTime: 2022-05-10 21:53:20
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -262,6 +262,15 @@ class Svnrep extends Base
json2($result); json2($result);
} }
/**
* 移除仓库钩子
*/
public function DelRepHook()
{
$result = $this->ServiceSvnrep->DelRepHook();
json2($result);
}
/** /**
* 修改仓库的钩子内容(针对单个钩子) * 修改仓库的钩子内容(针对单个钩子)
*/ */

44
02.php/app/function/ipc.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-05-07 01:00:10 * @Date: 2022-05-07 01:00:10
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-07 14:19:50 * @LastEditTime: 2022-05-11 02:01:26
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -14,13 +14,51 @@ function FunShellExec($shell)
{ {
$config_daemon = Config::get('daemon'); $config_daemon = Config::get('daemon');
$request = [
'type' => 'passthru',
'content' => $shell
];
$request = serialize($request);
//检测信息长度
if (strlen($request) >= $config_daemon['SOCKET_READ_LENGTH']) {
json1(200, 0, '数据长度超过' . $config_daemon['SOCKET_READ_LENGTH'] . ' 请向上调整参数:SOCKET_READ_LENGTH');
}
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("error:" . socket_strerror(socket_last_error()));
$server = socket_connect($socket, $config_daemon['IPC_ADDRESS'], (int)$config_daemon['IPC_PORT']);
socket_write($socket, $request);
$reply = socket_read($socket, (int)$config_daemon['SOCKET_READ_LENGTH']);
socket_close($socket);
return unserialize($reply);
}
/**
* file_put_contents
*/
function FunFilePutContents($filename, $data, $flags = 0, $context = '')
{
$config_daemon = Config::get('daemon');
$content = [
'filename' => $filename,
'data' => $data,
'flags' => $flags,
'context' => $context
];
$request = [
'type' => 'file_put_contents',
'content' => $content
];
$request = serialize($request);
//检测信息长度 //检测信息长度
if (strlen($shell) >= $config_daemon['SOCKET_READ_LENGTH']) { if (strlen($request) >= $config_daemon['SOCKET_READ_LENGTH']) {
json1(200, 0, '数据长度超过' . $config_daemon['SOCKET_READ_LENGTH'] . ' 请向上调整参数:SOCKET_READ_LENGTH'); json1(200, 0, '数据长度超过' . $config_daemon['SOCKET_READ_LENGTH'] . ' 请向上调整参数:SOCKET_READ_LENGTH');
} }
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("error:" . socket_strerror(socket_last_error())); $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("error:" . socket_strerror(socket_last_error()));
$server = socket_connect($socket, $config_daemon['IPC_ADDRESS'], (int)$config_daemon['IPC_PORT']); $server = socket_connect($socket, $config_daemon['IPC_ADDRESS'], (int)$config_daemon['IPC_PORT']);
socket_write($socket, $shell); socket_write($socket, $request);
$reply = socket_read($socket, (int)$config_daemon['SOCKET_READ_LENGTH']); $reply = socket_read($socket, (int)$config_daemon['SOCKET_READ_LENGTH']);
socket_close($socket); socket_close($socket);
return unserialize($reply); return unserialize($reply);

6
02.php/app/service/Personal.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:05 * @Date: 2022-04-24 23:37:05
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-10 14:22:43 * @LastEditTime: 2022-05-11 02:15:09
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -119,7 +119,9 @@ class Personal extends Base
return message(200, 0, '用户不存在'); return message(200, 0, '用户不存在');
} }
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_passwd_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_passwd_file']);
FunFilePutContents($this->config_svn['svn_passwd_file'], $result);
$this->database->update('svn_users', [ $this->database->update('svn_users', [
'svn_user_pass' => $this->payload['newPassword'] 'svn_user_pass' => $this->payload['newPassword']

10
02.php/app/service/Svn.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:05 * @Date: 2022-04-24 23:37:05
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-09 20:52:21 * @LastEditTime: 2022-05-11 02:15:44
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -248,7 +248,9 @@ class Svn extends Base
$config = sprintf("OPTIONS=\"-r '%s' --config-file '%s' --log-file '%s' --listen-port %s --listen-host %s\"", $this->config_svn['rep_base_path'], $this->config_svn['svn_conf_file'], $this->config_svn['svnserve_log_file'], $this->payload['bindPort'], $result['bindHost']); $config = sprintf("OPTIONS=\"-r '%s' --config-file '%s' --log-file '%s' --listen-port %s --listen-host %s\"", $this->config_svn['rep_base_path'], $this->config_svn['svn_conf_file'], $this->config_svn['svnserve_log_file'], $this->payload['bindPort'], $result['bindHost']);
//写入配置文件 //写入配置文件
FunShellExec('echo \'' . $config . '\' > ' . $this->config_svn['svnserve_env_file']); // FunShellExec('echo \'' . $config . '\' > ' . $this->config_svn['svnserve_env_file']);
FunFilePutContents($this->config_svn['svnserve_env_file'], $config);
//启动svnserve //启动svnserve
$result = FunShellExec('systemctl start svnserve'); $result = FunShellExec('systemctl start svnserve');
@ -282,7 +284,9 @@ class Svn extends Base
$config = sprintf("OPTIONS=\"-r '%s' --config-file '%s' --log-file '%s' --listen-port %s --listen-host %s\"", $this->config_svn['rep_base_path'], $this->config_svn['svn_conf_file'], $this->config_svn['svnserve_log_file'], $result['bindPort'], $this->payload['bindHost']); $config = sprintf("OPTIONS=\"-r '%s' --config-file '%s' --log-file '%s' --listen-port %s --listen-host %s\"", $this->config_svn['rep_base_path'], $this->config_svn['svn_conf_file'], $this->config_svn['svnserve_log_file'], $result['bindPort'], $this->payload['bindHost']);
//写入配置文件 //写入配置文件
FunShellExec('echo \'' . $config . '\' > ' . $this->config_svn['svnserve_env_file']); // FunShellExec('echo \'' . $config . '\' > ' . $this->config_svn['svnserve_env_file']);
FunFilePutContents($this->config_svn['svnserve_env_file'], $config);
//启动svnserve //启动svnserve
$result = FunShellExec('systemctl start svnserve'); $result = FunShellExec('systemctl start svnserve');

30
02.php/app/service/Svngroup.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:05 * @Date: 2022-04-24 23:37:05
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-10 14:49:53 * @LastEditTime: 2022-05-11 02:16:31
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -183,7 +183,9 @@ class Svngroup extends Base
} }
//写入配置文件 //写入配置文件
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
//写入数据库 //写入数据库
$this->database->insert('svn_groups', [ $this->database->insert('svn_groups', [
@ -218,7 +220,9 @@ class Svngroup extends Base
return message(200, 0, '分组不存在'); return message(200, 0, '分组不存在');
} }
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
//从数据库删除 //从数据库删除
$this->database->delete('svn_groups', [ $this->database->delete('svn_groups', [
@ -263,7 +267,9 @@ class Svngroup extends Base
return message(200, 0, '文件格式错误(不存在[groups]标识)'); return message(200, 0, '文件格式错误(不存在[groups]标识)');
} }
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
return message(); return message();
} }
@ -348,7 +354,9 @@ class Svngroup extends Base
return message(200, 0, '要添加的用户已存在该分组'); return message(200, 0, '要添加的用户已存在该分组');
} }
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
return message(); return message();
} }
@ -369,7 +377,9 @@ class Svngroup extends Base
return message(200, 0, '要删除的用户不在该分组'); return message(200, 0, '要删除的用户不在该分组');
} }
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
return message(); return message();
} }
@ -401,7 +411,9 @@ class Svngroup extends Base
return message(200, 0, '存在分组循环嵌套的情况'); return message(200, 0, '存在分组循环嵌套的情况');
} }
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
return message(); return message();
} }
@ -422,7 +434,9 @@ class Svngroup extends Base
return message(200, 0, '要删除的分组不在该分组'); return message(200, 0, '要删除的分组不在该分组');
} }
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
return message(); return message();
} }

195
02.php/app/service/Svnrep.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:05 * @Date: 2022-04-24 23:37:05
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-10 14:50:26 * @LastEditTime: 2022-05-11 02:19:00
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -76,7 +76,9 @@ class Svnrep extends Base
//向authz写入仓库信息 //向authz写入仓库信息
$status = $this->SVNAdminRep->SetRepAuthz($this->authzContent, $this->payload['rep_name'], '/'); $status = $this->SVNAdminRep->SetRepAuthz($this->authzContent, $this->payload['rep_name'], '/');
if ($status != '1') { if ($status != '1') {
FunShellExec('echo \'' . $status . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $status . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $status);
} }
//写入数据库 //写入数据库
@ -174,7 +176,9 @@ class Svnrep extends Base
} }
if ($authzContet != $this->authzContent) { if ($authzContet != $this->authzContent) {
FunShellExec('echo \'' . $authzContet . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $authzContet . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $authzContet);
} }
} }
@ -234,7 +238,9 @@ class Svnrep extends Base
//写入配置文件 //写入配置文件
if ($authzContent != $this->authzContent) { if ($authzContent != $this->authzContent) {
FunShellExec('echo \'' . $authzContent . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $authzContent . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $authzContent);
} }
} }
@ -913,7 +919,9 @@ class Svnrep extends Base
} }
//写入 //写入
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
//返回 //返回
return message(); return message();
@ -936,7 +944,9 @@ class Svnrep extends Base
return message(200, 0, '已被删除'); return message(200, 0, '已被删除');
} else { } else {
//写入 //写入
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
//返回 //返回
return message(); return message();
@ -965,7 +975,9 @@ class Svnrep extends Base
} }
//写入 //写入
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
//返回 //返回
return message(); return message();
@ -1018,7 +1030,9 @@ class Svnrep extends Base
} }
//写入 //写入
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
//返回 //返回
return message(); return message();
@ -1041,7 +1055,9 @@ class Svnrep extends Base
return message(200, 0, '已被删除'); return message(200, 0, '已被删除');
} else { } else {
//写入 //写入
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
//返回 //返回
return message(); return message();
@ -1072,7 +1088,9 @@ class Svnrep extends Base
} }
//写入 //写入
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
//返回 //返回
return message(); return message();
@ -1138,7 +1156,9 @@ class Svnrep extends Base
//从配置文件删除指定仓库的所有路径 //从配置文件删除指定仓库的所有路径
$result = $this->SVNAdminRep->DelRepAuthz($this->authzContent, $this->payload['rep_name']); $result = $this->SVNAdminRep->DelRepAuthz($this->authzContent, $this->payload['rep_name']);
if ($result != '1') { if ($result != '1') {
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $result);
} }
//从数据库中删除 //从数据库中删除
@ -1393,94 +1413,119 @@ class Svnrep extends Base
return message($checkResult['code'], $checkResult['status'], $checkResult['message'], $checkResult['data']); return message($checkResult['code'], $checkResult['status'], $checkResult['message'], $checkResult['data']);
} }
clearstatcache(); $repHooks = [
if (!is_dir($this->config_svn['rep_base_path'] . $this->payload['rep_name'] . '/' . 'hooks')) { 'start_commit' => [
return message(200, 0, '仓库不存在或文件损坏'); 'fileName' => 'start-commit',
} 'hasFile' => false,
'con' => '',
$hooks_type_list = [ 'tmpl' => ''
"start-commit" => [
"value" => "start-commit",
"label" => "start-commit---事务创建前",
"shell" => ""
], ],
"pre-commit" => [ 'pre_commit' => [
"value" => "pre-commit", 'fileName' => 'pre-commit',
"label" => "pre-commit---事务提交前", 'hasFile' => false,
"shell" => "" 'con' => '',
'tmpl' => ''
], ],
"post-commit" => [ 'post_commit' => [
"value" => "post-commit", 'fileName' => 'post-commit',
"label" => "post-commit---事务提交后", 'hasFile' => false,
"shell" => "" 'con' => '',
'tmpl' => ''
], ],
"pre-lock" => [ 'pre_lock' => [
"value" => "pre-lock", 'fileName' => 'pre-lock',
"label" => "pre-lock---锁定文件前", 'hasFile' => false,
"shell" => "" 'con' => '',
'tmpl' => ''
], ],
"post-lock" => [ 'post_lock' => [
"value" => "post-lock", 'fileName' => 'post-lock',
"label" => "post-lock---锁定文件后", 'hasFile' => false,
"shell" => "" 'con' => '',
'tmpl' => ''
], ],
"pre-unlock" => [ 'pre_unlock' => [
"value" => "pre-unlock", 'fileName' => 'pre-unlock',
"label" => "pre-unlock---解锁文件前", 'hasFile' => false,
"shell" => "" 'con' => '',
'tmpl' => ''
], ],
"post-unlock" => [ 'post_unlock' => [
"value" => "post-unlock", 'fileName' => 'post-unlock',
"label" => "post-unlock---解锁文件后", 'hasFile' => false,
"shell" => "" 'con' => '',
'tmpl' => ''
], ],
"pre-revprop-change" => [ 'pre_revprop_change' => [
"value" => "pre-revprop-change", 'fileName' => 'pre-revprop-change',
"label" => "pre-revprop-change---修改修订版属性前", 'hasFile' => false,
"shell" => "" 'con' => '',
'tmpl' => ''
], ],
"post-revprop-change" => [ 'post_revprop_change' => [
"value" => "post-revprop-change", 'fileName' => 'post-revprop-change',
"label" => "post-revprop-change---修改修订版属性后", 'hasFile' => false,
"shell" => "" 'con' => '',
'tmpl' => ''
], ],
]; ];
$hooks_file_list = [ $hooksPath = $this->config_svn['rep_base_path'] . $this->payload['rep_name'] . '/hooks/';
'start-commit',
'pre-commit', if (!is_dir($hooksPath)) {
'post-commit', return message(200, 0, '该仓库不存在hooks文件夹');
'pre-lock', }
'post-lock',
'pre-unlock', foreach ($repHooks as $key => $value) {
'post-unlock', if (file_exists($hooksPath . $value['fileName'])) {
'pre-revprop-change', $repHooks[$key]['hasFile'] = true;
'post-revprop-change' $temp = FunShellExec(sprintf("cat '%s'", $hooksPath . $value['fileName']));
]; $repHooks[$key]['con'] = $temp['result'];
}
if (file_exists($hooksPath . $value['fileName'] . '.tmpl')) {
$temp = FunShellExec(sprintf("cat '%s'", $hooksPath . $value['fileName'] . '.tmpl'));
$repHooks[$key]['tmpl'] = $temp['result'];
}
}
$file_arr = scandir($this->config_svn['rep_base_path'] . $this->payload['rep_name'] . '/' . 'hooks'); return message(200, 1, '成功', $repHooks);
}
foreach ($file_arr as $file_item) { /**
if ($file_item != '.' && $file_item != '..') { * 移除仓库钩子
if (in_array($file_item, $hooks_file_list)) { */
$temp = FunShellExec(sprintf("cat '%s'", $this->config_svn['rep_base_path'] . $this->payload['rep_name'] . '/' . 'hooks' . '/' . $file_item)); public function DelRepHook()
$hooks_type_list[$file_item]['shell'] = $temp['result']; {
$hooks_type_list[$file_item]['shell'] = trim($hooks_type_list[$file_item]['shell']); //检查仓库是否存在
$checkResult = $this->SVNAdminRep->CheckRepCreate($this->payload['rep_name'], '仓库不存在');
if ($checkResult['status'] != 1) {
return message($checkResult['code'], $checkResult['status'], $checkResult['message'], $checkResult['data']);
} }
$hooksPath = $this->config_svn['rep_base_path'] . $this->payload['rep_name'] . '/hooks/';
if (!is_dir($hooksPath)) {
return message(200, 0, '该仓库不存在hooks文件夹');
} }
if (!file_exists($hooksPath . $this->payload['fileName'])) {
return message(200, 0, '已经移除该仓库钩子');
} }
return message(200, 1, '成功', $hooks_type_list); FunShellExec(sprintf("cd '%s' && rm -f ./'%s'", $hooksPath, $this->payload['fileName']));
return message(200, 1, '移除成功');
} }
/** /**
* 修改仓库的钩子内容(针对单个钩子) * 修改仓库的某个钩子内容
*/ */
public function EditRepHook() public function EditRepHook()
{ {
$cmd = sprintf("echo '%s' > '%s'", trim($this->payload['content']), $this->config_svn['rep_base_path'] . $this->payload['rep_name'] . '/hooks/' . $this->payload['type']); $hooksPath = $this->config_svn['rep_base_path'] . $this->payload['rep_name'] . '/hooks/';
FunShellExec($cmd); //使用echo写入文件 当出现不规则的不成对的 ' " 等会出问题 当然也会包括其他问题
FunFilePutContents($hooksPath . $this->payload['fileName'],$this->payload['content']);
return message(); return message();
} }

26
02.php/app/service/Svnuser.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:05 * @Date: 2022-04-24 23:37:05
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-10 14:50:05 * @LastEditTime: 2022-05-11 02:21:30
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -166,7 +166,9 @@ class Svnuser extends Base
return message(200, 0, '要启用的用户不存在'); return message(200, 0, '要启用的用户不存在');
} }
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_passwd_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_passwd_file']);
FunFilePutContents($this->config_svn['svn_passwd_file'], $result);
return message(); return message();
} }
@ -184,7 +186,9 @@ class Svnuser extends Base
return message(200, 0, '要禁用的用户不存在'); return message(200, 0, '要禁用的用户不存在');
} }
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_passwd_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_passwd_file']);
FunFilePutContents($this->config_svn['svn_passwd_file'], $result);
return message(); return message();
} }
@ -229,7 +233,9 @@ class Svnuser extends Base
} }
//写入配置文件 //写入配置文件
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_passwd_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_passwd_file']);
FunFilePutContents($this->config_svn['svn_passwd_file'], $result);
//写入数据库 //写入数据库
$this->database->insert('svn_users', [ $this->database->insert('svn_users', [
@ -269,7 +275,9 @@ class Svnuser extends Base
} }
//写入配置文件 //写入配置文件
FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_passwd_file']); // FunShellExec('echo \'' . $result . '\' > ' . $this->config_svn['svn_passwd_file']);
FunFilePutContents($this->config_svn['svn_passwd_file'], $result);
//写入数据库 //写入数据库
$this->database->update('svn_users', [ $this->database->update('svn_users', [
@ -308,9 +316,13 @@ class Svnuser extends Base
'svn_user_name' => $this->payload['svn_user_name'] 'svn_user_name' => $this->payload['svn_user_name']
]); ]);
FunShellExec('echo \'' . $resultAuthz . '\' > ' . $this->config_svn['svn_authz_file']); // FunShellExec('echo \'' . $resultAuthz . '\' > ' . $this->config_svn['svn_authz_file']);
FunFilePutContents($this->config_svn['svn_authz_file'], $resultAuthz);
// FunShellExec('echo \'' . $resultPasswd . '\' > ' . $this->config_svn['svn_passwd_file']);
FunShellExec('echo \'' . $resultPasswd . '\' > ' . $this->config_svn['svn_passwd_file']); FunFilePutContents($this->config_svn['svn_passwd_file'], $resultPasswd);
//日志 //日志
$this->Logs->InsertLog( $this->Logs->InsertLog(

33
02.php/server/svnadmind.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:06 * @Date: 2022-04-24 23:37:06
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-09 22:30:20 * @LastEditTime: 2022-05-11 01:54:56
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -129,22 +129,27 @@ class Daemon
private function HandleRequest($client) private function HandleRequest($client)
{ {
//接收客户端发送的数据 //接收客户端发送的数据
$cmmand = socket_read($client, $this->config_daemon['SOCKET_READ_LENGTH']); $receive = socket_read($client, $this->config_daemon['SOCKET_READ_LENGTH']);
$receive = unserialize($receive);
$type = $receive['type'];
$content = $receive['content'];
//console模式 //console模式
if ($this->workMode == 'console') { if ($this->workMode == 'console') {
echo PHP_EOL . '---------receive---------' . PHP_EOL; echo PHP_EOL . '---------receive---------' . PHP_EOL;
echo $cmmand . PHP_EOL; print_r($receive);
} }
if (trim($cmmand) != '') { if ($type == 'passthru') {
if (trim($content) != '') {
//定义错误输出文件路径 //定义错误输出文件路径
$stderrFile = $this->config_svn['temp_base_path'] . uniqid(); $stderrFile = $this->config_svn['temp_base_path'] . uniqid();
//将标准错误重定向到文件 //将标准错误重定向到文件
//使用状态码来标识错误信息 //使用状态码来标识错误信息
ob_start(); ob_start();
passthru($cmmand . " 2>$stderrFile", $resultCode); passthru($content . " 2>$stderrFile", $resultCode);
$buffer = ob_get_contents(); $buffer = ob_get_contents();
ob_end_clean(); ob_end_clean();
@ -165,6 +170,24 @@ class Daemon
'error' => '' 'error' => ''
]; ];
} }
} else if ($type == 'file_put_contents') {
if ($content['flags'] == 0) {
file_put_contents($content['filename'], $content['data']);
} else {
file_put_contents($content['filename'], $content['data'], $content['flags'], $content['context']);
}
$result = [
'resultCode' => 0,
'result' => '',
'error' => ''
];
} else {
$result = [
'resultCode' => 0,
'result' => '',
'error' => ''
];
}
//console模式 //console模式
if ($this->workMode == 'console') { if ($this->workMode == 'console') {

Loading…
Cancel
Save