Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A POC for permission based field reading in Golang
package main
import (
"fmt"
"reflect"
)
type User struct {
Permissions []string
}
func (u User) HasPermission(perm string) bool {
for _, p := range u.Permissions {
if p == perm {
return true
}
}
return false
}
type EmbedType struct {
PublicField string
LimitedRead string `readpermission:"limited.read"`
LimitedEmbedRead string `readpermission:"limited.embed.read"`
LimitEmbedEmbedRead EmbedEmbedType
}
type EmbedEmbedType struct {
PublicField string
LimitedRead string `readpermission:"limited.read"`
LimitedEmbedRead string `readpermission:"limited.embed.read"`
LimitedEmbedEmbedRead string `readpermission:"limited.embed.embed.read"`
}
type HiddenStruct struct {
Hidden string
}
type TestPermission struct {
PublicField string
LimitedRead string `readpermission:"limited.read"`
Embeded EmbedType
Hidden HiddenStruct `readpermission:"hidden"`
ThisIsPtr *string `readpermission:"limited.read"`
}
func ClearStruct(object interface{}, u User) {
var typ reflect.Type
var val reflect.Value
if reflect.TypeOf(object).Kind() == reflect.Ptr {
typ = reflect.TypeOf(object).Elem()
val = reflect.ValueOf(object).Elem()
} else {
typ = reflect.TypeOf(object)
val = reflect.ValueOf(object)
}
var clearData func(t reflect.Type, v reflect.Value, u User)
clearData = func(t reflect.Type, v reflect.Value, u User) {
for i := 0; i < v.NumField(); i++ {
fieldVal := v.Field(i)
fieldTyp := t.Field(i)
if fieldVal.CanSet() {
if perm := fieldTyp.Tag.Get("readpermission"); perm != "" && !u.HasPermission(perm) {
fieldVal.Set(reflect.Zero(fieldTyp.Type))
}
if fieldVal.Kind() == reflect.Struct {
clearData(fieldTyp.Type, fieldVal, u)
}
}
}
}
clearData(typ, val, u)
}
func main() {
u1 := User{[]string{"edit", "create", "limited.read", "limited.embed.read", "limited.embed.embed.read"}}
u2 := User{[]string{"limited.read", "limited.embed.read"}}
u3 := User{}
ptrString := "pointerString"
t1 := TestPermission{
PublicField: "One",
LimitedRead: "Two",
Embeded: EmbedType{
PublicField: "Three",
LimitedRead: "Four",
LimitedEmbedRead: "Five",
LimitEmbedEmbedRead: EmbedEmbedType{
PublicField: "Six",
LimitedRead: "Seven",
LimitedEmbedRead: "Eight",
LimitedEmbedEmbedRead: "Nine",
},
},
Hidden: HiddenStruct{
Hidden: "Access denied",
},
ThisIsPtr: &ptrString,
}
t2 := t1
t3 := t1
fmt.Printf("Original: %#v\n", t1)
ClearStruct(&t1, u1)
fmt.Printf("Cleared with all permissions (except hidden): %#v\n", t1)
ClearStruct(&t2, u2)
fmt.Printf("Cleared with limited permissions: %#v\n", t2)
ClearStruct(&t3, u3)
fmt.Printf("Cleared without permissions: %#v\n", t3)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.