vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
|
c717d4eb
Keenan Nemetz
13d ago
|
1 | package web |
| 2 | ||
|
b1499c72
Keenan Nemetz
12d ago
|
3 | // The audit log. Vole records every privileged action in one tab-separated |
| 4 | // shape, so one file answers "who did this" whether the change arrived over SSH, | |
| 5 | // from the CLI, or from a form. internal/audit owns the shape and the escaping; | |
| 6 | // this file is only the web's way in. | |
|
c717d4eb
Keenan Nemetz
13d ago
|
7 | // |
|
b1499c72
Keenan Nemetz
12d ago
|
8 | // A write failure is reported to the server log at error level and nothing else: |
| 9 | // the action has already happened, and refusing the response would not undo it. | |
| 10 | // The acts that must fail closed — account, key and ACL changes, and a repository | |
| 11 | // deletion — are recorded before they happen by the store they go through | |
| 12 | // (forge/identity, forge/access, forge/repo), so a request that could not be | |
| 13 | // recorded never reaches this file's callers. | |
|
c717d4eb
Keenan Nemetz
13d ago
|
14 | |
| 15 | import ( | |
|
d37d301f
Keenan Nemetz
15h ago
|
16 | "rodent.software/vole/internal/audit" |
|
c717d4eb
Keenan Nemetz
13d ago
|
17 | ) |
| 18 | ||
|
b1499c72
Keenan Nemetz
12d ago
|
19 | // audit appends one record for an action that has already been taken. A failure |
| 20 | // is loud, never silent, and never changes the answer the browser already earned. | |
| 21 | func (w *Web) audit(action, actor, subject, detail string) { | |
| 22 | path := "" | |
| 23 | if w.Cfg != nil { | |
| 24 | path = w.Cfg.AuditLog() | |
|
c717d4eb
Keenan Nemetz
13d ago
|
25 | } |
|
b1499c72
Keenan Nemetz
12d ago
|
26 | if err := audit.Append(path, audit.Record{ |
| 27 | Action: action, | |
| 28 | Actor: actor, | |
| 29 | Subject: subject, | |
| 30 | Detail: detail, | |
| 31 | }); err != nil { | |
| 32 | if w.Logger != nil { | |
| 33 | w.Logger("audit log write failed: action=%s account=%s subject=%s: %v", | |
| 34 | action, actor, subject, err) | |
| 35 | } | |
|
c717d4eb
Keenan Nemetz
13d ago
|
36 | } |
|
eb07ff56
Keenan Nemetz
8d ago
|
37 | // A browser write commits to the metadata branch directly, without a push for the |
| 38 | // post-receive hook to observe. Nudging the event loop after every audited write | |
| 39 | // is cheap: it compares a cursor and does nothing when no metadata changed. | |
| 40 | if w.MetadataChanged != nil { | |
| 41 | w.MetadataChanged(subject) | |
| 42 | } | |
|
c717d4eb
Keenan Nemetz
13d ago
|
43 | } |