grim/hgkeeper

Introduce "rm <repo>" command

11 months ago, aklitzing
7485b844616f
Parents dca75ada402c
Children 5a19892df841
Introduce "rm " command

It is possible to create a new repository with "hg init" but it is not possible
to remove any repositories. So let's use "ssh command" to allow this.

$ ssh hg.host.com rm repoName

Bugs closed: HGKEEPER-25

Reviewed at https://reviews.imfreedom.org/r/2421/
--- a/access/access.go Wed Apr 12 23:51:38 2023 -0500
+++ b/access/access.go Wed Apr 12 23:57:06 2023 -0500
@@ -125,3 +125,7 @@
func CanInit(user, repo string) bool {
return check(user, repo, "init")
}
+
+func CanRemove(user, repo string) bool {
+ return check(user, repo, "remove")
+}
--- a/access/repositories.go Wed Apr 12 23:51:38 2023 -0500
+++ b/access/repositories.go Wed Apr 12 23:57:06 2023 -0500
@@ -7,6 +7,11 @@
"strings"
)
+func IsExistingRepo(repo string) bool {
+ _, ok := repositories[repo]
+ return ok
+}
+
func IsInExistingRepo(repo string) bool {
for existingRepo := range repositories {
existingRepo += "/"
--- a/hg/parser.go Wed Apr 12 23:51:38 2023 -0500
+++ b/hg/parser.go Wed Apr 12 23:57:06 2023 -0500
@@ -15,6 +15,10 @@
Repo string `kong:"arg"`
} `kong:"cmd"`
} `kong:"cmd"`
+
+ Rm struct {
+ Repo string `kong:"arg"`
+ } `kong:"cmd"`
}
func ParseCommandArguments(cmd string) (string, CommandArguments, error) {
--- a/setup/resources/policy.csv.template Wed Apr 12 23:51:38 2023 -0500
+++ b/setup/resources/policy.csv.template Wed Apr 12 23:57:06 2023 -0500
@@ -24,6 +24,10 @@
# give users in the admins group the ability to create repositories everywhere.
p, admins, /*, init, allow
+# give users in the admins group the ability to remove repositories.
+# The admin repository /hgkeeper cannot be removed.
+#p, admins, /*, remove, allow
+
# deny authenticated, but not explicitly defined users read access to the
# {{.AdminRepo}} repo
p, public, {{.AdminRepo}}, read, deny
@@ -53,5 +57,8 @@
# give the write action read permission
g2, read, write
+# give the remove action read permission
+g2, read, remove
+
# give the init action write permission (which has read)
g2, write, init
--- a/ssh/commands/commands.go Wed Apr 12 23:51:38 2023 -0500
+++ b/ssh/commands/commands.go Wed Apr 12 23:57:06 2023 -0500
@@ -23,6 +23,8 @@
return NewServe(reposPath, values.Hg.Repo), nil
case "hg init <repo>":
return NewInit(reposPath, values.Hg.Init.Repo), nil
+ case "rm <repo>":
+ return NewRemove(reposPath, values.Rm.Repo), nil
default:
return nil, fmt.Errorf("unknown command %s", cmd)
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ssh/commands/rm.go Wed Apr 12 23:57:06 2023 -0500
@@ -0,0 +1,61 @@
+package commands
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "github.com/gliderlabs/ssh"
+ "go.uber.org/zap"
+
+ "keep.imfreedom.org/grim/hgkeeper/access"
+)
+
+type Remove struct {
+ repoPath string
+ repoName string
+}
+
+func NewRemove(reposPath, repoName string) Command {
+ return &Remove{
+ repoPath: filepath.Join(reposPath, repoName),
+ repoName: repoName,
+ }
+}
+
+func (i *Remove) Run(session ssh.Session, username string) error {
+ if !access.CanRemove(username, "/"+i.repoName) {
+ return fmt.Errorf("access denied")
+ }
+
+ err := error(nil)
+ if access.IsExistingRepo(i.repoName) {
+ err = i.removePath(session)
+ } else {
+ err = fmt.Errorf("repository not found: %s", i.repoName)
+ }
+
+ if err != nil {
+ sendResponse(err.Error(), session)
+ }
+ return err
+}
+
+func (i *Remove) removePath(session ssh.Session) error {
+ if i.repoName == access.AdminRepo() {
+ return fmt.Errorf("repository protected: %s", i.repoName)
+ }
+
+ err := os.RemoveAll(i.repoPath)
+ if err == nil {
+ sendResponse("repository removed: "+i.repoName, session)
+ zap.S().Info("refreshing access control for removed repo")
+ return access.Refresh()
+ }
+ return err
+}
+
+func sendResponse(content string, session ssh.Session) {
+ session.Write([]byte(content))
+ session.Write([]byte("\n"))
+}