From ef81051f7d0a18709ce182bd706c1e4c5fc2a6e9 Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Fri, 30 Jun 2017 22:56:07 +0200 Subject: Use ACLs in tree objects --- objects/object_tree.go | 114 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 13 deletions(-) (limited to 'objects/object_tree.go') diff --git a/objects/object_tree.go b/objects/object_tree.go index 07c265c..2a8f982 100644 --- a/objects/object_tree.go +++ b/objects/object_tree.go @@ -3,6 +3,7 @@ package objects import ( "bufio" "bytes" + "code.laria.me/petrific/acl" "errors" "fmt" "sort" @@ -24,6 +25,9 @@ var treeEntryTypes = map[TreeEntryType]struct{}{ type TreeEntry interface { Type() TreeEntryType + ACL() acl.ACL + User() string + Group() string equalContent(TreeEntry) bool toProperties() properties } @@ -32,49 +36,93 @@ func compareTreeEntries(a, b TreeEntry) bool { return a.Type() == b.Type() && a.equalContent(b) } -type TreeEntryFile ObjectId +type TreeEntryBase struct { + acl acl.ACL + user, group string +} + +func (teb TreeEntryBase) ACL() acl.ACL { + return teb.acl +} + +func (teb TreeEntryBase) User() string { + return teb.user +} + +func (teb TreeEntryBase) Group() string { + return teb.group +} + +func (teb TreeEntryBase) toProperties() properties { + return properties{ + "acl": teb.acl.String(), + "user": teb.user, + "group": teb.group, + } +} + +func (a TreeEntryBase) equalContent(b TreeEntryBase) bool { + return a.acl.Equals(b.acl) && a.user == b.user && a.group == b.group +} + +type TreeEntryFile struct { + TreeEntryBase + Ref ObjectId +} func (tef TreeEntryFile) Type() TreeEntryType { return TETFile } func (tef TreeEntryFile) toProperties() properties { - return properties{"ref": ObjectId(tef).String()} + props := tef.TreeEntryBase.toProperties() + props["ref"] = tef.Ref.String() + return props } func (a TreeEntryFile) equalContent(_b TreeEntry) bool { b, ok := _b.(TreeEntryFile) - return ok && ObjectId(b).Equals(ObjectId(a)) + return ok && a.TreeEntryBase.equalContent(b.TreeEntryBase) && a.Ref.Equals(b.Ref) } -type TreeEntryDir ObjectId +type TreeEntryDir struct { + TreeEntryBase + Ref ObjectId +} func (ted TreeEntryDir) Type() TreeEntryType { return TETDir } func (ted TreeEntryDir) toProperties() properties { - return properties{"ref": ObjectId(ted).String()} + props := ted.TreeEntryBase.toProperties() + props["ref"] = ted.Ref.String() + return props } func (a TreeEntryDir) equalContent(_b TreeEntry) bool { b, ok := _b.(TreeEntryDir) - return ok && ObjectId(b).Equals(ObjectId(a)) + return ok && a.TreeEntryBase.equalContent(b.TreeEntryBase) && a.Ref.Equals(b.Ref) } -type TreeEntrySymlink string +type TreeEntrySymlink struct { + TreeEntryBase + Target string +} func (tes TreeEntrySymlink) Type() TreeEntryType { return TETSymlink } func (tes TreeEntrySymlink) toProperties() properties { - return properties{"target": string(tes)} + props := tes.TreeEntryBase.toProperties() + props["target"] = tes.Target + return props } func (a TreeEntrySymlink) equalContent(_b TreeEntry) bool { b, ok := _b.(TreeEntrySymlink) - return ok && b == a + return ok && a.TreeEntryBase.equalContent(b.TreeEntryBase) && a.Target == b.Target } type Tree map[string]TreeEntry @@ -117,6 +165,28 @@ func getObjectIdFromProps(p properties, key string) (ObjectId, error) { return oid, err } +func defaultFileTreeEntryBase(_acl *acl.ACL, props properties) (base TreeEntryBase) { + base.user = props["user"] + base.group = props["group"] + if _acl == nil { + base.acl = acl.ACLFromUnixPerms(0664) + } else { + base.acl = *_acl + } + return +} + +func defaultDirTreeEntryBase(_acl *acl.ACL, props properties) (base TreeEntryBase) { + base.user = props["user"] + base.group = props["group"] + if _acl == nil { + base.acl = acl.ACLFromUnixPerms(0775) + } else { + base.acl = *_acl + } + return +} + func (t Tree) FromPayload(payload []byte) error { sc := bufio.NewScanner(bytes.NewReader(payload)) @@ -128,7 +198,16 @@ func (t Tree) FromPayload(payload []byte) error { props := make(properties) if err := props.UnmarshalText(line); err != nil { - return nil + return err + } + + var _acl *acl.ACL + if acl_string, ok := props["acl"]; ok { + acltmp, err := acl.ParseACL(acl_string) + if err != nil { + return err + } + _acl = &acltmp } entry_type, ok := props["type"] @@ -143,19 +222,28 @@ func (t Tree) FromPayload(payload []byte) error { if err != nil { return err } - entry = TreeEntryFile(ref) + entry = TreeEntryFile{ + TreeEntryBase: defaultFileTreeEntryBase(_acl, props), + Ref: ref, + } case TETDir: ref, err := getObjectIdFromProps(props, "ref") if err != nil { return err } - entry = TreeEntryDir(ref) + entry = TreeEntryDir{ + TreeEntryBase: defaultDirTreeEntryBase(_acl, props), + Ref: ref, + } case TETSymlink: target, ok := props["target"] if !ok { return errors.New("Missing key: target") } - entry = TreeEntrySymlink(target) + entry = TreeEntrySymlink{ + TreeEntryBase: defaultFileTreeEntryBase(_acl, props), + Target: target, + } default: // TODO: Or should we just ignore this entry? There might be more types in the future... return fmt.Errorf("Unknown tree entry type: %s", entry_type) -- cgit v1.2.3-54-g00ecf