Files
outfit-voting-abi26/internal/auth/routes.go
T

134 lines
2.8 KiB
Go

package auth
import (
"log"
"net/http"
"net/url"
"strings"
"time"
)
func IsAuth(r *http.Request) (bool, error) {
jwt, err := getAuthToken(r)
if err != nil {
return false, err
}
_, err = ValidateJWT(jwt)
if err != nil {
return false, err
}
return true, nil
}
func LogoutEndpoint(w http.ResponseWriter, r *http.Request) {
setAuthCookie(w, r, "")
http.Redirect(w, r, "/", http.StatusSeeOther)
}
func AuthMiddleware(next http.HandlerFunc) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
jwt, err := getAuthToken(r)
if err != nil {
log.Println("Error during token retrieval", err)
Redirect(w, r)
return
}
user, err := ValidateJWT(jwt)
if err != nil {
log.Println("Error during authorization", err)
Redirect(w, r)
return
}
log.Printf("%s: Authorized user %s", r.URL.Path, user)
w.Header().Add("user", user)
next.ServeHTTP(w, r)
})
}
func CallbackHandler(mux *http.ServeMux) {
url, err := url.Parse(config.RedirectURL)
if err != nil {
log.Fatalf("Invalid Redirect URL Submitted: %s\n", config.RedirectURL)
}
mux.HandleFunc(url.Path, func(w http.ResponseWriter, r *http.Request) {
if err := CheckState(r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
code := r.URL.Query().Get("code")
idtoken, err := GetToken(code)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := CheckAudience(idtoken); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := CheckNonce(r, idtoken); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
var UsernameClaim struct {
PreferredUsername string `json:"preferred_username"`
}
if err := idtoken.Claims(&UsernameClaim); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
jwt, err := NewJWT(UsernameClaim.PreferredUsername)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
setAuthCookie(w, r, jwt)
redirect := GetRedirect(r.URL.Query().Get("state"))
log.Printf("DEBUG: REDIRECT %s\n", redirect)
http.Redirect(w, r, redirect, http.StatusFound)
})
}
func setAuthCookie(w http.ResponseWriter, r *http.Request, jwt string) {
c := &http.Cookie{
Name: authCookie,
Value: jwt,
MaxAge: int(time.Hour.Seconds()),
Secure: r.TLS != nil,
Path: "/",
HttpOnly: true,
}
http.SetCookie(w, c)
}
func getAuthToken(r *http.Request) (string, error) {
header := strings.Split(r.Header.Get("Authorization"), " ")
if len(header) > 1 {
token := header[1]
if len(strings.TrimSpace(token)) > 0 {
log.Printf("Got Auth Header %s\n", header[1])
return token, nil
}
}
cookie, err := r.Cookie(authCookie)
if err != nil {
return "", err
}
return cookie.Value, nil
}