svnhooks--分路径锁定仓库
在之前的文章简单的实现了锁定仓库已经授予用户权限提交文件,但是在实际项目中,有时候我们是要锁定资源路径,不允许提交资源了,但是还可以提交配置和代码,那就需要通过分路径锁定。
实现方式和思路也是借助pre-commit,我们先在程序里面定义一个字典,简单点我们就不用数据库了,数据先初始化先用一个json文件初始化,里面的key就是路径地址,value就是锁定状态。
在pre-commit的时候获取本次提交的所有路径,然后在程序里面做一个请求方法,获取路劲的value,再做一个更新路径状态的方法就差不多了,还需要把路劲状态和总开关联动起来,总开关打开就全部路径的状态都开,关闭就全部路径都关闭
客户端呢就做一个子开关,如果总开关打开了,子开关就动态显示当前子路径的状态,下面就是大概效果
下面就是pre-commit的核心判断代码,主要就是在判断到当前总开关打开后,先默认设置当前所有路径都是可以提交的,然后获取本次提交的路径,向服务端请求提交状态,只要有一个路径不允许提交,本次提交就需要判断用户权限
while true; do COMMIT_SWITCH=$(curl -s --max-time 3 http://192.168.61.116:5000/get_switch | jq -r '.commit_switch' 2>/dev/null) CURL_EXIT_CODE=$? if [ $CURL_EXIT_CODE -eq 0 ] && [ -n "$COMMIT_SWITCH" ]; then echo "获取成功,commit_switch 的值: $COMMIT_SWITCH" # 检查 commit_switch 的值 if [ "$COMMIT_SWITCH" = "true" ]; then # 获取当前提交的所有文件路径 CHANGED_FILES=$($SVNLOOK changed -t $TXN $REPOS | awk '{print \$2}') # 标志位,判断是否所有路径都可以提交 ALL_PATHS_ALLOWED=false for FILE_PATH in $CHANGED_FILES; do # 检查该路径的提交状态 PATH_STATUS=$(curl -s "http://xxxxx:5000/get_path_status?path=$FILE_PATH" | jq -r '.status') if [ "$PATH_STATUS" = "true" || [ "$PATH_STATUS" = "error" ];]; then #本次提交有一个路劲的文件被锁了,或者报错了本次提交状态就需要判断用户权限 ALL_PATHS_ALLOWED=true break fi done # 如果所有路径都允许提交,检查用户权限 if [ "$ALL_PATHS_ALLOWED" = true ]; then USERNAME=$($SVNLOOK author -t $TXN $REPOS) # 获取用户权限 USER_PERMISSIONS=$(curl -s http://xxxxx:5000/api/users2 | jq -r ".\"$USERNAME\"") if [ "$USER_PERMISSIONS" = "null" ]; then echo "提交被拒绝,SVN仓库已锁定,用户 $USERNAME 不存在。请联系QA更新名单,授予权限" >&2 exit 1 # 不允许提交 fi # 检查用户权限 if [ "$USER_PERMISSIONS" = "true" ]; then exit 0 # 允许提交 else echo "提交被拒绝,SVN仓库已锁定,用户 $USERNAME 没有权限,请联系QA授予权限。" >&2 exit 1 # 不允许提交 fi else echo "所有路径状态为 false,直接允许提交,无需验证用户权限。" exit 0 # 允许提交 fi fi #如果COMMIT_SWITCH是false,就是开关被关闭,允许提交 exit 0 fi # 检查是否超时 CURRENT_TIME=$(date +%s) ELAPSED_TIME=$((CURRENT_TIME - START_TIME)) if [ $ELAPSED_TIME -ge $TIMEOUT ]; then echo "超时了,获取失败。" exit 0 # 超时,允许提交 fi # 等待一段时间后重试 sleep 1 done
服务端的一些核心代码
#获取不同路径的提交状态 @app.route('/get_path_status', methods=['GET']) def get_path_status(): path = request.args.get('path') if not path: return jsonify({'status': 'error', 'message': '路径不能为空'}), 400 with open(PATH_STATUS_FILE, 'r') as f: path_status = json.load(f) # 检查路径的前缀 status = True for key in path_status.keys(): if path.startswith(key): # 判断路径是否以某个大路径开头 status = path_status[key] break return jsonify({'status': str(status).lower()}), 200 #获取所有路劲的状态 @app.route('/get_path', methods=['GET']) def get_path(): with open('path_status.json') as f: pathStatus = json.load(f) return jsonify(pathStatus) #更改不同路径的提交状态 @app.route('/update_path_status', methods=['POST']) def update_path_status(): new_status = request.json # 更新 JSON 文件的逻辑 with open('path_status.json', 'w') as f: json.dump(new_status, f) # 通知所有连接的客户端刷新页面 socketio.emit('refresh_page') return jsonify(success=True)