mirror of
https://github.com/gophish/gophish
synced 2024-11-15 00:37:14 +00:00
- 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.
This commit is contained in:
parent
e9aa8d2c88
commit
c60b9d584b
6 changed files with 84 additions and 19 deletions
|
@ -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!")
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
14
db/db.go
14
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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -20,10 +20,28 @@
|
|||
</ul>
|
||||
</div>
|
||||
<div class="col-md-9 sans">
|
||||
<h1 style="margin-top:0px">User Settings</h1>
|
||||
<p><b>Username:</b> {{.User.Username}}</p>
|
||||
<p><b>Api Key:</b> {{.User.APIKey}}</p>
|
||||
<h1 style="margin:0px 0px 15px 0px;">User Settings</h1>
|
||||
<div class="row">
|
||||
<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>
|
||||
{{end}}
|
||||
|
||||
|
|
Loading…
Reference in a new issue