2014-01-09 06:42:05 +00:00
|
|
|
package controllers
|
2013-12-03 04:56:55 +00:00
|
|
|
|
|
|
|
import (
|
2016-07-25 00:37:14 +00:00
|
|
|
"bytes"
|
2016-02-01 01:50:41 +00:00
|
|
|
"encoding/json"
|
2015-02-09 00:37:07 +00:00
|
|
|
"fmt"
|
2014-01-06 06:09:41 +00:00
|
|
|
"html/template"
|
2014-06-02 04:38:21 +00:00
|
|
|
"log"
|
2016-01-04 06:04:10 +00:00
|
|
|
"net"
|
2014-01-06 06:09:41 +00:00
|
|
|
"net/http"
|
2016-02-01 01:50:41 +00:00
|
|
|
"net/url"
|
2014-06-02 04:38:21 +00:00
|
|
|
"os"
|
2016-03-11 00:54:30 +00:00
|
|
|
"strings"
|
2014-01-06 06:09:41 +00:00
|
|
|
|
2016-01-10 17:03:17 +00:00
|
|
|
"github.com/gophish/gophish/auth"
|
2016-08-06 23:58:34 +00:00
|
|
|
"github.com/gophish/gophish/config"
|
2016-01-10 17:03:17 +00:00
|
|
|
mid "github.com/gophish/gophish/middleware"
|
|
|
|
"github.com/gophish/gophish/models"
|
2016-01-25 02:03:53 +00:00
|
|
|
ctx "github.com/gorilla/context"
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"github.com/gorilla/sessions"
|
2014-02-03 23:21:56 +00:00
|
|
|
"github.com/justinas/nosurf"
|
2013-12-03 04:56:55 +00:00
|
|
|
)
|
|
|
|
|
2015-02-07 16:41:53 +00:00
|
|
|
// Logger is used to send logging messages to stdout.
|
2014-06-02 04:38:21 +00:00
|
|
|
var Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile)
|
2014-02-01 02:49:22 +00:00
|
|
|
|
2014-07-02 01:32:34 +00:00
|
|
|
// CreateAdminRouter creates the routes for handling requests to the web interface.
|
|
|
|
// This function returns an http.Handler to be used in http.ListenAndServe().
|
2014-06-29 21:44:16 +00:00
|
|
|
func CreateAdminRouter() http.Handler {
|
2013-12-03 04:56:55 +00:00
|
|
|
router := mux.NewRouter()
|
|
|
|
// Base Front-end routes
|
2015-02-07 16:41:53 +00:00
|
|
|
router.HandleFunc("/", Use(Base, mid.RequireLogin))
|
2013-12-03 04:56:55 +00:00
|
|
|
router.HandleFunc("/login", Login)
|
2014-02-02 22:55:26 +00:00
|
|
|
router.HandleFunc("/logout", Use(Logout, mid.RequireLogin))
|
2015-06-15 21:49:16 +00:00
|
|
|
router.HandleFunc("/campaigns", Use(Campaigns, mid.RequireLogin))
|
|
|
|
router.HandleFunc("/campaigns/{id:[0-9]+}", Use(CampaignID, mid.RequireLogin))
|
|
|
|
router.HandleFunc("/templates", Use(Templates, mid.RequireLogin))
|
|
|
|
router.HandleFunc("/users", Use(Users, mid.RequireLogin))
|
|
|
|
router.HandleFunc("/landing_pages", Use(LandingPages, mid.RequireLogin))
|
2016-02-20 23:15:34 +00:00
|
|
|
router.HandleFunc("/sending_profiles", Use(SendingProfiles, mid.RequireLogin))
|
2016-02-10 04:19:06 +00:00
|
|
|
router.HandleFunc("/register", Use(Register, mid.RequireLogin))
|
2014-01-11 04:37:42 +00:00
|
|
|
router.HandleFunc("/settings", Use(Settings, mid.RequireLogin))
|
2013-12-03 04:56:55 +00:00
|
|
|
// Create the API routes
|
|
|
|
api := router.PathPrefix("/api").Subrouter()
|
2014-03-18 18:58:08 +00:00
|
|
|
api = api.StrictSlash(true)
|
2014-02-01 03:49:35 +00:00
|
|
|
api.HandleFunc("/", Use(API, mid.RequireLogin))
|
2014-02-02 20:47:06 +00:00
|
|
|
api.HandleFunc("/reset", Use(API_Reset, mid.RequireLogin))
|
2014-02-08 01:40:16 +00:00
|
|
|
api.HandleFunc("/campaigns/", Use(API_Campaigns, mid.RequireAPIKey))
|
2014-02-02 22:37:36 +00:00
|
|
|
api.HandleFunc("/campaigns/{id:[0-9]+}", Use(API_Campaigns_Id, mid.RequireAPIKey))
|
2016-06-08 03:31:55 +00:00
|
|
|
api.HandleFunc("/campaigns/{id:[0-9]+}/results", Use(API_Campaigns_Id_Results, mid.RequireAPIKey))
|
2016-07-12 03:11:40 +00:00
|
|
|
api.HandleFunc("/campaigns/{id:[0-9]+}/complete", Use(API_Campaigns_Id_Complete, mid.RequireAPIKey))
|
2014-02-08 01:40:16 +00:00
|
|
|
api.HandleFunc("/groups/", Use(API_Groups, mid.RequireAPIKey))
|
2014-02-02 22:37:36 +00:00
|
|
|
api.HandleFunc("/groups/{id:[0-9]+}", Use(API_Groups_Id, mid.RequireAPIKey))
|
2014-03-17 03:18:48 +00:00
|
|
|
api.HandleFunc("/templates/", Use(API_Templates, mid.RequireAPIKey))
|
2014-03-17 03:02:06 +00:00
|
|
|
api.HandleFunc("/templates/{id:[0-9]+}", Use(API_Templates_Id, mid.RequireAPIKey))
|
2015-02-07 02:24:10 +00:00
|
|
|
api.HandleFunc("/pages/", Use(API_Pages, mid.RequireAPIKey))
|
|
|
|
api.HandleFunc("/pages/{id:[0-9]+}", Use(API_Pages_Id, mid.RequireAPIKey))
|
2016-02-20 23:15:34 +00:00
|
|
|
api.HandleFunc("/smtp/", Use(API_SMTP, mid.RequireAPIKey))
|
|
|
|
api.HandleFunc("/smtp/{id:[0-9]+}", Use(API_SMTP_Id, mid.RequireAPIKey))
|
2016-01-25 02:03:53 +00:00
|
|
|
api.HandleFunc("/util/send_test_email", Use(API_Send_Test_Email, mid.RequireAPIKey))
|
2014-06-22 02:06:16 +00:00
|
|
|
api.HandleFunc("/import/group", API_Import_Group)
|
2015-02-16 03:53:30 +00:00
|
|
|
api.HandleFunc("/import/email", API_Import_Email)
|
2015-06-12 23:22:17 +00:00
|
|
|
api.HandleFunc("/import/site", API_Import_Site)
|
2013-12-03 04:56:55 +00:00
|
|
|
|
2014-02-04 21:23:09 +00:00
|
|
|
// Setup static file serving
|
2013-12-03 04:56:55 +00:00
|
|
|
router.PathPrefix("/").Handler(http.FileServer(http.Dir("./static/")))
|
2014-02-03 23:21:56 +00:00
|
|
|
|
2014-02-04 21:23:09 +00:00
|
|
|
// Setup CSRF Protection
|
2014-02-03 23:21:56 +00:00
|
|
|
csrfHandler := nosurf.New(router)
|
2014-02-04 21:23:09 +00:00
|
|
|
// Exempt API routes and Static files
|
2015-10-03 20:55:06 +00:00
|
|
|
csrfHandler.ExemptGlob("/api/campaigns")
|
|
|
|
csrfHandler.ExemptGlob("/api/campaigns/*")
|
|
|
|
csrfHandler.ExemptGlob("/api/groups")
|
|
|
|
csrfHandler.ExemptGlob("/api/groups/*")
|
|
|
|
csrfHandler.ExemptGlob("/api/templates")
|
|
|
|
csrfHandler.ExemptGlob("/api/templates/*")
|
|
|
|
csrfHandler.ExemptGlob("/api/pages")
|
|
|
|
csrfHandler.ExemptGlob("/api/pages/*")
|
2016-02-20 23:15:34 +00:00
|
|
|
csrfHandler.ExemptGlob("/api/smtp")
|
|
|
|
csrfHandler.ExemptGlob("/api/smtp/*")
|
2015-10-03 20:55:06 +00:00
|
|
|
csrfHandler.ExemptGlob("/api/import/*")
|
2016-01-25 02:03:53 +00:00
|
|
|
csrfHandler.ExemptGlob("/api/util/*")
|
2014-02-03 23:21:56 +00:00
|
|
|
csrfHandler.ExemptGlob("/static/*")
|
2014-06-29 21:44:16 +00:00
|
|
|
return Use(csrfHandler.ServeHTTP, mid.GetContext)
|
|
|
|
}
|
|
|
|
|
2015-01-28 23:56:56 +00:00
|
|
|
// CreatePhishingRouter creates the router that handles phishing connections.
|
2014-06-29 21:44:16 +00:00
|
|
|
func CreatePhishingRouter() http.Handler {
|
|
|
|
router := mux.NewRouter()
|
2016-03-23 19:11:47 +00:00
|
|
|
router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static/endpoint/"))))
|
2015-06-13 04:12:43 +00:00
|
|
|
router.HandleFunc("/track", PhishTracker)
|
2014-06-29 21:44:16 +00:00
|
|
|
router.HandleFunc("/{path:.*}", PhishHandler)
|
|
|
|
return router
|
|
|
|
}
|
|
|
|
|
2015-06-13 04:12:43 +00:00
|
|
|
// PhishTracker tracks emails as they are opened, updating the status for the given Result
|
|
|
|
func PhishTracker(w http.ResponseWriter, r *http.Request) {
|
|
|
|
r.ParseForm()
|
|
|
|
id := r.Form.Get("rid")
|
|
|
|
if id == "" {
|
2016-03-11 00:54:30 +00:00
|
|
|
Logger.Println("Missing Result ID")
|
2015-06-13 04:12:43 +00:00
|
|
|
http.NotFound(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
rs, err := models.GetResult(id)
|
|
|
|
if err != nil {
|
2016-03-11 00:54:30 +00:00
|
|
|
Logger.Println("No Results found")
|
2015-06-13 04:12:43 +00:00
|
|
|
http.NotFound(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
c, err := models.GetCampaign(rs.CampaignId, rs.UserId)
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
}
|
2016-07-12 03:11:40 +00:00
|
|
|
// Don't process events for completed campaigns
|
|
|
|
if c.Status == models.CAMPAIGN_COMPLETE {
|
|
|
|
http.NotFound(w, r)
|
|
|
|
return
|
|
|
|
}
|
2015-06-13 04:12:43 +00:00
|
|
|
c.AddEvent(models.Event{Email: rs.Email, Message: models.EVENT_OPENED})
|
2016-02-09 01:50:21 +00:00
|
|
|
// Don't update the status if the user already clicked the link
|
|
|
|
// or submitted data to the campaign
|
|
|
|
if rs.Status == models.STATUS_SUCCESS {
|
2016-03-19 04:35:07 +00:00
|
|
|
http.ServeFile(w, r, "static/images/pixel.png")
|
2016-02-09 01:50:21 +00:00
|
|
|
return
|
|
|
|
}
|
2015-10-23 03:29:10 +00:00
|
|
|
err = rs.UpdateStatus(models.EVENT_OPENED)
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
}
|
2016-01-04 06:04:10 +00:00
|
|
|
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
2016-03-11 00:54:30 +00:00
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Respect X-Forwarded headers
|
|
|
|
if fips := r.Header.Get("X-Forwarded-For"); fips != "" {
|
|
|
|
ip = strings.Split(fips, ", ")[0]
|
|
|
|
}
|
|
|
|
// Handle post processing such as GeoIP
|
|
|
|
err = rs.UpdateGeo(ip)
|
|
|
|
if err != nil {
|
2016-01-04 06:04:10 +00:00
|
|
|
Logger.Println(err)
|
|
|
|
}
|
2016-03-19 04:35:07 +00:00
|
|
|
http.ServeFile(w, r, "static/images/pixel.png")
|
2015-06-13 04:12:43 +00:00
|
|
|
}
|
|
|
|
|
2014-07-02 01:32:34 +00:00
|
|
|
// PhishHandler handles incoming client connections and registers the associated actions performed
|
|
|
|
// (such as clicked link, etc.)
|
2014-06-29 21:44:16 +00:00
|
|
|
func PhishHandler(w http.ResponseWriter, r *http.Request) {
|
2016-02-01 01:50:41 +00:00
|
|
|
err := r.ParseForm()
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
http.NotFound(w, r)
|
|
|
|
return
|
|
|
|
}
|
2014-07-02 01:32:34 +00:00
|
|
|
id := r.Form.Get("rid")
|
2016-08-26 01:56:05 +00:00
|
|
|
ftype := r.Form.Get("type")
|
2014-07-02 01:32:34 +00:00
|
|
|
if id == "" {
|
|
|
|
http.NotFound(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
rs, err := models.GetResult(id)
|
|
|
|
if err != nil {
|
|
|
|
http.NotFound(w, r)
|
|
|
|
return
|
|
|
|
}
|
2014-07-07 02:34:02 +00:00
|
|
|
c, err := models.GetCampaign(rs.CampaignId, rs.UserId)
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
}
|
2016-07-12 03:11:40 +00:00
|
|
|
// Don't process events for completed campaigns
|
|
|
|
if c.Status == models.CAMPAIGN_COMPLETE {
|
|
|
|
http.NotFound(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
rs.UpdateStatus(models.STATUS_SUCCESS)
|
2015-10-23 03:29:10 +00:00
|
|
|
p, err := models.GetPage(c.PageId, c.UserId)
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
}
|
2016-08-08 23:28:19 +00:00
|
|
|
d := struct {
|
|
|
|
Payload url.Values `json:"payload"`
|
|
|
|
Browser map[string]string `json:"browser"`
|
|
|
|
}{
|
|
|
|
Payload: r.Form,
|
|
|
|
Browser: make(map[string]string),
|
|
|
|
}
|
|
|
|
ip, _, err := net.SplitHostPort(r.RemoteAddr)
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Respect X-Forwarded headers
|
|
|
|
if fips := r.Header.Get("X-Forwarded-For"); fips != "" {
|
|
|
|
ip = strings.Split(fips, ", ")[0]
|
|
|
|
}
|
|
|
|
// Handle post processing such as GeoIP
|
|
|
|
err = rs.UpdateGeo(ip)
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
}
|
|
|
|
d.Browser["address"] = ip
|
|
|
|
d.Browser["user-agent"] = r.Header.Get("User-Agent")
|
|
|
|
rj, err := json.Marshal(d)
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
http.NotFound(w, r)
|
|
|
|
return
|
|
|
|
}
|
2016-02-01 01:50:41 +00:00
|
|
|
switch {
|
|
|
|
case r.Method == "GET":
|
2016-08-26 01:56:05 +00:00
|
|
|
switch {
|
|
|
|
case ftype == "html":
|
|
|
|
err = c.AddEvent(models.Event{Email: rs.Email, Message: models.EVENT_HTML_OPENED})
|
|
|
|
case ftype == "doc":
|
|
|
|
err = c.AddEvent(models.Event{Email: rs.Email, Message: models.EVENT_DOC_OPENED})
|
|
|
|
case ftype == "":
|
|
|
|
err = c.AddEvent(models.Event{Email: rs.Email, Message: models.EVENT_CLICKED})
|
|
|
|
}
|
2016-02-01 01:50:41 +00:00
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
}
|
|
|
|
case r.Method == "POST":
|
|
|
|
// If data was POST'ed, let's record it
|
|
|
|
// Store the data in an event
|
|
|
|
c.AddEvent(models.Event{Email: rs.Email, Message: models.EVENT_DATA_SUBMIT, Details: string(rj)})
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
}
|
2016-03-19 01:19:13 +00:00
|
|
|
// Redirect to the desired page
|
|
|
|
if p.RedirectURL != "" {
|
|
|
|
http.Redirect(w, r, p.RedirectURL, 302)
|
|
|
|
return
|
|
|
|
}
|
2016-02-01 01:50:41 +00:00
|
|
|
}
|
2016-07-25 00:37:14 +00:00
|
|
|
var htmlBuff bytes.Buffer
|
|
|
|
tmpl, err := template.New("html_template").Parse(p.HTML)
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
http.NotFound(w, r)
|
|
|
|
}
|
|
|
|
err = tmpl.Execute(&htmlBuff, rs)
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
http.NotFound(w, r)
|
|
|
|
}
|
|
|
|
w.Write(htmlBuff.Bytes())
|
2013-12-03 04:56:55 +00:00
|
|
|
}
|
|
|
|
|
2014-01-11 04:11:44 +00:00
|
|
|
// Use allows us to stack middleware to process the request
|
|
|
|
// Example taken from https://github.com/gorilla/mux/pull/36#issuecomment-25849172
|
2014-01-11 04:37:42 +00:00
|
|
|
func Use(handler http.HandlerFunc, mid ...func(http.Handler) http.HandlerFunc) http.HandlerFunc {
|
2014-01-11 04:11:44 +00:00
|
|
|
for _, m := range mid {
|
|
|
|
handler = m(handler)
|
|
|
|
}
|
|
|
|
return handler
|
|
|
|
}
|
|
|
|
|
2015-01-28 23:56:56 +00:00
|
|
|
// Register creates a new user
|
2013-12-03 04:56:55 +00:00
|
|
|
func Register(w http.ResponseWriter, r *http.Request) {
|
|
|
|
// If it is a post request, attempt to register the account
|
|
|
|
// Now that we are all registered, we can log the user in
|
2014-02-05 00:39:01 +00:00
|
|
|
params := struct {
|
|
|
|
Title string
|
|
|
|
Flashes []interface{}
|
|
|
|
User models.User
|
|
|
|
Token string
|
|
|
|
}{Title: "Register", Token: nosurf.Token(r)}
|
|
|
|
session := ctx.Get(r, "session").(*sessions.Session)
|
|
|
|
switch {
|
|
|
|
case r.Method == "GET":
|
|
|
|
params.Flashes = session.Flashes()
|
|
|
|
session.Save(r, w)
|
2015-02-07 23:30:22 +00:00
|
|
|
templates := template.New("template")
|
|
|
|
_, err := templates.ParseFiles("templates/register.html", "templates/flashes.html")
|
|
|
|
if err != nil {
|
|
|
|
Logger.Println(err)
|
|
|
|
}
|
|
|
|
template.Must(templates, err).ExecuteTemplate(w, "base", params)
|
2014-02-05 00:39:01 +00:00
|
|
|
case r.Method == "POST":
|
|
|
|
//Attempt to register
|
|
|
|
succ, err := auth.Register(r)
|
|
|
|
//If we've registered, redirect to the login page
|
|
|
|
if succ {
|
|
|
|
session.AddFlash(models.Flash{
|
|
|
|
Type: "success",
|
|
|
|
Message: "Registration successful!.",
|
|
|
|
})
|
|
|
|
session.Save(r, w)
|
|
|
|
http.Redirect(w, r, "/login", 302)
|
2016-02-13 22:37:12 +00:00
|
|
|
return
|
2014-02-05 00:39:01 +00:00
|
|
|
}
|
2016-02-13 22:37:12 +00:00
|
|
|
// Check the error
|
|
|
|
m := err.Error()
|
|
|
|
Logger.Println(err)
|
|
|
|
session.AddFlash(models.Flash{
|
|
|
|
Type: "danger",
|
|
|
|
Message: m,
|
|
|
|
})
|
|
|
|
session.Save(r, w)
|
|
|
|
http.Redirect(w, r, "/register", 302)
|
|
|
|
return
|
2014-02-05 00:39:01 +00:00
|
|
|
}
|
2013-12-03 04:56:55 +00:00
|
|
|
}
|
|
|
|
|
2015-01-28 23:56:56 +00:00
|
|
|
// Base handles the default path and template execution
|
2013-12-03 04:56:55 +00:00
|
|
|
func Base(w http.ResponseWriter, r *http.Request) {
|
2014-01-10 04:21:12 +00:00
|
|
|
params := struct {
|
|
|
|
User models.User
|
|
|
|
Title string
|
|
|
|
Flashes []interface{}
|
2014-05-27 01:29:12 +00:00
|
|
|
Token string
|
|
|
|
}{Title: "Dashboard", User: ctx.Get(r, "user").(models.User), Token: nosurf.Token(r)}
|
2014-01-30 21:08:14 +00:00
|
|
|
getTemplate(w, "dashboard").ExecuteTemplate(w, "base", params)
|
2013-12-03 04:56:55 +00:00
|
|
|
}
|
|
|
|
|
2015-06-15 21:49:16 +00:00
|
|
|
// Campaigns handles the default path and template execution
|
|
|
|
func Campaigns(w http.ResponseWriter, r *http.Request) {
|
|
|
|
// Example of using session - will be removed.
|
|
|
|
params := struct {
|
|
|
|
User models.User
|
|
|
|
Title string
|
|
|
|
Flashes []interface{}
|
|
|
|
Token string
|
|
|
|
}{Title: "Campaigns", User: ctx.Get(r, "user").(models.User), Token: nosurf.Token(r)}
|
|
|
|
getTemplate(w, "campaigns").ExecuteTemplate(w, "base", params)
|
|
|
|
}
|
|
|
|
|
|
|
|
// CampaignID handles the default path and template execution
|
|
|
|
func CampaignID(w http.ResponseWriter, r *http.Request) {
|
|
|
|
// Example of using session - will be removed.
|
|
|
|
params := struct {
|
|
|
|
User models.User
|
|
|
|
Title string
|
|
|
|
Flashes []interface{}
|
|
|
|
Token string
|
2016-02-20 23:44:15 +00:00
|
|
|
}{Title: "Campaign Results", User: ctx.Get(r, "user").(models.User), Token: nosurf.Token(r)}
|
2015-06-15 21:49:16 +00:00
|
|
|
getTemplate(w, "campaign_results").ExecuteTemplate(w, "base", params)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Templates handles the default path and template execution
|
|
|
|
func Templates(w http.ResponseWriter, r *http.Request) {
|
|
|
|
// Example of using session - will be removed.
|
|
|
|
params := struct {
|
|
|
|
User models.User
|
|
|
|
Title string
|
|
|
|
Flashes []interface{}
|
|
|
|
Token string
|
2016-02-20 23:44:15 +00:00
|
|
|
}{Title: "Email Templates", User: ctx.Get(r, "user").(models.User), Token: nosurf.Token(r)}
|
2015-06-15 21:49:16 +00:00
|
|
|
getTemplate(w, "templates").ExecuteTemplate(w, "base", params)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Users handles the default path and template execution
|
|
|
|
func Users(w http.ResponseWriter, r *http.Request) {
|
|
|
|
// Example of using session - will be removed.
|
|
|
|
params := struct {
|
|
|
|
User models.User
|
|
|
|
Title string
|
|
|
|
Flashes []interface{}
|
|
|
|
Token string
|
2016-02-20 23:44:15 +00:00
|
|
|
}{Title: "Users & Groups", User: ctx.Get(r, "user").(models.User), Token: nosurf.Token(r)}
|
2015-06-15 21:49:16 +00:00
|
|
|
getTemplate(w, "users").ExecuteTemplate(w, "base", params)
|
|
|
|
}
|
|
|
|
|
|
|
|
// LandingPages handles the default path and template execution
|
|
|
|
func LandingPages(w http.ResponseWriter, r *http.Request) {
|
|
|
|
// Example of using session - will be removed.
|
|
|
|
params := struct {
|
|
|
|
User models.User
|
|
|
|
Title string
|
|
|
|
Flashes []interface{}
|
|
|
|
Token string
|
2016-02-20 23:44:15 +00:00
|
|
|
}{Title: "Landing Pages", User: ctx.Get(r, "user").(models.User), Token: nosurf.Token(r)}
|
2015-06-15 21:49:16 +00:00
|
|
|
getTemplate(w, "landing_pages").ExecuteTemplate(w, "base", params)
|
|
|
|
}
|
|
|
|
|
2016-02-20 23:15:34 +00:00
|
|
|
// SendingProfiles handles the default path and template execution
|
|
|
|
func SendingProfiles(w http.ResponseWriter, r *http.Request) {
|
2016-02-22 03:09:14 +00:00
|
|
|
// Example of using session - will be removed.
|
|
|
|
params := struct {
|
|
|
|
User models.User
|
|
|
|
Title string
|
|
|
|
Flashes []interface{}
|
|
|
|
Token string
|
|
|
|
}{Title: "Sending Profiles", User: ctx.Get(r, "user").(models.User), Token: nosurf.Token(r)}
|
|
|
|
getTemplate(w, "sending_profiles").ExecuteTemplate(w, "base", params)
|
2016-02-20 23:15:34 +00:00
|
|
|
}
|
|
|
|
|
2015-01-28 23:56:56 +00:00
|
|
|
// Settings handles the changing of settings
|
2013-12-12 07:00:22 +00:00
|
|
|
func Settings(w http.ResponseWriter, r *http.Request) {
|
2014-02-10 19:02:44 +00:00
|
|
|
switch {
|
2015-06-21 21:10:47 +00:00
|
|
|
case r.Method == "GET":
|
|
|
|
params := struct {
|
|
|
|
User models.User
|
|
|
|
Title string
|
|
|
|
Flashes []interface{}
|
|
|
|
Token string
|
2016-08-06 23:58:34 +00:00
|
|
|
Version string
|
|
|
|
}{Title: "Settings", Version: config.Version, User: ctx.Get(r, "user").(models.User), Token: nosurf.Token(r)}
|
2015-06-21 21:10:47 +00:00
|
|
|
getTemplate(w, "settings").ExecuteTemplate(w, "base", params)
|
2014-02-10 19:02:44 +00:00
|
|
|
case r.Method == "POST":
|
|
|
|
err := auth.ChangePassword(r)
|
2014-06-02 03:30:23 +00:00
|
|
|
msg := models.Response{Success: true, Message: "Settings Updated Successfully"}
|
2014-02-10 19:02:44 +00:00
|
|
|
if err == auth.ErrInvalidPassword {
|
2014-05-29 04:29:41 +00:00
|
|
|
msg.Message = "Invalid Password"
|
|
|
|
msg.Success = false
|
2015-08-15 21:03:39 +00:00
|
|
|
JSONResponse(w, msg, http.StatusBadRequest)
|
|
|
|
return
|
2016-02-13 22:37:12 +00:00
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
msg.Message = err.Error()
|
2014-05-29 04:29:41 +00:00
|
|
|
msg.Success = false
|
2015-08-15 21:03:39 +00:00
|
|
|
JSONResponse(w, msg, http.StatusBadRequest)
|
|
|
|
return
|
2014-05-29 04:29:41 +00:00
|
|
|
}
|
2014-06-03 01:56:30 +00:00
|
|
|
JSONResponse(w, msg, http.StatusOK)
|
2014-02-10 19:02:44 +00:00
|
|
|
}
|
2013-12-12 07:00:22 +00:00
|
|
|
}
|
|
|
|
|
2015-01-28 23:56:56 +00:00
|
|
|
// Login handles the authentication flow for a user. If credentials are valid,
|
|
|
|
// a session is created
|
2013-12-03 04:56:55 +00:00
|
|
|
func Login(w http.ResponseWriter, r *http.Request) {
|
2014-01-10 03:21:54 +00:00
|
|
|
params := struct {
|
|
|
|
User models.User
|
|
|
|
Title string
|
|
|
|
Flashes []interface{}
|
2014-02-03 23:21:56 +00:00
|
|
|
Token string
|
|
|
|
}{Title: "Login", Token: nosurf.Token(r)}
|
2014-01-10 03:21:54 +00:00
|
|
|
session := ctx.Get(r, "session").(*sessions.Session)
|
2014-01-06 06:09:41 +00:00
|
|
|
switch {
|
|
|
|
case r.Method == "GET":
|
2014-02-02 20:47:06 +00:00
|
|
|
params.Flashes = session.Flashes()
|
|
|
|
session.Save(r, w)
|
2014-05-27 01:29:12 +00:00
|
|
|
templates := template.New("template")
|
|
|
|
_, err := templates.ParseFiles("templates/login.html", "templates/flashes.html")
|
|
|
|
if err != nil {
|
2014-06-02 04:38:21 +00:00
|
|
|
Logger.Println(err)
|
2014-05-27 01:29:12 +00:00
|
|
|
}
|
|
|
|
template.Must(templates, err).ExecuteTemplate(w, "base", params)
|
2014-01-06 06:09:41 +00:00
|
|
|
case r.Method == "POST":
|
|
|
|
//Attempt to login
|
2014-01-11 06:10:52 +00:00
|
|
|
succ, err := auth.Login(r)
|
2014-02-06 16:49:53 +00:00
|
|
|
if err != nil {
|
2014-06-02 04:38:21 +00:00
|
|
|
Logger.Println(err)
|
2014-01-31 22:25:02 +00:00
|
|
|
}
|
2014-01-07 06:58:48 +00:00
|
|
|
//If we've logged in, save the session and redirect to the dashboard
|
|
|
|
if succ {
|
2014-01-06 06:09:41 +00:00
|
|
|
session.Save(r, w)
|
|
|
|
http.Redirect(w, r, "/", 302)
|
2014-01-07 06:58:48 +00:00
|
|
|
} else {
|
2014-02-05 16:57:53 +00:00
|
|
|
Flash(w, r, "danger", "Invalid Username/Password")
|
2014-02-02 20:47:06 +00:00
|
|
|
http.Redirect(w, r, "/login", 302)
|
2014-01-06 06:09:41 +00:00
|
|
|
}
|
|
|
|
}
|
2013-12-03 04:56:55 +00:00
|
|
|
}
|
|
|
|
|
2015-02-07 16:41:53 +00:00
|
|
|
// Logout destroys the current user session
|
|
|
|
func Logout(w http.ResponseWriter, r *http.Request) {
|
|
|
|
// If it is a post request, attempt to register the account
|
|
|
|
// Now that we are all registered, we can log the user in
|
|
|
|
session := ctx.Get(r, "session").(*sessions.Session)
|
|
|
|
delete(session.Values, "id")
|
|
|
|
Flash(w, r, "success", "You have successfully logged out")
|
|
|
|
http.Redirect(w, r, "/login", 302)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Preview allows for the viewing of page html in a separate browser window
|
|
|
|
func Preview(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if r.Method != "POST" {
|
|
|
|
http.Error(w, "Method not allowed", http.StatusBadRequest)
|
2016-03-11 00:54:30 +00:00
|
|
|
return
|
2015-02-07 16:41:53 +00:00
|
|
|
}
|
2015-02-09 00:37:07 +00:00
|
|
|
fmt.Fprintf(w, "%s", r.FormValue("html"))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clone takes a URL as a POST parameter and returns the site HTML
|
|
|
|
func Clone(w http.ResponseWriter, r *http.Request) {
|
|
|
|
vars := mux.Vars(r)
|
|
|
|
if r.Method != "POST" {
|
|
|
|
http.Error(w, "Method not allowed", http.StatusBadRequest)
|
2016-03-11 00:54:30 +00:00
|
|
|
return
|
2015-02-09 00:37:07 +00:00
|
|
|
}
|
|
|
|
if url, ok := vars["url"]; ok {
|
|
|
|
Logger.Println(url)
|
|
|
|
}
|
|
|
|
http.Error(w, "No URL given.", http.StatusBadRequest)
|
2015-02-07 16:41:53 +00:00
|
|
|
}
|
|
|
|
|
2014-01-10 03:21:54 +00:00
|
|
|
func getTemplate(w http.ResponseWriter, tmpl string) *template.Template {
|
2014-02-01 02:49:22 +00:00
|
|
|
templates := template.New("template")
|
2014-05-27 01:29:12 +00:00
|
|
|
_, err := templates.ParseFiles("templates/base.html", "templates/"+tmpl+".html", "templates/flashes.html")
|
2014-02-01 02:49:22 +00:00
|
|
|
if err != nil {
|
2014-06-02 04:38:21 +00:00
|
|
|
Logger.Println(err)
|
2014-02-01 02:49:22 +00:00
|
|
|
}
|
|
|
|
return template.Must(templates, err)
|
2013-12-03 04:56:55 +00:00
|
|
|
}
|
2014-01-31 04:46:25 +00:00
|
|
|
|
2015-02-07 16:41:53 +00:00
|
|
|
// Flash handles the rendering flash messages
|
2014-02-05 16:57:53 +00:00
|
|
|
func Flash(w http.ResponseWriter, r *http.Request, t string, m string) {
|
|
|
|
session := ctx.Get(r, "session").(*sessions.Session)
|
|
|
|
session.AddFlash(models.Flash{
|
|
|
|
Type: t,
|
|
|
|
Message: m,
|
|
|
|
})
|
|
|
|
session.Save(r, w)
|
|
|
|
}
|