github.com/bluestoneag/bluephish@v0.1.0/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 }