Mostly just function signatures at the moment Signed-off-by: Ethan Wellenreiter <ewellenreiter@gmail.com>
92 lines
2.8 KiB
Go
92 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
func (app *application) loginHandler(w http.ResponseWriter, r *http.Request) {
|
|
// should give them a cookie in the response
|
|
authHeader := r.Header.Get("Authorization")
|
|
if authHeader == "" {
|
|
app.unauthorizedBasicErrorResponse(w, r, fmt.Errorf("authorization header is missing"))
|
|
return
|
|
}
|
|
|
|
ctx := r.Context()
|
|
|
|
// parse it -> get the base64
|
|
parts := strings.Split(authHeader, " ")
|
|
if len(parts) != 2 || parts[0] != "Basic" {
|
|
app.unauthorizedBasicErrorResponse(w, r, fmt.Errorf("authorization header is malformed"))
|
|
return
|
|
}
|
|
|
|
// decode it
|
|
decoded, err := base64.StdEncoding.DecodeString(parts[1])
|
|
if err != nil {
|
|
app.unauthorizedBasicErrorResponse(w, r, err)
|
|
return
|
|
}
|
|
|
|
// check the credentials
|
|
creds := strings.SplitN(string(decoded), ":", 2)
|
|
if len(creds) != 2 {
|
|
app.unauthorizedBasicErrorResponse(w, r, fmt.Errorf("invalid credentials"))
|
|
return
|
|
}
|
|
username, pass := creds[0], creds[1]
|
|
|
|
valid, user, err := app.auth.Users.SigninUser(ctx, username, pass)
|
|
if !valid || err != nil {
|
|
app.unauthorizedBasicErrorResponse(w, r, fmt.Errorf("invalid credentials"))
|
|
return
|
|
}
|
|
|
|
token, err := app.auth.Sessions.AddSession(ctx, user.ID)
|
|
if err != nil {
|
|
app.unauthorizedBasicErrorResponse(w, r, fmt.Errorf("failed to add session"))
|
|
return
|
|
}
|
|
|
|
w.Header().Add("Vary", "Cookie")
|
|
w.Header().Add("Cache-Control", `no-cache="Set-Cookie"`)
|
|
|
|
http.SetCookie(w, &http.Cookie{
|
|
Name: "Session_token",
|
|
Value: token,
|
|
Path: "/",
|
|
HttpOnly: true,
|
|
Secure: true,
|
|
SameSite: http.SameSiteStrictMode,
|
|
// Set an expiry and path
|
|
})
|
|
// also need to set the csrf or cors or refresh stuff here. Probably just the refresh token stuff (actually, with sessions, there will be no refresh token. Just updating the expiry)
|
|
|
|
// cache and ignore if the cache fails?
|
|
if !app.config.redisCfg.enabled {
|
|
if err := app.cacheStorage.Users.Set(ctx, user); err != nil {
|
|
app.internalServerError(w, r, fmt.Errorf("Failed to add user to cache"))
|
|
return
|
|
}
|
|
}
|
|
|
|
// since it could be a different storage system, idk if it makes sense to do any caching or to just deal with the overhead of logging in. It doesn't happen that often anyways so caching shouldn't make much of a difference. Maybe load it into cache after
|
|
|
|
// consider using the cached user stuff instead. that user will have the hashed password which is fine to move around. And then it can just do the compare stuff using whatever auth. Maybe instead, the checkpass can take in a user
|
|
}
|
|
|
|
func (app *application) logoutHandler(w http.ResponseWriter, r *http.Request) {
|
|
// should give them a cookie in the response
|
|
}
|
|
|
|
func (app *application) registerUserHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
}
|
|
|
|
func (app *application) refreshTokenHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
}
|