git.iko.soy/typeable/oauth2-proxy
on master help sign in
212 lines 5.9 kB history raw
1package providers
3import (
4 "context"
5 "errors"
6 "fmt"
7 "net/http"
8 "net/http/httptest"
9 "net/url"
11 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
12 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
13 . "github.com/onsi/ginkgo/v2"
14 . "github.com/onsi/gomega"
17const (
18 keycloakAccessToken = "eyJKeycloak.eyJAccess.Token"
19 keycloakUserinfoPath = "/api/v3/user"
22func testKeycloakProvider(backend *httptest.Server) (*KeycloakProvider, error) {
23 p := NewKeycloakProvider(
24 &ProviderData{
25 ProviderName: "",
26 LoginURL: &url.URL{},
27 RedeemURL: &url.URL{},
28 ProfileURL: &url.URL{},
29 ValidateURL: &url.URL{},
30 Scope: ""},
31 options.KeycloakOptions{})
33 if backend != nil {
34 bURL, err := url.Parse(backend.URL)
35 if err != nil {
36 return nil, err
37 }
38 hostname := bURL.Host
40 updateURL(p.Data().LoginURL, hostname)
41 updateURL(p.Data().RedeemURL, hostname)
42 updateURL(p.Data().ProfileURL, hostname)
43 updateURL(p.Data().ValidateURL, hostname)
44 }
46 return p, nil
49var _ = Describe("Keycloak Provider Tests", func() {
50 Context("New Provider Init", func() {
51 It("uses defaults", func() {
52 providerData := NewKeycloakProvider(&ProviderData{}, options.KeycloakOptions{}).Data()
53 Expect(providerData.ProviderName).To(Equal("Keycloak"))
54 Expect(providerData.LoginURL.String()).To(Equal("https://keycloak.org/oauth/authorize"))
55 Expect(providerData.RedeemURL.String()).To(Equal("https://keycloak.org/oauth/token"))
56 Expect(providerData.ProfileURL.String()).To(Equal(""))
57 Expect(providerData.ValidateURL.String()).To(Equal("https://keycloak.org/api/v3/user"))
58 Expect(providerData.Scope).To(Equal("api"))
59 })
61 It("overrides defaults", func() {
62 p := NewKeycloakProvider(
63 &ProviderData{
64 LoginURL: &url.URL{
65 Scheme: "https",
66 Host: "example.com",
67 Path: "/oauth/auth"},
68 RedeemURL: &url.URL{
69 Scheme: "https",
70 Host: "example.com",
71 Path: "/oauth/token"},
72 ProfileURL: &url.URL{
73 Scheme: "https",
74 Host: "example.com",
75 Path: "/api/v3/user"},
76 ValidateURL: &url.URL{
77 Scheme: "https",
78 Host: "example.com",
79 Path: "/api/v3/user"},
80 Scope: "profile"},
81 options.KeycloakOptions{})
82 providerData := p.Data()
84 Expect(providerData.ProviderName).To(Equal("Keycloak"))
85 Expect(providerData.LoginURL.String()).To(Equal("https://example.com/oauth/auth"))
86 Expect(providerData.RedeemURL.String()).To(Equal("https://example.com/oauth/token"))
87 Expect(providerData.ProfileURL.String()).To(Equal("https://example.com/api/v3/user"))
88 Expect(providerData.ValidateURL.String()).To(Equal("https://example.com/api/v3/user"))
89 Expect(providerData.Scope).To(Equal("profile"))
90 })
91 })
93 Context("EnrichSession", func() {
94 type enrichSessionTableInput struct {
95 backendHandler http.HandlerFunc
96 expectedError error
97 expectedEmail string
98 expectedGroups []string
99 }
101 DescribeTable("should return expected results",
102 func(in enrichSessionTableInput) {
103 backend := httptest.NewServer(in.backendHandler)
104 p, err := testKeycloakProvider(backend)
105 Expect(err).To(BeNil())
107 p.ProfileURL, err = url.Parse(
108 fmt.Sprintf("%s%s", backend.URL, keycloakUserinfoPath),
109 )
110 Expect(err).To(BeNil())
112 session := &sessions.SessionState{AccessToken: keycloakAccessToken}
113 err = p.EnrichSession(context.Background(), session)
115 if in.expectedError != nil {
116 Expect(err).To(Equal(in.expectedError))
117 } else {
118 Expect(err).To(BeNil())
119 }
121 Expect(session.Email).To(Equal(in.expectedEmail))
123 if in.expectedGroups != nil {
124 Expect(session.Groups).To(Equal(in.expectedGroups))
125 } else {
126 Expect(session.Groups).To(BeNil())
127 }
128 },
129 Entry("email and multiple groups", enrichSessionTableInput{
130 backendHandler: func(w http.ResponseWriter, _ *http.Request) {
131 w.WriteHeader(200)
132 _, err := w.Write([]byte(`
133 {
134 "email": "michael.bland@gsa.gov",
135 "groups": [
136 "test-grp1",
137 "test-grp2"
138 ]
139 }
140 `))
141 if err != nil {
142 panic(err)
143 }
144 },
145 expectedError: nil,
146 expectedEmail: "michael.bland@gsa.gov",
147 expectedGroups: []string{"test-grp1", "test-grp2"},
148 }),
149 Entry("email and single group", enrichSessionTableInput{
150 backendHandler: func(w http.ResponseWriter, _ *http.Request) {
151 w.WriteHeader(200)
152 _, err := w.Write([]byte(`
153 {
154 "email": "michael.bland@gsa.gov",
155 "groups": ["test-grp1"]
156 }
157 `))
158 if err != nil {
159 panic(err)
160 }
161 },
162 expectedError: nil,
163 expectedEmail: "michael.bland@gsa.gov",
164 expectedGroups: []string{"test-grp1"},
165 }),
166 Entry("email and no groups", enrichSessionTableInput{
167 backendHandler: func(w http.ResponseWriter, _ *http.Request) {
168 w.WriteHeader(200)
169 _, err := w.Write([]byte(`
170 {
171 "email": "michael.bland@gsa.gov"
172 }
173 `))
174 if err != nil {
175 panic(err)
176 }
177 },
178 expectedError: nil,
179 expectedEmail: "michael.bland@gsa.gov",
180 expectedGroups: nil,
181 }),
182 Entry("missing email", enrichSessionTableInput{
183 backendHandler: func(w http.ResponseWriter, _ *http.Request) {
184 w.WriteHeader(200)
185 _, err := w.Write([]byte(`
186 {
187 "groups": [
188 "test-grp1",
189 "test-grp2"
190 ]
191 }
192 `))
193 if err != nil {
194 panic(err)
195 }
196 },
197 expectedError: errors.New(
198 "unable to extract email from userinfo endpoint: type assertion to string failed"),
199 expectedEmail: "",
200 expectedGroups: []string{"test-grp1", "test-grp2"},
201 }),
202 Entry("request failure", enrichSessionTableInput{
203 backendHandler: func(w http.ResponseWriter, _ *http.Request) {
204 w.WriteHeader(500)
205 },
206 expectedError: errors.New(`unexpected status "500": `),
207 expectedEmail: "",
208 expectedGroups: nil,
209 }),
210 )
211 })
212})