forked from juanfont/headscale
-
Notifications
You must be signed in to change notification settings - Fork 2
/
console_api_keys.go
168 lines (157 loc) · 4.77 KB
/
console_api_keys.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package headscale
import (
_ "embed"
"encoding/json"
"net/http"
"strings"
"time"
)
type KeysData struct {
AuthKeys []Key `json:"authKeys"`
InvalidAuthKeys []InvalidKey `json:"invalidAuthKeys"` // 未实现
ApiKeys []Key `json:"apiKeys"` //未实现
InvalidApiKeys []InvalidKey `json:"invalidApiKeys"` //未实现
OauthClients []OauthClient `json:"oauthClients"` //未实现
InvalidOauthClients []InvalidOauthClient `json:"invalidOauthClients"` //未实现
}
type InvalidOauthClient struct{} //未实现
type OauthClient struct{} //未实现
type InvalidKey struct {
KeyData Key `json:"keyData"`
Revoked string `json:"revoked"`
}
type Key struct {
Id string `json:"id"`
Created string `json:"created"`
Creator string `json:"creator"`
Expiry string `json:"expiry"`
Type string `json:"type"` //"authkey","apikey"
Authkey AuthKeyTypes `json:"authkey"`
Apikey ApiKeyTypes `json:"apikey"`
}
type AuthKeyTypes struct {
Reusable bool `json:"reusable"`
Ephemeral bool `json:"ephemeral"`
Preauthorized bool `json:"preauthorized"` //未实现,建议true
ForAdminPanel bool `json:"forAdminPanel"` //未实现,未知含义,建议false
}
type ApiKeyTypes struct {
Api string `json:"api"` //"control"
}
type GenKeyData struct {
Id string `json:"id"`
FullKey string `json:"fullKey"`
Created string `json:"created"`
Expiry string `json:"expiry"`
}
// 接受/admin/api/keys的Get请求,用于查询AuthKey
func (h *Headscale) CAPIGetKeys(
w http.ResponseWriter,
r *http.Request,
) {
userName := h.verifyTokenIDandGetUser(w, r)
if userName == "" {
h.doAPIResponse(w, "用户信息核对失败", nil)
return
}
authKeys, err := h.ListPreAuthKeys(userName)
if err != nil {
h.doAPIResponse(w, "授权密钥查询失败", nil)
return
}
resData := KeysData{}
resData.AuthKeys = make([]Key, 0)
for _, key := range authKeys {
tmpAuthKey := Key{
Id: key.Key[:12], //key.ID,
Created: Time2SHString(*key.CreatedAt),
Creator: key.User.Name,
Expiry: Time2SHString(*key.Expiration),
Type: "authkey",
Authkey: AuthKeyTypes{
Reusable: key.Reusable,
Ephemeral: key.Ephemeral,
Preauthorized: true, //TODO
ForAdminPanel: false, //TODO
},
}
resData.AuthKeys = append(resData.AuthKeys, tmpAuthKey)
}
h.doAPIResponse(w, "", resData)
}
// 请求报文:{"keyData":{"type":"authkey","expirySeconds":7776000,"authkey":{"ephemeral":false,"reusable":false,"preauthorized":false}}}
type GenKeyREQ struct {
KeyData REQKeyData `json:"keyData"`
}
type REQKeyData struct {
Type string `json:"type"` //"authkey"
ExpirySeconds uint64 `json:"expirySeconds"`
Authkey AuthKeyTypes `json:"authkey"`
}
// 接受/admin/api/keys的Post请求,用于创建AuthKey
func (h *Headscale) CAPIPostKeys(
w http.ResponseWriter,
r *http.Request,
) {
userName := h.verifyTokenIDandGetUser(w, r)
if userName == "" {
h.doAPIResponse(w, "用户信息核对失败", nil)
return
}
err := r.ParseForm()
if err != nil {
h.doAPIResponse(w, "用户请求解析失败:"+err.Error(), nil)
return
}
reqData := GenKeyREQ{}
json.NewDecoder(r.Body).Decode(&reqData)
switch reqData.KeyData.Type {
case "authkey":
keyCfg := reqData.KeyData.Authkey
keyExpiration := time.Now().Add(time.Duration(reqData.KeyData.ExpirySeconds) * time.Second)
genedAuthKey, err := h.CreatePreAuthKey(userName, keyCfg.Reusable, keyCfg.Ephemeral, &keyExpiration, nil)
if err != nil {
h.doAPIResponse(w, "授权密钥创建失败", nil)
return
}
resData := GenKeyData{
Id: genedAuthKey.Key[:12], //genedAuthKey.ID,
FullKey: genedAuthKey.Key,
Created: Time2SHString(*genedAuthKey.CreatedAt),
Expiry: Time2SHString(*genedAuthKey.Expiration),
}
h.doAPIResponse(w, "", resData)
}
}
// 注销Key执行DELETE方法api/keys/:Id
func (h *Headscale) CAPIDelKeys(
w http.ResponseWriter,
r *http.Request,
) {
userName := h.verifyTokenIDandGetUser(w, r)
targetKeyID := strings.TrimPrefix(r.URL.Path, "/admin/api/keys/")
allKeys, err := h.ListPreAuthKeys(userName)
if err != nil {
h.doAPIResponse(w, "查询用户密钥信息失败", nil)
return
}
toDelKeys := make([]PreAuthKey, 0)
for _, key := range allKeys {
if key.Key[:12] == targetKeyID {
toDelKeys = append(toDelKeys, key)
}
}
if len(toDelKeys) == 0 {
h.doAPIResponse(w, "该密钥不存在", nil)
return
} else if len(toDelKeys) > 1 {
h.doAPIResponse(w, "存在多个密钥具备相同短形式(ID),请联系工作人员", nil)
return
}
err = h.DestroyPreAuthKey(toDelKeys[0])
if err != nil {
h.doAPIResponse(w, "执行密钥删除失败", nil)
return
}
h.doAPIResponse(w, "", targetKeyID)
}