aboutsummaryrefslogtreecommitdiff
path: root/objects/object_tree.go
diff options
context:
space:
mode:
Diffstat (limited to 'objects/object_tree.go')
-rw-r--r--objects/object_tree.go114
1 files changed, 101 insertions, 13 deletions
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)