github.com/infraboard/keyauth@v0.8.1/apps/policy/policy_ext.go (about)

     1  package policy
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"hash/fnv"
     7  	"strings"
     8  
     9  	"github.com/infraboard/mcube/http/request"
    10  	"github.com/infraboard/mcube/types/ftime"
    11  
    12  	"github.com/infraboard/keyauth/apps/namespace"
    13  	"github.com/infraboard/keyauth/apps/role"
    14  	"github.com/infraboard/keyauth/apps/user"
    15  )
    16  
    17  // New 新实例
    18  func New(req *CreatePolicyRequest) (*Policy, error) {
    19  	if err := req.Validate(); err != nil {
    20  		return nil, err
    21  	}
    22  
    23  	p := &Policy{
    24  		CreateAt:    ftime.Now().Timestamp(),
    25  		UpdateAt:    ftime.Now().Timestamp(),
    26  		Creater:     req.Creater,
    27  		Domain:      req.Domain,
    28  		NamespaceId: req.NamespaceId,
    29  		Account:     req.Account,
    30  		RoleId:      req.RoleId,
    31  		Scope:       req.Scope,
    32  		ExpiredTime: req.ExpiredTime,
    33  		Type:        req.Type,
    34  	}
    35  	p.genID()
    36  
    37  	return p, nil
    38  }
    39  
    40  // NewDefaultPolicy todo
    41  func NewDefaultPolicy() *Policy {
    42  	return &Policy{}
    43  }
    44  
    45  func (p *Policy) genID() {
    46  	h := fnv.New32a()
    47  	hashedStr := fmt.Sprintf("%s-%s-%s-%s",
    48  		p.Domain, p.NamespaceId, p.Account, p.RoleId)
    49  
    50  	h.Write([]byte(hashedStr))
    51  	p.Id = fmt.Sprintf("%x", h.Sum32())
    52  }
    53  
    54  // CheckDependence todo
    55  func (p *Policy) CheckDependence(ctx context.Context, u user.ServiceServer, r role.ServiceServer, ns namespace.ServiceServer) (*user.User, error) {
    56  	account, err := u.DescribeAccount(ctx, user.NewDescriptAccountRequestWithAccount(p.Account))
    57  	if err != nil {
    58  		return nil, fmt.Errorf("check user error, %s", err)
    59  	}
    60  
    61  	_, err = r.DescribeRole(ctx, role.NewDescribeRoleRequestWithID(p.RoleId))
    62  	if err != nil {
    63  		return nil, fmt.Errorf("check role error, %s", err)
    64  	}
    65  
    66  	if !p.IsAllNamespace() {
    67  		_, err = ns.DescribeNamespace(ctx, namespace.NewNewDescriptNamespaceRequestWithID(p.NamespaceId))
    68  		if err != nil {
    69  			return nil, fmt.Errorf("check namespace error, %s", err)
    70  		}
    71  	}
    72  
    73  	return account, nil
    74  }
    75  
    76  // IsAllNamespace 是否是对账所有namespace的测试
    77  func (p *Policy) IsAllNamespace() bool {
    78  	return p.NamespaceId == "*"
    79  }
    80  
    81  // NewCreatePolicyRequest 请求实例
    82  func NewCreatePolicyRequest() *CreatePolicyRequest {
    83  	return &CreatePolicyRequest{}
    84  }
    85  
    86  // Validate 校验请求合法
    87  func (req *CreatePolicyRequest) Validate() error {
    88  	return validate.Struct(req)
    89  }
    90  
    91  // NewPolicySet todo
    92  func NewPolicySet() *Set {
    93  	return &Set{
    94  		Items: []*Policy{},
    95  	}
    96  }
    97  
    98  // Users 策略包含的所有用户ID, 已去重
    99  func (s *Set) Users() []string {
   100  	users := map[string]struct{}{}
   101  	for i := range s.Items {
   102  		users[s.Items[i].Account] = struct{}{}
   103  	}
   104  
   105  	set := make([]string, 0, len(users))
   106  	for k := range users {
   107  		set = append(set, k)
   108  	}
   109  
   110  	return set
   111  }
   112  
   113  // Add 添加
   114  func (s *Set) Add(e *Policy) {
   115  	s.Items = append(s.Items, e)
   116  }
   117  
   118  // Length todo
   119  func (s *Set) Length() int {
   120  	return len(s.Items)
   121  }
   122  
   123  // GetRoles todo
   124  func (s *Set) GetRoles(ctx context.Context, r role.ServiceServer, withPermission bool) (*role.Set, error) {
   125  	set := role.NewRoleSet()
   126  	for i := range s.Items {
   127  		req := role.NewDescribeRoleRequestWithID(s.Items[i].RoleId)
   128  		req.WithPermissions = withPermission
   129  
   130  		ins, err := r.DescribeRole(ctx, req)
   131  		if err != nil {
   132  			return nil, err
   133  		}
   134  		// 继承policy上的范围限制
   135  		ins.Scope = s.Items[i].Scope
   136  		set.Add(ins)
   137  	}
   138  	return set, nil
   139  }
   140  
   141  // UserRoles 获取用户的角色
   142  func (s *Set) UserRoles(account string) []string {
   143  	rns := []string{}
   144  	for i := range s.Items {
   145  		item := s.Items[i]
   146  		if item.Account == account {
   147  			rns = append(rns, item.RoleId)
   148  		}
   149  	}
   150  
   151  	if len(rns) == 0 {
   152  		rns = append(rns, "vistor")
   153  	}
   154  
   155  	return rns
   156  }
   157  
   158  // GetScope todo
   159  func (s *Set) GetScope(account string) string {
   160  	scopes := []string{}
   161  	for i := range s.Items {
   162  		item := s.Items[i]
   163  		if item.Account == account {
   164  			scopes = append(scopes, item.Scope)
   165  		}
   166  	}
   167  	return strings.Join(scopes, " ")
   168  }
   169  
   170  func (s *Set) GetNamespace() (nss []string) {
   171  	nmap := map[string]struct{}{}
   172  	for i := range s.Items {
   173  		nmap[s.Items[i].NamespaceId] = struct{}{}
   174  	}
   175  
   176  	for k := range nmap {
   177  		nss = append(nss, k)
   178  	}
   179  
   180  	return
   181  }
   182  
   183  func (s *Set) GetNamespaceWithPage(page *request.PageRequest) (nss []string, total int64) {
   184  	nmap := map[string]struct{}{}
   185  	for i := range s.Items {
   186  		// 如果policy的namespace为* , 表示所有namespace
   187  		if s.Items[i].NamespaceId == "*" {
   188  			return []string{}, 0
   189  		}
   190  
   191  		nmap[s.Items[i].NamespaceId] = struct{}{}
   192  	}
   193  
   194  	offset := page.PageSize*page.PageNumber - 1
   195  	end := offset + page.PageSize
   196  
   197  	var count uint64 = 0
   198  	for k := range nmap {
   199  		if count >= offset && count < end {
   200  			nss = append(nss, k)
   201  		}
   202  
   203  		count++
   204  	}
   205  
   206  	return nss, int64(len(nmap))
   207  }