-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathaccess-controller.go
131 lines (107 loc) · 2.9 KB
/
access-controller.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package controllers
import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/dgrijalva/jwt-go"
"github.com/huaweicloud/golangsdk"
"github.com/opensourceways/app-cla-server/config"
"github.com/opensourceways/app-cla-server/util"
)
const (
PermissionOwnerOfOrg = "owner of org"
PermissionIndividualSigner = "individual signer"
PermissionCorpAdmin = "corporation administrator"
PermissionEmployeeManager = "employee manager"
)
type accessController struct {
RemoteAddr string `json:"remote_addr"`
Expiry int64 `json:"expiry"`
Permission string `json:"permission"`
Payload interface{} `json:"payload"`
}
func (this *accessController) newToken(secret string) (string, error) {
body, err := golangsdk.BuildRequestBody(this, "")
if err != nil {
return "", fmt.Errorf("Failed to create token: build body failed: %s", err.Error())
}
token := jwt.New(jwt.SigningMethodHS256)
token.Claims = jwt.MapClaims(body)
s, err := token.SignedString([]byte(secret))
if err != nil {
return "", err
}
return this.encryptToken(s)
}
func (this *accessController) refreshToken(expiry int64, secret string) (string, error) {
this.Expiry = util.Expiry(expiry)
return this.newToken(secret)
}
func (this *accessController) parseToken(token, secret string) error {
token1, err := this.decryptToken(token)
if err != nil {
return err
}
t, err := jwt.Parse(token1, func(t1 *jwt.Token) (interface{}, error) {
if _, ok := t1.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method")
}
return []byte(secret), nil
})
if err != nil {
return err
}
if !t.Valid {
return fmt.Errorf("Not a valid token")
}
claims, ok := t.Claims.(jwt.MapClaims)
if !ok {
return fmt.Errorf("Not valid claims")
}
d, err := json.Marshal(claims)
if err != nil {
return err
}
return json.Unmarshal(d, this)
}
func (this *accessController) isTokenExpired() bool {
return this.Expiry < util.Now()
}
func (this *accessController) verify(permission []string, addr string) error {
bingo := false
for _, item := range permission {
if this.Permission == item {
bingo = true
break
}
}
if !bingo {
return fmt.Errorf("Not allowed permission")
}
if this.RemoteAddr != addr {
return fmt.Errorf("Unmatched remote address")
}
return nil
}
func (this *accessController) newEncryption() util.SymmetricEncryption {
e, _ := util.NewSymmetricEncryption(config.AppConfig.SymmetricEncryptionKey, "")
return e
}
func (this *accessController) encryptToken(token string) (string, error) {
t, err := this.newEncryption().Encrypt([]byte(token))
if err != nil {
return "", err
}
return hex.EncodeToString(t), nil
}
func (this *accessController) decryptToken(token string) (string, error) {
dst, err := hex.DecodeString(token)
if err != nil {
return "", err
}
s, err := this.newEncryption().Decrypt(dst)
if err != nil {
return "", err
}
return string(s), nil
}