1
0
mirror of https://github.com/golang/go synced 2024-11-24 23:17:57 -07:00

dashboard: do not require key in source code

Or else eventually someone will check it in.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5504071
This commit is contained in:
Russ Cox 2011-12-22 10:21:59 -05:00
parent 98fe44bdfc
commit 550856c59d
2 changed files with 61 additions and 14 deletions

View File

@ -322,7 +322,7 @@ func AuthHandler(h dashHandler) http.HandlerFunc {
// Validate key query parameter for POST requests only. // Validate key query parameter for POST requests only.
key := r.FormValue("key") key := r.FormValue("key")
builder := r.FormValue("builder") builder := r.FormValue("builder")
if r.Method == "POST" && !validKey(key, builder) { if r.Method == "POST" && !validKey(c, key, builder) {
err = os.NewError("invalid key: " + key) err = os.NewError("invalid key: " + key)
} }
@ -368,7 +368,8 @@ func keyHandler(w http.ResponseWriter, r *http.Request) {
logErr(w, r, os.NewError("must supply builder in query string")) logErr(w, r, os.NewError("must supply builder in query string"))
return return
} }
fmt.Fprint(w, builderKey(builder)) c := appengine.NewContext(r)
fmt.Fprint(w, builderKey(c, builder))
} }
func init() { func init() {
@ -392,18 +393,18 @@ func validHash(hash string) bool {
return hash != "" return hash != ""
} }
func validKey(key, builder string) bool { func validKey(c appengine.Context, key, builder string) bool {
if appengine.IsDevAppServer() { if appengine.IsDevAppServer() {
return true return true
} }
if key == secretKey { if key == secretKey(c) {
return true return true
} }
return key == builderKey(builder) return key == builderKey(c, builder)
} }
func builderKey(builder string) string { func builderKey(c appengine.Context, builder string) string {
h := hmac.NewMD5([]byte(secretKey)) h := hmac.NewMD5([]byte(secretKey(c)))
h.Write([]byte(builder)) h.Write([]byte(builder))
return fmt.Sprintf("%x", h.Sum()) return fmt.Sprintf("%x", h.Sum())
} }

View File

@ -4,13 +4,59 @@
package build package build
import "appengine" import (
"sync"
// Delete this init function before deploying to production. "appengine"
func init() { "appengine/datastore"
if !appengine.IsDevAppServer() { )
panic("please read misc/dashboard/app/build/key.go")
} var theKey struct {
sync.RWMutex
BuilderKey
} }
const secretKey = "" // Important! Put a secret here before deploying! type BuilderKey struct {
Secret string
}
func (k *BuilderKey) Key(c appengine.Context) *datastore.Key {
return datastore.NewKey(c, "BuilderKey", "root", 0, nil)
}
func secretKey(c appengine.Context) string {
// check with rlock
theKey.RLock()
k := theKey.Secret
theKey.RUnlock()
if k != "" {
return k
}
// prepare to fill; check with lock and keep lock
theKey.Lock()
defer theKey.Unlock()
if theKey.Secret != "" {
return theKey.Secret
}
// fill
if err := datastore.Get(c, theKey.Key(c), &theKey.BuilderKey); err != nil {
if err == datastore.ErrNoSuchEntity {
// If the key is not stored in datastore, write it.
// This only happens at the beginning of a new deployment.
// The code is left here for SDK use and in case a fresh
// deployment is ever needed. "gophers rule" is not the
// real key.
if !appengine.IsDevAppServer() {
panic("lost key from datastore")
}
theKey.Secret = "gophers rule"
datastore.Put(c, theKey.Key(c), &theKey.BuilderKey)
return theKey.Secret
}
panic("cannot load builder key: " + err.String())
}
return theKey.Secret
}