auth

Paddy 2014-10-15 Parent:3a6a65ed380c Child:aff6863e3cb3

51:116342ffc65f Go to Latest

auth/grant_test.go

Create a grant confirmation endpoint and its first test. Lay the framework for how we're going to write endpoints, and how we're going to test them by doing a super simple grant confirmation endpoint (where the user authorizes the grant, which can then be exchanged for a token) and a simple test to ensure that a page gets rendered when valid input is provided. We're still missing a lot of test cases: when different forms of valid input are provided (e.g., no scope, no redirect URI, etc.); when invalid input is provided; etc.

History
paddy@29 1 package auth
paddy@29 2
paddy@29 3 import (
paddy@51 4 "html/template"
paddy@51 5 "net/http"
paddy@51 6 "net/http/httptest"
paddy@29 7 "testing"
paddy@29 8 "time"
paddy@29 9
paddy@45 10 "code.secondbit.org/uuid"
paddy@29 11 )
paddy@29 12
paddy@29 13 var grantStores = []GrantStore{NewMemstore()}
paddy@29 14
paddy@34 15 func compareGrants(grant1, grant2 Grant) (success bool, field string, grant1val, grant2val interface{}) {
paddy@34 16 if grant1.Code != grant2.Code {
paddy@34 17 return false, "code", grant1.Code, grant2.Code
paddy@34 18 }
paddy@34 19 if !grant1.Created.Equal(grant2.Created) {
paddy@34 20 return false, "created", grant1.Created, grant2.Created
paddy@34 21 }
paddy@34 22 if grant1.ExpiresIn != grant2.ExpiresIn {
paddy@34 23 return false, "expires in", grant1.ExpiresIn, grant2.ExpiresIn
paddy@34 24 }
paddy@34 25 if !grant1.ClientID.Equal(grant2.ClientID) {
paddy@34 26 return false, "client ID", grant1.ClientID, grant2.ClientID
paddy@34 27 }
paddy@34 28 if grant1.Scope != grant2.Scope {
paddy@34 29 return false, "scope", grant1.Scope, grant2.Scope
paddy@34 30 }
paddy@34 31 if grant1.RedirectURI != grant2.RedirectURI {
paddy@34 32 return false, "redirect URI", grant1.RedirectURI, grant2.RedirectURI
paddy@34 33 }
paddy@34 34 if grant1.State != grant2.State {
paddy@34 35 return false, "state", grant1.State, grant2.State
paddy@34 36 }
paddy@34 37 return true, "", nil, nil
paddy@34 38 }
paddy@34 39
paddy@29 40 func TestGrantStoreSuccess(t *testing.T) {
paddy@36 41 t.Parallel()
paddy@29 42 grant := Grant{
paddy@29 43 Code: "code",
paddy@29 44 Created: time.Now(),
paddy@29 45 ExpiresIn: 180,
paddy@29 46 ClientID: uuid.NewID(),
paddy@29 47 Scope: "scope",
paddy@29 48 RedirectURI: "redirectURI",
paddy@29 49 State: "state",
paddy@29 50 }
paddy@34 51 for _, store := range grantStores {
paddy@29 52 err := store.SaveGrant(grant)
paddy@29 53 if err != nil {
paddy@34 54 t.Errorf("Error saving grant to %T: %s", store, err)
paddy@34 55 }
paddy@34 56 err = store.SaveGrant(grant)
paddy@34 57 if err != ErrGrantAlreadyExists {
paddy@34 58 t.Errorf("Expected ErrGrantAlreadyExists from %T, got %+v", store, err)
paddy@29 59 }
paddy@29 60 retrieved, err := store.GetGrant(grant.Code)
paddy@29 61 if err != nil {
paddy@34 62 t.Errorf("Error retrieving grant from %T: %s", store, err)
paddy@29 63 }
paddy@34 64 match, field, expectation, result := compareGrants(grant, retrieved)
paddy@34 65 if !match {
paddy@34 66 t.Errorf("Expected `%v` in the `%s` field of grant retrieved from %T, got `%v`", expectation, field, store, result)
paddy@34 67 }
paddy@29 68 err = store.DeleteGrant(grant.Code)
paddy@29 69 if err != nil {
paddy@34 70 t.Errorf("Error removing grant from %T: %s", store, err)
paddy@29 71 }
paddy@29 72 retrieved, err = store.GetGrant(grant.Code)
paddy@29 73 if err != ErrGrantNotFound {
paddy@34 74 t.Errorf("Expected ErrGrantNotFound from %T, got %+v and %+v", store, retrieved, err)
paddy@34 75 }
paddy@34 76 err = store.DeleteGrant(grant.Code)
paddy@34 77 if err != ErrGrantNotFound {
paddy@34 78 t.Errorf("Expected ErrGrantNotFound from %T, got %+v", store, err)
paddy@29 79 }
paddy@29 80 }
paddy@29 81 }
paddy@51 82
paddy@51 83 func TestGrantCodeRedirect(t *testing.T) {
paddy@51 84 t.Parallel()
paddy@51 85 store := NewMemstore()
paddy@51 86 testContext := Context{
paddy@51 87 template: template.Must(template.New(getGrantTemplateName).Parse("Get auth grant")),
paddy@51 88 clients: store,
paddy@51 89 grants: store,
paddy@51 90 profiles: store,
paddy@51 91 tokens: store,
paddy@51 92 }
paddy@51 93 w := httptest.NewRecorder()
paddy@51 94 req, err := http.NewRequest("GET", "https://test.auth.secondbit.org/oauth2/grant", nil)
paddy@51 95 if err != nil {
paddy@51 96 t.Fatal("Can't build request:", err)
paddy@51 97 }
paddy@51 98 // see OAuth 2.0 spec, section 4.1.1
paddy@51 99 req.URL.Query().Set("response_type", "code")
paddy@51 100 req.URL.Query().Set("client_id", "test_client_id")
paddy@51 101 req.URL.Query().Set("redirect_uri", "https://test.secondbit.org/redirect")
paddy@51 102 req.URL.Query().Set("scope", "testscope")
paddy@51 103 req.URL.Query().Set("state", "my super secure state string")
paddy@51 104 GetGrantHandler(w, req, testContext)
paddy@51 105 if w.Code != http.StatusOK {
paddy@51 106 t.Errorf("Expected status code to be %d, got %d", http.StatusOK, w.Code)
paddy@51 107 }
paddy@51 108 if w.Body.String() != "Get auth grant" {
paddy@51 109 t.Errorf("Expected body to be `%s`, got `%s`", "Get auth grant", w.Body.String())
paddy@51 110 }
paddy@51 111 }