mirror of
https://github.com/aljazceru/gitpear.git
synced 2025-12-17 14:14:22 +01:00
20
src/acl.js
Normal file
20
src/acl.js
Normal file
@@ -0,0 +1,20 @@
|
||||
const home = require('./home')
|
||||
|
||||
const roles = {
|
||||
admin: {
|
||||
description: 'Read and write to all branches',
|
||||
},
|
||||
contributor: {
|
||||
description: 'Read and write to all branches except protected ones',
|
||||
},
|
||||
viewer: {
|
||||
description: 'Read all branches',
|
||||
},
|
||||
}
|
||||
const DEFAULT_ACL = {
|
||||
visibibility: 'public', // public|private
|
||||
protectedBranches: ['master'],
|
||||
ACL: {}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ const crypto = require('hypercore-crypto')
|
||||
|
||||
const git = require('./git.js')
|
||||
const home = require('./home')
|
||||
const acl = require('./acl')
|
||||
const auth = require('./auth')
|
||||
|
||||
const fs = require('fs')
|
||||
|
||||
@@ -42,7 +42,7 @@ swarm.on('connection', async (socket) => {
|
||||
|
||||
let payload = { body: { url, method: 'get-repos' } }
|
||||
if (process.env.GIT_PEAR_AUTH) {
|
||||
payload.header = await acl.getToken(payload.body)
|
||||
payload.header = await auth.getToken(payload.body)
|
||||
}
|
||||
|
||||
const reposRes = await rpc.request('get-repos', Buffer.from(JSON.stringify(payload)))
|
||||
@@ -71,10 +71,9 @@ swarm.on('connection', async (socket) => {
|
||||
|
||||
await drive.core.update({ wait: true })
|
||||
|
||||
// TODO: ACL
|
||||
payload = { body: { url, method: 'get-refs', data: repoName }}
|
||||
if (process.env.GIT_PEAR_AUTH) {
|
||||
payload.header = await acl.getToken(payload.body)
|
||||
payload.header = await auth.getToken(payload.body)
|
||||
}
|
||||
const refsRes = await rpc.request('get-refs', Buffer.from(JSON.stringify(payload)))
|
||||
|
||||
@@ -128,7 +127,7 @@ async function talkToGit (refs, drive, repoName, rpc, commit) {
|
||||
method
|
||||
} }
|
||||
if (process.env.GIT_PEAR_AUTH) {
|
||||
payload.header = await acl.getToken(payload.body)
|
||||
payload.header = await auth.getToken(payload.body)
|
||||
}
|
||||
const res = await rpc.request(method, Buffer.from(JSON.stringify(payload)))
|
||||
|
||||
|
||||
36
src/home.js
36
src/home.js
@@ -10,38 +10,10 @@ function createAppFolder (name) {
|
||||
fs.mkdirSync(`${APP_HOME}/${name}/code`, { recursive: true })
|
||||
}
|
||||
|
||||
function shareAppFolder (name, entry) {
|
||||
const p = `${APP_HOME}/${name}/.git-daemon-export-ok`
|
||||
fs.openSync(p, 'a')
|
||||
const aclFile = fs.readFileSync(p, 'utf8')
|
||||
const aclJson = JSON.parse(aclFile || '{ "protectedBranches": ["master"], "ACL": {}}')
|
||||
|
||||
let [userId = '*', permissions = 'r', branch = '*'] = entry?.split(':') || []
|
||||
|
||||
if (!aclJson.ACL[userId]) aclJson.ACL[userId] = { [branch]: permissions }
|
||||
fs.writeFileSync(p, JSON.stringify(aclJson))
|
||||
function shareAppFolder (name) {
|
||||
fs.openSync(`${APP_HOME}/${name}/.git-daemon-export-ok`, 'w')
|
||||
}
|
||||
|
||||
function addProtectedBranch (name, branch) {
|
||||
const aclFile = fs.readFileSync(`${APP_HOME}/${name}/.git-daemon-export-ok`, 'utf8')
|
||||
const aclJson = JSON.parse(aclFile || '{ "protectedBranches": [], "ACL": {}}')
|
||||
if (!aclJson.protectedBranches.includes(branch)) aclJson.protectedBranches.push(branch)
|
||||
fs.writeFileSync(aclFile, JSON.stringify(aclJson))
|
||||
}
|
||||
|
||||
function removeProtectedBranch (name, branch) {
|
||||
const aclFile = fs.readFileSync(`${APP_HOME}/${name}/.git-daemon-export-ok`, 'a')
|
||||
const aclJson = JSON.parse(aclFile || '{ "protectedBranches": [], "ACL": {}}')
|
||||
aclJson.protectedBranches = aclJson.protectedBranches.filter(b => b !== branch)
|
||||
fs.writeFileSync(aclFile, JSON.stringify(aclJson))
|
||||
}
|
||||
|
||||
function removeUserFromACL (name, userId) {
|
||||
const aclFile = fs.readFileSync(`${APP_HOME}/${name}/.git-daemon-export-ok`, 'a')
|
||||
const aclJson = JSON.parse(aclFile || '{ "protectedBranches": [], "ACL": {}}')
|
||||
delete aclJson.ACL[userId]
|
||||
fs.writeFileSync(aclFile, JSON.stringify(aclJson))
|
||||
}
|
||||
|
||||
function unshareAppFolder (name) {
|
||||
fs.unlinkSync(`${APP_HOME}/${name}/.git-daemon-export-ok`)
|
||||
@@ -57,10 +29,6 @@ function isShared (name) {
|
||||
|
||||
function getACL (name) {
|
||||
if (!fs.existsSync(`${APP_HOME}/${name}/.git-daemon-export-ok`)) throw new Error('Repo is not shared')
|
||||
|
||||
const aclFile = fs.readFileSync(`${APP_HOME}/${name}/.git-daemon-export-ok`, 'utf8')
|
||||
aclJson = JSON.parse(aclFile || '{ "protectedBranches": [], "ACL": {}}')
|
||||
return aclJson
|
||||
}
|
||||
|
||||
function list (sharedOnly) {
|
||||
|
||||
16
src/rpc.js
16
src/rpc.js
@@ -1,7 +1,7 @@
|
||||
const ProtomuxRPC = require('protomux-rpc')
|
||||
const { spawn } = require('child_process')
|
||||
const home = require('./home')
|
||||
const acl = require('./acl')
|
||||
const auth = require('./auth')
|
||||
|
||||
module.exports = class RPC {
|
||||
constructor (announcedRefs, repositories, drives) {
|
||||
@@ -98,7 +98,7 @@ module.exports = class RPC {
|
||||
})
|
||||
}
|
||||
|
||||
async parseReq(publicKey, req, access, branch = '*') {
|
||||
async parseReq(publicKey, req) {
|
||||
if (!req) throw new Error('Request is empty')
|
||||
let request = JSON.parse(req.toString())
|
||||
const parsed = {
|
||||
@@ -116,22 +116,12 @@ module.exports = class RPC {
|
||||
if (process.env.GIT_PEAR_AUTH === 'naitive') {
|
||||
userId = publicKey
|
||||
} else {
|
||||
userId = (await acl.getId({ ...request.body, payload: request.header })).userId
|
||||
userId = (await auth.getId({ ...request.body, payload: request.header })).userId
|
||||
}
|
||||
const aclObj = home.getACL(parsed.repoName)
|
||||
const userACL = aclObj[userId] || aclObj['*']
|
||||
if (!userACL) throw new Error('You are not allowed to access this repo')
|
||||
|
||||
if (aclObj.protectecBranches.includes(branch)) {
|
||||
// protected branch must have exaplicit access grant
|
||||
if (access === 'w') {
|
||||
|
||||
} else {
|
||||
//
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
return parsed
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user