gitoria
All repositories: gitoria
2.6 KB
// sshgate.hl — WHAT THE SSHD CONTAINER ASKS THIS APP (ticket gitoria#7; docker/sshd). Two internal function routes, only for the// container: every request must carry the shared secret (`X-Gitoria-Secret` = GITORIA_SSH_SECRET); without the secret set they// do not exist (404), and a request that came through the public proxy (it carries X-Forwarded-For / X-Real-IP) is refused.// GET /__git/keys?type=<ssh-ed25519>&key=<base64> sshd AuthorizedKeysCommand: the authorized_keys line for a known key// (`restrict,command="gitoria-shell <user id>" <type> <key>`), empty for an unknown one// GET /__git/access?user=<id>&slug=<slug>&write=0|1 gitoria-shell before it starts git: `ok` or 403. Read = every repo (public);// write = the repo's owner only — the same rule as the token on HTTPS (transport.hl)import { Response } from 'hl:http1'import { slugError, repoBySlug } from './repos.hl'import { userRecord } from './users.hl'import { sshSecret, sshEnabled, userOfKey } from './sshkeys.hl'static NL = ""static reply = (status, text) => {return new Response(text, { status = status headers = { 'Content-Type' = 'text/plain; charset=utf-8' 'Cache-Control' = 'no-store' } })}// null when the caller may ask, else the refusing answerstatic guard = (req) => {if (!sshEnabled) { return reply(404, 'not found' + NL) }if (req.method != 'GET') { return reply(405, 'GET only' + NL) }if (req.headers['x-forwarded-for'] != null || req.headers['x-real-ip'] != null) { return reply(403, 'internal only' + NL) }let given = req.headers['x-gitoria-secret']if (given == null || hlTypeName(given) != 'String' || given != sshSecret) { return reply(403, 'wrong secret' + NL) }return null}static gitKeys = (route, req) => {let no = guard(req)if (no != null) { return no }let q = req.query != null ? req.query : {}let userId = userOfKey(q.type, q.key)if (userId == null || userRecord(userId) == null) { return reply(200, '') }return reply(200, 'restrict,command="/usr/local/bin/gitoria-shell ' + userId + '" ' + q.type + ' ' + q.key + NL)}static gitAccess = (route, req) => {let no = guard(req)if (no != null) { return no }let q = req.query != null ? req.query : {}let slug = q.slugif (slug == null || hlTypeName(slug) != 'String' || slugError(slug) != null) { return reply(404, 'no such repository' + NL) }let repo = repoBySlug(slug)if (repo == null) { return reply(404, 'no such repository' + NL) }if (q.write == '1') {if (userRecord(q.user) == null || repo.owner != q.user) { return reply(403, 'only the owner of this repository can push to it' + NL) }}return reply(200, 'ok' + NL)}
Branches
- mainmain branch
Latest commits
- 68dcb603deploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
- e2deed6dgitoria#20: "Add code" only on the Code page of an empty repository, no collapsiblemre
- 8bb97ffddeploy.sh: never send .git or .gitignore to Byrodinmre
- fd981932State of 2026-09-27; bin/ no longer tracked (Hybriel commit is in README)mre
- 4a2d7125initial commitmre