git.iko.soy/typeable/oauth2-proxy
on master help sign in
Add request scope middleware
commit276832192984dfe6fd6efe7640bfc5bda0cf5ea1 authorJoel Speed <joel.speed@hotmail.co.uk> dateSat 4 Jul 2020, 18:41 (6 years ago) parent1aac37d
3 files changed+157
pkg/apis/middleware/scope.go+24 pkg/middleware/scope.go+39 pkg/middleware/scope_test.go+94
pkg/apis/middleware/scope.gonew file+24
@@ -0,0 +1,24 @@
1+package middleware
2+
3+import (
4+ "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions"
5+)
6+
7+// RequestScope contains information regarding the request that is being made.
8+// The RequestScope is used to pass information between different middlewares
9+// within the chain.
10+type RequestScope struct {
11+ // Session details the authenticated users information (if it exists).
12+ Session *sessions.SessionState
13+
14+ // SaveSession indicates whether the session storage should attempt to save
15+ // the session or not.
16+ SaveSession bool
17+
18+ // ClearSession indicates whether the user should be logged out or not.
19+ ClearSession bool
20+
21+ // SessionRevalidated indicates whether the session has been revalidated since
22+ // it was loaded or not.
23+ SessionRevalidated bool
24+}
pkg/middleware/scope.gonew file+39
@@ -0,0 +1,39 @@
1+package middleware
2+
3+import (
4+ "context"
5+ "net/http"
6+
7+ "github.com/justinas/alice"
8+ middlewareapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/middleware"
9+)
10+
11+type scopeKey string
12+
13+// requestScopeKey uses a typed string to reduce likelihood of clasing
14+// with other context keys
15+const requestScopeKey scopeKey = "request-scope"
16+
17+func NewScope() alice.Constructor {
18+ return addScope
19+}
20+
21+// addScope injects a new request scope into the request context.
22+func addScope(next http.Handler) http.Handler {
23+ return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
24+ scope := &middlewareapi.RequestScope{}
25+ contextWithScope := context.WithValue(req.Context(), requestScopeKey, scope)
26+ requestWithScope := req.WithContext(contextWithScope)
27+ next.ServeHTTP(rw, requestWithScope)
28+ })
29+}
30+
31+// GetRequestScope returns the current request scope from the given request
32+func GetRequestScope(req *http.Request) *middlewareapi.RequestScope {
33+ scope := req.Context().Value(requestScopeKey)
34+ if scope == nil {
35+ return nil
36+ }
37+
38+ return scope.(*middlewareapi.RequestScope)
39+}
pkg/middleware/scope_test.gonew file+94
@@ -0,0 +1,94 @@
1+package middleware
2+
3+import (
4+ "context"
5+ "net/http"
6+ "net/http/httptest"
7+
8+ middlewareapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/middleware"
9+ . "github.com/onsi/ginkgo"
10+ . "github.com/onsi/gomega"
11+)
12+
13+var _ = Describe("Scope Suite", func() {
14+ Context("NewScope", func() {
15+ var request, nextRequest *http.Request
16+ var rw http.ResponseWriter
17+
18+ BeforeEach(func() {
19+ var err error
20+ request, err = http.NewRequest("", "http://127.0.0.1/", nil)
21+ Expect(err).ToNot(HaveOccurred())
22+
23+ rw = httptest.NewRecorder()
24+
25+ handler := NewScope()(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
26+ nextRequest = r
27+ w.WriteHeader(200)
28+ }))
29+ handler.ServeHTTP(rw, request)
30+ })
31+
32+ It("does not add a scope to the original request", func() {
33+ Expect(request.Context().Value(requestScopeKey)).To(BeNil())
34+ })
35+
36+ It("cannot load a scope from the original request using GetRequestScope", func() {
37+ Expect(GetRequestScope(request)).To(BeNil())
38+ })
39+
40+ It("adds a scope to the request for the next handler", func() {
41+ Expect(nextRequest.Context().Value(requestScopeKey)).ToNot(BeNil())
42+ })
43+
44+ It("can load a scope from the next handler's request using GetRequestScope", func() {
45+ Expect(GetRequestScope(nextRequest)).ToNot(BeNil())
46+ })
47+ })
48+
49+ Context("GetRequestScope", func() {
50+ var request *http.Request
51+
52+ BeforeEach(func() {
53+ var err error
54+ request, err = http.NewRequest("", "http://127.0.0.1/", nil)
55+ Expect(err).ToNot(HaveOccurred())
56+ })
57+
58+ Context("with a scope", func() {
59+ var scope *middlewareapi.RequestScope
60+
61+ BeforeEach(func() {
62+ scope = &middlewareapi.RequestScope{}
63+ contextWithScope := context.WithValue(request.Context(), requestScopeKey, scope)
64+ request = request.WithContext(contextWithScope)
65+ })
66+
67+ It("returns the scope", func() {
68+ s := GetRequestScope(request)
69+ Expect(s).ToNot(BeNil())
70+ Expect(s).To(Equal(scope))
71+ })
72+
73+ Context("if the scope is then modified", func() {
74+ BeforeEach(func() {
75+ Expect(scope.SaveSession).To(BeFalse())
76+ scope.SaveSession = true
77+ })
78+
79+ It("returns the updated session", func() {
80+ s := GetRequestScope(request)
81+ Expect(s).ToNot(BeNil())
82+ Expect(s).To(Equal(scope))
83+ Expect(s.SaveSession).To(BeTrue())
84+ })
85+ })
86+ })
87+
88+ Context("without a scope", func() {
89+ It("returns nil", func() {
90+ Expect(GetRequestScope(request)).To(BeNil())
91+ })
92+ })
93+ })
94+})