feat(samba): Megosztas page + guarded folder picker (R-7 slice 1, Part 3)
New top-nav category with the Halozati megosztas page: enable/server-name card, household password, shares table (Nev/Mappa/Irasvedett/Felhomentes/Torles), and a create flow (new folder under <storage>/shares or an existing folder via the browse modal). Every customer path goes through sharingResolvePath: absolute -> EvalSymlinks -> containment in a registered live storage root -> deny-listed system subtree check -> is-a-directory. Refusals are UNIFORM so the picker is never a filesystem oracle. Deny-list derived from ProtectedHDDPaths (provably a subset); the drive root is an exact-match denial so user-data folders under it stay shareable. samba infra metadata + i-share icon. Gates green.
This commit is contained in:
@@ -29,6 +29,39 @@ const (
|
||||
sambaUID = 1000
|
||||
)
|
||||
|
||||
// SharingDeniedRoots returns the SYSTEM subset of ProtectedHDDPaths(root) whose SUBTREES may never
|
||||
// be exported over SMB: appdata/ (live app databases — writable SMB access to them is the [R3]
|
||||
// corruption foot-gun), backups/, and the legacy felhom-data nest.
|
||||
//
|
||||
// The drive root itself is deliberately NOT in this set: it is denied by an EXACT-match check at the
|
||||
// call site ("a whole drive is not shareable"). Putting it here would make every path under the drive
|
||||
// — i.e. every legitimate share — match the subtree rule and be refused.
|
||||
//
|
||||
// It is DERIVED from ProtectedHDDPaths, never a parallel list: each candidate is emitted only if that
|
||||
// guard already contains it, so this set can only ever SHRINK relative to the delete guard — it can
|
||||
// never drift into a stale second source of truth. media/ and Dokumentumok/ are protected THERE as
|
||||
// delete targets but are customer data and stay shareable (Scenario B shares media/filmek).
|
||||
func SharingDeniedRoots(root string) []string {
|
||||
if root == "" {
|
||||
return nil
|
||||
}
|
||||
protected := ProtectedHDDPaths(root)
|
||||
candidates := []string{
|
||||
filepath.Join(root, "appdata"),
|
||||
filepath.Join(root, "backups"),
|
||||
filepath.Join(root, felhomDataDir),
|
||||
filepath.Join(root, felhomDataDir, "appdata"),
|
||||
filepath.Join(root, felhomDataDir, "backups"),
|
||||
}
|
||||
var out []string
|
||||
for _, c := range candidates {
|
||||
if protected[c] {
|
||||
out = append(out, c)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// sambaDir is the samba stack directory.
|
||||
func (m *Manager) sambaDir() string {
|
||||
return filepath.Join(m.cfg.Paths.StacksDir, SambaStackName)
|
||||
|
||||
Reference in New Issue
Block a user