aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2023-10-21 00:45:58 +0700
committerShulhan <ms@kilabit.info>2023-10-21 11:25:36 +0700
commit664c121f5d52364901100b817e1fa641d245fad0 (patch)
tree25ec1b90efebed9bdb6d710307ac6caa2c2466e5
parentcda5c7c31a84b01e2231bed579d7f4bb6212a272 (diff)
downloadawwan-664c121f5d52364901100b817e1fa641d245fad0.tar.xz
all: implement local "#get:" and "#put:" with owner and mode
In local environment, using magic command "#get" or "#put" with mode like "#get:$USER:$GROUP+$MODE" or "#put:$USER:$GROUP+MODE" will changes the file owner to $USER or $GROUP and/or permission to $MODE. The file owner does not works if user does not have permission to changes the owner.
-rw-r--r--.gitignore1
-rw-r--r--awwan_test.go76
-rw-r--r--session.go16
-rw-r--r--testdata/local/get.aww4
-rw-r--r--testdata/local/put.aww4
5 files changed, 90 insertions, 11 deletions
diff --git a/.gitignore b/.gitignore
index e346c22..018f06b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,4 +24,5 @@
/testdata/encrypt-with-passphrase/.awwan.env.vault
/testdata/encrypt-without-passphrase/.awwan.env.vault
/testdata/local/.cache
+/testdata/local/put_with_mode.txt
/www-awwan
diff --git a/awwan_test.go b/awwan_test.go
index b724af6..db8121e 100644
--- a/awwan_test.go
+++ b/awwan_test.go
@@ -7,6 +7,7 @@ package awwan
import (
"bytes"
+ "io/fs"
"os"
"path/filepath"
"testing"
@@ -296,6 +297,8 @@ func TestAwwanLocal_Get(t *testing.T) {
fileDest string
expContent string
expError string
+
+ expFileMode fs.FileMode
}
// Load the test data.
@@ -327,10 +330,21 @@ func TestAwwanLocal_Get(t *testing.T) {
aww.cryptoc.termrw = &mockrw
var cases = []testCase{{
- desc: `Get_PlainFile`,
- lineRange: `1`,
- fileDest: filepath.Join(baseDir, `tmp`, `get_plain.txt`),
- expContent: string(tdata.Output[`tmp/get_plain.txt`]),
+ desc: `PlainFile`,
+ lineRange: `1`,
+ fileDest: filepath.Join(baseDir, `tmp`, `get_plain.txt`),
+ expContent: string(tdata.Output[`tmp/get_plain.txt`]),
+ expFileMode: fs.FileMode(384),
+ }, {
+ desc: `WithMode`,
+ lineRange: `5`,
+ fileDest: filepath.Join(baseDir, `tmp`, `get_with_mode.txt`),
+ expContent: string(tdata.Output[`tmp/get_plain.txt`]),
+ expFileMode: fs.FileMode(0561),
+ }, {
+ desc: `WithOwner`,
+ lineRange: `7`,
+ expError: `Local: Copy: chown root:root: exit status 1`,
}}
var (
@@ -343,6 +357,8 @@ func TestAwwanLocal_Get(t *testing.T) {
for _, c = range cases {
t.Log(c.desc)
+ _ = os.Remove(c.fileDest)
+
var req = NewRequest(CommandModeLocal, script, c.lineRange)
err = aww.Local(req)
@@ -357,10 +373,19 @@ func TestAwwanLocal_Get(t *testing.T) {
}
test.Assert(t, `content`, c.expContent, string(gotContent))
+
+ var fi os.FileInfo
+
+ fi, err = os.Stat(c.fileDest)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ test.Assert(t, `mode`, c.expFileMode, fi.Mode())
}
}
-func TestAwwanLocalPut(t *testing.T) {
+func TestAwwanLocal_Put(t *testing.T) {
type testCase struct {
desc string
passphrase string
@@ -368,6 +393,7 @@ func TestAwwanLocalPut(t *testing.T) {
fileDest string
expError string
expContent string
+ expMode fs.FileMode
}
// Load the test data output.
@@ -389,6 +415,7 @@ func TestAwwanLocalPut(t *testing.T) {
lineRange: `1`,
fileDest: filepath.Join(baseDir, `tmp`, `plain.txt`),
expContent: string(tdata.Output[`tmp/plain.txt`]),
+ expMode: 384,
}, {
desc: `With text file, one of value is encrypted`,
lineRange: `3`,
@@ -399,6 +426,7 @@ func TestAwwanLocalPut(t *testing.T) {
passphrase: "s3cret\r",
fileDest: filepath.Join(baseDir, `tmp`, `decrypted.txt`),
expContent: string(tdata.Output[`tmp/decrypted.txt`]),
+ expMode: 384,
}, {
desc: `With encrypted file, empty passphrase`,
lineRange: `5`,
@@ -408,6 +436,17 @@ func TestAwwanLocalPut(t *testing.T) {
passphrase: "invalid\r",
lineRange: `5`,
expError: string(tdata.Output[`encrypted_invalid_passphrase`]),
+ }, {
+ desc: `With mode`,
+ lineRange: `10`,
+ fileDest: filepath.Join(baseDir, `tmp`, `put_with_mode.txt`),
+ expContent: string(tdata.Output[`tmp/plain.txt`]),
+ expMode: 0611,
+ }, {
+ desc: `With owner`,
+ lineRange: `12`,
+ fileDest: filepath.Join(baseDir, `tmp`, `put_with_owner.txt`),
+ expError: `Local: Copy: chown audio:audio: exit status 1`,
}}
var (
@@ -422,6 +461,10 @@ func TestAwwanLocalPut(t *testing.T) {
for _, c = range cases {
t.Log(c.desc)
+ if len(c.fileDest) != 0 {
+ _ = os.Remove(c.fileDest)
+ }
+
aww, err = New(baseDir)
if err != nil {
t.Fatal(err)
@@ -449,13 +492,24 @@ func TestAwwanLocalPut(t *testing.T) {
continue
}
- if len(c.fileDest) != 0 {
- gotContent, err = os.ReadFile(c.fileDest)
- if err != nil {
- t.Fatal(err)
- }
+ if len(c.fileDest) == 0 {
+ continue
+ }
+
+ gotContent, err = os.ReadFile(c.fileDest)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ test.Assert(t, `content`, c.expContent, string(gotContent))
- test.Assert(t, `content`, c.expContent, string(gotContent))
+ var fi os.FileInfo
+
+ fi, err = os.Stat(c.fileDest)
+ if err != nil {
+ t.Fatal(err)
}
+
+ test.Assert(t, `error`, c.expMode, fi.Mode())
}
}
diff --git a/session.go b/session.go
index faca1d0..9320382 100644
--- a/session.go
+++ b/session.go
@@ -18,6 +18,7 @@ import (
"github.com/shuLhan/share/lib/ascii"
"github.com/shuLhan/share/lib/ini"
libos "github.com/shuLhan/share/lib/os"
+ libexec "github.com/shuLhan/share/lib/os/exec"
"github.com/shuLhan/share/lib/ssh/config"
)
@@ -148,6 +149,21 @@ func (ses *Session) Copy(stmt *Statement) (err error) {
if err != nil {
return fmt.Errorf(`%s: %w`, logp, err)
}
+
+ if len(stmt.owner) != 0 {
+ var cmd = fmt.Sprintf(`chown %s %s`, stmt.owner, dst)
+ err = libexec.Run(cmd, nil, nil)
+ if err != nil {
+ return fmt.Errorf(`%s: chown %s: %w`, logp, stmt.owner, err)
+ }
+ }
+ if stmt.mode != 0 {
+ err = os.Chmod(dst, stmt.mode)
+ if err != nil {
+ return fmt.Errorf(`%s: %w`, logp, err)
+ }
+ }
+
return nil
}
diff --git a/testdata/local/get.aww b/testdata/local/get.aww
index d889f22..f4f4dc8 100644
--- a/testdata/local/get.aww
+++ b/testdata/local/get.aww
@@ -1,3 +1,7 @@
#get: {{.ScriptDir}}/plain.txt {{.ScriptDir}}/tmp/get_plain.txt
#get! /etc/os-release {{.ScriptDir}}/tmp/os-release
+
+#get:+0561 {{.ScriptDir}}/plain.txt {{.ScriptDir}}/tmp/get_with_mode.txt
+
+#get:root:root {{.ScriptDir}}/plain.txt {{.ScriptDir}}/tmp/get_with_owner.txt
diff --git a/testdata/local/put.aww b/testdata/local/put.aww
index e3040f1..d26fd55 100644
--- a/testdata/local/put.aww
+++ b/testdata/local/put.aww
@@ -6,3 +6,7 @@
#put! {{.ScriptDir}}/plain.txt /etc/plain.txt
sudo chmod 0644 /etc/plain.txt
+
+#put:+0611 {{.ScriptDir}}/plain.txt {{.ScriptDir}}/tmp/put_with_mode.txt
+
+#put:audio:audio {{.ScriptDir}}/plain.txt {{.ScriptDir}}/tmp/put_with_owner.txt