Check GET permissions in the HTTP handler.
authorTim Pierce <twp@curoverse.com>
Tue, 6 May 2014 15:16:19 +0000 (11:16 -0400)
committerTim Pierce <twp@curoverse.com>
Tue, 6 May 2014 15:16:19 +0000 (11:16 -0400)
Move the check for the permission signature to the HTTP handler, so the
back end can still call GetBlock without having to move permissions all
the way down the stack. Refs #2328

services/keep/src/keep/keep.go

index d98965c07616da8c377e087b7b4b3b509998322c..6619a80fe62940217006206f1f07c1135f490665 100644 (file)
@@ -200,13 +200,14 @@ func FindKeepVolumes() []string {
 func GetBlockHandler(w http.ResponseWriter, req *http.Request) {
        hash := mux.Vars(req)["hash"]
 
-       // Find an API token, if present.
-       var api_token string
-       if auth, ok := req.Header["Authorization"]; ok {
-               if strings.StartsWith(auth[0], "OAuth ") {
-                       api_token = auth[0][6:]
+       // If permission checking is in effect, verify this
+       // request's permission signature.
+       if PermissionSecret != nil {
+               if !VerifySignature(hash, GetApiToken(req)) {
+                       http.Error(w, PermissionError.Error(), 401)
                }
        }
+
        block, err := GetBlock(hash)
        if err != nil {
                http.Error(w, err.Error(), 404)
@@ -342,13 +343,6 @@ func GetVolumeStatus(volume string) *VolumeStatus {
 }
 
 func GetBlock(hash string) ([]byte, error) {
-       // Check the permission signature of this request if necessary.
-       if PermissionSecret != nil {
-               if !VerifySignature(hash) {
-                       return nil, PermissionError
-               }
-       }
-
        // Attempt to read the requested hash from a keep volume.
        for _, vol := range KeepVM.Volumes() {
                if buf, err := vol.Get(hash); err != nil {
@@ -494,3 +488,15 @@ func IsValidLocator(loc string) bool {
        log.Printf("IsValidLocator: %s\n", err)
        return false
 }
+
+// GetApiToken returns the OAuth token from the Authorization
+// header of a HTTP request, or an empty string if no matching
+// token is found.
+func GetApiToken(req *http.Request) string {
+       if auth, ok := req.Header["Authorization"]; ok {
+               if strings.HasPrefix(auth[0], "OAuth ") {
+                       return auth[0][6:]
+               }
+       }
+       return ""
+}