first commit
This commit is contained in:
156
backend/internal/interfaces/handlers/public_handler.go
Normal file
156
backend/internal/interfaces/handlers/public_handler.go
Normal file
@@ -0,0 +1,156 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
|
||||
"github.com/noteapp/backend/internal/application/dto"
|
||||
"github.com/noteapp/backend/internal/application/services"
|
||||
)
|
||||
|
||||
// PublicHandler handles unauthenticated public read-only requests
|
||||
type PublicHandler struct {
|
||||
spaceService *services.SpaceService
|
||||
noteService *services.NoteService
|
||||
}
|
||||
|
||||
// NewPublicHandler creates a new PublicHandler
|
||||
func NewPublicHandler(spaceService *services.SpaceService, noteService *services.NoteService) *PublicHandler {
|
||||
return &PublicHandler{spaceService: spaceService, noteService: noteService}
|
||||
}
|
||||
|
||||
// GetPublicSpace handles GET /public/spaces/{spaceId}
|
||||
func (h *PublicHandler) GetPublicSpace(w http.ResponseWriter, r *http.Request) {
|
||||
spaceID, err := bson.ObjectIDFromHex(mux.Vars(r)["spaceId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid space id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
space, err := h.spaceService.GetPublicSpace(r.Context(), spaceID)
|
||||
if err != nil {
|
||||
if err.Error() == "space is not public" {
|
||||
http.Error(w, "not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(space)
|
||||
}
|
||||
|
||||
// ListPublicSpaces handles GET /public/spaces
|
||||
func (h *PublicHandler) ListPublicSpaces(w http.ResponseWriter, r *http.Request) {
|
||||
spaces, err := h.spaceService.GetPublicSpaces(r.Context())
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{"spaces": spaces})
|
||||
}
|
||||
|
||||
// GetPublicNotes handles GET /public/spaces/{spaceId}/notes
|
||||
func (h *PublicHandler) GetPublicNotes(w http.ResponseWriter, r *http.Request) {
|
||||
spaceID, err := bson.ObjectIDFromHex(mux.Vars(r)["spaceId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid space id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
skip := 0
|
||||
limit := 50
|
||||
if v := r.URL.Query().Get("skip"); v != "" {
|
||||
if n, err := strconv.Atoi(v); err == nil && n >= 0 {
|
||||
skip = n
|
||||
}
|
||||
}
|
||||
if v := r.URL.Query().Get("limit"); v != "" {
|
||||
if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 100 {
|
||||
limit = n
|
||||
}
|
||||
}
|
||||
|
||||
notes, err := h.noteService.GetPublicNotesBySpace(r.Context(), spaceID, skip, limit)
|
||||
if err != nil {
|
||||
if err.Error() == "space is not public" {
|
||||
http.Error(w, "not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{"notes": notes})
|
||||
}
|
||||
|
||||
// GetPublicNote handles GET /public/spaces/{spaceId}/notes/{noteId}
|
||||
func (h *PublicHandler) GetPublicNote(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
spaceID, err := bson.ObjectIDFromHex(vars["spaceId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid space id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
noteID, err := bson.ObjectIDFromHex(vars["noteId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid note id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
note, err := h.noteService.GetPublicNoteBySpaceAndID(r.Context(), spaceID, noteID)
|
||||
if err != nil {
|
||||
if err.Error() == "space is not public" || err.Error() == "note is not public" || err.Error() == "space not found" || err.Error() == "note not found" {
|
||||
http.Error(w, "not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(note)
|
||||
}
|
||||
|
||||
// UnlockPublicNote verifies a public note password and returns full note content
|
||||
func (h *PublicHandler) UnlockPublicNote(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
spaceID, err := bson.ObjectIDFromHex(vars["spaceId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid space id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
noteID, err := bson.ObjectIDFromHex(vars["noteId"])
|
||||
if err != nil {
|
||||
http.Error(w, "invalid note id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var req dto.UnlockNoteRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
note, err := h.noteService.UnlockPublicNote(r.Context(), spaceID, noteID, req.Password)
|
||||
if err != nil {
|
||||
if err.Error() == "invalid note password" {
|
||||
http.Error(w, err.Error(), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
if err.Error() == "space is not public" || err.Error() == "space not found" || err.Error() == "note not found" {
|
||||
http.Error(w, "not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(note)
|
||||
}
|
||||
Reference in New Issue
Block a user