package httpapi import ( "context" "errors" "net/http" "github.com/vasyansk/imap-copier/internal/crypto" "github.com/vasyansk/imap-copier/internal/csvimport" "github.com/vasyansk/imap-copier/internal/orchestrator" "github.com/vasyansk/imap-copier/internal/store" ) func (s *Server) handleImportCSV(w http.ResponseWriter, r *http.Request) { taskID, err := pathID(r, "id") if err != nil { http.Error(w, "bad id", http.StatusBadRequest) return } file, _, err := r.FormFile("file") if err != nil { http.Error(w, "file required", http.StatusBadRequest) return } defer file.Close() rows, err := csvimport.Parse(file) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } for _, row := range rows { srcEnc, err := crypto.Encrypt(s.cfg.EncKey, []byte(row.SrcPass)) if err != nil { http.Error(w, "encrypt", http.StatusInternalServerError) return } dstEnc, err := crypto.Encrypt(s.cfg.EncKey, []byte(row.DstPass)) if err != nil { http.Error(w, "encrypt", http.StatusInternalServerError) return } if _, err := s.store.CreateAccount(r.Context(), store.Account{ TaskID: taskID, SrcLogin: row.SrcLogin, SrcPassEnc: srcEnc, DstLogin: row.DstLogin, DstPassEnc: dstEnc, }); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } writeJSON(w, http.StatusCreated, map[string]int{"imported": len(rows)}) } func (s *Server) handleTestAccounts(w http.ResponseWriter, r *http.Request) { taskID, err := pathID(r, "id") if err != nil { http.Error(w, "bad id", http.StatusBadRequest) return } // Detach from the request context: the request context is cancelled when // this handler returns, which would otherwise kill the background test run. ctx := context.WithoutCancel(r.Context()) go s.orch.TestAccounts(ctx, taskID) // прогресс через WS w.WriteHeader(http.StatusAccepted) } func (s *Server) handleRun(w http.ResponseWriter, r *http.Request) { taskID, err := pathID(r, "id") if err != nil { http.Error(w, "bad id", http.StatusBadRequest) return } runID, err := s.orch.Run(r.Context(), taskID) if errors.Is(err, orchestrator.ErrNotTested) { http.Error(w, "accounts must pass connection tests first", http.StatusConflict) return } if errors.Is(err, orchestrator.ErrAlreadyRunning) { http.Error(w, "task is already running", http.StatusConflict) return } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } writeJSON(w, http.StatusAccepted, map[string]int64{"run_id": runID}) }