Implemented Flashes (Model and functionality)

Working on login functionality
Changed the way templates are loaded and rendered
pull/24/head
Jordan 2014-01-09 21:21:54 -06:00
parent 7eb90b27ad
commit bb627396ee
8 changed files with 61 additions and 16 deletions

View File

@ -33,6 +33,9 @@ func CheckLogin(r *http.Request) (bool, error) {
u := models.User{} u := models.User{}
err = stmt.QueryRow(username).Scan(&u.Id, &u.Username, &u.Hash, &u.APIKey) err = stmt.QueryRow(username).Scan(&u.Id, &u.Username, &u.Hash, &u.APIKey)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
//Return false, but don't return an error
return false, nil
} else if err != nil {
return false, err return false, err
} }
//If we've made it here, we should have a valid user stored in u //If we've made it here, we should have a valid user stored in u

View File

@ -33,5 +33,5 @@ func API_Campaigns_Id(w http.ResponseWriter, r *http.Request) {
//API_Doc renders a template describing the API documentation. //API_Doc renders a template describing the API documentation.
func API_Doc(w http.ResponseWriter, r *http.Request) { func API_Doc(w http.ResponseWriter, r *http.Request) {
renderTemplate(w, "api_doc") getTemplate(w, "api_doc").ExecuteTemplate(w, "base", nil)
} }

View File

@ -30,8 +30,11 @@ import (
"html/template" "html/template"
"net/http" "net/http"
ctx "github.com/gorilla/context"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/gorilla/sessions"
"github.com/jordan-wright/gophish/auth" "github.com/jordan-wright/gophish/auth"
"github.com/jordan-wright/gophish/models"
) )
func CreateRouter() http.Handler { func CreateRouter() http.Handler {
@ -63,31 +66,35 @@ func Register(w http.ResponseWriter, r *http.Request) {
} }
func Base(w http.ResponseWriter, r *http.Request) { func Base(w http.ResponseWriter, r *http.Request) {
session, _ := auth.Store.Get(r, "gophish")
// Example of using session - will be removed. // Example of using session - will be removed.
session.Save(r, w) getTemplate(w, "dashboard").ExecuteTemplate(w, "base", nil)
renderTemplate(w, "dashboard")
} }
func Users(w http.ResponseWriter, r *http.Request) { func Users(w http.ResponseWriter, r *http.Request) {
renderTemplate(w, "users") getTemplate(w, "users").ExecuteTemplate(w, "base", nil)
} }
func Settings(w http.ResponseWriter, r *http.Request) { func Settings(w http.ResponseWriter, r *http.Request) {
renderTemplate(w, "settings") getTemplate(w, "settings").ExecuteTemplate(w, "base", nil)
} }
func Base_Campaigns(w http.ResponseWriter, r *http.Request) { func Base_Campaigns(w http.ResponseWriter, r *http.Request) {
//session, _ := auth.Store.Get(r, "gophish") //session, _ := auth.Store.Get(r, "gophish")
renderTemplate(w, "dashboard") getTemplate(w, "dashboard").ExecuteTemplate(w, "base", nil)
} }
func Login(w http.ResponseWriter, r *http.Request) { func Login(w http.ResponseWriter, r *http.Request) {
params := struct {
User models.User
Title string
Flashes []interface{}
}{}
session := ctx.Get(r, "session").(*sessions.Session)
params.Title = "Login"
switch { switch {
case r.Method == "GET": case r.Method == "GET":
renderTemplate(w, "login") getTemplate(w, "login").ExecuteTemplate(w, "base", params)
case r.Method == "POST": case r.Method == "POST":
session, _ := auth.Store.Get(r, "gophish")
//Attempt to login //Attempt to login
if err := r.ParseForm(); err != nil { if err := r.ParseForm(); err != nil {
http.Error(w, "Error parsing request", http.StatusInternalServerError) http.Error(w, "Error parsing request", http.StatusInternalServerError)
@ -101,13 +108,16 @@ func Login(w http.ResponseWriter, r *http.Request) {
session.Save(r, w) session.Save(r, w)
http.Redirect(w, r, "/", 302) http.Redirect(w, r, "/", 302)
} else { } else {
session.AddFlash("Invalid Username/Password") session.AddFlash(models.Flash{
renderTemplate(w, "login") Type: "danger",
Message: "Invalid Username/Password",
})
params.Flashes = session.Flashes()
getTemplate(w, "login").ExecuteTemplate(w, "base", params)
} }
} }
} }
func renderTemplate(w http.ResponseWriter, tmpl string) { func getTemplate(w http.ResponseWriter, tmpl string) *template.Template {
t := template.Must(template.New("template").ParseFiles("templates/base.html", "templates/nav.html", "templates/"+tmpl+".html")) return template.Must(template.New("template").ParseFiles("templates/base.html", "templates/nav.html", "templates/"+tmpl+".html", "templates/flashes.html"))
t.ExecuteTemplate(w, "base", "T")
} }

View File

@ -5,6 +5,7 @@ import (
"net/http" "net/http"
ctx "github.com/gorilla/context" ctx "github.com/gorilla/context"
"github.com/jordan-wright/gophish/auth"
) )
// Use allows us to stack middleware to process the request // Use allows us to stack middleware to process the request
@ -22,7 +23,13 @@ func GetContext(handler http.Handler) http.Handler {
// Set the context here // Set the context here
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Set the context appropriately here. // Set the context appropriately here.
// Set the session
session, _ := auth.Store.Get(r, "gophish")
ctx.Set(r, "session", session)
handler.ServeHTTP(w, r) handler.ServeHTTP(w, r)
// Save the session
session.Save()
// Remove context contents
ctx.Clear(r) ctx.Clear(r)
}) })
} }

View File

@ -1,20 +1,29 @@
package models package models
// SMTPServer is used to provide a default SMTP server preference.
type SMTPServer struct { type SMTPServer struct {
Host string `json:"host"` Host string `json:"host"`
User string `json:"user"` User string `json:"user"`
Password string `json:"password"` Password string `json:"password"`
} }
// Config represents the configuration information.
type Config struct { type Config struct {
URL string `json:"url"` URL string `json:"url"`
SMTP SMTPServer `json:"smtp"` SMTP SMTPServer `json:"smtp"`
DBPath string `json:"dbpath"` DBPath string `json:"dbpath"`
} }
// User represents the user model for gophish.
type User struct { type User struct {
Id int Id int
Username string Username string
Hash string Hash string
APIKey string APIKey string
} }
// Flash is used to hold flash information for use in templates.
type Flash struct {
Type string
Message string
}

View File

@ -10,7 +10,7 @@
<meta name="author" content=""> <meta name="author" content="">
<link rel="shortcut icon" href="../../docs-assets/ico/favicon.png"> <link rel="shortcut icon" href="../../docs-assets/ico/favicon.png">
<title>Gophish - Dashboard</title> <title>Gophish - {{.Title}}</title>
<!-- Bootstrap core CSS --> <!-- Bootstrap core CSS -->
<link href="/css/bootstrap.css" rel="stylesheet"> <link href="/css/bootstrap.css" rel="stylesheet">
@ -22,7 +22,7 @@
</head> </head>
<body> <body>
{{template "content"}} {{template "content" .}}
<!-- Footer --> <!-- Footer -->
<div class="container"> <div class="container">
<hr> <hr>

15
templates/flashes.html Normal file
View File

@ -0,0 +1,15 @@
{{define "flashes"}}
{{range .}}
<div style="text-align:center" class="alert alert-{{.Type}}">
<i class="fa
{{if eq .Type "danger"}}
fa-exclamation-circle
{{else if eq .Type "warning"}}
fa-exclamation-triangle
{{else if eq .Type "success"}}
fa-check-circle
{{end}}"></i>
{{.Message}}
</div>
{{end}}
{{end}}

View File

@ -3,6 +3,7 @@
<form class="form-signin" action="/login" method="POST"> <form class="form-signin" action="/login" method="POST">
<img id="logo" src="/images/logo.png" /> <img id="logo" src="/images/logo.png" />
<h2 class="form-signin-heading">Please sign in</h2> <h2 class="form-signin-heading">Please sign in</h2>
{{template "flashes" .Flashes}}
<input type="text" name="username" class="form-control" placeholder="Username" required autofocus> <input type="text" name="username" class="form-control" placeholder="Username" required autofocus>
<input type="password" name="password" class="form-control" placeholder="Password" required> <input type="password" name="password" class="form-control" placeholder="Password" required>
<label class="checkbox"> <label class="checkbox">