mirror of https://github.com/gophish/gophish
Added /campaigns/:id/results endpoint to return campaign summary and make results page much quicker.
Fixes 282.pull/291/head
parent
3d5b330c61
commit
c5d6792bba
|
@ -111,6 +111,23 @@ func API_Campaigns_Id(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// API_Campaigns_Id_Results returns just the results for a given campaign to
|
||||||
|
// significantly reduce the information returned.
|
||||||
|
func API_Campaigns_Id_Results(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
id, _ := strconv.ParseInt(vars["id"], 0, 64)
|
||||||
|
cr, err := models.GetCampaignResults(id, ctx.Get(r, "user_id").(int64))
|
||||||
|
if err != nil {
|
||||||
|
Logger.Println(err)
|
||||||
|
JSONResponse(w, models.Response{Success: false, Message: "Campaign not found"}, http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.Method == "GET" {
|
||||||
|
JSONResponse(w, cr, http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// API_Groups returns details about the requested group. If the campaign is not
|
// API_Groups returns details about the requested group. If the campaign is not
|
||||||
// valid, API_Groups returns null.
|
// valid, API_Groups returns null.
|
||||||
func API_Groups(w http.ResponseWriter, r *http.Request) {
|
func API_Groups(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
|
@ -46,6 +46,7 @@ func CreateAdminRouter() http.Handler {
|
||||||
api.HandleFunc("/reset", Use(API_Reset, mid.RequireLogin))
|
api.HandleFunc("/reset", Use(API_Reset, mid.RequireLogin))
|
||||||
api.HandleFunc("/campaigns/", Use(API_Campaigns, mid.RequireAPIKey))
|
api.HandleFunc("/campaigns/", Use(API_Campaigns, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/campaigns/{id:[0-9]+}", Use(API_Campaigns_Id, mid.RequireAPIKey))
|
api.HandleFunc("/campaigns/{id:[0-9]+}", Use(API_Campaigns_Id, mid.RequireAPIKey))
|
||||||
|
api.HandleFunc("/campaigns/{id:[0-9]+}/results", Use(API_Campaigns_Id_Results, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/groups/", Use(API_Groups, mid.RequireAPIKey))
|
api.HandleFunc("/groups/", Use(API_Groups, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/groups/{id:[0-9]+}", Use(API_Groups_Id, mid.RequireAPIKey))
|
api.HandleFunc("/groups/{id:[0-9]+}", Use(API_Groups_Id, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/templates/", Use(API_Templates, mid.RequireAPIKey))
|
api.HandleFunc("/templates/", Use(API_Templates, mid.RequireAPIKey))
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Campaign is a struct representing a created campaign
|
// Campaign is a struct representing a created campaign
|
||||||
type Campaign struct {
|
type Campaign struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id"`
|
||||||
UserId int64 `json:"-"`
|
UserId int64 `json:"-"`
|
||||||
|
@ -28,6 +28,15 @@ type Campaign struct {
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CampaignResults is a struct representing the results from a campaign
|
||||||
|
type CampaignResults struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Results []Result `json:"results, omitempty"`
|
||||||
|
Events []Event `json:"timeline,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// ErrCampaignNameNotSpecified indicates there was no template given by the user
|
// ErrCampaignNameNotSpecified indicates there was no template given by the user
|
||||||
var ErrCampaignNameNotSpecified = errors.New("Campaign name not specified")
|
var ErrCampaignNameNotSpecified = errors.New("Campaign name not specified")
|
||||||
|
|
||||||
|
@ -190,6 +199,26 @@ func GetCampaign(id int64, uid int64) (Campaign, error) {
|
||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetCampaignResults(id int64, uid int64) (CampaignResults, error) {
|
||||||
|
cr := CampaignResults{}
|
||||||
|
err := db.Table("campaigns").Where("id=? and user_id=?", id, uid).Find(&cr).Error
|
||||||
|
if err != nil {
|
||||||
|
Logger.Printf("%s: campaign not found\n", err)
|
||||||
|
return cr, err
|
||||||
|
}
|
||||||
|
err = db.Table("results").Where("campaign_id=? and user_id=?", cr.Id, uid).Find(&cr.Results).Error
|
||||||
|
if err != nil {
|
||||||
|
Logger.Printf("%s: results not found for campaign\n", err)
|
||||||
|
return cr, err
|
||||||
|
}
|
||||||
|
err = db.Table("events").Where("campaign_id=?", cr.Id).Find(&cr.Events).Error
|
||||||
|
if err != nil {
|
||||||
|
Logger.Printf("%s: events not found for campaign\n", err)
|
||||||
|
return cr, err
|
||||||
|
}
|
||||||
|
return cr, err
|
||||||
|
}
|
||||||
|
|
||||||
// GetQueuedCampaigns returns the campaigns that are queued up for this given minute
|
// GetQueuedCampaigns returns the campaigns that are queued up for this given minute
|
||||||
func GetQueuedCampaigns(t time.Time) ([]Campaign, error) {
|
func GetQueuedCampaigns(t time.Time) ([]Campaign, error) {
|
||||||
cs := []Campaign{}
|
cs := []Campaign{}
|
||||||
|
|
|
@ -191,7 +191,7 @@ function renderTimeline(data) {
|
||||||
* * Datatables
|
* * Datatables
|
||||||
*/
|
*/
|
||||||
function poll() {
|
function poll() {
|
||||||
api.campaignId.get(campaign.id)
|
api.campaignId.results(campaign.id)
|
||||||
.success(function(c) {
|
.success(function(c) {
|
||||||
campaign = c
|
campaign = c
|
||||||
/* Update the timeline */
|
/* Update the timeline */
|
||||||
|
@ -289,7 +289,7 @@ function poll() {
|
||||||
|
|
||||||
function load() {
|
function load() {
|
||||||
campaign.id = window.location.pathname.split('/').slice(-1)[0]
|
campaign.id = window.location.pathname.split('/').slice(-1)[0]
|
||||||
api.campaignId.get(campaign.id)
|
api.campaignId.results(campaign.id)
|
||||||
.success(function(c) {
|
.success(function(c) {
|
||||||
campaign = c
|
campaign = c
|
||||||
if (campaign) {
|
if (campaign) {
|
||||||
|
|
|
@ -26,12 +26,12 @@ function query(endpoint, method, data, async) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeHtml(text){
|
function escapeHtml(text) {
|
||||||
return $("<div/>").text(text).html()
|
return $("<div/>").text(text).html()
|
||||||
}
|
}
|
||||||
|
|
||||||
function unescapeHtml(html){
|
function unescapeHtml(html) {
|
||||||
return $("<div/>").html(html).text()
|
return $("<div/>").html(html).text()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -58,6 +58,10 @@ var api = {
|
||||||
// delete() - Deletes a campaign at DELETE /campaigns/:id
|
// delete() - Deletes a campaign at DELETE /campaigns/:id
|
||||||
delete: function(id) {
|
delete: function(id) {
|
||||||
return query("/campaigns/" + id, "DELETE", {}, false)
|
return query("/campaigns/" + id, "DELETE", {}, false)
|
||||||
|
},
|
||||||
|
// results() - Queries the API for GET /campaigns/:id/results
|
||||||
|
results: function(id) {
|
||||||
|
return query("/campaigns/" + id + "/results", "GET", {}, true)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// groups contains the endpoints for /groups
|
// groups contains the endpoints for /groups
|
||||||
|
@ -173,8 +177,8 @@ var api = {
|
||||||
return query("/import/site", "POST", req, false)
|
return query("/import/site", "POST", req, false)
|
||||||
},
|
},
|
||||||
// send_test_email sends an email to the specified email address
|
// send_test_email sends an email to the specified email address
|
||||||
send_test_email: function(req){
|
send_test_email: function(req) {
|
||||||
return query("/util/send_test_email", "POST", req, true)
|
return query("/util/send_test_email", "POST", req, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue