cognito-auth/handlers.go

247 lines
6.2 KiB
Go

package cognito_auth
import (
"encoding/json"
"html/template"
"net/http"
"path/filepath"
)
type Handlers struct {
Client *Client
Templates *template.Template
}
func NewHandlers(client *Client, templateDir string) (*Handlers, error) {
templates, err := template.ParseGlob(filepath.Join(templateDir, "*.html"))
if err != nil {
return nil, err
}
return &Handlers{
Client: client,
Templates: templates,
}, nil
}
func (h *Handlers) RenderTemplate(w http.ResponseWriter, tmpl string, data interface{}) {
err := h.Templates.ExecuteTemplate(w, tmpl+".html", data)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}
type JSONResponse struct {
Message string `json:"message,omitempty"`
Data interface{} `json:"data,omitempty"`
Error string `json:"error,omitempty"`
}
func (h *Handlers) SignUpHTMLHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
// Render the sign-up form
h.RenderTemplate(w, "signup", nil)
return
}
if r.Method == http.MethodPost {
// Parse form data
if err := r.ParseForm(); err != nil {
h.RenderTemplate(w, "signup", map[string]string{"Error": "Invalid form data"})
return
}
username := r.FormValue("username")
email := r.FormValue("email")
password := r.FormValue("password")
// Sign up the user
err := h.Client.SignUp(SignUpRequest{
Context: r.Context(),
Username: username,
Password: password,
Email: email,
})
if err != nil {
h.RenderTemplate(w, "signup", map[string]string{"Error": err.Error()})
return
}
// Redirect to confirmation page or show success message
http.Redirect(w, r, "/confirm_signup", http.StatusSeeOther)
return
}
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
}
func (h *Handlers) SignUpJSONHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
return
}
var req struct {
Username string `json:"username"`
Email string `json:"email"`
Password string `json:"password"`
}
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&req); err != nil {
http.Error(w, "Bad Request: "+err.Error(), http.StatusBadRequest)
return
}
err := h.Client.SignUp(SignUpRequest{
Username: req.Username,
Password: req.Password,
Email: req.Email,
Context: r.Context(),
})
if err != nil {
response := JSONResponse{Error: err.Error()}
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(response)
return
}
response := JSONResponse{Message: "User signed up successfully. Please confirm your email."}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}
func (h *Handlers) ConfirmSignUpHTMLHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
// Render the confirm sign-up form
h.RenderTemplate(w, "confirm_signup", nil)
return
}
if r.Method == http.MethodPost {
// Parse form data
if err := r.ParseForm(); err != nil {
h.RenderTemplate(w, "confirm_signup", map[string]string{"Error": "Invalid form data"})
return
}
username := r.FormValue("username")
confirmationCode := r.FormValue("confirmation_code")
// Confirm sign-up
err := h.Client.ConfirmSignUp(ConfirmSignUpRequest{
Context: r.Context(),
Username: username,
ConfirmationCode: confirmationCode,
})
if err != nil {
h.RenderTemplate(w, "confirm_signup", map[string]string{"Error": err.Error()})
return
}
// Redirect to sign-in page or show success message
http.Redirect(w, r, "/signin", http.StatusSeeOther)
return
}
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
}
func (h *Handlers) ConfirmSignUpJSONHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
return
}
var req struct {
Username string `json:"username"`
ConfirmationCode string `json:"confirmation_code"`
}
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&req); err != nil {
http.Error(w, "Bad Request: "+err.Error(), http.StatusBadRequest)
return
}
err := h.Client.ConfirmSignUp(ConfirmSignUpRequest{
Context: r.Context(),
Username: req.Username,
ConfirmationCode: req.ConfirmationCode,
})
if err != nil {
response := JSONResponse{Error: err.Error()}
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(response)
return
}
response := JSONResponse{Message: "User confirmed successfully."}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}
// SignInHTMLHandler handles HTML sign-in requests
func (h *Handlers) SignInHTMLHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
// Render the sign-in form
h.RenderTemplate(w, "signin", nil)
return
}
if r.Method == http.MethodPost {
// Parse form data
if err := r.ParseForm(); err != nil {
h.RenderTemplate(w, "signin", map[string]string{"Error": "Invalid form data"})
return
}
username := r.FormValue("username")
password := r.FormValue("password")
// Sign in the user
authResult, err := h.Client.SignIn(r.Context(), username, password)
if err != nil {
h.RenderTemplate(w, "signin", map[string]string{"Error": err.Error()})
return
}
// Render a success page or display tokens
h.RenderTemplate(w, "signin_success", authResult)
return
}
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
}
func (h *Handlers) SignInJSONHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
return
}
var req struct {
Username string `json:"username"`
Password string `json:"password"`
}
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&req); err != nil {
http.Error(w, "Bad Request: "+err.Error(), http.StatusBadRequest)
return
}
authResult, err := h.Client.SignIn(r.Context(), req.Username, req.Password)
if err != nil {
response := JSONResponse{Error: err.Error()}
w.WriteHeader(http.StatusUnauthorized)
json.NewEncoder(w).Encode(response)
return
}
response := JSONResponse{Data: authResult}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}