basicauth_test.go 3.55 KB
Newer Older
1 2 3 4
package setup

import (
	"fmt"
5 6 7
	"io/ioutil"
	"os"
	"strings"
8 9 10 11 12 13
	"testing"

	"github.com/mholt/caddy/middleware/basicauth"
)

func TestBasicAuth(t *testing.T) {
14
	c := NewTestController(`basicauth user pwd`)
15 16 17 18 19 20 21 22 23

	mid, err := BasicAuth(c)
	if err != nil {
		t.Errorf("Expected no errors, but got: %v", err)
	}
	if mid == nil {
		t.Fatal("Expected middleware, was nil instead")
	}

24
	handler := mid(EmptyNext)
25 26 27 28 29
	myHandler, ok := handler.(basicauth.BasicAuth)
	if !ok {
		t.Fatalf("Expected handler to be type BasicAuth, got: %#v", handler)
	}

30
	if !SameNext(myHandler.Next, EmptyNext) {
31 32 33 34 35
		t.Error("'Next' field of handler was not set properly")
	}
}

func TestBasicAuthParse(t *testing.T) {
36 37 38 39 40 41 42
	htpasswdPasswd := "IedFOuGmTpT8"
	htpasswdFile := `sha1:{SHA}dcAUljwz99qFjYR0YLTXx0RqLww=
md5:$apr1$l42y8rex$pOA2VJ0x/0TwaFeAF9nX61`

	var skipHtpassword bool
	htfh, err := ioutil.TempFile("", "basicauth-")
	if err != nil {
43
		t.Logf("Error creating temp file (%v), will skip htpassword test", err)
44 45 46 47 48 49 50 51 52
		skipHtpassword = true
	} else {
		if _, err = htfh.Write([]byte(htpasswdFile)); err != nil {
			t.Fatalf("write htpasswd file %q: %v", htfh.Name(), err)
		}
		htfh.Close()
		defer os.Remove(htfh.Name())
	}

53 54 55
	tests := []struct {
		input     string
		shouldErr bool
56
		password  string
57 58
		expected  []basicauth.Rule
	}{
59 60
		{`basicauth user pwd`, false, "pwd", []basicauth.Rule{
			{Username: "user"},
61 62
		}},
		{`basicauth user pwd {
63 64
		}`, false, "pwd", []basicauth.Rule{
			{Username: "user"},
65 66 67 68
		}},
		{`basicauth user pwd {
			/resource1
			/resource2
69 70
		}`, false, "pwd", []basicauth.Rule{
			{Username: "user", Resources: []string{"/resource1", "/resource2"}},
71
		}},
72 73
		{`basicauth /resource user pwd`, false, "pwd", []basicauth.Rule{
			{Username: "user", Resources: []string{"/resource"}},
74 75
		}},
		{`basicauth /res1 user1 pwd1
76 77 78 79 80 81 82 83 84 85
		  basicauth /res2 user2 pwd2`, false, "pwd", []basicauth.Rule{
			{Username: "user1", Resources: []string{"/res1"}},
			{Username: "user2", Resources: []string{"/res2"}},
		}},
		{`basicauth user`, true, "", []basicauth.Rule{}},
		{`basicauth`, true, "", []basicauth.Rule{}},
		{`basicauth /resource user pwd asdf`, true, "", []basicauth.Rule{}},

		{`basicauth sha1 htpasswd=` + htfh.Name(), false, htpasswdPasswd, []basicauth.Rule{
			{Username: "sha1"},
86 87 88 89
		}},
	}

	for i, test := range tests {
90
		c := NewTestController(test.input)
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
		actual, err := basicAuthParse(c)

		if err == nil && test.shouldErr {
			t.Errorf("Test %d didn't error, but it should have", i)
		} else if err != nil && !test.shouldErr {
			t.Errorf("Test %d errored, but it shouldn't have; got '%v'", i, err)
		}

		if len(actual) != len(test.expected) {
			t.Fatalf("Test %d expected %d rules, but got %d",
				i, len(test.expected), len(actual))
		}

		for j, expectedRule := range test.expected {
			actualRule := actual[j]

			if actualRule.Username != expectedRule.Username {
				t.Errorf("Test %d, rule %d: Expected username '%s', got '%s'",
					i, j, expectedRule.Username, actualRule.Username)
			}

112 113 114 115 116 117 118 119
			if strings.Contains(test.input, "htpasswd=") && skipHtpassword {
				continue
			}
			pwd := test.password
			if len(actual) > 1 {
				pwd = fmt.Sprintf("%s%d", pwd, j+1)
			}
			if !actualRule.Password(pwd) || actualRule.Password(test.password+"!") {
120
				t.Errorf("Test %d, rule %d: Expected password '%v', got '%v'",
121
					i, j, test.password, actualRule.Password)
122 123 124 125 126 127 128 129 130 131 132
			}

			expectedRes := fmt.Sprintf("%v", expectedRule.Resources)
			actualRes := fmt.Sprintf("%v", actualRule.Resources)
			if actualRes != expectedRes {
				t.Errorf("Test %d, rule %d: Expected resource list %s, but got %s",
					i, j, expectedRes, actualRes)
			}
		}
	}
}