refactor(zddc): extract writeAutoOwnZddc into zddc.WriteAutoOwnZddc
Pure refactor. The mkdir post-hook in handler/fileapi.go duplicated zddc-package types; lifting the body into the package itself lets the upcoming EnsureCanonicalAncestors helper share it without re-exposing the file API's internals. No behaviour change. The grant shape (creator email → rwcda + CreatedBy audit field) and the atomic-write path through zddc.WriteFile are unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5fa5d13b10
commit
a471de8788
2 changed files with 23 additions and 14 deletions
|
|
@ -526,7 +526,7 @@ func serveFileMkdir(cfg config.Config, w http.ResponseWriter, r *http.Request) {
|
||||||
if email := EmailFromContext(r); email != "" {
|
if email := EmailFromContext(r); email != "" {
|
||||||
parentName := filepath.Base(filepath.Dir(abs))
|
parentName := filepath.Base(filepath.Dir(abs))
|
||||||
if zddc.IsAutoOwnParent(parentName) {
|
if zddc.IsAutoOwnParent(parentName) {
|
||||||
if err := writeAutoOwnZddc(abs, email); err != nil {
|
if err := zddc.WriteAutoOwnZddc(abs, email); err != nil {
|
||||||
slog.Warn("auto-own .zddc write failed", "path", abs, "err", err)
|
slog.Warn("auto-own .zddc write failed", "path", abs, "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -537,19 +537,6 @@ func serveFileMkdir(cfg config.Config, w http.ResponseWriter, r *http.Request) {
|
||||||
auditFile(r, "mkdir", cleanURL, http.StatusCreated, 0, nil)
|
auditFile(r, "mkdir", cleanURL, http.StatusCreated, 0, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeAutoOwnZddc serializes a creator-grant .zddc into newDir.
|
|
||||||
// Marshals via the same yaml encoder ParseFile reads (round-trip
|
|
||||||
// guaranteed) and writes atomically via zddc.WriteAtomic.
|
|
||||||
func writeAutoOwnZddc(newDir, email string) error {
|
|
||||||
zf := zddc.ZddcFile{
|
|
||||||
ACL: zddc.ACLRules{
|
|
||||||
Permissions: map[string]string{email: "rwcda"},
|
|
||||||
},
|
|
||||||
CreatedBy: email,
|
|
||||||
}
|
|
||||||
return zddc.WriteFile(newDir, zf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// auditFile emits a structured log line for each file API operation.
|
// auditFile emits a structured log line for each file API operation.
|
||||||
// AccessLogMiddleware already logs every request — this adds an
|
// AccessLogMiddleware already logs every request — this adds an
|
||||||
// op-tagged line so audit consumers can filter by operation without
|
// op-tagged line so audit consumers can filter by operation without
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,28 @@ var AutoOwnFolderNames = []string{"Incoming", "Working", "Staging"}
|
||||||
// Deprecated: use PartyFolders + IsWormPath.
|
// Deprecated: use PartyFolders + IsWormPath.
|
||||||
var WormFolderNames = []string{"Issued", "Received"}
|
var WormFolderNames = []string{"Issued", "Received"}
|
||||||
|
|
||||||
|
// WriteAutoOwnZddc serialises a creator-grant .zddc into dir, granting
|
||||||
|
// principalEmail rwcda and recording it in CreatedBy. Used by the file
|
||||||
|
// API's mkdir post-hook (and by EnsureCanonicalAncestors) to seed
|
||||||
|
// ownership when a new auto-own folder is materialised.
|
||||||
|
//
|
||||||
|
// The grant is identical to what an operator would write by hand —
|
||||||
|
// direct email pattern, "rwcda" verb set — so the creator can later
|
||||||
|
// edit the file normally to add collaborators.
|
||||||
|
//
|
||||||
|
// Atomic: marshals via the same yaml encoder ParseFile reads
|
||||||
|
// (round-trip guaranteed) and writes via zddc.WriteFile (which
|
||||||
|
// performs an atomic temp-write + rename via zddc.WriteAtomic).
|
||||||
|
func WriteAutoOwnZddc(dir, principalEmail string) error {
|
||||||
|
zf := ZddcFile{
|
||||||
|
ACL: ACLRules{
|
||||||
|
Permissions: map[string]string{principalEmail: "rwcda"},
|
||||||
|
},
|
||||||
|
CreatedBy: principalEmail,
|
||||||
|
}
|
||||||
|
return WriteFile(dir, zf)
|
||||||
|
}
|
||||||
|
|
||||||
// ResolveCanonical returns the on-disk name of the canonical folder
|
// ResolveCanonical returns the on-disk name of the canonical folder
|
||||||
// 'logical' (lowercase) inside parentDir, or "" if no case variant
|
// 'logical' (lowercase) inside parentDir, or "" if no case variant
|
||||||
// exists. Caller decides whether to MkdirAll(parentDir+"/"+logical)
|
// exists. Caller decides whether to MkdirAll(parentDir+"/"+logical)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue