2016-09-15 03:24:51 +00:00
|
|
|
package controllers
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
2017-12-11 00:11:32 +00:00
|
|
|
"strings"
|
2020-02-02 03:44:50 +00:00
|
|
|
"testing"
|
2017-12-11 00:11:32 +00:00
|
|
|
|
|
|
|
"github.com/PuerkitoBio/goquery"
|
2016-09-15 03:24:51 +00:00
|
|
|
)
|
|
|
|
|
2020-02-02 03:44:50 +00:00
|
|
|
func attemptLogin(t *testing.T, ctx *testContext, client *http.Client, username, password, optionalPath string) *http.Response {
|
|
|
|
resp, err := http.Get(fmt.Sprintf("%s/login", ctx.adminServer.URL))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error requesting the /login endpoint: %v", err)
|
|
|
|
}
|
|
|
|
got := resp.StatusCode
|
|
|
|
expected := http.StatusOK
|
|
|
|
if got != expected {
|
|
|
|
t.Fatalf("invalid status code received. expected %d got %d", expected, got)
|
|
|
|
}
|
2017-12-11 00:11:32 +00:00
|
|
|
|
|
|
|
doc, err := goquery.NewDocumentFromResponse(resp)
|
2020-02-02 03:44:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error parsing /login response body")
|
|
|
|
}
|
2017-12-11 00:11:32 +00:00
|
|
|
elem := doc.Find("input[name='csrf_token']").First()
|
|
|
|
token, ok := elem.Attr("value")
|
2020-02-02 03:44:50 +00:00
|
|
|
if !ok {
|
|
|
|
t.Fatal("unable to find csrf_token value in login response")
|
|
|
|
}
|
|
|
|
if client == nil {
|
|
|
|
client = &http.Client{}
|
|
|
|
}
|
2017-12-11 00:11:32 +00:00
|
|
|
|
2020-02-02 03:44:50 +00:00
|
|
|
req, err := http.NewRequest("POST", fmt.Sprintf("%s/login%s", ctx.adminServer.URL, optionalPath), strings.NewReader(url.Values{
|
|
|
|
"username": {username},
|
|
|
|
"password": {password},
|
2017-12-11 00:11:32 +00:00
|
|
|
"csrf_token": {token},
|
|
|
|
}.Encode()))
|
2020-02-02 03:44:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error creating new /login request: %v", err)
|
|
|
|
}
|
2017-12-11 00:11:32 +00:00
|
|
|
|
|
|
|
req.Header.Set("Cookie", resp.Header.Get("Set-Cookie"))
|
|
|
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
|
|
|
|
resp, err = client.Do(req)
|
2020-02-02 03:44:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error requesting the /login endpoint: %v", err)
|
|
|
|
}
|
|
|
|
return resp
|
2017-12-11 00:11:32 +00:00
|
|
|
}
|
|
|
|
|
2020-02-02 03:44:50 +00:00
|
|
|
func TestLoginCSRF(t *testing.T) {
|
|
|
|
ctx := setupTest(t)
|
|
|
|
defer tearDown(t, ctx)
|
|
|
|
resp, err := http.PostForm(fmt.Sprintf("%s/login", ctx.adminServer.URL),
|
|
|
|
url.Values{
|
|
|
|
"username": {"admin"},
|
|
|
|
"password": {"gophish"},
|
|
|
|
})
|
2017-12-11 00:11:32 +00:00
|
|
|
|
2020-02-02 03:44:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error requesting the /login endpoint: %v", err)
|
|
|
|
}
|
2017-12-11 00:11:32 +00:00
|
|
|
|
2020-02-02 03:44:50 +00:00
|
|
|
got := resp.StatusCode
|
|
|
|
expected := http.StatusForbidden
|
|
|
|
if got != expected {
|
|
|
|
t.Fatalf("invalid status code received. expected %d got %d", expected, got)
|
|
|
|
}
|
|
|
|
}
|
2017-12-11 00:11:32 +00:00
|
|
|
|
2020-02-02 03:44:50 +00:00
|
|
|
func TestInvalidCredentials(t *testing.T) {
|
|
|
|
ctx := setupTest(t)
|
|
|
|
defer tearDown(t, ctx)
|
|
|
|
resp := attemptLogin(t, ctx, nil, "admin", "bogus", "")
|
|
|
|
got := resp.StatusCode
|
|
|
|
expected := http.StatusUnauthorized
|
|
|
|
if got != expected {
|
|
|
|
t.Fatalf("invalid status code received. expected %d got %d", expected, got)
|
|
|
|
}
|
|
|
|
}
|
2017-12-11 00:11:32 +00:00
|
|
|
|
2020-02-02 03:44:50 +00:00
|
|
|
func TestSuccessfulLogin(t *testing.T) {
|
|
|
|
ctx := setupTest(t)
|
|
|
|
defer tearDown(t, ctx)
|
|
|
|
resp := attemptLogin(t, ctx, nil, "admin", "gophish", "")
|
|
|
|
got := resp.StatusCode
|
|
|
|
expected := http.StatusOK
|
|
|
|
if got != expected {
|
|
|
|
t.Fatalf("invalid status code received. expected %d got %d", expected, got)
|
|
|
|
}
|
2017-12-11 00:11:32 +00:00
|
|
|
}
|
2017-12-11 03:40:46 +00:00
|
|
|
|
2020-02-02 03:44:50 +00:00
|
|
|
func TestSuccessfulRedirect(t *testing.T) {
|
|
|
|
ctx := setupTest(t)
|
|
|
|
defer tearDown(t, ctx)
|
2017-12-11 03:40:46 +00:00
|
|
|
next := "/campaigns"
|
|
|
|
client := &http.Client{
|
|
|
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
|
|
|
return http.ErrUseLastResponse
|
2020-02-02 03:44:50 +00:00
|
|
|
}}
|
|
|
|
resp := attemptLogin(t, ctx, client, "admin", "gophish", fmt.Sprintf("?next=%s", next))
|
|
|
|
got := resp.StatusCode
|
|
|
|
expected := http.StatusFound
|
|
|
|
if got != expected {
|
|
|
|
t.Fatalf("invalid status code received. expected %d got %d", expected, got)
|
2017-12-11 03:40:46 +00:00
|
|
|
}
|
|
|
|
url, err := resp.Location()
|
2020-02-02 03:44:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error parsing response Location header: %v", err)
|
|
|
|
}
|
|
|
|
if url.Path != next {
|
|
|
|
t.Fatalf("unexpected Location header received. expected %s got %s", next, url.Path)
|
|
|
|
}
|
2017-12-11 03:40:46 +00:00
|
|
|
}
|