2
2
// Use of this source code is governed by a BSD-style
3
3
// license that can be found in the LICENSE file.
4
4
5
- //go:build go1.16
6
-
7
5
package legacydash
8
6
9
7
import (
10
- "context"
11
8
"crypto/hmac"
12
9
"crypto/md5"
13
10
"encoding/json"
@@ -32,7 +29,7 @@ const (
32
29
// creates a new Result entity, and creates or updates the relevant Commit entity.
33
30
// If the Log field is not empty, resultHandler creates a new Log entity
34
31
// and updates the LogHash field before putting the Commit entity.
35
- func resultHandler (r * http.Request ) (interface {}, error ) {
32
+ func ( h handler ) resultHandler (r * http.Request ) (interface {}, error ) {
36
33
if r .Method != "POST" {
37
34
return nil , errBadMethod (r .Method )
38
35
}
@@ -54,7 +51,7 @@ func resultHandler(r *http.Request) (interface{}, error) {
54
51
}
55
52
// store the Log text if supplied
56
53
if len (res .Log ) > 0 {
57
- hash , err := PutLog (ctx , res .Log )
54
+ hash , err := h . putLog (ctx , res .Log )
58
55
if err != nil {
59
56
return nil , fmt .Errorf ("putting Log: %v" , err )
60
57
}
@@ -75,23 +72,27 @@ func resultHandler(r *http.Request) (interface{}, error) {
75
72
}
76
73
return nil
77
74
}
78
- _ , err := datastoreClient .RunInTransaction (ctx , tx )
75
+ _ , err := h . datastoreCl .RunInTransaction (ctx , tx )
79
76
return nil , err
80
77
}
81
78
82
79
// logHandler displays log text for a given hash.
83
80
// It handles paths like "/log/hash".
84
- func logHandler (w http.ResponseWriter , r * http.Request ) {
81
+ func (h handler ) logHandler (w http.ResponseWriter , r * http.Request ) {
82
+ if h .datastoreCl == nil {
83
+ http .Error (w , "no datastore client" , http .StatusNotFound )
84
+ return
85
+ }
85
86
c := r .Context ()
86
87
hash := r .URL .Path [strings .LastIndex (r .URL .Path , "/" )+ 1 :]
87
88
key := dsKey ("Log" , hash , nil )
88
89
l := new (Log )
89
- if err := datastoreClient .Get (c , key , l ); err != nil {
90
+ if err := h . datastoreCl .Get (c , key , l ); err != nil {
90
91
if err == datastore .ErrNoSuchEntity {
91
92
// Fall back to default namespace;
92
93
// maybe this was on the old dashboard.
93
94
key .Namespace = ""
94
- err = datastoreClient .Get (c , key , l )
95
+ err = h . datastoreCl .Get (c , key , l )
95
96
}
96
97
if err != nil {
97
98
log .Printf ("Error: %v" , err )
@@ -111,7 +112,7 @@ func logHandler(w http.ResponseWriter, r *http.Request) {
111
112
112
113
// clearResultsHandler purge a single build failure from the dashboard.
113
114
// It currently only supports the main Go repo.
114
- func clearResultsHandler (r * http.Request ) (interface {}, error ) {
115
+ func ( h handler ) clearResultsHandler (r * http.Request ) (interface {}, error ) {
115
116
if r .Method != "POST" {
116
117
return nil , errBadMethod (r .Method )
117
118
}
@@ -126,7 +127,7 @@ func clearResultsHandler(r *http.Request) (interface{}, error) {
126
127
127
128
ctx := r .Context ()
128
129
129
- _ , err := datastoreClient .RunInTransaction (ctx , func (tx * datastore.Transaction ) error {
130
+ _ , err := h . datastoreCl .RunInTransaction (ctx , func (tx * datastore.Transaction ) error {
130
131
c := & Commit {
131
132
PackagePath : "" , // TODO(adg): support clearing sub-repos
132
133
Hash : hash ,
@@ -186,12 +187,15 @@ func builderKeyRevoked(builder string) bool {
186
187
return false
187
188
}
188
189
189
- // AuthHandler wraps an http.HandlerFunc with a handler that validates the
190
- // supplied key and builder query parameters.
191
- func AuthHandler (h dashHandler ) http.Handler {
192
- return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
193
- c := r .Context ()
190
+ // authHandler wraps an http.HandlerFunc with a handler that validates the
191
+ // supplied key and builder query parameters with the provided key checker.
192
+ type authHandler struct {
193
+ kc keyCheck
194
+ h dashHandler
195
+ }
194
196
197
+ func (a authHandler ) ServeHTTP (w http.ResponseWriter , r * http.Request ) {
198
+ { // Block to improve diff readability. Can be unnested later.
195
199
// Put the URL Query values into r.Form to avoid parsing the
196
200
// request body when calling r.FormValue.
197
201
r .Form = r .URL .Query ()
@@ -202,13 +206,13 @@ func AuthHandler(h dashHandler) http.Handler {
202
206
// Validate key query parameter for POST requests only.
203
207
key := r .FormValue ("key" )
204
208
builder := r .FormValue ("builder" )
205
- if r .Method == "POST" && ! validKey ( c , key , builder ) {
209
+ if r .Method == "POST" && ! a . kc . ValidKey ( key , builder ) {
206
210
err = fmt .Errorf ("invalid key %q for builder %q" , key , builder )
207
211
}
208
212
209
213
// Call the original HandlerFunc and return the response.
210
214
if err == nil {
211
- resp , err = h (r )
215
+ resp , err = a . h (r )
212
216
}
213
217
214
218
// Write JSON response.
@@ -221,7 +225,7 @@ func AuthHandler(h dashHandler) http.Handler {
221
225
if err = json .NewEncoder (w ).Encode (dashResp ); err != nil {
222
226
log .Printf ("encoding response: %v" , err )
223
227
}
224
- })
228
+ }
225
229
}
226
230
227
231
// validHash reports whether hash looks like a valid git commit hash.
@@ -231,22 +235,27 @@ func validHash(hash string) bool {
231
235
return hash != ""
232
236
}
233
237
234
- func validKey (c context.Context , key , builder string ) bool {
235
- if isMasterKey (c , key ) {
238
+ type keyCheck struct {
239
+ // The builder master key.
240
+ masterKey string
241
+ }
242
+
243
+ func (kc keyCheck ) ValidKey (key , builder string ) bool {
244
+ if kc .isMasterKey (key ) {
236
245
return true
237
246
}
238
247
if builderKeyRevoked (builder ) {
239
248
return false
240
249
}
241
- return key == builderKey (c , builder )
250
+ return key == kc . builderKey (builder )
242
251
}
243
252
244
- func isMasterKey ( ctx context. Context , k string ) bool {
245
- return k == masterKey
253
+ func ( kc keyCheck ) isMasterKey ( k string ) bool {
254
+ return k == kc . masterKey
246
255
}
247
256
248
- func builderKey ( ctx context. Context , builder string ) string {
249
- h := hmac .New (md5 .New , []byte (masterKey ))
257
+ func ( kc keyCheck ) builderKey ( builder string ) string {
258
+ h := hmac .New (md5 .New , []byte (kc . masterKey ))
250
259
h .Write ([]byte (builder ))
251
260
return fmt .Sprintf ("%x" , h .Sum (nil ))
252
261
}
0 commit comments