github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/modules/access_key/access_key_privileges.go (about)

     1  package access_key
     2  
     3  import (
     4  	"net/http"
     5  	"sort"
     6  	"sync"
     7  
     8  	"github.com/pkg/errors"
     9  
    10  	"github.com/machinefi/w3bstream/pkg/depends/kit/httptransport"
    11  	"github.com/machinefi/w3bstream/pkg/depends/kit/kit"
    12  	"github.com/machinefi/w3bstream/pkg/enums"
    13  	"github.com/machinefi/w3bstream/pkg/models"
    14  )
    15  
    16  type OperatorMeta struct {
    17  	OperatorID  string
    18  	Summary     string
    19  	Method      string
    20  	Attr        enums.ApiOperatorAttr
    21  	MinimalPerm enums.AccessPermission
    22  }
    23  
    24  type WithOperatorAttr interface {
    25  	OperatorAttr() enums.ApiOperatorAttr
    26  }
    27  
    28  type GroupMetaBase struct {
    29  	Name string `json:"name"`
    30  	Desc string `json:"desc"`
    31  }
    32  
    33  type GroupMeta struct {
    34  	GroupMetaBase
    35  	Operators map[string]*OperatorMeta
    36  }
    37  
    38  type GroupAccessPrivilege struct {
    39  	Name string                 `json:"name"`
    40  	Perm enums.AccessPermission `json:"perm"`
    41  }
    42  
    43  type GroupAccessPrivileges []GroupAccessPrivilege
    44  
    45  func (gaps GroupAccessPrivileges) ConvToPrivilegeModel() models.GroupAccessPrivileges {
    46  	ret := make(models.GroupAccessPrivileges)
    47  
    48  	for k := range gOperatorGroups {
    49  		ret[k] = enums.ACCESS_PERMISSION__NO_ACCESS
    50  	}
    51  
    52  	for i := range gaps {
    53  		p := &gaps[i]
    54  		if _, ok := ret[p.Name]; !ok {
    55  			continue
    56  		}
    57  
    58  		switch p.Perm {
    59  		case enums.ACCESS_PERMISSION__READ_WRITE, enums.ACCESS_PERMISSION__READONLY, enums.ACCESS_PERMISSION__NO_ACCESS:
    60  			ret[p.Name] = p.Perm
    61  		default:
    62  			ret[p.Name] = enums.ACCESS_PERMISSION__NO_ACCESS
    63  		}
    64  	}
    65  	return ret
    66  }
    67  
    68  func ConvToGroupMetaWithPrivileges(privileges models.GroupAccessPrivileges) []*GroupMetaWithPrivilege {
    69  	ret := make([]*GroupMetaWithPrivilege, 0, len(privileges))
    70  	for name, perm := range privileges {
    71  		ret = append(ret, &GroupMetaWithPrivilege{
    72  			GroupMetaBase: GroupMetaBase{
    73  				Name: name,
    74  				Desc: gOperatorGroups[name].Desc,
    75  			},
    76  			Perm: perm,
    77  		})
    78  	}
    79  	return ret
    80  }
    81  
    82  type GroupMetaWithPrivilege struct {
    83  	GroupMetaBase
    84  	Perm enums.AccessPermission `json:"perm"`
    85  }
    86  
    87  var (
    88  	// gOperatorGroups mapping group name and  group meta
    89  	gOperatorGroups = map[string]*GroupMeta{}
    90  	// gOperators mapping operator id and group name
    91  	gOperators = map[string]string{}
    92  
    93  	// gOperatorGroupMetas group meta list
    94  	gOperatorGroupMetas         []*GroupMetaBase
    95  	gOperatorGroupMetasInitOnce = &sync.Once{}
    96  )
    97  
    98  func RouterRegister(r *kit.Router, name, desc string) {
    99  	if _, ok := gOperatorGroups[name]; ok {
   100  		panic(errors.Errorf("group already registered: group[%s]", name))
   101  	}
   102  
   103  	routes := r.Routes()
   104  	group := &GroupMeta{
   105  		GroupMetaBase: GroupMetaBase{
   106  			Name: name,
   107  			Desc: desc,
   108  		},
   109  		Operators: map[string]*OperatorMeta{},
   110  	}
   111  
   112  	for _, route := range routes {
   113  		factories := httptransport.NewHttpRouteMeta(route).Metas
   114  
   115  		fact := factories[len(factories)-1]
   116  		op := &OperatorMeta{
   117  			OperatorID: fact.Type.Name(),
   118  			Summary:    fact.Summary,
   119  			Method:     fact.Method,
   120  			Attr:       enums.API_OPERATOR_ATTR__COMMON,
   121  		}
   122  
   123  		switch op.Method {
   124  		case http.MethodGet:
   125  			op.MinimalPerm = enums.ACCESS_PERMISSION__READONLY
   126  		case http.MethodPost, http.MethodPut, http.MethodDelete:
   127  			op.MinimalPerm = enums.ACCESS_PERMISSION__READ_WRITE
   128  		default:
   129  			continue
   130  		}
   131  
   132  		if with, ok := fact.Operator.(WithOperatorAttr); ok {
   133  			op.Attr = with.OperatorAttr()
   134  		}
   135  
   136  		if groupName, ok := gOperators[op.OperatorID]; ok {
   137  			panic(errors.Errorf("operator id already registered in group: operator[%s] group[%s]", op.OperatorID, groupName))
   138  		}
   139  
   140  		gOperators[op.OperatorID] = name
   141  		group.Operators[op.OperatorID] = op
   142  	}
   143  	gOperatorGroups[name] = group
   144  }
   145  
   146  func OperatorGroupMetaList() []*GroupMetaBase {
   147  	gOperatorGroupMetasInitOnce.Do(func() {
   148  		for _, meta := range gOperatorGroups {
   149  			v := meta.GroupMetaBase
   150  			gOperatorGroupMetas = append(gOperatorGroupMetas, &v)
   151  		}
   152  		sort.Slice(gOperatorGroupMetas, func(i, j int) bool {
   153  			return gOperatorGroupMetas[i].Name < gOperatorGroupMetas[j].Name
   154  		})
   155  	})
   156  	return gOperatorGroupMetas
   157  }