Autogenerate roles function bullshit
New small script to generate various functions for roles because manually typing out all the permissions sucks
This commit is contained in:
parent
220a3c89af
commit
7f7bf1cacf
1 changed files with 139 additions and 0 deletions
139
cmd/RolesColapser/main.go
Normal file
139
cmd/RolesColapser/main.go
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"gitlab.com/mstarongitlab/goutils/sliceutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
var findRoleStructRegex = regexp.MustCompile(`type Role struct \{([\s\S]+)\}\n\n/\*`)
|
||||||
|
|
||||||
|
var (
|
||||||
|
flagInputFile = flag.String("input", "", "Specify the input file. If empty, read from stdin")
|
||||||
|
flagOutputFile = flag.String("output", "", "Specify the output file. If empty, writes to stdout")
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
var input io.Reader
|
||||||
|
var output io.Writer
|
||||||
|
|
||||||
|
if *flagInputFile == "" {
|
||||||
|
input = os.Stdin
|
||||||
|
} else {
|
||||||
|
file, err := os.Open(*flagInputFile)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
input = file
|
||||||
|
}
|
||||||
|
if *flagOutputFile == "" {
|
||||||
|
output = os.Stdout
|
||||||
|
} else {
|
||||||
|
file, err := os.Create(*flagOutputFile)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
output = file
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := io.ReadAll(input)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !findRoleStructRegex.Match(data) {
|
||||||
|
panic("Input doesn't contain role struct")
|
||||||
|
}
|
||||||
|
content := findRoleStructRegex.FindStringSubmatch(string(data))[1]
|
||||||
|
lines := strings.Split(content, "\n")
|
||||||
|
lines = sliceutils.Map(lines, func(t string) string { return strings.TrimSpace(t) })
|
||||||
|
importantLines := sliceutils.Filter(lines, func(t string) bool {
|
||||||
|
if strings.HasPrefix(t, "//") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if strings.Contains(t, "gorm.Model") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
data := sliceutils.Filter(strings.Split(t, " "), func(t string) bool { return t != "" })
|
||||||
|
if len(data) < 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(data[1], "*") && !strings.HasPrefix(data[1], "[]") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
nameTypeMap := map[string]string{}
|
||||||
|
for _, line := range importantLines {
|
||||||
|
parts := sliceutils.Filter(strings.Split(line, " "), func(t string) bool { return t != "" })
|
||||||
|
nameTypeMap[parts[0]] = parts[1]
|
||||||
|
}
|
||||||
|
pkgString, _, _ := strings.Cut(string(data), "\n")
|
||||||
|
|
||||||
|
outBuilder := strings.Builder{}
|
||||||
|
outBuilder.WriteString(`// This file is autogenerated, do not edit
|
||||||
|
// If you need to refresh the content, run go generate again
|
||||||
|
`)
|
||||||
|
outBuilder.WriteString(pkgString + "\n\n")
|
||||||
|
outBuilder.WriteString("import \"slices\"\n\n")
|
||||||
|
|
||||||
|
// Build role collapse function
|
||||||
|
outBuilder.WriteString(
|
||||||
|
`func CollapseRolesIntoOne(roles ...*Role) Role {
|
||||||
|
startingRole := RoleDeepCopy(&DefaultUserRole)
|
||||||
|
slices.SortFunc(roles, func(a, b *Role) int { return int(int64(a.Priority)-int64(b.Priority)) })
|
||||||
|
for _, role := range roles {
|
||||||
|
`)
|
||||||
|
// Write all the stupid conditions here
|
||||||
|
for valName, valType := range nameTypeMap {
|
||||||
|
if strings.HasPrefix(valType, "[]") {
|
||||||
|
outBuilder.WriteString(fmt.Sprintf(` if role.%s != nil {
|
||||||
|
startingRole.%s = append(startingRole.%s, role.%s...)
|
||||||
|
}
|
||||||
|
`, valName, valName, valName, valName))
|
||||||
|
} else {
|
||||||
|
outBuilder.WriteString(fmt.Sprintf(` if role.%s != nil {
|
||||||
|
*startingRole.%s = *role.%s
|
||||||
|
}
|
||||||
|
`, valName, valName, valName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Then finish up with the end of the function
|
||||||
|
outBuilder.WriteString(
|
||||||
|
` }
|
||||||
|
return startingRole
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
// Then build the deep copy function
|
||||||
|
outBuilder.WriteString("\n\nfunc RoleDeepCopy(o *Role) Role {\n")
|
||||||
|
outBuilder.WriteString(` n := Role{}
|
||||||
|
n.Model = o.Model
|
||||||
|
n.Name = o.Name
|
||||||
|
n.Priority = o.Priority
|
||||||
|
n.IsUserRole = o.IsUserRole
|
||||||
|
n.IsBuiltIn = o.IsBuiltIn
|
||||||
|
`)
|
||||||
|
for valName, valType := range nameTypeMap {
|
||||||
|
if strings.HasPrefix(valType, "[]") {
|
||||||
|
outBuilder.WriteString(fmt.Sprintf(" n.%s = slices.Clone(o.%s)\n", valName, valName))
|
||||||
|
} else {
|
||||||
|
outBuilder.WriteString(fmt.Sprintf(` if o.%s == nil { n.%s = nil } else {
|
||||||
|
t := *o.%s
|
||||||
|
n.%s = &t
|
||||||
|
}
|
||||||
|
`, valName, valName, valName, valName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outBuilder.WriteString(" return n\n}\n")
|
||||||
|
|
||||||
|
// And write the entire thing to the output
|
||||||
|
fmt.Fprint(output, outBuilder.String())
|
||||||
|
}
|
Loading…
Reference in a new issue