Пример #1
0
// NewListResponse creates new ListResponse instance
func NewListResponse(count, page int, self, first, last, previous, next, embedName string, items interface{}) *ListResponse {
	response := &ListResponse{
		Count: uint(count),
		Page:  uint(page),
	}

	response.SetLink("self", self, "")
	response.SetLink("first", first, "")
	response.SetLink("last", last, "")
	response.SetLink("prev", previous, "")
	response.SetLink("next", next, "")

	response.SetEmbedded(embedName, jsonhal.Embedded(items))

	return response
}
Пример #2
0
func TestGetEmbedded(t *testing.T) {
	helloWorld := new(HelloWorld)

	var (
		embedded jsonhal.Embedded
		err      error
		foobars  []*Foobar
	)

	// Test when object has no embedded resources
	embedded, err = helloWorld.GetEmbedded("foobars")
	assert.Nil(t, embedded)
	if assert.NotNil(t, err) {
		assert.Equal(t, "Embedded \"foobars\" not found", err.Error())
	}

	// Add embedded foobars
	foobars = []*Foobar{
		&Foobar{ID: 1, Name: "Foo bar 1"},
		&Foobar{ID: 2, Name: "Foo bar 2"},
	}
	helloWorld.SetEmbedded("foobars", jsonhal.Embedded(foobars))

	// Test geting bogus embedded resources
	embedded, err = helloWorld.GetEmbedded("bogus")
	assert.Nil(t, embedded)
	if assert.NotNil(t, err) {
		assert.Equal(t, "Embedded \"bogus\" not found", err.Error())
	}

	// Test geting valid embedded resources
	embedded, err = helloWorld.GetEmbedded("foobars")
	assert.Nil(t, err)
	if assert.NotNil(t, embedded) {
		reflectedValue := reflect.ValueOf(embedded)
		expectedType := reflect.SliceOf(reflect.TypeOf(new(Foobar)))
		if assert.Equal(t, expectedType, reflectedValue.Type()) {
			assert.Equal(t, 2, reflectedValue.Len())
		}
	}
}
Пример #3
0
// TestListValidResponseWithParams tests a list endpoint for a valid response with default settings
func TestListValidResponseWithParams(t *testing.T, router *mux.Router, entity string, items []interface{}, assertExpectations func(), params map[string]string) {
	u, err := url.Parse(fmt.Sprintf("http://1.2.3.4/v1/%s", entity))

	// add any params
	for k, v := range params {
		q := u.Query()
		q.Set(k, v)
		u.RawQuery = q.Encode()
	}

	// Prepare a request
	r, err := http.NewRequest(
		"GET",
		u.String(),
		nil,
	)
	assert.NoError(t, err)

	// Mock authentication
	r.Header.Set("Authorization", "Bearer test_token")

	// And serve the request
	w := httptest.NewRecorder()
	router.ServeHTTP(w, r)

	// Check that the mock object expectations were met
	assertExpectations()
	assert.Equal(t, http.StatusOK, w.Code)

	baseURI := u.RequestURI()

	q := u.Query()
	q.Set("page", "1")
	u.RawQuery = q.Encode()

	pagedURI := u.RequestURI()

	expected := &ListResponse{
		Hal: jsonhal.Hal{
			Links: map[string]*jsonhal.Link{
				"self": &jsonhal.Link{
					Href: baseURI,
				},
				"first": &jsonhal.Link{
					Href: pagedURI,
				},
				"last": &jsonhal.Link{
					Href: pagedURI,
				},
				"prev": new(jsonhal.Link),
				"next": new(jsonhal.Link),
			},
			Embedded: map[string]jsonhal.Embedded{
				entity: jsonhal.Embedded(items),
			},
		},
		Count: uint(len(items)),
		Page:  1,
	}
	expectedJSON, err := json.Marshal(expected)

	if assert.NoError(t, err, "JSON marshalling failed") {
		TestResponseBody(t, w, string(expectedJSON))
	}
}
Пример #4
0
func (suite *AccountsTestSuite) TestConfirmEmailWithAutologinFlag() {
	var (
		testOauthUser    *oauth.User
		testUser         *accounts.User
		testConfirmation *accounts.Confirmation
		err              error
	)

	// Insert a test user
	testOauthUser, err = suite.service.GetOauthService().CreateUser(
		roles.User,
		"harold@finch",
		"test_password",
	)
	assert.NoError(suite.T(), err, "Failed to insert a test oauth user")
	testUser, err = accounts.NewUser(
		suite.accounts[0],
		testOauthUser,
		"",    //facebook ID
		false, // confirmed
		&accounts.UserRequest{
			FirstName: "Harold",
			LastName:  "Finch",
		},
	)
	assert.NoError(suite.T(), err, "Failed to create a new user object")
	err = suite.db.Create(testUser).Error
	assert.NoError(suite.T(), err, "Failed to insert a test user")
	testUser.Account = suite.accounts[0]

	// Insert a test confirmation
	testConfirmation, err = accounts.NewConfirmation(
		testUser,
		suite.cnf.AppSpecific.ConfirmationLifetime,
	)
	assert.NoError(suite.T(), err, "Failed to create a new confirmation object")
	err = suite.db.Create(testConfirmation).Error
	assert.NoError(suite.T(), err, "Failed to insert a test confirmation")
	testConfirmation.User = testUser

	// Prepare a request
	r, err := http.NewRequest(
		"GET",
		fmt.Sprintf(
			"http://1.2.3.4/v1/confirmations/%s?autologin=true",
			testConfirmation.Reference,
		),
		nil,
	)
	assert.NoError(suite.T(), err, "Request setup should not get an error")
	r.Header.Set(
		"Authorization",
		fmt.Sprintf(
			"Basic %s",
			b64.StdEncoding.EncodeToString([]byte("test_client_1:test_secret")),
		),
	)

	// Check the routing
	match := new(mux.RouteMatch)
	suite.router.Match(r, match)
	if assert.NotNil(suite.T(), match.Route) {
		assert.Equal(suite.T(), "confirm_email", match.Route.GetName())
	}

	// Count before
	var (
		countBefore              int
		accessTokensCountBefore  int
		refreshTokensCountBefore int
	)
	suite.db.Model(new(accounts.Confirmation)).Count(&countBefore)
	suite.db.Model(new(oauth.AccessToken)).Count(&accessTokensCountBefore)
	suite.db.Model(new(oauth.RefreshToken)).Count(&refreshTokensCountBefore)

	// And serve the request
	w := httptest.NewRecorder()
	suite.router.ServeHTTP(w, r)

	// Count after
	var (
		countAfter              int
		accessTokensCountAfter  int
		refreshTokensCountAfter int
	)
	suite.db.Model(new(accounts.Confirmation)).Count(&countAfter)
	suite.db.Model(new(oauth.AccessToken)).Count(&accessTokensCountAfter)
	suite.db.Model(new(oauth.RefreshToken)).Count(&refreshTokensCountAfter)
	assert.Equal(suite.T(), countBefore-1, countAfter)
	assert.Equal(suite.T(), accessTokensCountBefore+1, accessTokensCountAfter)
	assert.Equal(suite.T(), refreshTokensCountBefore+1, refreshTokensCountAfter)

	// Fetch the updated user
	user := new(accounts.User)
	notFound := accounts.UserPreload(suite.db).First(user, testUser.ID).RecordNotFound()
	assert.False(suite.T(), notFound)

	// Confirmation should have been soft deleteted
	assert.True(suite.T(), suite.db.Last(new(accounts.Confirmation)).RecordNotFound())

	// And correct data was saved
	assert.True(suite.T(), user.Confirmed)

	// Fetch login data
	accessToken, refreshToken := new(oauth.AccessToken), new(oauth.RefreshToken)
	assert.False(suite.T(), oauth.AccessTokenPreload(suite.db).
		Last(accessToken).RecordNotFound())
	assert.False(suite.T(), oauth.RefreshTokenPreload(suite.db).
		Last(refreshToken).RecordNotFound())

	// Check the response
	expectedEmbeddedTokenResponse, err := oauth.NewAccessTokenResponse(
		accessToken,
		refreshToken,
		suite.cnf.Oauth.AccessTokenLifetime,
		tokentypes.Bearer,
	)
	assert.NoError(suite.T(), err, "Failed to create expected response object")
	expected, err := accounts.NewConfirmationResponse(testConfirmation)
	expected.SetEmbedded(
		"access-token",
		jsonhal.Embedded(expectedEmbeddedTokenResponse),
	)
	assert.NoError(suite.T(), err, "Failed to create expected response object")
	testutil.TestResponseObject(suite.T(), w, expected, 200)
}
Пример #5
0
func TestHal(t *testing.T) {
	var (
		helloWorld *HelloWorld
		expected   *bytes.Buffer
		actual     []byte
		err        error
		foobar     *Foobar
		foobars    []*Foobar
		quxes      []*Qux
	)

	// Let's test the simplest scenario without links
	helloWorld = &HelloWorld{ID: 1, Name: "Hello World"}

	expected = bytes.NewBuffer([]byte{})
	err = json.Compact(expected, expectedJSON)
	if err != nil {
		log.Fatal(err)
	}
	actual, err = json.Marshal(helloWorld)
	if err != nil {
		log.Fatal(err)
	}
	assert.Equal(t, expected.String(), string(actual))

	// Let's add a self link
	helloWorld.SetLink(
		"self",              // name
		"/v1/hello/world/1", // href
		"",                  // title
	)

	expected = bytes.NewBuffer([]byte{})
	err = json.Compact(expected, expectedJSON2)
	if err != nil {
		log.Fatal(err)
	}
	actual, err = json.Marshal(helloWorld)
	if err != nil {
		log.Fatal(err)
	}
	assert.Equal(t, expected.String(), string(actual))

	// Let's add more links and a single embedded resource
	helloWorld = &HelloWorld{ID: 1, Name: "Hello World"}
	helloWorld.SetLink(
		"self", // name
		"/v1/hello/world?offset=2&limit=2", // href
		"", // title
	)
	helloWorld.SetLink(
		"next", // name
		"/v1/hello/world?offset=4&limit=2", // href
		"", // title
	)
	helloWorld.SetLink(
		"previous",                         // name
		"/v1/hello/world?offset=0&limit=2", // href
		"", // title
	)
	foobar = &Foobar{ID: 1, Name: "Foo bar 1"}
	foobar.SetLink("self", "/v1/foo/bar/1", "")
	helloWorld.SetEmbedded("foobar", jsonhal.Embedded(foobar))

	// Assert JSON after marshalling is as expected
	expected = bytes.NewBuffer([]byte{})
	err = json.Compact(expected, expectedJSON3)
	if err != nil {
		log.Fatal(err)
	}
	actual, err = json.Marshal(helloWorld)
	if err != nil {
		log.Fatal(err)
	}
	assert.Equal(t, expected.String(), string(actual))

	// Let's test embedded resources
	helloWorld = &HelloWorld{ID: 1, Name: "Hello World"}
	helloWorld.SetLink(
		"self",              // name
		"/v1/hello/world/1", // href
		"",                  // title
	)

	// Add embedded foobars
	foobars = []*Foobar{
		&Foobar{
			Hal: jsonhal.Hal{
				Links: map[string]*jsonhal.Link{
					"self": &jsonhal.Link{Href: "/v1/foo/bar/1"},
				},
			},
			ID:   1,
			Name: "Foo bar 1",
		},
		&Foobar{
			Hal: jsonhal.Hal{
				Links: map[string]*jsonhal.Link{
					"self": &jsonhal.Link{Href: "/v1/foo/bar/2"},
				},
			},
			ID:   2,
			Name: "Foo bar 2",
		},
	}
	helloWorld.SetEmbedded("foobars", jsonhal.Embedded(foobars))

	// Assert JSON after marshalling is as expected
	expected = bytes.NewBuffer([]byte{})
	err = json.Compact(expected, expectedJSON4)
	if err != nil {
		log.Fatal(err)
	}
	actual, err = json.Marshal(helloWorld)
	if err != nil {
		log.Fatal(err)
	}
	assert.Equal(t, expected.String(), string(actual))

	// Let's test multiple embedded resources
	helloWorld = &HelloWorld{ID: 1, Name: "Hello World"}
	helloWorld.SetLink(
		"self",              // name
		"/v1/hello/world/1", // href
		"",                  // title
	)

	// Add embedded foobars
	foobars = []*Foobar{
		&Foobar{
			Hal: jsonhal.Hal{
				Links: map[string]*jsonhal.Link{
					"self": &jsonhal.Link{Href: "/v1/foo/bar/1"},
				},
			},
			ID:   1,
			Name: "Foo bar 1",
		},
		&Foobar{
			Hal: jsonhal.Hal{
				Links: map[string]*jsonhal.Link{
					"self": &jsonhal.Link{Href: "/v1/foo/bar/2"},
				},
			},
			ID:   2,
			Name: "Foo bar 2",
		},
	}
	helloWorld.SetEmbedded("foobars", jsonhal.Embedded(foobars))

	// Add embedded quxes
	quxes = []*Qux{
		&Qux{
			Hal: jsonhal.Hal{
				Links: map[string]*jsonhal.Link{
					"self": &jsonhal.Link{Href: "/v1/qux/1"},
				},
			},
			ID:   1,
			Name: "Qux 1",
		},
		&Qux{
			Hal: jsonhal.Hal{
				Links: map[string]*jsonhal.Link{
					"self": &jsonhal.Link{Href: "/v1/qux/2"},
				},
			},
			ID:   2,
			Name: "Qux 2",
		},
	}
	helloWorld.SetEmbedded("quxes", jsonhal.Embedded(quxes))

	// Assert JSON after marshalling is as expected
	expected = bytes.NewBuffer([]byte{})
	err = json.Compact(expected, expectedJSON5)
	if err != nil {
		log.Fatal(err)
	}
	actual, err = json.Marshal(helloWorld)
	if err != nil {
		log.Fatal(err)
	}
	assert.Equal(t, expected.String(), string(actual))
}
Пример #6
0
// Handles requests to confirm user's email
// GET /v1/confirmations/{reference:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}}
func (s *Service) confirmEmailHandler(w http.ResponseWriter, r *http.Request) {
	// Get the authenticated account from the request context
	authenticatedAccount, err := GetAuthenticatedAccount(r)
	if err != nil {
		response.UnauthorizedError(w, err.Error())
		return
	}

	// Get the reference from request URI
	vars := mux.Vars(r)
	reference := vars["reference"]

	// Fetch the confirmation we want to work with (by reference from email link)
	confirmation, err := s.FindConfirmationByReference(reference)
	if err != nil {
		response.Error(w, err.Error(), http.StatusNotFound)
		return
	}

	// Confirm the user
	if err = s.ConfirmUser(confirmation); err != nil {
		response.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Create confirmation response
	confirmationResponse, err := NewConfirmationResponse(confirmation)
	if err != nil {
		response.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Was autologin flag passed in the query string
	autoLogin, _ := strconv.ParseBool(r.URL.Query().Get("autologin"))

	// If autologin == true, login the user and embed access token in the response object
	if autoLogin {
		// Login the user
		accessToken, refreshToken, err := s.GetOauthService().Login(
			authenticatedAccount.OauthClient,
			confirmation.User.OauthUser,
			"read_write",
		)
		if err != nil {
			response.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		// Create access token response
		accessTokenResponse, err := oauth.NewAccessTokenResponse(
			accessToken,
			refreshToken,
			s.cnf.Oauth.AccessTokenLifetime,
			tokentypes.Bearer,
		)
		if err != nil {
			response.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		// Set embedded access token
		confirmationResponse.SetEmbedded(
			"access-token",
			jsonhal.Embedded(accessTokenResponse),
		)
	}

	// Write the response
	response.WriteJSON(w, confirmationResponse, 200)
}