Add post login redirect
This commit is contained in:
parent
5778fd45df
commit
80cd6d3d72
@ -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
|
||||||
}
|
}
|
||||||
@ -29,25 +30,57 @@ 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
|
||||||
}
|
}
|
||||||
|
8
main.go
8
main.go
@ -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)
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
web/env.go
37
web/env.go
@ -23,12 +23,13 @@ const (
|
|||||||
|
|
||||||
// Env describes an environement object passed to all handlers
|
// Env describes an environement object passed to all handlers
|
||||||
type Env struct {
|
type Env struct {
|
||||||
Database *sqlx.DB
|
Database *sqlx.DB
|
||||||
Log *logrus.Entry
|
Log *logrus.Entry
|
||||||
Router *mux.Router
|
Router *mux.Router
|
||||||
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user