예제 #1
1
func TestHasRole(t *testing.T) {

	ctx, done, _ := aetest.NewContext()
	defer done()
	ctx = test.WithConfig(ctx, map[string]interface{}{"AuthSecret": "foo"})

	w := httptest.NewRecorder()
	r, _ := http.NewRequest("GET", "/", nil)
	r.Header.Set("Authorization", "wrong")

	// Make up a fake user
	acct, _ := account.New(ctx, "*****@*****.**", "foobar")
	acct.Roles = append(acct.Roles, "tyrant")
	account.Save(ctx, acct)

	// Unretrievable user, because middleware hasn't been run.
	if err := HasRole("foo")(ctx, w, r); err != ErrCannotGetAccount {
		t.Errorf("Unexpected error, wanted ErrCannotGetAccount, got %s", err)
	}

	// User's set, but claimset isn't for some reason.
	ctx2 := context.WithValue(ctx, internal.AuthContextKey, &account.Nobody)
	if err := HasRole("foo")(ctx2, w, r); err != ErrCannotGetClaimSet {
		t.Errorf("Unexpected error, wanted ErrCannotGetClaimSet, got %s", err)
	}

	// Account doesn't have the role.
	r.Header.Set("Authorization", test.JWT(&jws.ClaimSet{Sub: "*****@*****.**", Scope: AllScope}, "foo"))
	ctx2 = Middleware(ctx, w, r)
	if err := HasRole("foo")(ctx2, w, r); err != ErrRoleMissing {
		t.Errorf("Unexpected error, wanted ErrRoleMissing, got %s", err)
	}

	// Token doesn't have the role in scope.
	r.Header.Set("Authorization", test.JWT(&jws.ClaimSet{Sub: "*****@*****.**", Scope: "somethingelse"}, "foo"))
	ctx2 = Middleware(ctx, w, r)
	if err := HasRole("tyrant")(ctx2, w, r); err != ErrRoleNotInScope {
		t.Errorf("Unexpected error, wanted ErrRoleNotInScope, got %s", err)
	}

	// Token is consumable, but hasn't been used yet.
	consumableToken := test.ConsumableJWT(&jws.ClaimSet{Sub: "*****@*****.**", Scope: "tyrant"}, "foo", 1)
	r.Header.Set("Authorization", consumableToken)
	ctx2 = Middleware(ctx, w, r)
	if err := HasRole("tyrant")(ctx2, w, r); err != nil {
		t.Errorf("Unexpected error, wanted nil, got %s", err)
	}

	// We used this token once already. Should be used up.
	ctx2 = Middleware(ctx, w, r)
	if err := HasRole("tyrant")(ctx2, w, r); err != ErrClaimSetUsedUp {
		t.Errorf("Unexpected error, wanted ErrClaimSetUsedUp, got %s", err)
	}

}
예제 #2
1
func newAccount(ctx context.Context, w http.ResponseWriter, r *http.Request) {

	var acctReq accountCreationRequest
	if err := rest.ReadJSON(r, &acctReq); err != nil {
		rest.WriteJSON(w, err)
	} else if newAcct, err := account.New(ctx, acctReq.Email, acctReq.Password); err != nil {
		rest.WriteJSON(w, err)
	} else {
		newAccountURL, _ := r.URL.Parse(newAcct.Key(ctx).StringID())
		w.Header().Set("Location", newAccountURL.String())
		rest.WriteJSON(w, rest.CreatedResponse(newAcct))
	}

}
예제 #3
1
func TestMiddleware(t *testing.T) {

	var acct account.Account
	ctx := test.WithConfig(context.Background(), map[string]interface{}{"AuthSecret": "foo"})

	// a user is no one (i.e., no Authorization header)
	w := httptest.NewRecorder()
	r, _ := http.NewRequest("GET", "/", nil)

	resultCtx := Middleware(ctx, w, r)

	err := GetAccount(resultCtx, &acct)
	if err != nil {
		t.Errorf("Unexpected error %s", err)
	}
	if !acct.Nobody() {
		t.Errorf("acct should have been the zero value, but got %+v", acct)
	}

	// bad jwt
	w = httptest.NewRecorder()
	r, _ = http.NewRequest("GET", "/", nil)
	r.Header.Set("Authorization", "wrong")

	resultCtx = Middleware(ctx, w, r)

	err = GetAccount(resultCtx, &acct)
	if err != InvalidJWTError {
		t.Errorf("Unexpected error %s", err)
	}

	// super (i.e., they passed in the secret itself)
	w = httptest.NewRecorder()
	r, _ = http.NewRequest("GET", "/", nil)
	r.Header.Set("Authorization", "foo")

	resultCtx = Middleware(ctx, w, r)

	err = GetAccount(resultCtx, &acct)
	if err != nil {
		t.Errorf("Unexpected error %s", err)
	}
	if !acct.Super() {
		t.Errorf("Expected the super account, but got %+v", acct)
	}

	// super (i.e., they passed in the secret itself)
	w = httptest.NewRecorder()
	r, _ = http.NewRequest("GET", "/", nil)
	r.Header.Set("Authorization", "foo")

	resultCtx = Middleware(ctx, w, r)

	err = GetAccount(resultCtx, &acct)
	if err != nil {
		t.Errorf("Unexpected error %s", err)
	}
	if !acct.Super() {
		t.Errorf("Expected the super account, but got %+v", acct)
	}

	// test against App Engine dev environment from this point forward
	realCtx, done, _ := aetest.NewContext()
	defer done()

	account.New(realCtx, "*****@*****.**", "foobar")

	realCtx = test.WithConfig(realCtx, map[string]interface{}{"AuthSecret": "foo"})

	// nonexistent account
	w = httptest.NewRecorder()
	r, _ = http.NewRequest("GET", "/", nil)
	r.Header.Set("Authorization", test.JWT(&jws.ClaimSet{Sub: "*****@*****.**"}, "foo"))

	resultCtx = Middleware(realCtx, w, r)
	if resultCtx != nil {
		t.Errorf("Expected Middleware to terminate (i.e. to return nil), but it didn't", err)
	}

	// existent account (i.e., the happy path)
	w = httptest.NewRecorder()
	r, _ = http.NewRequest("GET", "/", nil)
	r.Header.Set("Authorization", test.JWT(&jws.ClaimSet{Sub: "*****@*****.**"}, "foo"))

	resultCtx = Middleware(realCtx, w, r)
	if resultCtx == nil {
		t.Errorf("Expected Middleware not to terminate (i.e. to return another context), but it terminated")
	} else if err = GetAccount(resultCtx, &acct); err != nil {
		t.Errorf("Expected no error when getting a properly authenticated account, but got %s", err)
	} else if acct.Email != "*****@*****.**" {
		t.Errorf("Unexpected account on retrieval: %+v", acct)
	}

}