@@ -0,0 +1,132 @@
1+package middleware
2+
3+import (
4+ "context"
5+ "fmt"
6+ "net/http"
7+ "net/http/httptest"
8+
9+ middlewareapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/middleware"
10+ sessionsapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions"
11+ . "github.com/onsi/ginkgo"
12+ . "github.com/onsi/ginkgo/extensions/table"
13+ . "github.com/onsi/gomega"
14+)
15+
16+const (
17+ adminUser = "admin"
18+ adminPassword = "Adm1n1str$t0r"
19+ user1 = "user1"
20+ user1Password = "UsErOn3P455"
21+ user2 = "user2"
22+ user2Password = "us3r2P455W0Rd!"
23+)
24+
25+var _ = Describe("Basic Auth Session Suite", func() {
26+ Context("BasicAuthSessionLoader", func() {
27+
28+ type basicAuthSessionLoaderTableInput struct {
29+ authorizationHeader string
30+ existingSession *sessionsapi.SessionState
31+ expectedSession *sessionsapi.SessionState
32+ }
33+
34+ DescribeTable("with an authorization header",
35+ func(in basicAuthSessionLoaderTableInput) {
36+ scope := &middlewareapi.RequestScope{
37+ Session: in.existingSession,
38+ }
39+
40+ // Set up the request with the authorization header and a request scope
41+ req := httptest.NewRequest("", "/", nil)
42+ req.Header.Set("Authorization", in.authorizationHeader)
43+ contextWithScope := context.WithValue(req.Context(), requestScopeKey, scope)
44+ req = req.WithContext(contextWithScope)
45+
46+ rw := httptest.NewRecorder()
47+
48+ validator := fakeBasicValidator{
49+ users: map[string]string{
50+ adminUser: adminPassword,
51+ user1: user1Password,
52+ user2: user2Password,
53+ },
54+ }
55+
56+ // Create the handler with a next handler that will capture the session
57+ // from the scope
58+ var gotSession *sessionsapi.SessionState
59+ handler := NewBasicAuthSessionLoader(validator)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
60+ gotSession = r.Context().Value(requestScopeKey).(*middlewareapi.RequestScope).Session
61+ }))
62+ handler.ServeHTTP(rw, req)
63+
64+ Expect(gotSession).To(Equal(in.expectedSession))
65+ },
66+ Entry("<no value>", basicAuthSessionLoaderTableInput{
67+ authorizationHeader: "",
68+ existingSession: nil,
69+ expectedSession: nil,
70+ }),
71+ Entry("abcdef", basicAuthSessionLoaderTableInput{
72+ authorizationHeader: "abcdef",
73+ existingSession: nil,
74+ expectedSession: nil,
75+ }),
76+ Entry("abcdef (with existing session)", basicAuthSessionLoaderTableInput{
77+ authorizationHeader: "abcdef",
78+ existingSession: &sessionsapi.SessionState{User: "user"},
79+ expectedSession: &sessionsapi.SessionState{User: "user"},
80+ }),
81+ Entry("Bearer <password>", basicAuthSessionLoaderTableInput{
82+ authorizationHeader: fmt.Sprintf("Bearer %s", adminPassword),
83+ existingSession: nil,
84+ expectedSession: nil,
85+ }),
86+ Entry("Basic <password>", basicAuthSessionLoaderTableInput{
87+ authorizationHeader: fmt.Sprintf("Basic %s", adminPassword),
88+ existingSession: nil,
89+ expectedSession: nil,
90+ }),
91+ Entry("Basic Base64(:<password>) (with existing session)", basicAuthSessionLoaderTableInput{
92+ authorizationHeader: "Basic OlVzRXJPbjNQNDU1",
93+ existingSession: &sessionsapi.SessionState{User: "user"},
94+ expectedSession: &sessionsapi.SessionState{User: "user"},
95+ }),
96+ Entry("Basic Base64(user1:<user1Password>)", basicAuthSessionLoaderTableInput{
97+ authorizationHeader: "Basic dXNlcjE6VXNFck9uM1A0NTU=",
98+ existingSession: nil,
99+ expectedSession: &sessionsapi.SessionState{User: "user1"},
100+ }),
101+ Entry("Basic Base64(user2:<user1Password>)", basicAuthSessionLoaderTableInput{
102+ authorizationHeader: "Basic dXNlcjI6VXNFck9uM1A0NTU=",
103+ existingSession: nil,
104+ expectedSession: nil,
105+ }),
106+ Entry("Basic Base64(user2:<user2Password>)", basicAuthSessionLoaderTableInput{
107+ authorizationHeader: "Basic dXNlcjI6dXMzcjJQNDU1VzBSZCE=",
108+ existingSession: nil,
109+ expectedSession: &sessionsapi.SessionState{User: "user2"},
110+ }),
111+ Entry("Basic Base64(admin:<adminPassword>)", basicAuthSessionLoaderTableInput{
112+ authorizationHeader: "Basic YWRtaW46QWRtMW4xc3RyJHQwcg==",
113+ existingSession: nil,
114+ expectedSession: &sessionsapi.SessionState{User: "admin"},
115+ }),
116+ )
117+ })
118+})
119+
120+type fakeBasicValidator struct {
121+ users map[string]string
122+}
123+
124+func (f fakeBasicValidator) Validate(user, password string) bool {
125+ if f.users == nil {
126+ return false
127+ }
128+ if realPassword, ok := f.users[user]; ok {
129+ return realPassword == password
130+ }
131+ return false
132+}