// SPDX-FileCopyrightText: 2025 Romain Maneschi // // SPDX-License-Identifier: EUPL-1.2 package plugin import ( "errors" "fmt" "io/fs" "os" "slices" "strings" "github.com/go-git/go-git/v6/plumbing" pluginLib "gitroot.dev/libs/golang/plugin/model" ) func checkBranch(pluginRun PluginRun, branch plumbing.ReferenceName) bool { if len(pluginRun.Branch) == 0 { return false } isAuthorized := true for _, b := range pluginRun.Branch { if b == "*" { isAuthorized = true break } if branch.Short() != b { isAuthorized = false } } //negate check for _, b := range pluginRun.Branch { if strings.HasPrefix(b, "!") && strings.TrimPrefix(b, "!") == branch.Short() { isAuthorized = false } } return isAuthorized } var ErrCantAdd = errors.New("plugin try to add new file but can't") var ErrCantMod = errors.New("plugin try to mod file but can't") func checkWrite(pluginWriteRight []PluginWriteRight, f fs.FS, path string) (bool, error) { canAdd := slices.ContainsFunc(pluginWriteRight, func(pwr PluginWriteRight) bool { return slices.Contains(pwr.Can, pluginLib.PluginWriteRightCanAdd) && pwr.glob.Match(path) }) canMod := slices.ContainsFunc(pluginWriteRight, func(pwr PluginWriteRight) bool { return slices.Contains(pwr.Can, pluginLib.PluginWriteRightCanMod) && pwr.glob.Match(path) }) if !canAdd && !canMod { return false, nil } if !canAdd || !canMod { _, err := fs.Stat(f, path) if errors.Is(err, os.ErrNotExist) && !canAdd { return false, ErrCantAdd } else if err == nil && !canMod { return false, ErrCantMod } else if err != nil && !errors.Is(err, os.ErrNotExist) { return false, err } } return true, nil } func checkDelete(pluginWriteRight []PluginWriteRight, path string) (bool, error) { canDel := slices.ContainsFunc(pluginWriteRight, func(pwr PluginWriteRight) bool { return slices.Contains(pwr.Can, pluginLib.PluginWriteRightCanDel) && pwr.glob.Match(path) }) if !canDel { return false, nil } return true, nil } func checkExec(pluginWriteRight []PluginExecRight, exec pluginLib.Exec) bool { authorized := false for _, per := range pluginWriteRight { authorized = slices.ContainsFunc(exec.Cmds, func(exec pluginLib.Cmd) bool { cmd := fmt.Sprintf("%s %s", exec.Cmd, strings.Join(exec.Args, " ")) return per.regexp.Match([]byte(cmd)) }) if authorized { break } } return authorized }