Skip to content

Commit

Permalink
feat(app): define permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
Siroshun09 committed Dec 25, 2024
1 parent 8afae75 commit 6a3ba7b
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 0 deletions.
44 changes: 44 additions & 0 deletions app/internal/domain/permission/codegen/definition/model.go
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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),
)
50 changes: 50 additions & 0 deletions app/internal/domain/permission/codegen/identifier/identifier.go
Original file line number Diff line number Diff line change
@@ -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
}
80 changes: 80 additions & 0 deletions app/internal/domain/permission/codegen/main.go
Original file line number Diff line number Diff line change
@@ -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()
}
5 changes: 5 additions & 0 deletions app/internal/domain/permission/gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//go:build tools

package permission

//go:generate go run ./codegen/main.go
9 changes: 9 additions & 0 deletions app/internal/domain/permission/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package permission

type PermissionID = int16

type Permission struct {
ID PermissionID
Name string
DefaultValue bool
}
11 changes: 11 additions & 0 deletions app/internal/domain/permission/permission_ids.json
Original file line number Diff line number Diff line change
@@ -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
}
39 changes: 39 additions & 0 deletions app/internal/domain/permission/permissions.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6a3ba7b

Please sign in to comment.