diff --git a/controllers/api.go b/controllers/api.go index 80e20f5c..b9af6ad4 100644 --- a/controllers/api.go +++ b/controllers/api.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "time" ctx "github.com/gorilla/context" "github.com/gorilla/mux" @@ -11,6 +12,13 @@ import ( "github.com/jordan-wright/gophish/models" ) +const ( + IN_PROGRESS string = "In progress" + WAITING string = "Waiting" + COMPLETE string = "Completed" + ERROR string = "Error" +) + func API(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { @@ -32,19 +40,39 @@ func API_Campaigns(w http.ResponseWriter, r *http.Request) { switch { case r.Method == "GET": cs := []models.Campaign{} - _, err := db.Conn.Select(&cs, "SELECT name, created_date, completed_date, status, template FROM campaigns, users WHERE campaigns.uid=users.id AND users.apikey=?", ctx.Get(r, "api_key")) + _, err := db.Conn.Select(&cs, "SELECT campaigns.id, name, created_date, completed_date, status, template FROM campaigns, users WHERE campaigns.uid=users.id AND users.api_key=?", ctx.Get(r, "api_key")) if err != nil { fmt.Println(err) } - d, err := json.MarshalIndent(cs, "", " ") - if err != nil { - fmt.Println(err) + cj, err := json.MarshalIndent(cs, "", " ") + if checkError(err, w, "Error looking up campaigns") { + return } - writeJSON(w, d) + writeJSON(w, cj) case r.Method == "POST": - fmt.Fprintf(w, "Hello POST!") + c := models.Campaign{} + // Put the request into a campaign + err := json.NewDecoder(r.Body).Decode(&c) + checkError(err, w, "Invalid Request") + // Fill in the details + c.CreatedDate = time.Now() + c.CompletedDate = time.Time{} + c.Status = IN_PROGRESS + c.Uid, err = db.Conn.SelectInt("SELECT id FROM users WHERE api_key=?", ctx.Get(r, "api_key")) + if checkError(err, w, "Invalid API Key") { + return + } + // Insert into the DB + err = db.Conn.Insert(&c) + if checkError(err, w, "Cannot insert campaign into database") { + return + } + cj, err := json.MarshalIndent(c, "", " ") + if checkError(err, w, "Error creating JSON response") { + return + } + writeJSON(w, cj) } - //fmt.Fprintf(w, "Hello api") } //API_Campaigns_Id returns details about the requested campaign. If the campaign is not diff --git a/controllers/route.go b/controllers/route.go index 46243f91..5bbb494f 100644 --- a/controllers/route.go +++ b/controllers/route.go @@ -122,9 +122,13 @@ func Login(w http.ResponseWriter, r *http.Request) { case r.Method == "POST": //Attempt to login err := r.ParseForm() - checkError(err, w, "Error parsing request") + if checkError(err, w, "Error parsing request") { + return + } succ, err := auth.Login(r) - checkError(err, w, "Error logging in") + if checkError(err, w, "Error logging in") { + return + } //If we've logged in, save the session and redirect to the dashboard if succ { session.Save(r, w) @@ -144,9 +148,11 @@ func getTemplate(w http.ResponseWriter, tmpl string) *template.Template { return template.Must(template.New("template").ParseFiles("templates/base.html", "templates/nav.html", "templates/"+tmpl+".html", "templates/flashes.html")) } -func checkError(e error, w http.ResponseWriter, m string) { +func checkError(e error, w http.ResponseWriter, m string) bool { if e != nil { fmt.Println(e) - http.Error(w, m, http.StatusInternalServerError) + http.Error(w, "Error: "+m, http.StatusInternalServerError) + return true } + return false } diff --git a/db/db.go b/db/db.go index 76973d2d..37132706 100644 --- a/db/db.go +++ b/db/db.go @@ -29,7 +29,7 @@ func Setup() error { fmt.Println("Database not found, recreating...") createTablesSQL := []string{ //Create tables - `CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL, hash VARCHAR(60) NOT NULL, apikey VARCHAR(32));`, + `CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL, hash VARCHAR(60) NOT NULL, api_key VARCHAR(32));`, `CREATE TABLE campaigns (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, created_date TIMESTAMP NOT NULL, completed_date TIMESTAMP, template TEXT, status TEXT NOT NULL, uid INTEGER, FOREIGN KEY (uid) REFERENCES Users(id));`, } fmt.Println("Creating db at " + config.Conf.DBPath) diff --git a/models/models.go b/models/models.go index ca6242ec..0e9b2974 100644 --- a/models/models.go +++ b/models/models.go @@ -22,10 +22,10 @@ type Config struct { // User represents the user model for gophish. type User struct { - Id int `json:"id"` + Id int64 `json:"id"` Username string `json:"username"` Hash string `json:"-"` - APIKey string `json:"apikey"` + APIKey string `json:"api_key" db:"api_key"` } // Flash is used to hold flash information for use in templates. @@ -36,32 +36,32 @@ type Flash struct { //Campaign is a struct representing a created campaign type Campaign struct { - Id int `json:"id"` + Id int64 `json:"id"` Name string `json:"name"` CreatedDate time.Time `json:"created_date" db:"created_date"` CompletedDate time.Time `json:"completed_date" db:"completed_date"` Template string `json:"template"` //This may change Status string `json:"status"` - Uid int `json:"-"` + Uid int64 `json:"-"` } type UserCampaigns struct { - CampaignId int - UserId int + CampaignId int64 + UserId int64 } type Result struct { - Id int - TargetId int + Id int64 + TargetId int64 Status string `json:"status"` } type CampaignResults struct { - CampaignId int - TargetId int + CampaignId int64 + TargetId int64 } type Target struct { - Id int `json:"-"` + Id int64 `json:"-"` Email mail.Address `json:"email"` }