Add request scope middleware
This commit is contained in:
		
							parent
							
								
									1aac37d2b1
								
							
						
					
					
						commit
						2768321929
					
				|  | @ -0,0 +1,24 @@ | ||||||
|  | package middleware | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // RequestScope contains information regarding the request that is being made.
 | ||||||
|  | // The RequestScope is used to pass information between different middlewares
 | ||||||
|  | // within the chain.
 | ||||||
|  | type RequestScope struct { | ||||||
|  | 	// Session details the authenticated users information (if it exists).
 | ||||||
|  | 	Session *sessions.SessionState | ||||||
|  | 
 | ||||||
|  | 	// SaveSession indicates whether the session storage should attempt to save
 | ||||||
|  | 	// the session or not.
 | ||||||
|  | 	SaveSession bool | ||||||
|  | 
 | ||||||
|  | 	// ClearSession indicates whether the user should be logged out or not.
 | ||||||
|  | 	ClearSession bool | ||||||
|  | 
 | ||||||
|  | 	// SessionRevalidated indicates whether the session has been revalidated since
 | ||||||
|  | 	// it was loaded or not.
 | ||||||
|  | 	SessionRevalidated bool | ||||||
|  | } | ||||||
|  | @ -0,0 +1,39 @@ | ||||||
|  | package middleware | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"net/http" | ||||||
|  | 
 | ||||||
|  | 	"github.com/justinas/alice" | ||||||
|  | 	middlewareapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/middleware" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type scopeKey string | ||||||
|  | 
 | ||||||
|  | // requestScopeKey uses a typed string to reduce likelihood of clasing
 | ||||||
|  | // with other context keys
 | ||||||
|  | const requestScopeKey scopeKey = "request-scope" | ||||||
|  | 
 | ||||||
|  | func NewScope() alice.Constructor { | ||||||
|  | 	return addScope | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // addScope injects a new request scope into the request context.
 | ||||||
|  | func addScope(next http.Handler) http.Handler { | ||||||
|  | 	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { | ||||||
|  | 		scope := &middlewareapi.RequestScope{} | ||||||
|  | 		contextWithScope := context.WithValue(req.Context(), requestScopeKey, scope) | ||||||
|  | 		requestWithScope := req.WithContext(contextWithScope) | ||||||
|  | 		next.ServeHTTP(rw, requestWithScope) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetRequestScope returns the current request scope from the given request
 | ||||||
|  | func GetRequestScope(req *http.Request) *middlewareapi.RequestScope { | ||||||
|  | 	scope := req.Context().Value(requestScopeKey) | ||||||
|  | 	if scope == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return scope.(*middlewareapi.RequestScope) | ||||||
|  | } | ||||||
|  | @ -0,0 +1,94 @@ | ||||||
|  | package middleware | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/http/httptest" | ||||||
|  | 
 | ||||||
|  | 	middlewareapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/middleware" | ||||||
|  | 	. "github.com/onsi/ginkgo" | ||||||
|  | 	. "github.com/onsi/gomega" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var _ = Describe("Scope Suite", func() { | ||||||
|  | 	Context("NewScope", func() { | ||||||
|  | 		var request, nextRequest *http.Request | ||||||
|  | 		var rw http.ResponseWriter | ||||||
|  | 
 | ||||||
|  | 		BeforeEach(func() { | ||||||
|  | 			var err error | ||||||
|  | 			request, err = http.NewRequest("", "http://127.0.0.1/", nil) | ||||||
|  | 			Expect(err).ToNot(HaveOccurred()) | ||||||
|  | 
 | ||||||
|  | 			rw = httptest.NewRecorder() | ||||||
|  | 
 | ||||||
|  | 			handler := NewScope()(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 				nextRequest = r | ||||||
|  | 				w.WriteHeader(200) | ||||||
|  | 			})) | ||||||
|  | 			handler.ServeHTTP(rw, request) | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		It("does not add a scope to the original request", func() { | ||||||
|  | 			Expect(request.Context().Value(requestScopeKey)).To(BeNil()) | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		It("cannot load a scope from the original request using GetRequestScope", func() { | ||||||
|  | 			Expect(GetRequestScope(request)).To(BeNil()) | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		It("adds a scope to the request for the next handler", func() { | ||||||
|  | 			Expect(nextRequest.Context().Value(requestScopeKey)).ToNot(BeNil()) | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		It("can load a scope from the next handler's request using GetRequestScope", func() { | ||||||
|  | 			Expect(GetRequestScope(nextRequest)).ToNot(BeNil()) | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	Context("GetRequestScope", func() { | ||||||
|  | 		var request *http.Request | ||||||
|  | 
 | ||||||
|  | 		BeforeEach(func() { | ||||||
|  | 			var err error | ||||||
|  | 			request, err = http.NewRequest("", "http://127.0.0.1/", nil) | ||||||
|  | 			Expect(err).ToNot(HaveOccurred()) | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		Context("with a scope", func() { | ||||||
|  | 			var scope *middlewareapi.RequestScope | ||||||
|  | 
 | ||||||
|  | 			BeforeEach(func() { | ||||||
|  | 				scope = &middlewareapi.RequestScope{} | ||||||
|  | 				contextWithScope := context.WithValue(request.Context(), requestScopeKey, scope) | ||||||
|  | 				request = request.WithContext(contextWithScope) | ||||||
|  | 			}) | ||||||
|  | 
 | ||||||
|  | 			It("returns the scope", func() { | ||||||
|  | 				s := GetRequestScope(request) | ||||||
|  | 				Expect(s).ToNot(BeNil()) | ||||||
|  | 				Expect(s).To(Equal(scope)) | ||||||
|  | 			}) | ||||||
|  | 
 | ||||||
|  | 			Context("if the scope is then modified", func() { | ||||||
|  | 				BeforeEach(func() { | ||||||
|  | 					Expect(scope.SaveSession).To(BeFalse()) | ||||||
|  | 					scope.SaveSession = true | ||||||
|  | 				}) | ||||||
|  | 
 | ||||||
|  | 				It("returns the updated session", func() { | ||||||
|  | 					s := GetRequestScope(request) | ||||||
|  | 					Expect(s).ToNot(BeNil()) | ||||||
|  | 					Expect(s).To(Equal(scope)) | ||||||
|  | 					Expect(s.SaveSession).To(BeTrue()) | ||||||
|  | 				}) | ||||||
|  | 			}) | ||||||
|  | 		}) | ||||||
|  | 
 | ||||||
|  | 		Context("without a scope", func() { | ||||||
|  | 			It("returns nil", func() { | ||||||
|  | 				Expect(GetRequestScope(request)).To(BeNil()) | ||||||
|  | 			}) | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  | }) | ||||||
		Loading…
	
		Reference in New Issue