This repository has been archived on 2023-11-13. You can view files and clone it, but cannot push or open issues or pull requests.
imagini/internal/api/auth.go

96 lines
2.8 KiB
Go
Raw Normal View History

2021-01-16 22:00:17 +00:00
package api
2021-01-10 00:44:02 +00:00
import (
2021-01-12 04:48:32 +00:00
"time"
"encoding/json"
2021-01-10 00:44:02 +00:00
"net/http"
2021-01-12 04:48:32 +00:00
"reichard.io/imagini/internal/models"
2021-01-16 22:00:17 +00:00
// "github.com/lestrrat-go/jwx/jwt"
// "github.com/lestrrat-go/jwx/jwa"
2021-01-12 04:48:32 +00:00
// log "github.com/sirupsen/logrus"
2021-01-10 00:44:02 +00:00
)
2021-01-16 22:00:17 +00:00
// https://www.calhoun.io/pitfalls-of-context-values-and-how-to-avoid-or-mitigate-them/
// https://pace.dev/blog/2018/05/09/how-I-write-http-services-after-eight-years.html
// https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1#333c
// https://www.alexedwards.net/blog/organising-database-access <---- best
// - TLDR: Do what you're doing, but use closeures for the handlers
func (api *API) loginHandler(w http.ResponseWriter, r *http.Request) {
2021-01-12 04:48:32 +00:00
if r.Method != http.MethodPost {
2021-01-16 22:00:17 +00:00
errorJSON(w, "Method is not supported.", http.StatusMethodNotAllowed)
2021-01-12 04:48:32 +00:00
return
}
// Decode into Struct
var creds models.APICredentials
err := json.NewDecoder(r.Body).Decode(&creds)
if err != nil {
2021-01-16 22:00:17 +00:00
errorJSON(w, "Invalid parameters.", http.StatusBadRequest)
2021-01-12 04:48:32 +00:00
return
}
// Validate
if creds.User == "" || creds.Password == "" {
2021-01-16 22:00:17 +00:00
errorJSON(w, "Invalid parameters.", http.StatusBadRequest)
2021-01-12 04:48:32 +00:00
return
}
2021-01-10 00:44:02 +00:00
2021-01-12 04:48:32 +00:00
// Do login
2021-01-16 22:00:17 +00:00
resp := api.Auth.AuthenticateUser(creds)
2021-01-18 04:56:56 +00:00
if !resp {
2021-01-16 22:00:17 +00:00
errorJSON(w, "Invalid credentials.", http.StatusUnauthorized)
2021-01-18 04:56:56 +00:00
return
2021-01-12 04:48:32 +00:00
}
2021-01-18 04:56:56 +00:00
// Create tokens
accessToken := api.Auth.CreateJWTAccessToken()
refreshToken := api.Auth.CreateRefreshToken()
// Set appropriate cookies
accessCookie := http.Cookie{Name: "AccessToken", Value: accessToken}
refreshCookie := http.Cookie{Name: "RefreshToken", Value: refreshToken}
http.SetCookie(w, &accessCookie)
http.SetCookie(w, &refreshCookie)
// Response success
successJSON(w, "Login success.", http.StatusOK)
2021-01-10 00:44:02 +00:00
}
2021-01-16 22:00:17 +00:00
func (api *API) logoutHandler(w http.ResponseWriter, r *http.Request) {
2021-01-12 04:48:32 +00:00
if r.Method != http.MethodPost {
http.Error(w, "Method is not supported.", http.StatusMethodNotAllowed)
return
}
// Do logout
// TODO: Clear Session Server Side
2021-01-10 00:44:02 +00:00
2021-01-12 04:48:32 +00:00
// Tell Client to Expire Token
cookie := &http.Cookie{
Name: "Token",
Value: "",
Path: "/",
Expires: time.Unix(0, 0),
HttpOnly: true,
}
http.SetCookie(w, cookie)
2021-01-10 00:44:02 +00:00
}
2021-01-18 04:56:56 +00:00
func (api *API) refreshLoginHandler(w http.ResponseWriter, r *http.Request) {
ok := api.Auth.ValidateRefreshToken()
if !ok {
// TODO: Clear Access & Refresh Cookies
errorJSON(w, "Invalid credentials.", http.StatusUnauthorized)
return
}
// Update token
accessToken := api.Auth.CreateJWTAccessToken()
accessCookie := http.Cookie{Name: "AccessToken", Value: accessToken}
http.SetCookie(w, &accessCookie)
// Response success
successJSON(w, "Refresh success.", http.StatusOK)
}