diff --git a/app/internal/domain/permission/codegen/definition/model.go b/app/internal/domain/permission/codegen/definition/model.go new file mode 100644 index 0000000..fedf7a8 --- /dev/null +++ b/app/internal/domain/permission/codegen/definition/model.go @@ -0,0 +1,44 @@ +package definition + +type DefaultPermissionValue bool + +const ( + allowedByDefault DefaultPermissionValue = true + restrictedByDefault DefaultPermissionValue = false +) + +func (value DefaultPermissionValue) IsAllowedByDefault() bool { + return value == allowedByDefault +} + +type DefinedPermission struct { + Name string + DefaultValue DefaultPermissionValue +} + +type DefinedPermissions []DefinedPermission + +func permission(name string, value DefaultPermissionValue) DefinedPermission { + return DefinedPermission{name, value} +} + +type PermissionDefiner struct { + definedPermissions DefinedPermissions +} + +func (def *PermissionDefiner) define(perms ...DefinedPermission) *PermissionDefiner { + def.definedPermissions = append(def.definedPermissions, perms...) + return def +} + +func (def *PermissionDefiner) GetPermissions() DefinedPermissions { + return def.definedPermissions +} + +var definer = &PermissionDefiner{ + definedPermissions: make(DefinedPermissions, 0, 100), +} + +func GetPermissions() DefinedPermissions { + return definer.definedPermissions +} diff --git a/app/internal/domain/permission/codegen/definition/permisions_user.go b/app/internal/domain/permission/codegen/definition/permisions_user.go new file mode 100644 index 0000000..45b0c16 --- /dev/null +++ b/app/internal/domain/permission/codegen/definition/permisions_user.go @@ -0,0 +1,15 @@ +package definition + +// user permissions +var _ = definer.define( + permission("user.list", restrictedByDefault), + permission("user.create", restrictedByDefault), + permission("user.edit.nickname", restrictedByDefault), + permission("user.delete", restrictedByDefault), +) + +// mypage permissions +var _ = definer.define( + permission("mypage.view", allowedByDefault), + permission("mypage.edit.nickname", allowedByDefault), +) diff --git a/app/internal/domain/permission/codegen/identifier/identifier.go b/app/internal/domain/permission/codegen/identifier/identifier.go new file mode 100644 index 0000000..9ab88cd --- /dev/null +++ b/app/internal/domain/permission/codegen/identifier/identifier.go @@ -0,0 +1,50 @@ +package identifier + +import ( + "encoding/json" + "github.com/Siroshun09/serrors" +) + +type PermissionIdentifier interface { + GetOrCreateID(name string) int16 + EncodeToJson() ([]byte, error) +} + +type jsonFile struct { + PermissionToIdMap map[string]int16 `json:"permissions"` + LastUsedID int16 `json:"last_used_id"` +} + +func DecodeFromJson(data []byte) (PermissionIdentifier, error) { + file := &jsonFile{ + PermissionToIdMap: make(map[string]int16), + LastUsedID: 0, + } + + if len(data) == 0 { + return file, nil + } + + if err := json.Unmarshal(data, file); err != nil { + return nil, serrors.WithStackTrace(err) + } + return file, nil +} + +func (i *jsonFile) EncodeToJson() ([]byte, error) { + data, err := json.MarshalIndent(*i, "", " ") + if err != nil { + return nil, serrors.WithStackTrace(err) + } + return data, nil +} + +func (i *jsonFile) GetOrCreateID(name string) int16 { + if id, ok := i.PermissionToIdMap[name]; ok { + return id + } + i.LastUsedID++ + id := i.LastUsedID + i.PermissionToIdMap[name] = id + return id +} diff --git a/app/internal/domain/permission/codegen/main.go b/app/internal/domain/permission/codegen/main.go new file mode 100644 index 0000000..7370aa4 --- /dev/null +++ b/app/internal/domain/permission/codegen/main.go @@ -0,0 +1,80 @@ +package main + +import ( + "fmt" + "github.com/okocraft/monitor/internal/domain/permission/codegen/definition" + "github.com/okocraft/monitor/internal/domain/permission/codegen/identifier" + "go/format" + "os" + "strings" + "unicode" +) + +func main() { + idFile, err := os.ReadFile("permission_ids.json") + if err != nil && !os.IsNotExist(err) { + panic(err) + } + + idProvider, err := identifier.DecodeFromJson(idFile) + if err != nil { + panic(err) + } + + w := strings.Builder{} + + _, err = w.WriteString("// Code generated by permission/codegen; DO NOT EDIT\n\n") + if err != nil { + panic(err) + } + + _, err = w.WriteString("package permission\n") + if err != nil { + panic(err) + } + + for _, perm := range definition.GetPermissions() { + id := idProvider.GetOrCreateID(perm.Name) + w.WriteString(fmt.Sprintf( + "var %s = Permission{\n"+ + "ID: %d,\n"+ + "Name: \"%s\",\n"+ + "DefaultValue: %v,\n"+ + "}\n\n", + toVarName(perm), id, perm.Name, perm.DefaultValue, + )) + } + + formatted, err := format.Source([]byte(w.String())) + err = os.WriteFile("permissions.gen.go", formatted, os.ModePerm) + if err != nil { + panic(err) + } + + data, err := idProvider.EncodeToJson() + if err != nil { + panic(err) + } + + err = os.WriteFile("permission_ids.json", data, os.ModePerm) + if err != nil { + panic(err) + } +} + +func toVarName(perm definition.DefinedPermission) string { + upperCase := true + varName := strings.Builder{} + for _, c := range perm.Name { + switch { + case c == '.': + upperCase = true + case upperCase: + varName.WriteRune(unicode.ToUpper(c)) + upperCase = false + default: + varName.WriteRune(c) + } + } + return varName.String() +} diff --git a/app/internal/domain/permission/gen.go b/app/internal/domain/permission/gen.go new file mode 100644 index 0000000..ff71241 --- /dev/null +++ b/app/internal/domain/permission/gen.go @@ -0,0 +1,5 @@ +//go:build tools + +package permission + +//go:generate go run ./codegen/main.go diff --git a/app/internal/domain/permission/model.go b/app/internal/domain/permission/model.go new file mode 100644 index 0000000..6975ea6 --- /dev/null +++ b/app/internal/domain/permission/model.go @@ -0,0 +1,9 @@ +package permission + +type PermissionID = int16 + +type Permission struct { + ID PermissionID + Name string + DefaultValue bool +} diff --git a/app/internal/domain/permission/permission_ids.json b/app/internal/domain/permission/permission_ids.json new file mode 100644 index 0000000..c342e05 --- /dev/null +++ b/app/internal/domain/permission/permission_ids.json @@ -0,0 +1,11 @@ +{ + "permissions": { + "mypage.edit.nickname": 6, + "mypage.view": 5, + "user.create": 2, + "user.delete": 4, + "user.edit.nickname": 3, + "user.list": 1 + }, + "last_used_id": 6 +} \ No newline at end of file diff --git a/app/internal/domain/permission/permissions.gen.go b/app/internal/domain/permission/permissions.gen.go new file mode 100644 index 0000000..49a45ed --- /dev/null +++ b/app/internal/domain/permission/permissions.gen.go @@ -0,0 +1,39 @@ +// Code generated by permission/codegen; DO NOT EDIT + +package permission + +var UserList = Permission{ + ID: 1, + Name: "user.list", + DefaultValue: false, +} + +var UserCreate = Permission{ + ID: 2, + Name: "user.create", + DefaultValue: false, +} + +var UserEditNickname = Permission{ + ID: 3, + Name: "user.edit.nickname", + DefaultValue: false, +} + +var UserDelete = Permission{ + ID: 4, + Name: "user.delete", + DefaultValue: false, +} + +var MypageView = Permission{ + ID: 5, + Name: "mypage.view", + DefaultValue: true, +} + +var MypageEditNickname = Permission{ + ID: 6, + Name: "mypage.edit.nickname", + DefaultValue: true, +}