github.com/gophish/gophish@v0.12.2-0.20230915144530-8e7929441393/controllers/route_test.go (about)

     1  package controllers
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"net/url"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/PuerkitoBio/goquery"
    11  )
    12  
    13  func attemptLogin(t *testing.T, ctx *testContext, client *http.Client, username, password, optionalPath string) *http.Response {
    14  	resp, err := http.Get(fmt.Sprintf("%s/login", ctx.adminServer.URL))
    15  	if err != nil {
    16  		t.Fatalf("error requesting the /login endpoint: %v", err)
    17  	}
    18  	got := resp.StatusCode
    19  	expected := http.StatusOK
    20  	if got != expected {
    21  		t.Fatalf("invalid status code received. expected %d got %d", expected, got)
    22  	}
    23  
    24  	doc, err := goquery.NewDocumentFromResponse(resp)
    25  	if err != nil {
    26  		t.Fatalf("error parsing /login response body")
    27  	}
    28  	elem := doc.Find("input[name='csrf_token']").First()
    29  	token, ok := elem.Attr("value")
    30  	if !ok {
    31  		t.Fatal("unable to find csrf_token value in login response")
    32  	}
    33  	if client == nil {
    34  		client = &http.Client{}
    35  	}
    36  
    37  	req, err := http.NewRequest("POST", fmt.Sprintf("%s/login%s", ctx.adminServer.URL, optionalPath), strings.NewReader(url.Values{
    38  		"username":   {username},
    39  		"password":   {password},
    40  		"csrf_token": {token},
    41  	}.Encode()))
    42  	if err != nil {
    43  		t.Fatalf("error creating new /login request: %v", err)
    44  	}
    45  
    46  	req.Header.Set("Cookie", resp.Header.Get("Set-Cookie"))
    47  	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
    48  
    49  	resp, err = client.Do(req)
    50  	if err != nil {
    51  		t.Fatalf("error requesting the /login endpoint: %v", err)
    52  	}
    53  	return resp
    54  }
    55  
    56  func TestLoginCSRF(t *testing.T) {
    57  	ctx := setupTest(t)
    58  	defer tearDown(t, ctx)
    59  	resp, err := http.PostForm(fmt.Sprintf("%s/login", ctx.adminServer.URL),
    60  		url.Values{
    61  			"username": {"admin"},
    62  			"password": {"gophish"},
    63  		})
    64  
    65  	if err != nil {
    66  		t.Fatalf("error requesting the /login endpoint: %v", err)
    67  	}
    68  
    69  	got := resp.StatusCode
    70  	expected := http.StatusForbidden
    71  	if got != expected {
    72  		t.Fatalf("invalid status code received. expected %d got %d", expected, got)
    73  	}
    74  }
    75  
    76  func TestInvalidCredentials(t *testing.T) {
    77  	ctx := setupTest(t)
    78  	defer tearDown(t, ctx)
    79  	resp := attemptLogin(t, ctx, nil, "admin", "bogus", "")
    80  	got := resp.StatusCode
    81  	expected := http.StatusUnauthorized
    82  	if got != expected {
    83  		t.Fatalf("invalid status code received. expected %d got %d", expected, got)
    84  	}
    85  }
    86  
    87  func TestSuccessfulLogin(t *testing.T) {
    88  	ctx := setupTest(t)
    89  	defer tearDown(t, ctx)
    90  	resp := attemptLogin(t, ctx, nil, "admin", "gophish", "")
    91  	got := resp.StatusCode
    92  	expected := http.StatusOK
    93  	if got != expected {
    94  		t.Fatalf("invalid status code received. expected %d got %d", expected, got)
    95  	}
    96  }
    97  
    98  func TestSuccessfulRedirect(t *testing.T) {
    99  	ctx := setupTest(t)
   100  	defer tearDown(t, ctx)
   101  	next := "/campaigns"
   102  	client := &http.Client{
   103  		CheckRedirect: func(req *http.Request, via []*http.Request) error {
   104  			return http.ErrUseLastResponse
   105  		}}
   106  	resp := attemptLogin(t, ctx, client, "admin", "gophish", fmt.Sprintf("?next=%s", next))
   107  	got := resp.StatusCode
   108  	expected := http.StatusFound
   109  	if got != expected {
   110  		t.Fatalf("invalid status code received. expected %d got %d", expected, got)
   111  	}
   112  	url, err := resp.Location()
   113  	if err != nil {
   114  		t.Fatalf("error parsing response Location header: %v", err)
   115  	}
   116  	if url.Path != next {
   117  		t.Fatalf("unexpected Location header received. expected %s got %s", next, url.Path)
   118  	}
   119  }
   120  
   121  func TestAccountLocked(t *testing.T) {
   122  	ctx := setupTest(t)
   123  	defer tearDown(t, ctx)
   124  	resp := attemptLogin(t, ctx, nil, "houdini", "gophish", "")
   125  	got := resp.StatusCode
   126  	expected := http.StatusUnauthorized
   127  	if got != expected {
   128  		t.Fatalf("invalid status code received. expected %d got %d", expected, got)
   129  	}
   130  }