github.com/Richardknop/go-oauth2-server@v1.0.1/web/middleware.go (about) 1 package web 2 3 import ( 4 "net/http" 5 6 "github.com/RichardKnop/go-oauth2-server/session" 7 "github.com/gorilla/context" 8 ) 9 10 // parseFormMiddleware parses the form so r.Form becomes available 11 type parseFormMiddleware struct{} 12 13 // ServeHTTP as per the negroni.Handler interface 14 func (m *parseFormMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 15 if err := r.ParseForm(); err != nil { 16 http.Error(w, err.Error(), http.StatusInternalServerError) 17 return 18 } 19 20 next(w, r) 21 } 22 23 // guestMiddleware just initialises session 24 type guestMiddleware struct { 25 service ServiceInterface 26 } 27 28 // newGuestMiddleware creates a new guestMiddleware instance 29 func newGuestMiddleware(service ServiceInterface) *guestMiddleware { 30 return &guestMiddleware{service: service} 31 } 32 33 // ServeHTTP as per the negroni.Handler interface 34 func (m *guestMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 35 // Initialise the session service 36 m.service.setSessionService(r, w) 37 sessionService := m.service.GetSessionService() 38 39 // Attempt to start the session 40 if err := sessionService.StartSession(); err != nil { 41 http.Error(w, err.Error(), http.StatusInternalServerError) 42 return 43 } 44 45 context.Set(r, sessionServiceKey, sessionService) 46 47 next(w, r) 48 } 49 50 // loggedInMiddleware initialises session and makes sure the user is logged in 51 type loggedInMiddleware struct { 52 service ServiceInterface 53 } 54 55 // newLoggedInMiddleware creates a new loggedInMiddleware instance 56 func newLoggedInMiddleware(service ServiceInterface) *loggedInMiddleware { 57 return &loggedInMiddleware{service: service} 58 } 59 60 // ServeHTTP as per the negroni.Handler interface 61 func (m *loggedInMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 62 // Initialise the session service 63 m.service.setSessionService(r, w) 64 sessionService := m.service.GetSessionService() 65 66 // Attempt to start the session 67 if err := sessionService.StartSession(); err != nil { 68 http.Error(w, err.Error(), http.StatusInternalServerError) 69 return 70 } 71 72 context.Set(r, sessionServiceKey, sessionService) 73 74 // Try to get a user session 75 userSession, err := sessionService.GetUserSession() 76 if err != nil { 77 query := r.URL.Query() 78 query.Set("login_redirect_uri", r.URL.Path) 79 redirectWithQueryString("/web/login", query, w, r) 80 return 81 } 82 83 // Authenticate 84 if err := m.authenticate(userSession); err != nil { 85 query := r.URL.Query() 86 query.Set("login_redirect_uri", r.URL.Path) 87 redirectWithQueryString("/web/login", query, w, r) 88 return 89 } 90 91 // Update the user session 92 sessionService.SetUserSession(userSession) 93 94 next(w, r) 95 } 96 97 func (m *loggedInMiddleware) authenticate(userSession *session.UserSession) error { 98 // Try to authenticate with the stored access token 99 _, err := m.service.GetOauthService().Authenticate(userSession.AccessToken) 100 if err == nil { 101 // Access token valid, return 102 return nil 103 } 104 // Access token might be expired, let's try refreshing... 105 106 // Fetch the client 107 client, err := m.service.GetOauthService().FindClientByClientID( 108 userSession.ClientID, // client ID 109 ) 110 if err != nil { 111 return err 112 } 113 114 // Validate the refresh token 115 theRefreshToken, err := m.service.GetOauthService().GetValidRefreshToken( 116 userSession.RefreshToken, // refresh token 117 client, // client 118 ) 119 if err != nil { 120 return err 121 } 122 123 // Log in the user 124 accessToken, refreshToken, err := m.service.GetOauthService().Login( 125 theRefreshToken.Client, 126 theRefreshToken.User, 127 theRefreshToken.Scope, 128 ) 129 if err != nil { 130 return err 131 } 132 133 userSession.AccessToken = accessToken.Token 134 userSession.RefreshToken = refreshToken.Token 135 136 return nil 137 } 138 139 // clientMiddleware takes client_id param from the query string and 140 // makes a database lookup for a client with the same client ID 141 type clientMiddleware struct { 142 service ServiceInterface 143 } 144 145 // newClientMiddleware creates a new clientMiddleware instance 146 func newClientMiddleware(service ServiceInterface) *clientMiddleware { 147 return &clientMiddleware{service: service} 148 } 149 150 // ServeHTTP as per the negroni.Handler interface 151 func (m *clientMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 152 // Fetch the client 153 client, err := m.service.GetOauthService().FindClientByClientID( 154 r.Form.Get("client_id"), // client ID 155 ) 156 if err != nil { 157 http.Error(w, err.Error(), http.StatusBadRequest) 158 return 159 } 160 161 context.Set(r, clientKey, client) 162 163 next(w, r) 164 }