Add post login redirect

This commit is contained in:
Nicolas Duhamel 2016-04-26 07:43:29 +02:00
parent 5778fd45df
commit 80cd6d3d72
4 changed files with 87 additions and 20 deletions

View File

@ -1,6 +1,7 @@
package auth package auth
import ( import (
"fmt"
"net/http" "net/http"
"github.com/gorilla/context" "github.com/gorilla/context"
@ -8,9 +9,9 @@ import (
type key int type key int
const ukey key = 0 const ukey key = 0 //user key
// AuthMiddleware get User from session and put it in context // Middleware get User from session and put it in context
type Middleware struct { type Middleware struct {
authorizer *Authorizer authorizer *Authorizer
} }
@ -31,23 +32,55 @@ func (m *Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request, next http
type MiddlewareRole struct { type MiddlewareRole struct {
authorizer *Authorizer authorizer *Authorizer
role string role string
loginPageGetter func() string
} }
func NewMiddlewareRole(authorizer *Authorizer, role string) *MiddlewareRole { func NewMiddlewareRole(authorizer *Authorizer, loginPageGetter func() string, role string) *MiddlewareRole {
return &MiddlewareRole{authorizer, role} return &MiddlewareRole{authorizer, role, loginPageGetter}
} }
func (m *MiddlewareRole) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { func (m *MiddlewareRole) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
user := GetCurrentUser(r) user := GetCurrentUser(r)
if user == nil || !user.HasRole(m.role) { if user == nil || !user.HasRole(m.role) {
//TODO: redirect to login page and save wanted page cookie, err := m.authorizer.cookiejar.Get(r, "rlogin")
if err != nil {
panic(err)
}
cookie.Values["redirect"] = r.URL.Path
err = cookie.Save(r, w)
if err != nil {
panic(err)
}
http.Redirect(w, r, m.loginPageGetter(), http.StatusTemporaryRedirect)
return return
} }
next(w, r) next(w, r)
} }
func GetPostLoginRedirect(a *Authorizer, w http.ResponseWriter, r *http.Request) (string, error) {
cookie, err := a.cookiejar.Get(r, "rlogin")
if err != nil {
return "", err
}
val := cookie.Values["redirect"]
if val == nil {
return "", nil
}
path, ok := val.(string)
if !ok {
return "", fmt.Errorf("invalid redirect type")
}
cookie.Values["rlogin"] = ""
err = cookie.Save(r, w)
if err != nil {
return "", err
}
return path, nil
}
func GetCurrentUser(r *http.Request) User { func GetCurrentUser(r *http.Request) User {
u := context.Get(r, ukey) u := context.Get(r, ukey)
if u == nil { if u == nil {
@ -55,7 +88,7 @@ func GetCurrentUser(r *http.Request) User {
} }
user, ok := u.(User) user, ok := u.(User)
if !ok { if !ok {
panic("Invalid user type") panic("invalid user type")
} }
return user return user
} }

View File

@ -38,11 +38,17 @@ func main() {
authMiddleware := auth.NewMiddleware(env.Auth) authMiddleware := auth.NewMiddleware(env.Auth)
env.Handle("users.login", "/users/login", users.LoginHandler) env.Handle("users.login", "/users/login", users.LoginHandler)
env.Handle("users.logout", "users/logout", users.LogoutHandler) env.Handle("users.logout", "/users/logout", users.LogoutHandler)
env.HandleRole("users.details", "/users/details", users.DetailsHandler, users.UserRole) env.HandleRole("users.details", "/users/details", users.DetailsHandler, users.UserRole)
env.HandleRole("movies.polochon", "/", movies.PolochonMovies, users.UserRole) env.HandleRole("movies.polochon", "/", movies.PolochonMovies, users.UserRole)
err = env.SetLoginRoute("users.login")
if err != nil {
log.Error(err)
os.Exit(1)
}
n := negroni.Classic() n := negroni.Classic()
n.Use(authMiddleware) n.Use(authMiddleware)
n.UseHandler(env.Router) n.UseHandler(env.Router)

View File

@ -41,13 +41,22 @@ func LoginHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
return err return err
} }
//TODO: redirect to user details or to previous location path, err := auth.GetPostLoginRedirect(e.Auth, w, r)
if err != nil {
return err
}
if path != "" {
http.Redirect(w, r, path, http.StatusTemporaryRedirect)
return nil
}
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return nil return nil
} }
func LogoutHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { func LogoutHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error {
e.Auth.Logout(w, r) e.Auth.Logout(w, r)
//TODO: redirect to login page route := e.GetLoginRouteGetter()()
http.Redirect(w, r, route, http.StatusTemporaryRedirect)
return nil return nil
} }

View File

@ -29,6 +29,7 @@ type Env struct {
Render *render.Render Render *render.Render
Auth *auth.Authorizer Auth *auth.Authorizer
Mode Mode Mode Mode
loginRoute string
} }
// NewEnv returns a new *Env // NewEnv returns a new *Env
@ -49,6 +50,15 @@ func NewEnv(db *sqlx.DB, auth *auth.Authorizer, log *logrus.Entry, templatesDir
} }
} }
func (e *Env) SetLoginRoute(name string) error {
route, err := e.GetURL(name)
if err != nil {
return err
}
e.loginRoute = route
return nil
}
// GetURL returns URL string from URL name and params // GetURL returns URL string from URL name and params
// Usefull for redirection and templates // Usefull for redirection and templates
func (e *Env) GetURL(name string, pairs ...string) (string, error) { func (e *Env) GetURL(name string, pairs ...string) (string, error) {
@ -66,14 +76,14 @@ func (e *Env) GetURL(name string, pairs ...string) (string, error) {
type HandlerFunc func(e *Env, w http.ResponseWriter, r *http.Request) error type HandlerFunc func(e *Env, w http.ResponseWriter, r *http.Request) error
func (e *Env) Handle(name, route string, H HandlerFunc) { func (e *Env) Handle(name, route string, H HandlerFunc) {
e.Router.Handle(route, Handler{e, H}) e.Router.Handle(route, Handler{e, H}).Name(name)
} }
func (e *Env) HandleRole(name, route string, H HandlerFunc, role string) { func (e *Env) HandleRole(name, route string, H HandlerFunc, role string) {
e.Router.Handle(route, negroni.New( e.Router.Handle(route, negroni.New(
auth.NewMiddlewareRole(e.Auth, role), auth.NewMiddlewareRole(e.Auth, e.GetLoginRouteGetter(), role),
negroni.Wrap(Handler{e, H}), negroni.Wrap(Handler{e, H}),
)) )).Name(name)
} }
// The Handler struct that takes a configured Env and a function matching our // The Handler struct that takes a configured Env and a function matching our
@ -94,3 +104,12 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
http.StatusInternalServerError) http.StatusInternalServerError)
} }
} }
func (e *Env) GetLoginRouteGetter() func() string {
return func() string {
if e.loginRoute == "" {
panic("Env: login route not set")
}
return e.loginRoute
}
}