Created
June 25, 2019 06:19
-
-
Save hosszukalman/bd8e952298feb02c903ad0f85c2dbc21 to your computer and use it in GitHub Desktop.
Permission based struct clearing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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