Skip to content

Commit

Permalink
fixes login redirect to the previous page
Browse files Browse the repository at this point in the history
  • Loading branch information
ivarprudnikov committed Apr 27, 2024
1 parent 636df9d commit 18c4401
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
38 changes: 33 additions & 5 deletions routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"errors"
"net/http"
"net/url"

"github.com/gorilla/sessions"
"github.com/ivarprudnikov/secretshare/internal/crypto"
Expand All @@ -22,6 +23,7 @@ const SESS_USER_KEY = "user"
const VIEW_SESS_KEY = "session"
const VIEW_DATA_KEY = "data"
const VIEW_ERROR_KEY = "error"
const failedPathQueryKey = "failedPath"

// contextKey is the type used to store the user in the context.
type contextKey int
Expand Down Expand Up @@ -82,8 +84,18 @@ func indexPageHandler(sessions *sessions.CookieStore) http.HandlerFunc {
func loginPageHandler(sessions *sessions.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
sess, _ := sessions.Get(r, SESS_COOKIE)
redirectPath := ""
failedPath := r.URL.Query().Get(failedPathQueryKey)
if failedPath != "" {
slog.LogAttrs(r.Context(), slog.LevelInfo, "needs to redirect to protected path")
parsedFailedPath, err := url.Parse(failedPath)
if err == nil {
redirectPath = parsedFailedPath.Path
}
}
tmpl.ExecuteTemplate(w, "account.login.tmpl", map[string]interface{}{
VIEW_SESS_KEY: sess.Values,
VIEW_SESS_KEY: sess.Values,
failedPathQueryKey: redirectPath,
})
}
}
Expand Down Expand Up @@ -127,7 +139,19 @@ func loginAccountHandler(sessions *sessions.CookieStore, store storage.UserStore
sendError(r.Context(), sess, w, "failed to save session", err)
return
}
http.Redirect(w, r, "/", http.StatusSeeOther)

redirectPath := "/"
failedPath := r.PostForm.Get(failedPathQueryKey)
if failedPath != "" {
slog.LogAttrs(r.Context(), slog.LevelInfo, "needs to redirect to protected path")
parsedFailedPath, err := url.Parse(failedPath)
if err == nil {
redirectPath = parsedFailedPath.Path
}
}

slog.LogAttrs(r.Context(), slog.LevelInfo, "user successfully logged in, redirecting", slog.String("username", username), slog.String("path", redirectPath))
http.Redirect(w, r, redirectPath, http.StatusSeeOther)
}
}

Expand Down Expand Up @@ -333,8 +357,9 @@ func statsHandler(sessions *sessions.CookieStore, userStore storage.UserStore, m
}
}

// adds CSRF token to the session of the get requests
// adds user to the context if session exists
// Main app middleware handles the session cookie
// also, finds and adds the user to the context if the session is valid
// also, adds a CSRF token to the session of GET requests, to be used in forms
func newAppMiddleware(sessions *sessions.CookieStore, users storage.UserStore) func(h http.Handler) http.Handler {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -379,21 +404,24 @@ func newAppMiddleware(sessions *sessions.CookieStore, users storage.UserStore) f
}
}

// authentication check expects the user to be set when the session cookie was parsed
func hasAuth(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var ctx = r.Context()
user := ctx.Value(userKey)
u, ok := user.(*storage.User)
if user == nil || !ok {
slog.LogAttrs(ctx, slog.LevelInfo, "user not set, redirecting to login", slog.String("path", r.URL.Path))
http.Redirect(w, r, fmt.Sprintf("/accounts/login?uri=%s", r.URL.Path), http.StatusSeeOther)
http.Redirect(w, r, fmt.Sprintf("/accounts/login?%s=%s", failedPathQueryKey, r.URL.Path), http.StatusSeeOther)
return
}
slog.LogAttrs(ctx, slog.LevelInfo, "user authenticated", slog.String("username", u.PartitionKey), slog.String("path", r.URL.Path))
h.ServeHTTP(w, r)
})
}

// This ought to be used after the authentication check (hasAuth)
// Additional check for user here is to avoid unexpected usage
func hasPermission(permission string, h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var ctx = r.Context()
Expand Down
1 change: 1 addition & 0 deletions web/account.login.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<h3>Login</h3>
<form id="login" class="my-4" name="login" action="/accounts/login" method="POST">
<input type="hidden" name="_csrf" value="{{ .session.csrf }}" />
<input type="hidden" name="failedPath" value="{{ .failedPath }}" />
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" name="username" class="form-control" id="username" placeholder="doejoe" />
Expand Down

0 comments on commit 18c4401

Please sign in to comment.