mirror of https://github.com/gophish/gophish
- Working on implementing the API (started working on /api/campaigns)
- Implemented APIKey middleware - Changed settings template to look a bit nicer and to, you know, work.pull/24/head
parent
e9aa8d2c88
commit
c60b9d584b
|
@ -7,9 +7,18 @@ import (
|
||||||
|
|
||||||
ctx "github.com/gorilla/context"
|
ctx "github.com/gorilla/context"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/jordan-wright/gophish/db"
|
||||||
|
"github.com/jordan-wright/gophish/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func API(w http.ResponseWriter, r *http.Request) {
|
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 {
|
if u, err := json.Marshal(ctx.Get(r, "user")); err == nil {
|
||||||
writeJSON(w, u)
|
writeJSON(w, u)
|
||||||
} else {
|
} else {
|
||||||
|
@ -20,10 +29,18 @@ func API(w http.ResponseWriter, r *http.Request) {
|
||||||
//API_Campaigns returns a list of campaigns if requested via GET.
|
//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.
|
//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) {
|
func API_Campaigns(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
switch {
|
switch {
|
||||||
case r.Method == "GET":
|
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":
|
case r.Method == "POST":
|
||||||
fmt.Fprintf(w, "Hello POST!")
|
fmt.Fprintf(w, "Hello POST!")
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,9 +52,9 @@ func CreateRouter() *mux.Router {
|
||||||
|
|
||||||
// Create the API routes
|
// Create the API routes
|
||||||
api := router.PathPrefix("/api").Subrouter()
|
api := router.PathPrefix("/api").Subrouter()
|
||||||
api.HandleFunc("/", Use(API, mid.RequireLogin))
|
api.HandleFunc("/", Use(API, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/campaigns", API_Campaigns)
|
api.HandleFunc("/campaigns", Use(API_Campaigns, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/campaigns/{id}", API_Campaigns_Id)
|
api.HandleFunc("/campaigns/{id}", Use(API_Campaigns_Id, mid.RequireAPIKey))
|
||||||
api.HandleFunc("/doc", API_Doc)
|
api.HandleFunc("/doc", API_Doc)
|
||||||
|
|
||||||
//Setup static file serving
|
//Setup static file serving
|
||||||
|
@ -121,14 +121,10 @@ func Login(w http.ResponseWriter, r *http.Request) {
|
||||||
getTemplate(w, "login").ExecuteTemplate(w, "base", params)
|
getTemplate(w, "login").ExecuteTemplate(w, "base", params)
|
||||||
case r.Method == "POST":
|
case r.Method == "POST":
|
||||||
//Attempt to login
|
//Attempt to login
|
||||||
if err := r.ParseForm(); err != nil {
|
err := r.ParseForm()
|
||||||
http.Error(w, "Error parsing request", http.StatusInternalServerError)
|
checkError(err, w, "Error parsing request")
|
||||||
}
|
|
||||||
succ, err := auth.Login(r)
|
succ, err := auth.Login(r)
|
||||||
if err != nil {
|
checkError(err, w, "Error logging in")
|
||||||
fmt.Println(err)
|
|
||||||
http.Error(w, "Error logging in", http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
//If we've logged in, save the session and redirect to the dashboard
|
//If we've logged in, save the session and redirect to the dashboard
|
||||||
if succ {
|
if succ {
|
||||||
session.Save(r, w)
|
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 {
|
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"))
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
14
db/db.go
14
db/db.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/coopernurse/gorp"
|
"github.com/coopernurse/gorp"
|
||||||
"github.com/jordan-wright/gophish/config"
|
"github.com/jordan-wright/gophish/config"
|
||||||
|
@ -28,8 +29,8 @@ func Setup() error {
|
||||||
fmt.Println("Database not found, recreating...")
|
fmt.Println("Database not found, recreating...")
|
||||||
createTablesSQL := []string{
|
createTablesSQL := []string{
|
||||||
//Create tables
|
//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, 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 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)
|
fmt.Println("Creating db at " + config.Conf.DBPath)
|
||||||
//Create the tables needed
|
//Create the tables needed
|
||||||
|
@ -49,6 +50,15 @@ func Setup() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
// 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.
|
// If not, the function returns a 302 redirect to the login page.
|
||||||
func RequireLogin(handler http.Handler) http.HandlerFunc {
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ type Campaign struct {
|
||||||
CompletedDate time.Time `json:"completed_date" db:"completed_date"`
|
CompletedDate time.Time `json:"completed_date" db:"completed_date"`
|
||||||
Template string `json:"template"` //This may change
|
Template string `json:"template"` //This may change
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Uid int
|
Uid int `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserCampaigns struct {
|
type UserCampaigns struct {
|
||||||
|
|
|
@ -20,10 +20,28 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9 sans">
|
<div class="col-md-9 sans">
|
||||||
<h1 style="margin-top:0px">User Settings</h1>
|
<h1 style="margin:0px 0px 15px 0px;">User Settings</h1>
|
||||||
<p><b>Username:</b> {{.User.Username}}</p>
|
<div class="row">
|
||||||
<p><b>Api Key:</b> {{.User.APIKey}}</p>
|
<div class="col-md-2">
|
||||||
|
<p><b>Username:</b>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input type="text" value="{{.User.Username}}" class="form-control" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<p><b>API Key:</b>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input type="text" value="{{.User.APIKey}}" class="form-control" readonly/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<button class="btn btn-primary">Save</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue