Skip to content

Commit 3670f3f

Browse files
committed
streamlined access info check, especially for insecure_mode
1 parent 66a4e73 commit 3670f3f

File tree

4 files changed

+35
-42
lines changed

4 files changed

+35
-42
lines changed

internal/api/access.go

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package api
88

99
import (
1010
"encoding/json"
11+
"fmt"
1112
"net/http"
1213
"strings"
1314

@@ -18,7 +19,6 @@ import (
1819
type accessInfo struct {
1920
user string
2021
service bool
21-
insecureMode bool // full access to everything; can not be obtained from bits
2222
protectedPrefixes []string
2323
bitAdmin bool
2424
bitDeveloper bool
@@ -37,19 +37,22 @@ func parseAccessToken(jwtHelper *vkuth.JWTHelper,
3737
insecureMode bool) (accessInfo, error) {
3838
if localMode || insecureMode {
3939
ai := accessInfo{
40-
user: "@local_mode",
40+
user: "@insecure_mode",
4141
protectedPrefixes: protectedPrefixes,
4242
bitViewDefault: true,
4343
bitEditDefault: true,
44+
bitAdmin: localMode,
4445
bitDeveloper: localMode,
4546
bitViewPrefix: map[string]bool{},
4647
bitEditPrefix: map[string]bool{},
4748
bitViewMetric: map[string]bool{},
4849
bitEditMetric: map[string]bool{},
49-
insecureMode: insecureMode,
5050
}
5151
return ai, nil
5252
}
53+
if accessToken == "" { // For better error text. Validation would return cryptic "invalid number of segments"
54+
return accessInfo{}, httpErr(http.StatusUnauthorized, fmt.Errorf("empty access token, auth service (vkuth) is down"))
55+
}
5356
data, err := jwtHelper.ParseVkuthData(accessToken)
5457
if err != nil {
5558
return accessInfo{}, httpErr(http.StatusUnauthorized, err)
@@ -62,7 +65,6 @@ func parseAccessToken(jwtHelper *vkuth.JWTHelper,
6265
bitEditPrefix: map[string]bool{},
6366
bitViewMetric: map[string]bool{},
6467
bitEditMetric: map[string]bool{},
65-
insecureMode: insecureMode,
6668
}
6769

6870
bits := data.Bits
@@ -120,9 +122,6 @@ func (ai *accessInfo) protectedMetric(name string) bool {
120122
}
121123

122124
func (ai *accessInfo) CanViewMetricName(name string) bool {
123-
if ai.insecureMode {
124-
return true
125-
}
126125
if format.RemoteConfigMetric(name) && !ai.bitAdmin {
127126
return false // remote config can only be viewed by administrators
128127
}
@@ -136,7 +135,7 @@ func (ai *accessInfo) CanViewMetric(metric format.MetricMetaValue) bool {
136135
}
137136

138137
func (ai *accessInfo) canChangeMetricByName(create bool, old format.MetricMetaValue, new_ format.MetricMetaValue) bool {
139-
if ai.insecureMode || ai.bitAdmin {
138+
if ai.bitAdmin {
140139
return true
141140
}
142141

@@ -152,9 +151,6 @@ func (ai *accessInfo) canChangeMetricByName(create bool, old format.MetricMetaVa
152151
}
153152

154153
func (ai *accessInfo) CanEditMetric(create bool, old format.MetricMetaValue, new_ format.MetricMetaValue) bool {
155-
if ai.insecureMode {
156-
return true
157-
}
158154
if ai.canChangeMetricByName(create, old, new_) {
159155
if ai.bitAdmin {
160156
return true
@@ -177,13 +173,6 @@ func (ai *accessInfo) CanEditMetric(create bool, old format.MetricMetaValue, new
177173
return false
178174
}
179175

180-
func (ai *accessInfo) isAdmin() bool {
181-
if ai.insecureMode {
182-
return true
183-
}
184-
return ai.bitAdmin
185-
}
186-
187176
func preKey(m format.MetricMetaValue) uint32 {
188177
return m.PreKeyFrom
189178
}

internal/api/handler.go

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ const (
159159
journalUpdateTimeout = 2 * time.Second
160160

161161
// healthcheck should query any lightweight metric, this one was chosen randomly
162-
healthcheckMetric = "__agg_bucket_receive_delay_sec"
162+
healthcheckMetric = "__agg_bucket_receive_delay_sec" // format.BuiltinMetricMetaAggBucketReceiveDelaySec.Name
163163
healthcheckQuery = `{@name="` + healthcheckMetric + `",@what="avg"}`
164164
)
165165

@@ -1172,7 +1172,7 @@ func HandleGetMetric(r *httpRequestHandler) {
11721172
}
11731173

11741174
func HandleGetPromConfig(h *httpRequestHandler) {
1175-
if !h.accessInfo.isAdmin() {
1175+
if !h.accessInfo.bitAdmin {
11761176
err := httpErr(http.StatusNotFound, fmt.Errorf("config is not found"))
11771177
respondJSON(h, nil, 0, 0, err)
11781178
return
@@ -1186,7 +1186,7 @@ func HandleGetPromConfig(h *httpRequestHandler) {
11861186
}
11871187

11881188
func HandleGetPromConfigGenerated(h *httpRequestHandler) {
1189-
if !h.accessInfo.isAdmin() {
1189+
if !h.accessInfo.bitAdmin {
11901190
err := httpErr(http.StatusNotFound, fmt.Errorf("config is not found"))
11911191
respondJSON(h, nil, 0, 0, err)
11921192
return
@@ -1288,7 +1288,7 @@ func HandlePostResetFlood(r *httpRequestHandler) {
12881288
if r.checkReadOnlyMode() {
12891289
return
12901290
}
1291-
if !r.accessInfo.isAdmin() {
1291+
if !r.accessInfo.bitAdmin {
12921292
err := httpErr(http.StatusForbidden, fmt.Errorf("admin access required"))
12931293
respondJSON(r, nil, 0, 0, err)
12941294
return
@@ -1316,7 +1316,7 @@ func HandlePostPromConfig(r *httpRequestHandler) {
13161316
if r.checkReadOnlyMode() {
13171317
return
13181318
}
1319-
if !r.accessInfo.isAdmin() {
1319+
if !r.accessInfo.bitAdmin {
13201320
err := httpErr(http.StatusNotFound, fmt.Errorf("config is not found"))
13211321
respondJSON(r, nil, 0, 0, err)
13221322
return
@@ -1357,7 +1357,7 @@ func HandlePostKnownTags(r *httpRequestHandler) {
13571357
if r.checkReadOnlyMode() {
13581358
return
13591359
}
1360-
if !r.accessInfo.isAdmin() {
1360+
if !r.accessInfo.bitAdmin {
13611361
err := httpErr(http.StatusNotFound, fmt.Errorf("not found"))
13621362
respondJSON(r, nil, 0, 0, err)
13631363
return
@@ -1393,7 +1393,7 @@ func HandlePostKnownTags(r *httpRequestHandler) {
13931393
}
13941394

13951395
func HandleGetKnownTags(h *httpRequestHandler) {
1396-
if !h.accessInfo.isAdmin() {
1396+
if !h.accessInfo.bitAdmin {
13971397
err := httpErr(http.StatusNotFound, fmt.Errorf("config is not found"))
13981398
respondJSON(h, nil, 0, 0, err)
13991399
return
@@ -1621,7 +1621,7 @@ func (h *Handler) handleGetNamespaceList(ai accessInfo, showInvisible bool) (*Ge
16211621
}
16221622

16231623
func (h *Handler) handlePostNamespace(ctx context.Context, ai accessInfo, namespace format.NamespaceMeta, create bool) (*NamespaceInfo, error) {
1624-
if !ai.isAdmin() {
1624+
if !ai.bitAdmin {
16251625
return nil, httpErr(http.StatusNotFound, fmt.Errorf("namespace %s not found", namespace.Name))
16261626
}
16271627
if !create {
@@ -1656,7 +1656,7 @@ func (h *Handler) handlePostNamespace(ctx context.Context, ai accessInfo, namesp
16561656
}
16571657

16581658
func (h *Handler) handlePostGroup(ctx context.Context, ai accessInfo, group format.MetricsGroup, create bool) (*MetricsGroupInfo, error) {
1659-
if !ai.isAdmin() {
1659+
if !ai.bitAdmin {
16601660
return nil, httpErr(http.StatusNotFound, fmt.Errorf("group %s not found", group.Name))
16611661
}
16621662
if !create {
@@ -2177,15 +2177,19 @@ func HandleFrontendStat(r *httpRequestHandler) {
21772177
func (h *requestHandler) queryBadges(ctx context.Context, req seriesRequest, meta *format.MetricMetaValue) (res seriesResponse, cleanup func()) {
21782178
timeNow := time.Now()
21792179
badges := requestHandler{
2180-
Handler: h.Handler,
2181-
accessInfo: accessInfo{insecureMode: true},
2180+
Handler: h.Handler,
2181+
accessInfo: accessInfo{
2182+
user: h.accessInfo.user,
2183+
service: h.accessInfo.service,
2184+
bitViewMetric: map[string]bool{format.BuiltinMetricMetaBadges.Name: true},
2185+
},
21822186
endpointStat: endpointStat{
21832187
timestamp: timeNow,
21842188
endpoint: h.endpointStat.endpoint,
21852189
protocol: h.endpointStat.protocol,
21862190
method: h.endpointStat.method,
21872191
dataFormat: h.endpointStat.dataFormat,
2188-
metric: "-35", // format.BuiltinMetricIDBadges
2192+
metric: "-35", // strconv.Itoa(format.BuiltinMetricIDBadges)
21892193
tokenName: h.endpointStat.tokenName,
21902194
user: h.endpointStat.user,
21912195
priority: h.endpointStat.priority,
@@ -3267,7 +3271,7 @@ func (r *DashboardTimeShifts) UnmarshalJSON(bs []byte) error {
32673271
}
32683272

32693273
func (r *seriesRequest) validate(h *requestHandler) error {
3270-
if r.avoidCache && !h.accessInfo.isAdmin() {
3274+
if r.avoidCache && !h.accessInfo.bitAdmin {
32713275
return httpErr(404, fmt.Errorf(""))
32723276
}
32733277
if r.step == _1M {
@@ -3322,14 +3326,14 @@ func HandleProfTrace(h *httpRequestHandler) {
33223326
}
33233327

33243328
func pprofAccessAllowed(h *httpRequestHandler) bool {
3325-
if ok := h.accessInfo.insecureMode || h.accessInfo.bitAdmin; !ok {
3329+
if !h.accessInfo.bitAdmin {
33263330
h.Response().WriteHeader(http.StatusForbidden)
33273331
return false
33283332
}
33293333
return true
33303334
}
33313335

3332-
func defaultAccessInfo(h *requestHandler) (accessInfo, bool) {
3336+
func healthcheckAccessInfo(h *requestHandler) (accessInfo, bool) {
33333337
switch h.endpointStat.endpoint {
33343338
// healthcheck endpoint is used by nginx checks directly without token
33353339
case EndpointHealthcheck:
@@ -3356,7 +3360,7 @@ func (h *requestHandler) init(accessToken, version string) (err error) {
33563360
return fmt.Errorf("invalid version: %q", version)
33573361
}
33583362
if h.accessInfo, err = parseAccessToken(h.jwtHelper, accessToken, h.protectedMetricPrefixes, h.LocalMode, h.insecureMode); err != nil {
3359-
if ai, ok := defaultAccessInfo(h); !ok {
3363+
if ai, ok := healthcheckAccessInfo(h); !ok {
33603364
return err
33613365
} else {
33623366
h.accessInfo = ai

internal/api/http_router.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ func (r *httpRoute) handle(w http.ResponseWriter, req *http.Request) {
162162

163163
func DumpInternalServerErrors(r *httpRequestHandler) {
164164
w := r.Response()
165-
if ok := r.accessInfo.insecureMode || r.accessInfo.bitAdmin; !ok {
165+
if !r.accessInfo.bitAdmin {
166166
w.WriteHeader(http.StatusForbidden)
167167
return
168168
}
@@ -187,7 +187,7 @@ func DumpInternalServerErrors(r *httpRequestHandler) {
187187

188188
func DumpQueryTopMemUsage(r *httpRequestHandler) {
189189
w := r.Response()
190-
if ok := r.accessInfo.insecureMode || r.accessInfo.bitAdmin; !ok {
190+
if !r.accessInfo.bitAdmin {
191191
w.WriteHeader(http.StatusForbidden)
192192
return
193193
}
@@ -220,7 +220,7 @@ func DumpQueryTopMemUsage(r *httpRequestHandler) {
220220

221221
func DumpQueryTopDuration(r *httpRequestHandler) {
222222
w := r.Response()
223-
if ok := r.accessInfo.insecureMode || r.accessInfo.bitAdmin; !ok {
223+
if !r.accessInfo.bitAdmin {
224224
w.WriteHeader(http.StatusForbidden)
225225
return
226226
}

internal/api/tscache2_debug.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type cache2DebugLogMessage struct {
1717

1818
func DebugCacheLog(r *httpRequestHandler) {
1919
w := r.Response()
20-
if ok := r.accessInfo.insecureMode || r.accessInfo.bitAdmin; !ok {
20+
if !r.accessInfo.bitAdmin {
2121
w.WriteHeader(http.StatusForbidden)
2222
return
2323
}
@@ -46,7 +46,7 @@ func DebugCacheLog(r *httpRequestHandler) {
4646

4747
func DebugCacheReset(r *httpRequestHandler) {
4848
w := r.Response()
49-
if ok := r.accessInfo.insecureMode || r.accessInfo.bitAdmin; !ok {
49+
if !r.accessInfo.bitAdmin {
5050
w.WriteHeader(http.StatusForbidden)
5151
return
5252
}
@@ -57,7 +57,7 @@ func DebugCacheReset(r *httpRequestHandler) {
5757

5858
func DebugCacheInfo(r *httpRequestHandler) {
5959
w := r.Response()
60-
if ok := r.accessInfo.insecureMode || r.accessInfo.bitAdmin; !ok {
60+
if !r.accessInfo.bitAdmin {
6161
w.WriteHeader(http.StatusForbidden)
6262
return
6363
}
@@ -110,7 +110,7 @@ func DebugCacheInfo(r *httpRequestHandler) {
110110

111111
func DebugCacheCreateMetrics(r *httpRequestHandler) {
112112
w := r.Response()
113-
if ok := r.accessInfo.insecureMode || r.accessInfo.bitAdmin; !ok {
113+
if !r.accessInfo.bitAdmin {
114114
w.WriteHeader(http.StatusForbidden)
115115
return
116116
}
@@ -242,7 +242,7 @@ func debugCacheCreateMetric(r *httpRequestHandler, metric format.MetricMetaValue
242242
metric.MetricID = v.MetricID
243243
metric.Version = v.Version
244244
}
245-
if _, err := r.handlePostMetric(context.Background(), accessInfo{insecureMode: true}, "", metric); err != nil {
245+
if _, err := r.handlePostMetric(context.Background(), r.accessInfo, "", metric); err != nil {
246246
w.Write([]byte(err.Error()))
247247
} else {
248248
w.Write([]byte("OK"))

0 commit comments

Comments
 (0)