From 25243b3a9d271fac1f8da233a0fdd99573224731 Mon Sep 17 00:00:00 2001 From: mStar Date: Thu, 7 Nov 2024 16:27:46 +0100 Subject: [PATCH] Work on --- cmd/RolesApiConverter/main.go | 103 ++++++++++++++++++++++++++++++++++ cmd/RolesGenerator/main.go | 9 +++ server/apiLinstromTypes.go | 6 +- 3 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 cmd/RolesApiConverter/main.go diff --git a/cmd/RolesApiConverter/main.go b/cmd/RolesApiConverter/main.go new file mode 100644 index 0000000..0967fbd --- /dev/null +++ b/cmd/RolesApiConverter/main.go @@ -0,0 +1,103 @@ +/* +Tool for auto-generating API helper functions in regards to roles +*/ +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(`// Code generated by cmd/RolesApiConverter DO NOT EDIT. +// If you need to refresh the content, run go generate again +`) + outBuilder.WriteString(pkgString + "\n\n") + + outBuilder.WriteString("func convertStorageRoleToApiRole(r storage.Role) linstromRole {\n") + outBuilder.WriteString("return linstromRole{") + outBuilder.WriteString("Id:r.ID,CreatedAt:r.CreatedAt,UpdatedAt:&r.UpdatedAt,Name:r.Name,") + outBuilder.WriteString("Priority:r.Priority,IsUserRole:r.IsUserRole,IsBuiltIn:r.IsBuiltIn,") + for k := range nameTypeMap { + outBuilder.WriteString(fmt.Sprintf("%s:r.%s,", k, k)) + } + outBuilder.WriteString("}\n}\n") + + fmt.Fprint(output, outBuilder.String()) +} diff --git a/cmd/RolesGenerator/main.go b/cmd/RolesGenerator/main.go index 24b7f60..2c856dc 100644 --- a/cmd/RolesGenerator/main.go +++ b/cmd/RolesGenerator/main.go @@ -1,3 +1,12 @@ +/* +Tool for generating helper functions for storage.Role structs inside of the storage package +It generates the following functions: + - CollapseRolesIntoOne: Collapse a list of roles into one singular role. Each value will be set to the + value of the role with the highest priority + - RoleDeepCopy: Copy a role, including all arrays. Every value will be copied too + - CompareRoles: Compare two roles. Returns true only if all fields are equal + (if one of the fields is nil, that field is seen as equal) +*/ package main import ( diff --git a/server/apiLinstromTypes.go b/server/apiLinstromTypes.go index 5a5170e..22bbaf6 100644 --- a/server/apiLinstromTypes.go +++ b/server/apiLinstromTypes.go @@ -6,10 +6,6 @@ import "time" var ( _ = linstromNote{} - _ = linstromOriginServer{} - _ = linstromMediaMetadata{} - _ = linstromAccount{} - _ = linstromCustomAccountField{} _ = linstromRole{} ) @@ -108,7 +104,7 @@ type linstromRole struct { // If two roles have the same priority, the order is undetermined and may be random // Default priority for new roles is 1 to always overwrite default user // And full admin has max priority possible - Priority uint `jsonapi:"attr,priority"` + Priority uint32 `jsonapi:"attr,priority"` // Whether this role is for a for a single user only (like custom, per user permissions in Discord) // If yes, Name will be the id of the user in question IsUserRole bool `jsonapi:"attr,is-user-role"`