package handler import ( "net/http" "accounting-app/pkg/api" "accounting-app/internal/service" "github.com/gin-gonic/gin" ) // BackupHandler handles HTTP requests for backup operations type BackupHandler struct { service *service.BackupService } // NewBackupHandler creates a new BackupHandler instance func NewBackupHandler(service *service.BackupService) *BackupHandler { return &BackupHandler{ service: service, } } // ExportBackup handles POST /api/v1/backup/export // @Summary Export encrypted database backup // @Description Creates an encrypted backup of the database with SHA256 integrity checking // @Tags backup // @Accept json // @Produce json // @Param request body service.BackupRequest true "Backup request" // @Success 200 {object} service.BackupResponse // @Failure 400 {object} api.ErrorResponse // @Failure 500 {object} api.ErrorResponse // @Router /api/v1/backup/export [post] func (h *BackupHandler) ExportBackup(c *gin.Context) { var req service.BackupRequest if err := c.ShouldBindJSON(&req); err != nil { api.Error(c, http.StatusBadRequest, "INVALID_REQUEST", "Invalid request: "+err.Error()) return } response, err := h.service.ExportBackup(req) if err != nil { if err == service.ErrInvalidPassword { api.Error(c, http.StatusBadRequest, "INVALID_PASSWORD", err.Error()) return } api.Error(c, http.StatusInternalServerError, "BACKUP_FAILED", "Failed to create backup: "+err.Error()) return } api.Success(c, response) } // ImportBackup handles POST /api/v1/backup/import // @Summary Import and restore from encrypted backup // @Description Restores the database from an encrypted backup file with integrity verification // @Tags backup // @Accept json // @Produce json // @Param request body service.RestoreRequest true "Restore request" // @Success 200 {object} api.SuccessResponse // @Failure 400 {object} api.ErrorResponse // @Failure 500 {object} api.ErrorResponse // @Router /api/v1/backup/import [post] func (h *BackupHandler) ImportBackup(c *gin.Context) { var req service.RestoreRequest if err := c.ShouldBindJSON(&req); err != nil { api.Error(c, http.StatusBadRequest, "INVALID_REQUEST", "Invalid request: "+err.Error()) return } err := h.service.ImportBackup(req) if err != nil { switch err { case service.ErrInvalidBackupFile: api.Error(c, http.StatusBadRequest, "INVALID_BACKUP_FILE", "Invalid backup file format") return case service.ErrChecksumMismatch: api.Error(c, http.StatusBadRequest, "CHECKSUM_MISMATCH", "Backup file integrity check failed") return case service.ErrDecryptionFailed: api.Error(c, http.StatusBadRequest, "DECRYPTION_FAILED", "Failed to decrypt backup - incorrect password") return default: api.Error(c, http.StatusInternalServerError, "RESTORE_FAILED", "Failed to restore backup: "+err.Error()) return } } api.Success(c, gin.H{ "message": "Database restored successfully from backup", }) } // VerifyBackup handles POST /api/v1/backup/verify // @Summary Verify backup file integrity // @Description Verifies the integrity of a backup file without restoring it // @Tags backup // @Accept json // @Produce json // @Param request body map[string]string true "Verify request with file_path" // @Success 200 {object} map[string]interface{} // @Failure 400 {object} api.ErrorResponse // @Failure 500 {object} api.ErrorResponse // @Router /api/v1/backup/verify [post] func (h *BackupHandler) VerifyBackup(c *gin.Context) { var req struct { FilePath string `json:"file_path" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { api.Error(c, http.StatusBadRequest, "INVALID_REQUEST", "Invalid request: "+err.Error()) return } isValid, checksum, err := h.service.VerifyBackup(req.FilePath) if err != nil { if err == service.ErrInvalidBackupFile { api.Error(c, http.StatusBadRequest, "INVALID_BACKUP_FILE", "Invalid backup file format") return } api.Error(c, http.StatusInternalServerError, "VERIFY_FAILED", "Failed to verify backup: "+err.Error()) return } api.Success(c, gin.H{ "valid": isValid, "checksum": checksum, "message": getVerificationMessage(isValid), }) } func getVerificationMessage(isValid bool) string { if isValid { return "Backup file integrity verified successfully" } return "Backup file integrity check failed - file may be corrupted" }