/
subject_resolver.go
72 lines (64 loc) · 1.78 KB
/
subject_resolver.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package authz
import (
"context"
"github.com/goxiaoy/go-saas-kit/pkg/authn"
)
type SubjectResolver interface {
//ResolveFromContext extract subjects from current ctx
ResolveFromContext(ctx context.Context) ([]Subject, error)
//ResolveProcessed recursively find related subjects. (RBAC)
ResolveProcessed(ctx context.Context, subjects ...Subject) ([]Subject, error)
}
type SubjectResolverImpl struct {
opt *Option
}
var _ SubjectResolver = (*SubjectResolverImpl)(nil)
func NewSubjectResolver(opt *Option) *SubjectResolverImpl {
return &SubjectResolverImpl{opt: opt}
}
func (s *SubjectResolverImpl) ResolveFromContext(ctx context.Context) ([]Subject, error) {
var subjects []Subject
var userId string
userInfo, _ := authn.FromUserContext(ctx)
userId = userInfo.GetId()
//append empty user
subjects = append(subjects, NewUserSubject(userId))
if clientId, ok := authn.FromClientContext(ctx); ok && len(clientId) > 0 {
//do not append empty client
subjects = append(subjects, NewClientSubject(clientId))
}
return subjects, nil
}
func (s *SubjectResolverImpl) ResolveProcessed(ctx context.Context, subjects ...Subject) ([]Subject, error) {
//use contributor
var subjectList []Subject
addIfNotPresent := func(subject Subject) bool {
for _, s := range subjectList {
if s.GetIdentity() == subject.GetIdentity() {
return false
}
}
subjectList = append(subjectList, subject)
return true
}
for _, s := range subjects {
addIfNotPresent(s)
}
i := 0
for {
if i == len(subjectList) {
break
}
for _, contributor := range s.opt.SubjectContributorList {
if subjects, err := contributor.Process(ctx, subjectList[i]); err != nil {
return nil, err
} else {
for _, s2 := range subjects {
addIfNotPresent(s2)
}
}
}
i++
}
return subjectList, nil
}