GitRoot
craft your forge, build your project, grow your community freely
1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: EUPL-1.2
4
5package plugin
6
7import (
8 "errors"
9 "fmt"
10 "io/fs"
11 "os"
12 "slices"
13 "strings"
14
15 "github.com/go-git/go-git/v5/plumbing"
16 pluginLib "gitroot.dev/libs/golang/plugin/model"
17)
18
19func checkBranch(pluginRun PluginRun, branch plumbing.ReferenceName) bool {
20 if len(pluginRun.Branch) == 0 {
21 return false
22 }
23
24 isAuthorized := true
25 for _, b := range pluginRun.Branch {
26 if b == "*" {
27 isAuthorized = true
28 break
29 }
30 if branch.Short() != b {
31 isAuthorized = false
32 }
33 }
34
35 //negate check
36 for _, b := range pluginRun.Branch {
37 if strings.HasPrefix(b, "!") && strings.TrimPrefix(b, "!") == branch.Short() {
38 isAuthorized = false
39 }
40 }
41
42 return isAuthorized
43}
44
45var ErrCantAdd = errors.New("plugin try to add new file but can't")
46var ErrCantMod = errors.New("plugin try to mod file but can't")
47
48func checkWrite(pluginWriteRight []PluginWriteRight, f fs.FS, path string) (bool, error) {
49 canAdd := slices.ContainsFunc(pluginWriteRight, func(pwr PluginWriteRight) bool {
50 return slices.Contains(pwr.Can, pluginLib.PluginWriteRightCanAdd) && pwr.glob.Match(path)
51 })
52 canMod := slices.ContainsFunc(pluginWriteRight, func(pwr PluginWriteRight) bool {
53 return slices.Contains(pwr.Can, pluginLib.PluginWriteRightCanMod) && pwr.glob.Match(path)
54 })
55 if !canAdd && !canMod {
56 return false, nil
57 }
58 if !canAdd || !canMod {
59 _, err := fs.Stat(f, path)
60 if errors.Is(err, os.ErrNotExist) && !canAdd {
61 return false, ErrCantAdd
62 } else if err == nil && !canMod {
63 return false, ErrCantMod
64 } else if err != nil && !errors.Is(err, os.ErrNotExist) {
65 return false, err
66 }
67 }
68 return true, nil
69}
70
71func checkExec(pluginWriteRight []PluginExecRight, execs []pluginLib.Exec) (bool, error) {
72 for _, per := range pluginWriteRight {
73 notAuthorized := slices.IndexFunc(execs, func(exec pluginLib.Exec) bool {
74 cmd := fmt.Sprintf("%s %s", exec.Cmd, strings.Join(exec.Args, " "))
75 return per.regexp.Match([]byte(cmd))
76 })
77 if notAuthorized > -1 {
78 return false, fmt.Errorf("not authorized %s", execs[notAuthorized].Cmd)
79 }
80 }
81 return true, nil
82}