98 lines
2.5 KiB
Go
98 lines
2.5 KiB
Go
|
|
package handlers
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"log/slog"
|
||
|
|
"net/http"
|
||
|
|
|
||
|
|
"gitlab.com/unboundsoftware/auth0mock/auth"
|
||
|
|
"gitlab.com/unboundsoftware/auth0mock/store"
|
||
|
|
)
|
||
|
|
|
||
|
|
// SessionHandler handles session-related endpoints
|
||
|
|
type SessionHandler struct {
|
||
|
|
jwtService *auth.JWTService
|
||
|
|
sessionStore *store.SessionStore
|
||
|
|
logger *slog.Logger
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewSessionHandler creates a new session handler
|
||
|
|
func NewSessionHandler(jwtService *auth.JWTService, sessionStore *store.SessionStore, logger *slog.Logger) *SessionHandler {
|
||
|
|
return &SessionHandler{
|
||
|
|
jwtService: jwtService,
|
||
|
|
sessionStore: sessionStore,
|
||
|
|
logger: logger,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// UserInfo handles GET /userinfo
|
||
|
|
func (h *SessionHandler) UserInfo(w http.ResponseWriter, r *http.Request) {
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
json.NewEncoder(w).Encode(map[string]string{
|
||
|
|
"picture": "https://cdn.playbuzz.com/cdn/5458360f-32ea-460e-a707-1a2d26760558/70bda687-cb84-4756-8a44-8cf735ed87b3.jpg",
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// TokenInfo handles POST /tokeninfo
|
||
|
|
func (h *SessionHandler) TokenInfo(w http.ResponseWriter, r *http.Request) {
|
||
|
|
var req struct {
|
||
|
|
IDToken string `json:"id_token"`
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||
|
|
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
if req.IDToken == "" {
|
||
|
|
h.logger.Debug("no token given in body")
|
||
|
|
http.Error(w, "missing id_token", http.StatusUnauthorized)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
claims, err := h.jwtService.DecodeToken(req.IDToken)
|
||
|
|
if err != nil {
|
||
|
|
h.logger.Debug("failed to decode token", "error", err)
|
||
|
|
http.Error(w, "invalid id_token", http.StatusUnauthorized)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
if userID, ok := claims["sub"].(string); ok {
|
||
|
|
h.logger.Debug("returning token data", "user_id", userID)
|
||
|
|
}
|
||
|
|
|
||
|
|
w.Header().Set("Content-Type", "application/json")
|
||
|
|
json.NewEncoder(w).Encode(claims)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Logout handles GET /v2/logout
|
||
|
|
func (h *SessionHandler) Logout(w http.ResponseWriter, r *http.Request) {
|
||
|
|
returnTo := r.URL.Query().Get("returnTo")
|
||
|
|
|
||
|
|
// Try to get session from cookie
|
||
|
|
cookie, err := r.Cookie("auth0")
|
||
|
|
if err == nil && cookie.Value != "" {
|
||
|
|
h.sessionStore.Delete(cookie.Value)
|
||
|
|
h.logger.Debug("deleted session", "code", cookie.Value)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Clear the cookie
|
||
|
|
http.SetCookie(w, &http.Cookie{
|
||
|
|
Name: "auth0",
|
||
|
|
Value: "",
|
||
|
|
Path: "/",
|
||
|
|
MaxAge: -1,
|
||
|
|
SameSite: http.SameSiteNoneMode,
|
||
|
|
Secure: true,
|
||
|
|
HttpOnly: true,
|
||
|
|
})
|
||
|
|
|
||
|
|
if returnTo != "" {
|
||
|
|
http.Redirect(w, r, returnTo, http.StatusFound)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
w.WriteHeader(http.StatusOK)
|
||
|
|
w.Write([]byte("Logged out"))
|
||
|
|
}
|