github.com/korniux/gophish@v0.9.0/controllers/api/campaign.go (about)

     1  package api
     2  
     3  import (
     4  	"encoding/json"
     5  	"net/http"
     6  	"strconv"
     7  
     8  	ctx "github.com/gophish/gophish/context"
     9  	log "github.com/gophish/gophish/logger"
    10  	"github.com/gophish/gophish/models"
    11  	"github.com/gorilla/mux"
    12  	"github.com/jinzhu/gorm"
    13  )
    14  
    15  // Campaigns returns a list of campaigns if requested via GET.
    16  // If requested via POST, APICampaigns creates a new campaign and returns a reference to it.
    17  func (as *Server) Campaigns(w http.ResponseWriter, r *http.Request) {
    18  	switch {
    19  	case r.Method == "GET":
    20  		cs, err := models.GetCampaigns(ctx.Get(r, "user_id").(int64))
    21  		if err != nil {
    22  			log.Error(err)
    23  		}
    24  		JSONResponse(w, cs, http.StatusOK)
    25  	//POST: Create a new campaign and return it as JSON
    26  	case r.Method == "POST":
    27  		c := models.Campaign{}
    28  		// Put the request into a campaign
    29  		err := json.NewDecoder(r.Body).Decode(&c)
    30  		if err != nil {
    31  			JSONResponse(w, models.Response{Success: false, Message: "Invalid JSON structure"}, http.StatusBadRequest)
    32  			return
    33  		}
    34  		err = models.PostCampaign(&c, ctx.Get(r, "user_id").(int64))
    35  		if err != nil {
    36  			JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusBadRequest)
    37  			return
    38  		}
    39  		// If the campaign is scheduled to launch immediately, send it to the worker.
    40  		// Otherwise, the worker will pick it up at the scheduled time
    41  		if c.Status == models.CampaignInProgress {
    42  			go as.worker.LaunchCampaign(c)
    43  		}
    44  		JSONResponse(w, c, http.StatusCreated)
    45  	}
    46  }
    47  
    48  // CampaignsSummary returns the summary for the current user's campaigns
    49  func (as *Server) CampaignsSummary(w http.ResponseWriter, r *http.Request) {
    50  	switch {
    51  	case r.Method == "GET":
    52  		cs, err := models.GetCampaignSummaries(ctx.Get(r, "user_id").(int64))
    53  		if err != nil {
    54  			log.Error(err)
    55  			JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusInternalServerError)
    56  			return
    57  		}
    58  		JSONResponse(w, cs, http.StatusOK)
    59  	}
    60  }
    61  
    62  // Campaign returns details about the requested campaign. If the campaign is not
    63  // valid, APICampaign returns null.
    64  func (as *Server) Campaign(w http.ResponseWriter, r *http.Request) {
    65  	vars := mux.Vars(r)
    66  	id, _ := strconv.ParseInt(vars["id"], 0, 64)
    67  	c, err := models.GetCampaign(id, ctx.Get(r, "user_id").(int64))
    68  	if err != nil {
    69  		log.Error(err)
    70  		JSONResponse(w, models.Response{Success: false, Message: "Campaign not found"}, http.StatusNotFound)
    71  		return
    72  	}
    73  	switch {
    74  	case r.Method == "GET":
    75  		JSONResponse(w, c, http.StatusOK)
    76  	case r.Method == "DELETE":
    77  		err = models.DeleteCampaign(id)
    78  		if err != nil {
    79  			JSONResponse(w, models.Response{Success: false, Message: "Error deleting campaign"}, http.StatusInternalServerError)
    80  			return
    81  		}
    82  		JSONResponse(w, models.Response{Success: true, Message: "Campaign deleted successfully!"}, http.StatusOK)
    83  	}
    84  }
    85  
    86  // CampaignResults returns just the results for a given campaign to
    87  // significantly reduce the information returned.
    88  func (as *Server) CampaignResults(w http.ResponseWriter, r *http.Request) {
    89  	vars := mux.Vars(r)
    90  	id, _ := strconv.ParseInt(vars["id"], 0, 64)
    91  	cr, err := models.GetCampaignResults(id, ctx.Get(r, "user_id").(int64))
    92  	if err != nil {
    93  		log.Error(err)
    94  		JSONResponse(w, models.Response{Success: false, Message: "Campaign not found"}, http.StatusNotFound)
    95  		return
    96  	}
    97  	if r.Method == "GET" {
    98  		JSONResponse(w, cr, http.StatusOK)
    99  		return
   100  	}
   101  }
   102  
   103  // CampaignSummary returns the summary for a given campaign.
   104  func (as *Server) CampaignSummary(w http.ResponseWriter, r *http.Request) {
   105  	vars := mux.Vars(r)
   106  	id, _ := strconv.ParseInt(vars["id"], 0, 64)
   107  	switch {
   108  	case r.Method == "GET":
   109  		cs, err := models.GetCampaignSummary(id, ctx.Get(r, "user_id").(int64))
   110  		if err != nil {
   111  			if err == gorm.ErrRecordNotFound {
   112  				JSONResponse(w, models.Response{Success: false, Message: "Campaign not found"}, http.StatusNotFound)
   113  			} else {
   114  				JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusInternalServerError)
   115  			}
   116  			log.Error(err)
   117  			return
   118  		}
   119  		JSONResponse(w, cs, http.StatusOK)
   120  	}
   121  }
   122  
   123  // CampaignComplete effectively "ends" a campaign.
   124  // Future phishing emails clicked will return a simple "404" page.
   125  func (as *Server) CampaignComplete(w http.ResponseWriter, r *http.Request) {
   126  	vars := mux.Vars(r)
   127  	id, _ := strconv.ParseInt(vars["id"], 0, 64)
   128  	switch {
   129  	case r.Method == "GET":
   130  		err := models.CompleteCampaign(id, ctx.Get(r, "user_id").(int64))
   131  		if err != nil {
   132  			JSONResponse(w, models.Response{Success: false, Message: "Error completing campaign"}, http.StatusInternalServerError)
   133  			return
   134  		}
   135  		JSONResponse(w, models.Response{Success: true, Message: "Campaign completed successfully!"}, http.StatusOK)
   136  	}
   137  }