diff --git a/controllers/api.go b/controllers/api.go index 87678c6f..3b27fa05 100644 --- a/controllers/api.go +++ b/controllers/api.go @@ -7,9 +7,18 @@ import ( ctx "github.com/gorilla/context" "github.com/gorilla/mux" + "github.com/jordan-wright/gophish/db" + "github.com/jordan-wright/gophish/models" ) func API(w http.ResponseWriter, r *http.Request) { + if r.Method == "GET" { + + } + if r.Method == "POST" { + //Add a new campaign + //v := + } if u, err := json.Marshal(ctx.Get(r, "user")); err == nil { writeJSON(w, u) } else { @@ -20,10 +29,18 @@ func API(w http.ResponseWriter, r *http.Request) { //API_Campaigns returns a list of campaigns if requested via GET. //If requested via POST, API_Campaigns creates a new campaign and returns a reference to it. func API_Campaigns(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") 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")) + if err != nil { + fmt.Println(err) + } + d, err := json.Marshal(cs) + if err != nil { + fmt.Println(err) + } + writeJSON(w, d) case r.Method == "POST": fmt.Fprintf(w, "Hello POST!") } diff --git a/controllers/route.go b/controllers/route.go index b1752efe..46243f91 100644 --- a/controllers/route.go +++ b/controllers/route.go @@ -52,9 +52,9 @@ func CreateRouter() *mux.Router { // Create the API routes api := router.PathPrefix("/api").Subrouter() - api.HandleFunc("/", Use(API, mid.RequireLogin)) - api.HandleFunc("/campaigns", API_Campaigns) - api.HandleFunc("/campaigns/{id}", API_Campaigns_Id) + api.HandleFunc("/", Use(API, mid.RequireAPIKey)) + api.HandleFunc("/campaigns", Use(API_Campaigns, mid.RequireAPIKey)) + api.HandleFunc("/campaigns/{id}", Use(API_Campaigns_Id, mid.RequireAPIKey)) api.HandleFunc("/doc", API_Doc) //Setup static file serving @@ -121,14 +121,10 @@ func Login(w http.ResponseWriter, r *http.Request) { getTemplate(w, "login").ExecuteTemplate(w, "base", params) case r.Method == "POST": //Attempt to login - if err := r.ParseForm(); err != nil { - http.Error(w, "Error parsing request", http.StatusInternalServerError) - } + err := r.ParseForm() + checkError(err, w, "Error parsing request") succ, err := auth.Login(r) - if err != nil { - fmt.Println(err) - http.Error(w, "Error logging in", http.StatusInternalServerError) - } + checkError(err, w, "Error logging in") //If we've logged in, save the session and redirect to the dashboard if succ { session.Save(r, w) @@ -147,3 +143,10 @@ func Login(w http.ResponseWriter, r *http.Request) { 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) { + if e != nil { + fmt.Println(e) + http.Error(w, m, http.StatusInternalServerError) + } +} diff --git a/db/db.go b/db/db.go index 4c5f7331..b737016c 100644 --- a/db/db.go +++ b/db/db.go @@ -4,6 +4,7 @@ import ( "database/sql" "fmt" "os" + "time" "github.com/coopernurse/gorp" "github.com/jordan-wright/gophish/config" @@ -28,8 +29,8 @@ 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 Campaigns (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, created_date TEXT NOT NULL, completed_date TEXT, template TEXT, status TEXT NOT NULL, uid INTEGER, FOREIGN KEY (uid) REFERENCES Users(id));`, + `CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL, hash VARCHAR(60) NOT NULL, apikey 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) //Create the tables needed @@ -49,6 +50,15 @@ func Setup() error { if err != nil { fmt.Println(err) } + c := models.Campaign{ + Name: "Test Campaigns", + CreatedDate: time.Now().UTC(), + CompletedDate: time.Now().UTC(), + Template: "test template", + Status: "In progress", + Uid: init_user.Id, + } + Conn.Insert(&c) } return nil } diff --git a/middleware/middleware.go b/middleware/middleware.go index 2105cf3e..3230de32 100644 --- a/middleware/middleware.go +++ b/middleware/middleware.go @@ -32,6 +32,19 @@ func GetContext(handler http.Handler) http.HandlerFunc { } } +func RequireAPIKey(handler http.Handler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + ak := r.Form.Get("api_key") + if ak == "" { + JSONError(w, 500, "API Key not set") + } else { + ctx.Set(r, "api_key", ak) + handler.ServeHTTP(w, r) + } + } +} + // RequireLogin is a simple middleware which checks to see if the user is currently logged in. // If not, the function returns a 302 redirect to the login page. func RequireLogin(handler http.Handler) http.HandlerFunc { @@ -43,3 +56,7 @@ func RequireLogin(handler http.Handler) http.HandlerFunc { } } } + +func JSONError(w http.ResponseWriter, c int, m string) { + http.Error(w, m, c) +} diff --git a/models/models.go b/models/models.go index b6761f47..ca6242ec 100644 --- a/models/models.go +++ b/models/models.go @@ -42,7 +42,7 @@ type Campaign struct { CompletedDate time.Time `json:"completed_date" db:"completed_date"` Template string `json:"template"` //This may change Status string `json:"status"` - Uid int + Uid int `json:"-"` } type UserCampaigns struct { diff --git a/templates/settings.html b/templates/settings.html index 17995579..6b84cea5 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -20,10 +20,28 @@
Username: {{.User.Username}}
-Api Key: {{.User.APIKey}}
+Username: +
+API Key: +
+