Created
November 16, 2021 13:33
-
-
Save aloftin/579bf29b0a8a1595fb9c4adb9b07f12a to your computer and use it in GitHub Desktop.
This is a simplified example of how struct tags can be used to mask data.
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 ( | |
| "encoding/json" | |
| "fmt" | |
| "log" | |
| "os" | |
| "reflect" | |
| ) | |
| // Name of the struct tag used in examples | |
| const tagName = "phi" | |
| type User struct { | |
| Id int `json:"id"` | |
| Name string `json:"name"` | |
| Email string `json:"email"` | |
| SSN string `json:"ssn" phi:"XXX-XX-XXXX"` | |
| } | |
| func GetUsers() []User { | |
| users := []User{ | |
| {Id: 1, Name: "John Smith", Email: "jsmith@test.com", SSN: "987-65-4321"}, | |
| {Id: 2, Name: "Jane Doe", Email: "jdoe@test.com", SSN: "123-45-6789"}, | |
| } | |
| return users | |
| } | |
| func maskPHI(s interface{}) interface{} { | |
| t := reflect.TypeOf(s) | |
| unmasked := reflect.ValueOf(s) | |
| // Make updatable copy of the struct in reflection land | |
| masked := reflect.New(unmasked.Type()).Elem() | |
| masked.Set(unmasked) | |
| // Iterate over all available fields and read the tag value | |
| for i := 0; i < t.NumField(); i++ { | |
| field := t.Field(i) | |
| value := masked.FieldByName(field.Name) | |
| phiTagValue := field.Tag.Get(tagName) | |
| if phiTagValue != "" { | |
| // Overwrite the field value with the tag value | |
| value.SetString(phiTagValue) | |
| } | |
| } | |
| // Return as interface{} instead of struct type | |
| return masked.Interface() | |
| } | |
| func main() { | |
| users := GetUsers() | |
| res := make([]User, 0, len(users)) | |
| for _, u := range users { | |
| mu := maskPHI(u).(User) // masking underlying values on the User | |
| res = append(res, mu) | |
| } | |
| out, err := json.MarshalIndent(res, "", " ") | |
| if err != nil { | |
| log.Println(err) | |
| os.Exit(1) | |
| } | |
| fmt.Println(string(out)) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment