126 lines
2.6 KiB
Go
126 lines
2.6 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
|
|
}
|
|
|
|
jwt, err := NewJWT(idtoken.Subject)
|
|
|
|
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
|
|
}
|