@@ -0,0 +1,417 @@
8+ "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
9+ sessionsapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
10+ . "github.com/onsi/ginkgo"
11+ . "github.com/onsi/ginkgo/extensions/table"
12+ . "github.com/onsi/gomega"
15+var _ = Describe("Injector Suite", func() {
16+ Context("NewInjector", func() {
17+ type newInjectorTableInput struct {
18+ headers []options.Header
19+ initialHeaders http.Header
20+ session *sessionsapi.SessionState
21+ expectedHeaders http.Header
25+ DescribeTable("creates an injector",
26+ func(in newInjectorTableInput) {
27+ injector, err := NewInjector(in.headers)
28+ if in.expectedErr != nil {
29+ Expect(err).To(MatchError(in.expectedErr))
30+ Expect(injector).To(BeNil())
34+ Expect(err).ToNot(HaveOccurred())
35+ Expect(injector).ToNot(BeNil())
37+ headers := in.initialHeaders.Clone()
38+ injector.Inject(headers, in.session)
39+ Expect(headers).To(Equal(in.expectedHeaders))
41+ Entry("with no configured headers", newInjectorTableInput{
42+ headers: []options.Header{},
43+ initialHeaders: http.Header{
44+ "foo": []string{"bar", "baz"},
46+ session: &sessionsapi.SessionState{},
47+ expectedHeaders: http.Header{
48+ "foo": []string{"bar", "baz"},
52+ Entry("with a static valued header from base64", newInjectorTableInput{
53+ headers: []options.Header{
56+ Values: []options.HeaderValue{
58+ SecretSource: &options.SecretSource{
59+ Value: []byte(base64.StdEncoding.EncodeToString([]byte("super-secret"))),
65+ initialHeaders: http.Header{
66+ "foo": []string{"bar", "baz"},
68+ session: &sessionsapi.SessionState{},
69+ expectedHeaders: http.Header{
70+ "foo": []string{"bar", "baz"},
71+ "Secret": []string{"super-secret"},
75+ Entry("with a static valued header from env", newInjectorTableInput{
76+ headers: []options.Header{
79+ Values: []options.HeaderValue{
81+ SecretSource: &options.SecretSource{
82+ FromEnv: "SECRET_ENV",
88+ initialHeaders: http.Header{
89+ "foo": []string{"bar", "baz"},
91+ session: &sessionsapi.SessionState{},
92+ expectedHeaders: http.Header{
93+ "foo": []string{"bar", "baz"},
94+ "Secret": []string{"super-secret-env"},
98+ Entry("with a claim valued header", newInjectorTableInput{
99+ headers: []options.Header{
102+ Values: []options.HeaderValue{
104+ ClaimSource: &options.ClaimSource{
111+ initialHeaders: http.Header{
112+ "foo": []string{"bar", "baz"},
114+ session: &sessionsapi.SessionState{
115+ IDToken: "IDToken-1234",
117+ expectedHeaders: http.Header{
118+ "foo": []string{"bar", "baz"},
119+ "Claim": []string{"IDToken-1234"},
123+ Entry("with a claim valued header and a nil session", newInjectorTableInput{
124+ headers: []options.Header{
127+ Values: []options.HeaderValue{
129+ ClaimSource: &options.ClaimSource{
136+ initialHeaders: http.Header{
137+ "foo": []string{"bar", "baz"},
140+ expectedHeaders: http.Header{
141+ "foo": []string{"bar", "baz"},
145+ Entry("with a prefixed claim valued header", newInjectorTableInput{
146+ headers: []options.Header{
149+ Values: []options.HeaderValue{
151+ ClaimSource: &options.ClaimSource{
159+ initialHeaders: http.Header{
160+ "foo": []string{"bar", "baz"},
162+ session: &sessionsapi.SessionState{
163+ IDToken: "IDToken-1234",
165+ expectedHeaders: http.Header{
166+ "foo": []string{"bar", "baz"},
167+ "Claim": []string{"Bearer IDToken-1234"},
171+ Entry("with a prefixed claim valued header missing the claim", newInjectorTableInput{
172+ headers: []options.Header{
175+ Values: []options.HeaderValue{
177+ ClaimSource: &options.ClaimSource{
185+ initialHeaders: http.Header{
186+ "foo": []string{"bar", "baz"},
188+ session: &sessionsapi.SessionState{},
189+ expectedHeaders: http.Header{
190+ "foo": []string{"bar", "baz"},
194+ Entry("with a basicAuthPassword and claim valued header", newInjectorTableInput{
195+ headers: []options.Header{
197+ Name: "X-Auth-Request-Authorization",
198+ Values: []options.HeaderValue{
200+ ClaimSource: &options.ClaimSource{
202+ BasicAuthPassword: &options.SecretSource{
203+ Value: []byte(base64.StdEncoding.EncodeToString([]byte("basic-password"))),
210+ initialHeaders: http.Header{
211+ "foo": []string{"bar", "baz"},
213+ session: &sessionsapi.SessionState{
216+ expectedHeaders: http.Header{
217+ "foo": []string{"bar", "baz"},
218+ "X-Auth-Request-Authorization": []string{"Basic " + base64.StdEncoding.EncodeToString([]byte("user-123:basic-password"))},
222+ Entry("with a basicAuthPassword and claim valued header missing the claim", newInjectorTableInput{
223+ headers: []options.Header{
225+ Name: "X-Auth-Request-Authorization",
226+ Values: []options.HeaderValue{
228+ ClaimSource: &options.ClaimSource{
230+ BasicAuthPassword: &options.SecretSource{
231+ Value: []byte(base64.StdEncoding.EncodeToString([]byte("basic-password"))),
238+ initialHeaders: http.Header{
239+ "foo": []string{"bar", "baz"},
241+ session: &sessionsapi.SessionState{},
242+ expectedHeaders: http.Header{
243+ "foo": []string{"bar", "baz"},
247+ Entry("with a header that already exists", newInjectorTableInput{
248+ headers: []options.Header{
250+ Name: "X-Auth-Request-User",
251+ Values: []options.HeaderValue{
253+ ClaimSource: &options.ClaimSource{
260+ initialHeaders: http.Header{
261+ "X-Auth-Request-User": []string{"user"},
263+ session: &sessionsapi.SessionState{
266+ expectedHeaders: http.Header{
267+ "X-Auth-Request-User": []string{"user", "user-123"},
271+ Entry("with a claim and secret valued header value", newInjectorTableInput{
272+ headers: []options.Header{
275+ Values: []options.HeaderValue{
277+ ClaimSource: &options.ClaimSource{
280+ SecretSource: &options.SecretSource{
281+ FromEnv: "SECRET_ENV",
287+ initialHeaders: http.Header{
288+ "foo": []string{"bar", "baz"},
290+ session: &sessionsapi.SessionState{
291+ IDToken: "IDToken-1234",
293+ expectedHeaders: nil,
294+ expectedErr: errors.New("error building injector for header \"Claim\": header \"Claim\" value has multiple entries: only one entry per value is allowed"),
296+ Entry("with an invalid static valued header", newInjectorTableInput{
297+ headers: []options.Header{
300+ Values: []options.HeaderValue{
302+ SecretSource: &options.SecretSource{
303+ FromEnv: "SECRET_ENV",
304+ FromFile: "secret-file",
310+ initialHeaders: http.Header{
311+ "foo": []string{"bar", "baz"},
313+ session: &sessionsapi.SessionState{},
314+ expectedHeaders: nil,
315+ expectedErr: errors.New("error building injector for header \"Secret\": error getting secret value: secret source is invalid: exactly one entry required, specify either value, fromEnv or fromFile"),
317+ Entry("with an invalid basicAuthPassword claim valued header", newInjectorTableInput{
318+ headers: []options.Header{
320+ Name: "X-Auth-Request-Authorization",
321+ Values: []options.HeaderValue{
323+ ClaimSource: &options.ClaimSource{
325+ BasicAuthPassword: &options.SecretSource{
326+ Value: []byte(base64.StdEncoding.EncodeToString([]byte("basic-password"))),
327+ FromEnv: "SECRET_ENV",
334+ initialHeaders: http.Header{
335+ "foo": []string{"bar", "baz"},
337+ session: &sessionsapi.SessionState{
340+ expectedHeaders: nil,
341+ expectedErr: errors.New("error building injector for header \"X-Auth-Request-Authorization\": error loading basicAuthPassword: secret source is invalid: exactly one entry required, specify either value, fromEnv or fromFile"),
343+ Entry("with a mix of configured headers", newInjectorTableInput{
344+ headers: []options.Header{
346+ Name: "X-Auth-Request-Authorization",
347+ Values: []options.HeaderValue{
349+ ClaimSource: &options.ClaimSource{
351+ BasicAuthPassword: &options.SecretSource{
352+ Value: []byte(base64.StdEncoding.EncodeToString([]byte("basic-password"))),
359+ Name: "X-Auth-Request-User",
360+ Values: []options.HeaderValue{
362+ ClaimSource: &options.ClaimSource{
369+ Name: "X-Auth-Request-Email",
370+ Values: []options.HeaderValue{
372+ ClaimSource: &options.ClaimSource{
379+ Name: "X-Auth-Request-Version-Info",
380+ Values: []options.HeaderValue{
382+ SecretSource: &options.SecretSource{
383+ Value: []byte(base64.StdEncoding.EncodeToString([]byte("major=1"))),
387+ SecretSource: &options.SecretSource{
388+ Value: []byte(base64.StdEncoding.EncodeToString([]byte("minor=2"))),
392+ SecretSource: &options.SecretSource{
393+ Value: []byte(base64.StdEncoding.EncodeToString([]byte("patch=3"))),
399+ initialHeaders: http.Header{
400+ "foo": []string{"bar", "baz"},
402+ session: &sessionsapi.SessionState{
404+ Email: "user@example.com",
406+ expectedHeaders: http.Header{
407+ "foo": []string{"bar", "baz"},
408+ "X-Auth-Request-Authorization": []string{"Basic " + base64.StdEncoding.EncodeToString([]byte("user-123:basic-password"))},
409+ "X-Auth-Request-User": []string{"user-123"},
410+ "X-Auth-Request-Email": []string{"user@example.com"},
411+ "X-Auth-Request-Version-Info": []string{"major=1", "minor=2", "patch=3"},