aboutsummaryrefslogtreecommitdiffhomepage
path: root/acl/acl_test.go
diff options
context:
space:
mode:
authorOphestra Umiker <cat@ophivana.moe>2024-12-16 15:57:00 +0900
committerOphestra Umiker <cat@ophivana.moe>2024-12-16 16:00:31 +0900
commitee41b37606fbf9085e239922a1362f1c8c13d542 (patch)
tree7cbbc70dce16dcadaa5de70901ea8aa83c0e790f /acl/acl_test.go
parente3f1d7ba60bfc727e8308c386a306928fcf10130 (diff)
acl: add tests
These tests test UpdatePerm correctness by parsing getfacl output. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
Diffstat (limited to 'acl/acl_test.go')
-rw-r--r--acl/acl_test.go117
1 files changed, 117 insertions, 0 deletions
diff --git a/acl/acl_test.go b/acl/acl_test.go
new file mode 100644
index 00000000..3a974bad
--- /dev/null
+++ b/acl/acl_test.go
@@ -0,0 +1,117 @@
+package acl_test
+
+import (
+ "errors"
+ "os"
+ "reflect"
+ "testing"
+
+ "git.ophivana.moe/security/fortify/acl"
+)
+
+const testFileName = "acl.test"
+
+var (
+ uid = os.Geteuid()
+ cred = int32(os.Geteuid())
+)
+
+func TestUpdatePerm(t *testing.T) {
+ if f, err := os.Create(testFileName); err != nil {
+ t.Fatalf("Create: error = %v", err)
+ } else {
+ if err = f.Close(); err != nil {
+ t.Fatalf("Close: error = %v", err)
+ }
+ }
+ defer func() {
+ if err := os.Remove(testFileName); err != nil {
+ t.Fatalf("Remove: error = %v", err)
+ }
+ }()
+
+ cur := getfacl(t, testFileName)
+
+ t.Run("default entry count", func(t *testing.T) {
+ if len(cur) != 3 {
+ t.Fatalf("unexpected test file acl length %d", len(cur))
+ }
+ })
+
+ t.Run("default clear mask", func(t *testing.T) {
+ if err := acl.UpdatePerm(testFileName, uid); err != nil {
+ t.Fatalf("UpdatePerm: error = %v", err)
+ }
+ if cur = getfacl(t, testFileName); len(cur) != 4 {
+ t.Fatalf("UpdatePerm: %v", cur)
+ }
+ })
+
+ t.Run("default clear consistency", func(t *testing.T) {
+ if err := acl.UpdatePerm(testFileName, uid); err != nil {
+ t.Fatalf("UpdatePerm: error = %v", err)
+ }
+ if val := getfacl(t, testFileName); !reflect.DeepEqual(val, cur) {
+ t.Fatalf("UpdatePerm: %v, want %v", val, cur)
+ }
+ })
+
+ testUpdate(t, "r--", cur, fAclPermRead, acl.Read)
+ testUpdate(t, "-w-", cur, fAclPermWrite, acl.Write)
+ testUpdate(t, "--x", cur, fAclPermExecute, acl.Execute)
+ testUpdate(t, "-wx", cur, fAclPermWrite|fAclPermExecute, acl.Write, acl.Execute)
+ testUpdate(t, "r-x", cur, fAclPermRead|fAclPermExecute, acl.Read, acl.Execute)
+ testUpdate(t, "rw-", cur, fAclPermRead|fAclPermWrite, acl.Read, acl.Write)
+ testUpdate(t, "rwx", cur, fAclPermRead|fAclPermWrite|fAclPermExecute, acl.Read, acl.Write, acl.Execute)
+}
+
+func testUpdate(t *testing.T, name string, cur []*getFAclResp, val fAclPerm, perms ...acl.Perm) {
+ t.Run(name, func(t *testing.T) {
+ t.Cleanup(func() {
+ if err := acl.UpdatePerm(testFileName, uid); err != nil {
+ t.Fatalf("UpdatePerm: error = %v", err)
+ }
+ if v := getfacl(t, testFileName); !reflect.DeepEqual(v, cur) {
+ t.Fatalf("UpdatePerm: %v, want %v", v, cur)
+ }
+ })
+
+ if err := acl.UpdatePerm(testFileName, uid, perms...); err != nil {
+ t.Fatalf("UpdatePerm: error = %v", err)
+ }
+ r := respByCred(getfacl(t, testFileName), fAclTypeUser, cred)
+ if r == nil {
+ t.Fatalf("UpdatePerm did not add an ACL entry")
+ }
+ if !r.equals(fAclTypeUser, cred, val) {
+ t.Fatalf("UpdatePerm(%s) = %s", name, r)
+ }
+ })
+}
+
+func getfacl(t *testing.T, name string) []*getFAclResp {
+ c := new(getFAclInvocation)
+ if err := c.run(name); err != nil {
+ t.Fatalf("getfacl: error = %v", err)
+ }
+ if len(c.pe) != 0 {
+ t.Errorf("errors encountered parsing getfacl output\n%s", errors.Join(c.pe...).Error())
+ }
+ return c.val
+}
+
+func respByCred(v []*getFAclResp, typ fAclType, cred int32) *getFAclResp {
+ j := -1
+ for i, r := range v {
+ if r.typ == typ && r.cred == cred {
+ if j != -1 {
+ panic("invalid acl")
+ }
+ j = i
+ }
+ }
+ if j == -1 {
+ return nil
+ }
+ return v[j]
+}