add: implement shortlink
This commit is contained in:
129
internal/api/handlers/shortlink.go
Normal file
129
internal/api/handlers/shortlink.go
Normal file
@@ -0,0 +1,129 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"devone.aplikasi.web.id/gitea/mario/go-ohif-proxy/internal/api/middleware"
|
||||
"devone.aplikasi.web.id/gitea/mario/go-ohif-proxy/internal/api/models"
|
||||
"devone.aplikasi.web.id/gitea/mario/go-ohif-proxy/internal/api/service"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// ShortLinkHandler handles shortlink operations
|
||||
type ShortLinkHandler struct {
|
||||
logger *zap.Logger
|
||||
shortLinkService *service.ShortLinkService
|
||||
}
|
||||
|
||||
// NewShortLinkHandler creates a new shortlink handler
|
||||
func NewShortLinkHandler(logger *zap.Logger, shortLinkService *service.ShortLinkService) *ShortLinkHandler {
|
||||
return &ShortLinkHandler{
|
||||
logger: logger,
|
||||
shortLinkService: shortLinkService,
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateShortLink handles shortlink generation requests
|
||||
func (h *ShortLinkHandler) GenerateShortLink(w http.ResponseWriter, r *http.Request) {
|
||||
// Only allow admin or expertise_doctor roles to generate shortlinks
|
||||
userRole, ok := r.Context().Value(middleware.UserRoleKey).(string)
|
||||
if !ok || (userRole != "admin" && userRole != "expertise_doctor") {
|
||||
h.logger.Warn("Unauthorized attempt to generate shortlink",
|
||||
zap.String("role", userRole))
|
||||
http.Error(w, "Only admin or expertise doctor can generate short links", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Parse request body
|
||||
var req models.GenerateShortLinkRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
h.logger.Error("Failed to parse shortlink generation request", zap.Error(err))
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Get user ID from context
|
||||
userID, ok := r.Context().Value(middleware.UserIDKey).(string)
|
||||
if !ok {
|
||||
h.logger.Error("User ID not found in context")
|
||||
http.Error(w, "User context not found", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Generate shortlink using configured baseURL from service
|
||||
response, err := h.shortLinkService.GenerateShortLink(&req, userID)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to generate shortlink",
|
||||
zap.Error(err),
|
||||
zap.String("patientID", req.PatientID),
|
||||
zap.String("studyUID", req.StudyUID))
|
||||
|
||||
statusCode := http.StatusInternalServerError
|
||||
message := "Failed to generate shortlink"
|
||||
|
||||
if err == service.ErrInvalidStudyUID {
|
||||
statusCode = http.StatusBadRequest
|
||||
message = "Invalid StudyInstanceUID"
|
||||
}
|
||||
|
||||
http.Error(w, message, statusCode)
|
||||
return
|
||||
}
|
||||
|
||||
// Log successful shortlink generation
|
||||
h.logger.Info("Shortlink generated successfully",
|
||||
zap.String("token", response.ShortToken),
|
||||
zap.String("patientID", req.PatientID),
|
||||
zap.String("studyUID", req.StudyUID),
|
||||
zap.String("createdBy", userID))
|
||||
|
||||
// Return response
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
// ShortLinkAuth handles authentication requests using shortlinks
|
||||
func (h *ShortLinkHandler) ShortLinkAuth(w http.ResponseWriter, r *http.Request) {
|
||||
// Parse request body
|
||||
var req models.ShortLinkAuthRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
h.logger.Error("Failed to parse shortlink auth request", zap.Error(err))
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Validate and authenticate
|
||||
response, err := h.shortLinkService.AuthenticateWithShortLink(&req)
|
||||
if err != nil {
|
||||
h.logger.Warn("Shortlink authentication failed",
|
||||
zap.Error(err),
|
||||
zap.String("token", req.ShortToken))
|
||||
|
||||
statusCode := http.StatusUnauthorized
|
||||
message := "Authentication failed"
|
||||
|
||||
switch err {
|
||||
case service.ErrShortLinkNotFound, service.ErrShortLinkExpired:
|
||||
message = "Short link not found or expired"
|
||||
case service.ErrInvalidDOB:
|
||||
message = "Invalid date of birth"
|
||||
case service.ErrTooManyAttempts:
|
||||
message = "Too many failed attempts"
|
||||
}
|
||||
|
||||
http.Error(w, message, statusCode)
|
||||
return
|
||||
}
|
||||
|
||||
// Log successful authentication
|
||||
h.logger.Info("Shortlink authentication successful",
|
||||
zap.String("token", req.ShortToken))
|
||||
|
||||
// Return response
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
Reference in New Issue
Block a user