根据用户角色控制字段可见性 [英] Control field visibility depending on User role

查看:35
本文介绍了根据用户角色控制字段可见性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想根据用户角色隐藏/显示模型的某些字段。

实现它最常用的方式是什么?

我真的不想创建相同模型的N个不同类型(其中N是用户角色的数量)。比如: UserEmployee、AdminEmployee、诸如此类的员工。

如果有为它使用标签的解决方案,那就太好了:

type Employee struct {
   ID string `visibility:"admin,user"`
   Name string `visibility:"admin,user"`
   Salary int `visibility:"admin"`
}

jsonBytes, _ := someLib.Marshal(Employee{"1", "John", 5000}, "user")

fmt.Println(string(jsonBytes)) // {"id":"1","name":"John"}

这个问题真的很广泛。我只是想知道你是如何处理这种情况的,或者在围棋界最常见的方式是什么。我想要干净和集中(所有型号相同)的解决方案,不需要产生大量的重复代码。

我以前尝试过什么:我只是尝试对所有情况使用单独的模型,并在它们之间进行转换。

推荐答案

  1. 创建您的类型(在此问题中为Employee)的空结构,该结构将保存筛选的数据。
  2. 使用reflect包比较字段标记是否包含所需的标记值(可见性角色)。
  3. 当我们找到匹配的标记和json marshal输出结构时,将基本结构的值复制到筛选器结构:

package main

import (
    "encoding/json"
    "fmt"
    "reflect"
    "strings"
)

type Employee struct {
    ID       string          `visibility:"admin, hr, user" json:"id,omitempty"`
    Name     string          `visibility:"admin, hr, user" json:"name,omitempty"`
    Salary   int             `visibility:"admin, hr" json:"salary,omitempty"`
    Password string          `visibility:"admin" json:"password,omitempty"`
    Rights   map[string]bool `visibility:"admin" json:"rights,omitempty"`
    Boss     *Employee       `visibility:"admin, hr" json:"boss,omitempty"`
}

func filterEmployee(emp Employee, role string) Employee {
    var fEmployee Employee
    ev := reflect.ValueOf(emp)
    et := reflect.TypeOf(emp)

    // Iterate through each field within the struct
    for i := 0; i < ev.NumField(); i++ {
        v := ev.Field(i)
        t := et.Field(i)
        roles := t.Tag.Get("visibility")

        if strings.Contains(roles, role) {
            switch i {
            case 0: // ID
                fEmployee.ID = v.String()
            case 1: // Name
                fEmployee.Name = v.String()
            case 2: // Salary
                fEmployee.Salary = int(v.Int())
            case 3: // Password
                fEmployee.Password = v.String()
            case 4: // Rights
                fEmployee.Rights = v.Interface().(map[string]bool)
            case 5: // Boss
                fEmployee.Boss = v.Interface().(*Employee)
            }
        }
    }
    return fEmployee
}

func main() {

    e := Employee{
        "1",
        "Jack",
        100000,
        "password321",
        map[string]bool{"create": false, "update": false},
        &Employee{
            "2",
            "John",
            120000,
            "pwd",
            map[string]bool{"create": true, "update": true},
            nil,
        },
    }

    fuser := filterEmployee(e, "user")
    fhr := filterEmployee(e, "hr")
    fadmin := filterEmployee(e, "admin")

    buser, err := json.MarshalIndent(fuser, "", "  ")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("Filtering with role user: ")
    fmt.Println(string(buser))

    bhr, err := json.MarshalIndent(fhr, "", "  ")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("
Filtering with role hr: ")
    fmt.Println(string(bhr))

    badmin, err := json.MarshalIndent(fadmin, "", "  ")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("
Filtering with role admin: ")
    fmt.Println(string(badmin))
}

输出:

Filtering with role user: 
{
  "id": "1",
  "name": "Jack"
}

Filtering with role hr: 
{
  "id": "1",
  "name": "Jack",
  "salary": 100000,
  "boss": {
    "id": "2",
    "name": "John",
    "salary": 120000,
    "password": "pwd",
    "rights": {
      "create": true,
      "update": true
    }
  }
}

Filtering with role admin: 
{
  "id": "1",
  "name": "Jack",
  "salary": 100000,
  "password": "password321",
  "rights": {
    "create": false,
    "update": false
  },
  "boss": {
    "id": "2",
    "name": "John",
    "salary": 120000,
    "password": "pwd",
    "rights": {
      "create": true,
      "update": true
    }
  }
}

Playground

编辑:已更新请求者请求的答案。

查看以前遇到问题的答案的旧操场。

Old Playground

这篇关于根据用户角色控制字段可见性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆