shell

Git shell for sbi.re
Log | Files | Refs | README

commit 928854bcb5538241fc1e18f3a446ace4af5cd8e5
parent b1a052aab64511e2ac6dfd0efae4acbcfe4b60c1
Author: flupe <flupe@sbi.re>
Date:   Fri, 19 Nov 2021 10:23:45 +0100

added command for updating description

Diffstat:
MREADME.md | 20+++++++++-----------
Mshell.py | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 69 insertions(+), 17 deletions(-)

diff --git a/README.md b/README.md @@ -42,7 +42,15 @@ SSH-ing as git user will drop you into a custom shell: You can also run one-off commands directly: - $ ssh git@sbi.re keys + $ ssh git@sbi.re cmd + +### Change description of repository + +Provided you have access to `myrepo`, you can read and set its description with +the following command: + + $ ssh git@sbi.re desc myrepo + $ ssh git@sbi.re desc myrepo "A new description for the repo" ### Managing SSH keys @@ -50,13 +58,3 @@ You can also run one-off commands directly: $ cat ~/.ssh/mykey.pub > ssh git@sbi.re keys add mykey $ ssh git@sbi.re keys remove myoldkey -### Change description of repository - -Provided you have access to `myrepo`, you can set its description with the -following command: - - $ ssh git@sbi.re desc myrepo "A description for the repo" - -### TODO - - $ ssh user@sbi.re desc myrepo This is a repo of me diff --git a/shell.py b/shell.py @@ -5,12 +5,21 @@ import os import subprocess import shlex import cmd +from glob import glob from os.path import basename, splitext, isfile, isdir, join import policy +from policy import BASEDIR -USERS = os.path.expanduser('~/users') +USERS = os.path.expanduser('~/users') TEMPLATE = os.path.expanduser('~/template') +REPOS = os.path.expanduser('~/repositories') + +# STAGIT CONFIG +HTMLDIR = '/var/lib/www/git' +CACHEFILE = '.htmlcache' +COMMITS = 100 +BASEURL = 'https://git.sbi.re' def die(msg, status=1): sys.stderr.write(msg) @@ -19,6 +28,26 @@ def die(msg, status=1): sys.stdout.flush() sys.exit(status) +def git(*args): + return (subprocess + .run(['git', *args], capture_output=True, encoding='utf-8') + .stdout) + +def stagit(repo): + path = join(policy.BASEDIR, repo) + + outdir = join(HTMLDIR, repo) + os.makedirs(outdir, exist_ok=True) + + # change current dir and generate html + os.chdir(outdir) + subprocess.run(['stagit', '-l', str(COMMITS), '-u', BASEURL , path]) + + # render index again + with open(join(HTMLDIR, 'index.html'), 'w') as index: + files = sorted(glob(join(REPOS, '*'))) + subprocess.run(['stagit-index', *files], stdout=index) + def do_git_receive_pack(user, cmd, args): if len(args) < 1: @@ -34,11 +63,11 @@ def do_git_receive_pack(user, cmd, args): if not policy.CREATE & perm: die('error: sorry %s, %s does not exist and you are not allowed to create it' % (user, repo)) subprocess.run( - [ 'git', 'init', '--bare', + [ 'git', 'init', '--bare', '--template=%s' % TEMPLATE, path, ], - stdout=sys.stderr.buffer + stdout=sys.stderr.buffer, ) sys.stderr.write('info: created new repo %s' % repo) @@ -77,6 +106,7 @@ def do_git_upload_archive(user, cmd, args): os.execvp('git-upload-archive', ['git-upload-archive', *args[:-1], path]) def do_keys(user, cmd, args): + """List authorized SSH keys for current user""" sys.stdout.write('You currently allow the following SSH keys:\n') for path in os.listdir(os.path.join(USERS, user)): abs_path = join(USERS, user, path) @@ -85,8 +115,31 @@ def do_keys(user, cmd, args): key_name, _ = splitext(path) sys.stdout.write('%s: %s\n' % (key_name, key.read())) +def do_desc(user, cmd, args): + """Get/set description of repository""" + if len(args) < 1: + do_help(user, 'help', []) + return + repo = args[0] + path = os.path.join(policy.BASEDIR, repo) + perm = policy.get_perm(user, repo) + + if not policy.READ & perm: + sys.stderr.write('Sorry %s, you are not allowed to access %s' % (user, repo)) + return + + if len(args) == 2: + with open(join(path, 'description'), 'w') as desc: + desc.write('%s\n' % args[1]) + stagit(repo) + else: + with open(join(path, 'description'), 'r') as desc: + sys.stdout.write(desc.read()) + def do_help(user, cmd, args): - sys.stdout.write('Need help?\n') + """Print all available commands""" + for key, func in SHELL_COMMANDS.items(): + sys.stdout.write('%s:\n %s\n' % (key, func.__doc__)) def do_unknown(user, cmd, args): die('Sorry %s, I don\'t know the command `%s` :(.' % (user, cmd), status=1) @@ -94,13 +147,14 @@ def do_unknown(user, cmd, args): SHELL_COMMANDS = { 'keys': do_keys, + 'desc': do_desc, 'help': do_help, } COMMANDS = { **SHELL_COMMANDS, - 'git-receive-pack': do_git_receive_pack, - 'git-upload-pack': do_git_upload_pack, + 'git-receive-pack': do_git_receive_pack, + 'git-upload-pack': do_git_upload_pack, 'git-upload-archive': do_git_upload_archive, }