5416: Add BasicAuth compatibility shim for go1.3.
authorTom Clegg <tom@curoverse.com>
Tue, 24 Mar 2015 20:19:50 +0000 (16:19 -0400)
committerTom Clegg <tom@curoverse.com>
Tue, 24 Mar 2015 20:19:50 +0000 (16:19 -0400)
services/arv-git-httpd/auth_handler.go
services/arv-git-httpd/basic_go13.go [new file with mode: 0644]
services/arv-git-httpd/basic_go14.go [new file with mode: 0644]
services/arv-git-httpd/basic_test.go [new file with mode: 0644]

index 3d299939d786348725d623b1542c9f0ce3bdc493..f91ed3f8c087c8cc987a05f2cc6779b8c34255d1 100644 (file)
@@ -57,7 +57,7 @@ func (h *authHandler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 
        // HTTP request username is logged, but unused. Password is an
        // Arvados API token.
-       username, password, ok := r.BasicAuth()
+       username, password, ok := BasicAuth(r)
        if !ok || username == "" || password == "" {
                statusCode, statusText = http.StatusUnauthorized, "no credentials provided"
                w.Header().Add("WWW-Authenticate", "basic")
diff --git a/services/arv-git-httpd/basic_go13.go b/services/arv-git-httpd/basic_go13.go
new file mode 100644 (file)
index 0000000..2839b16
--- /dev/null
@@ -0,0 +1,28 @@
+// +build !go1.4
+
+package main
+
+import (
+       "encoding/base64"
+       "net/http"
+       "strings"
+)
+
+func BasicAuth(r *http.Request) (username, password string, ok bool) {
+       toks := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
+       if len(toks) != 2 || toks[0] != "Basic" {
+               return "", "", false
+       }
+
+       decoded, err := base64.StdEncoding.DecodeString(toks[1])
+       if err != nil {
+               return "", "", false
+       }
+
+       userAndPass := strings.SplitN(string(decoded), ":", 2)
+       if len(userAndPass) != 2 {
+               return "", "", false
+       }
+
+       return userAndPass[0], userAndPass[1], true
+}
diff --git a/services/arv-git-httpd/basic_go14.go b/services/arv-git-httpd/basic_go14.go
new file mode 100644 (file)
index 0000000..6a0079a
--- /dev/null
@@ -0,0 +1,11 @@
+// +build go1.4
+
+package main
+
+import (
+       "net/http"
+)
+
+func BasicAuth(r *http.Request) (username, password string, ok bool) {
+       return r.BasicAuth()
+}
diff --git a/services/arv-git-httpd/basic_test.go b/services/arv-git-httpd/basic_test.go
new file mode 100644 (file)
index 0000000..6bc88cb
--- /dev/null
@@ -0,0 +1,30 @@
+package main
+
+import (
+       "net/http"
+       "testing"
+)
+
+type basicAuthTestCase struct {
+       hdr  string
+       user string
+       pass string
+       ok   bool
+}
+
+func TestBasicAuth(t *testing.T) {
+       tests := []basicAuthTestCase{
+               basicAuthTestCase{"Basic Zm9vOmJhcg==", "foo", "bar", true},
+               basicAuthTestCase{"Bogus Zm9vOmJhcg==", "", "", false},
+               basicAuthTestCase{"Zm9vOmJhcg==", "", "", false},
+               basicAuthTestCase{"Basic", "", "", false},
+               basicAuthTestCase{"", "", "", false},
+       }
+       for _, test := range tests {
+               if u, p, ok := BasicAuth(&http.Request{Header: map[string][]string{
+                       "Authorization": []string{test.hdr},
+               }}); u != test.user || p != test.pass || ok != test.ok {
+                       t.Error("got:", u, p, ok, "expected:", test.user, test.pass, test.ok, "from:", test.hdr)
+               }
+       }
+}