Skip to content

Commit

Permalink
Bugfix: better auth header parsing.
Browse files Browse the repository at this point in the history
Fixes #104

This is a regression brought on by recent refactorings. The new
functionality is more robust in that l2met no longer cares whether
you have a user:password format of decoded authorization. It will
take everything up to and excluding the `:`.
  • Loading branch information
ryandotsmith committed Aug 15, 2013
1 parent 5ee91ed commit 27b6331
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 28 deletions.
15 changes: 7 additions & 8 deletions auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ package auth
import (
"encoding/base64"
"errors"
"fmt"
"github.com/kr/fernet"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
"io/ioutil"
"net/http"
"fmt"
)

var (
Expand Down Expand Up @@ -54,16 +54,15 @@ func Parse(authLine string) (string, error) {
if err != nil {
return "", err
}
return string(decodedPayload), nil
return strings.TrimSuffix(string(decodedPayload), ":"), nil
}

func Decrypt(s string) (string, string, error) {
func Decrypt(s string) (string, error) {
msg := fernet.VerifyAndDecrypt([]byte(s), ttl, keys)
if msg == nil {
return "", "", errors.New("Unable to decrypt.")
return "", errors.New("Unable to decrypt.")
}
parts := strings.Split(string(msg), ":")
return parts[0], parts[1], nil
return string(msg), nil
}

func ServeHTTP(w http.ResponseWriter, r *http.Request) {
Expand Down
37 changes: 24 additions & 13 deletions auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,38 @@ import (
"testing"
)

type authTest struct {
input string
output string
}

var authTests = []authTest{
{
"user:password",
"user:password",
},
}

func TestAuth(t *testing.T) {
for _, ts := range authTests {
testEncryptDecrypt(t, ts)
}
}

func testEncryptDecrypt(t *testing.T, ts authTest) {
if len(keys) == 0 {
t.Fatalf("Must set $SECRETS\n")
}

var b bytes.Buffer
r, err := http.NewRequest("GET", "http://does-not-matter.com", &b)
if err != nil {
t.Error(err)
t.Fatalf("error=%s\n", err)
}

expectedUser := "ryan@heroku.com"
expectedPass := "abc123"
tok, err := fernet.EncryptAndSign([]byte(expectedUser+":"+expectedPass),
keys[0])
tok, err := fernet.EncryptAndSign([]byte(ts.input), keys[0])
if err != nil {
t.Error(err)
t.Fatalf("error=%s\n", err)
}
r.Header.Set("Authorization",
"Basic "+base64.StdEncoding.EncodeToString(tok))
Expand All @@ -34,16 +49,12 @@ func TestAuth(t *testing.T) {
t.Fatalf("error=%s\n", err)
}

actualUser, actualPass, err := Decrypt(parseRes)
actualOutput, err := Decrypt(parseRes)
if err != nil {
t.Fatalf("error=%s\n", err)
}

if actualUser != expectedUser {
t.Fatalf("actual=%q expected=%q\n", actualUser, expectedUser)
}

if actualPass != expectedPass {
t.Fatalf("actual=%q expected=%q\n", actualPass, expectedPass)
if actualOutput != ts.output {
t.Fatalf("actual=%q expected=%q\n", actualOutput, ts.output)
}
}
12 changes: 9 additions & 3 deletions outlet/librato_outlet.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"net"
"net/http"
"runtime"
"strings"
"time"
)

Expand Down Expand Up @@ -123,18 +124,23 @@ func (l *LibratoOutlet) outlet() {
//Since a playload contains all metrics for
//a unique librato user/pass, we can extract the user/pass
//from any one of the payloads.
user, pass, err := auth.Decrypt(payloads[0].Auth)
decr, err := auth.Decrypt(payloads[0].Auth)
if err != nil {
fmt.Printf("error=%s\n", err)
continue
}
creds := strings.Split(decr, ":")
if len(creds) != 2 {
fmt.Printf("error=missing-creds\n")
continue
}
libratoReq := &libratoRequest{payloads}
j, err := json.Marshal(libratoReq)
if err != nil {
fmt.Printf("at=json error=%s user=%s\n", err, user)
fmt.Printf("at=json error=%s user=%s\n", err, creds[0])
continue
}
if err := l.postWithRetry(user, pass, j); err != nil {
if err := l.postWithRetry(creds[0], creds[1], j); err != nil {
l.Mchan.Measure("outlet.drop", 1)
}
}
Expand Down
7 changes: 3 additions & 4 deletions receiver/receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import (
"github.com/ryandotsmith/l2met/bucket"
"github.com/ryandotsmith/l2met/conf"
"github.com/ryandotsmith/l2met/metchan"
"io/ioutil"
"github.com/ryandotsmith/l2met/parser"
"github.com/ryandotsmith/l2met/store"
"io/ioutil"
"net/http"
"runtime"
"sync"
"sync/atomic"
"time"
"net/http"
)

// We read the body of an http request and then close the request.
Expand Down Expand Up @@ -206,8 +206,7 @@ func (r *Receiver) ServeHTTP(w http.ResponseWriter, req *http.Request) {
http.Error(w, "Fail: Parse auth.", 400)
return
}
_, _, err = auth.Decrypt(parseRes)
if err != nil {
if _, err = auth.Decrypt(parseRes); err != nil {
fmt.Printf("error=%s\n", err)
http.Error(w, "Invalid Request", 400)
return
Expand Down

0 comments on commit 27b6331

Please sign in to comment.