Пример #1
0
func TestEdit(t *testing.T) {
	defer context.Close()
	c := context.NewContext(nil)

	// Set it.

	m := map[string]string{
		"A": "1",
	}
	cnfg, err := GetOrInsert(c, "first", m)

	// Change it.

	cnfg.Values["A"] = "2"

	// Save it.

	err = cnfg.Put(c)
	checkErr(t, err)

	// Confirm.

	cnfg, err = Get(c, "first")

	checkErr(t, err)
	if x := cnfg.Values["A"]; x != "2" {
		t.Errorf(`cnfg["A"]: %v, want %v`, x, "2")
	}
}
Пример #2
0
func verifyHandler(w http.ResponseWriter, r *http.Request) {
	//code := r.FormValue("code")
	var e *Email
	var et *token.Token
	var err error
	c := context.NewContext(r)
	code := r.URL.Query().Get("code")
	errURL := "/"
	successURL := "/"
	et, err = token.Get(c, code)
	if err != nil {
		goto Error
	}
	e, err = Get(c, et.EmailAddress)
	if err != nil {
		goto Error
	}
	e.Status = verified
	if err = e.Put(c); err != nil {
		goto Error
	}
	http.Redirect(w, r, successURL, http.StatusFound)

Error:
	// TODO added error to session
	http.Redirect(w, r, errURL, http.StatusNotFound)
}
Пример #3
0
// Authenticate process the request and returns a populated UserProfile.
// If the Authenticate method can not authenticate the User based on the
// request, an error or a redirect URL wll be return.
func (p *Provider) Authenticate(w http.ResponseWriter, r *http.Request) (
	up *profile.Profile, redirectURL string, err error) {

	c := context.NewContext(r)

	url := r.FormValue("provider")
	// Set provider info.
	up = profile.New(p.Name, url)

	// Check for current User.

	u := aeuser.Current(c)

	if u == nil {
		redirectURL := r.URL.Path + "/callback"
		loginUrl, err := aeuser.LoginURLFederated(c, redirectURL, url)
		return up, loginUrl, err
	}

	if u.FederatedIdentity != "" {
		up.ID = u.FederatedIdentity
	} else {
		up.ID = u.ID
	}

	per := new(person.Person)
	per.Email = u.Email
	per.Emails = []*person.PersonEmails{
		&person.PersonEmails{true, "home", u.Email},
	}
	per.URL = u.FederatedIdentity
	up.Person = per

	return up, "", nil
}
Пример #4
0
func Test_handler(t *testing.T) {
	setup()
	defer teardown()
	_ = context.NewContext(nil)

	// Register the Provider

	p := &TPComplete{}
	Register("example5", p)
	r, _ := http.NewRequest("GET", "http://localhost:8080/-/auth/example5", nil)
	w := httptest.NewRecorder()

	// Run it through the auth handler.

	handler(w, r)

	// Inspected the redirect.

	hdr := w.Header()
	if hdr["Location"][0] != SuccessURL {
		t.Errorf(`hdr["Location"]: %q, want %q`, hdr["Location"][0], SuccessURL)
		t.Errorf(`w: %q`, w)
		t.Errorf(`hdr: %q`, hdr)
	}
}
Пример #5
0
func TestDelete(t *testing.T) {
	setup()
	c := context.NewContext(nil)
	defer tearDown()
	var x interface{}
	// Put A
	x = &A{S: "a", I: 1, B: []byte{}, T: now}
	key := datastore.NewKey(c, "A", "1", 0, nil)
	key, _ = Put(c, key, x)
	// Delete A
	err := Delete(c, key)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	// Test Store for absence of values
	x = &A{}
	err = memory.Get(c, key, x)
	if err != dserrors.ErrNoSuchEntity {
		t.Errorf(`err = %s; expected %s`, err, dserrors.ErrNoSuchEntity)
	}
	err = memcache.Get(c, key, x)
	if err != dserrors.ErrNoSuchEntity {
		t.Errorf(`err = %s; expected %s`, err, dserrors.ErrNoSuchEntity)
	}
	err = dsds.Get(c, key, x)
	if err != dserrors.ErrNoSuchEntity {
		t.Errorf(`err = %s; expected %s`, err, dserrors.ErrNoSuchEntity)
	}
}
Пример #6
0
func TestDelete(t *testing.T) {
	setup()
	defer tearDown()
	c := context.NewContext(nil)

	// Put.

	k, x := NewX(c, "1")
	_, err := s.Put(c, k, x)

	// Delete.
	err = s.Delete(c, k)
	if err != nil {
		t.Errorf("err: %v; want: %v.", err, nil)
	}

	// Delete non-existence

	k = datastore.NewKey(c, "X", "fakekey", 0, nil)
	r := new(X)
	err = s.Get(c, k, r)

	if err != dse.ErrNoSuchEntity {
		t.Errorf("err: %v; want: %v.", err, dse.ErrNoSuchEntity)
	}
}
Пример #7
0
func TestGetOrInsert(t *testing.T) {
	defer context.Close()
	c := context.NewContext(nil)

	// Set it.

	m := map[string]string{
		"A": "1",
	}
	cnfg, err := GetOrInsert(c, "first", m)

	// Confirm.

	checkErr(t, err)
	if x := cnfg.Values["A"]; x != "1" {
		t.Errorf(`config["A"]: %v, want %v`, x, "1")
	}

	// The orginal map should be returned.

	m = map[string]string{
		"A": "2",
	}

	cnfg, err = GetOrInsert(c, "first", m)

	// Confirm.

	checkErr(t, err)
	if x := cnfg.Values["A"]; x != "1" {
		t.Errorf(`config["A"]: %v, want %v`, x, "1")
	}
}
Пример #8
0
func TestPut(t *testing.T) {
	setup()
	defer tearDown()
	c := context.NewContext(nil)

	k, x1 := NewX(c, "1")
	_, err := s.Put(c, k, x1)
	if err != nil {
		t.Errorf("err: %v; want: %v.", err, nil)
	}
}
Пример #9
0
func TestNewKey(t *testing.T) {
	c := context.NewContext(nil)
	defer tearDown()

	k1 := datastore.NewKey(c, "AuthProfile", "google|12345", 0, nil)
	k2 := newKey(c, "Google", "12345")
	if k1.String() != k2.String() {
		t.Errorf("k2: %q, want %q.", k2, k1)
		t.Errorf("k1:", k1)
		t.Errorf("k2:", k2)
	}
}
Пример #10
0
func (p *Provider) callback(r *http.Request) error {
	// Exchange code for an access token at OAuth provider.
	code := r.FormValue("code")
	t := &oauth.Transport{
		Config: p.Config(r.URL),
		Transport: &urlfetch.Transport{
			Context: context.NewContext(r),
		},
	}
	_, err := t.Exchange(code)
	return err
}
Пример #11
0
// CreateAndLogin does the following:
//
//  - Search for an existing user - session -> Profile -> email address
//  - Saves the Profile to the datastore
//  - Creates a User or appends the AuthID to the Requesting user's account
//  - Logs in the User
//  - Adds the admin role to the User if they are an GAE Admin.
func CreateAndLogin(w http.ResponseWriter, r *http.Request,
	p *profile.Profile) (u *user.User, err error) {
	c := context.NewContext(r)
	if u, err = p.UpdateUser(w, r); err != nil {
		return
	}
	if err = user.CurrentUserSetID(w, r, p.UserID); err != nil {
		return
	}
	err = p.Put(c)
	return
}
Пример #12
0
// Current returns the current users password object minus the password
func (s *Service) Current(w http.ResponseWriter, r *http.Request,
	args *Args, reply *Args) (err error) {

	c := context.NewContext(r)
	var isSet bool
	userID, _ := user.CurrentUserID(r)
	_, err = profile.Get(c, profile.GenAuthID("Password", userID))
	if err == nil {
		isSet = true
	}
	reply.Password = &Password{IsSet: isSet}
	return nil
}
Пример #13
0
// Current checks the requesting User's session to see if they have an
// account. If they do, the provided User struct is populated with the
// information that is saved in the datastore. If they don't an error is
// returned.
func Current(r *http.Request) (*User, error) {
	id, _ := CurrentUserID(r)

	if id != "" {
		c := context.NewContext(r)
		u := new(User)
		key := datastore.NewKey(c, "User", id, 0, nil)
		err := ds.Get(c, key, u)
		u.Key = key
		return u, err
	}
	return nil, ErrNoLoggedInUser
}
Пример #14
0
func (s *Service) GetAll(w http.ResponseWriter, r *http.Request,
	args *Args, reply *Reply) (err error) {

	c := context.NewContext(r)
	u, err := user.Current(r)
	if err != nil {
		return err
	}
	if reply.Profiles, err = GetPersonMulti(c, u.AuthIDs); err != nil {
		return err
	}
	return nil
}
Пример #15
0
func TestGetMulti(t *testing.T) {
	setup()
	defer tearDown()
	c := context.NewContext(nil)

	if cnt := s.Count(c); cnt != 0 {
		t.Errorf(`Before Put; s.Count(c): %v; want %v`, cnt, 0)
	}

	// Put.

	k1, x1 := NewX(c, "1")
	k2, x2 := NewX(c, "2")
	k3, x3 := NewX(c, "3")
	keys := []*datastore.Key{k1, k2, k3}
	xs := []*X{x1, x2, x3}
	keys, err := s.PutMulti(c, keys, xs)

	// Get.

	xs = []*X{&X{}, &X{}, &X{}}
	err = s.GetMulti(c, keys, xs)

	// Confirm.

	if err != nil {
		t.Errorf("err: %v; want: %v.", err, nil)
	}
	CheckX(c, t, xs[0], "1")
	CheckX(c, t, xs[1], "2")
	CheckX(c, t, xs[2], "3")

	// Get non-existence

	k4, _ := NewX(c, "4")
	k5, _ := NewX(c, "5")
	xs = []*X{&X{}, &X{}, &X{}, &X{}, &X{}}
	keys = []*datastore.Key{k1, k2, k3, k4, k5}

	err = s.GetMulti(c, keys, xs)

	if err.Error() != "ds: no such entity (and 1 other error)" {
		t.Errorf("err: %v; want: %v.", err.Error(), "ds: no such entity (and 1 other error)")
	}

	// Check.

	CheckX(c, t, xs[0], "1")
	CheckX(c, t, xs[1], "2")
	CheckX(c, t, xs[2], "3")
}
Пример #16
0
func TestDeleteMulti(t *testing.T) {
	setup()
	defer tearDown()
	c := context.NewContext(nil)

	// Put.

	k1, x1 := NewX(c, "1")
	k2, x2 := NewX(c, "2")
	k3, x3 := NewX(c, "3")
	keys := []*datastore.Key{k1, k2, k3}
	xs := []*X{x1, x2, x3}
	keys, err := s.PutMulti(c, keys, xs)

	// Delete.

	err = s.DeleteMulti(c, keys)

	// Confirm.

	if err != nil {
		t.Errorf("err: %v; want: %v.", err, nil)
	}
	if cnt := len(xs); cnt != 3 {
		t.Errorf(`After DeleteMulti; len(xs): %v; want %v`, cnt, 3)
	}

	// Delete non-existence

	// Put.

	k1, x1 = NewX(c, "1")
	k2, x2 = NewX(c, "2")
	k3, x3 = NewX(c, "3")
	keys = []*datastore.Key{k1, k2, k3}
	xs = []*X{x1, x2, x3}
	keys, err = s.PutMulti(c, keys, xs)

	k4, _ := NewX(c, "4")
	k5, _ := NewX(c, "5")
	xs = []*X{&X{}, &X{}, &X{}, &X{}, &X{}}
	keys = []*datastore.Key{k1, k2, k3, k4, k5}

	err = s.DeleteMulti(c, keys)

	//if err.Error() != "ds: no such entity (and 1 other error)" {
	//	t.Errorf("err: %v; want: %v.", err.Error(), "ds: no such entity (and 1 other error)")
	//}
}
Пример #17
0
func TestCan(t *testing.T) {

	setUp()
	defer tearDown()

	c := context.NewContext(nil)

	u := New()
	// User key
	key := datastore.NewKey(c, "User", "1", 0, nil)
	u.Key = key
	if !u.Can(c, "write", key) {
		t.Error(`User should be able to "write" their own User object`)
	}
}
Пример #18
0
func TestPutMulti(t *testing.T) {
	setup()
	defer tearDown()
	c := context.NewContext(nil)

	k1, x1 := NewX(c, "X1")
	k2, x2 := NewX(c, "X2")
	k3, x3 := NewX(c, "X3")
	keys := []*datastore.Key{k1, k2, k3}
	xs := []*X{x1, x2, x3}

	keys, err := s.PutMulti(c, keys, xs)
	if err != nil {
		t.Errorf("err: %v; want: %v.", err, nil)
	}
}
Пример #19
0
func (s *Service) Authenticate(w http.ResponseWriter, r *http.Request,
	args *Args, reply *Args) (err error) {

	c := context.NewContext(r)
	args.Person.Email = args.Password.Email
	userID, _ := user.CurrentUserIDByEmail(r, args.Password.Email)
	pf, err := authenticate(c, args.Password, args.Person, userID)
	if err != nil {
		return err
	}
	if _, err = auth.CreateAndLogin(w, r, pf); err != nil {
		return err
	}
	reply.Person = pf.Person
	return nil
}
Пример #20
0
func TestAllocateIDs(t *testing.T) {
	setup()
	c := context.NewContext(nil)
	defer tearDown()

	cnt := 5
	low, high, err := AllocateIDs(c, "D", nil, cnt)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	ncnt := int(high - low)
	if ncnt != cnt {
		t.Errorf(`ncnt = %v, %v`, ncnt, cnt)
		t.Errorf(`low = %v`, low)
		t.Errorf(`high = %v`, high)
	}
}
Пример #21
0
// Authenticate process the request and returns a populated Profile.
// If the Authenticate method can not authenticate the User based on the
// request, an error or a redirect URL wll be return.
func (p *Provider) Authenticate(w http.ResponseWriter, r *http.Request) (
	pf *profile.Profile, url string, err error) {

	p.URL = r.URL.Host
	pf = profile.New(p.Name, p.URL)

	pass := &Password{
		New:     r.FormValue("Password.New"),
		Current: r.FormValue("Password.Current"),
		Email:   r.FormValue("Email"),
	}
	c := context.NewContext(r)
	userID, _ := user.CurrentUserIDByEmail(r, pass.Email)
	pers := decodePerson(r)
	pf, err = authenticate(c, pass, pers, userID)
	return pf, "", err
}
Пример #22
0
func TestPut(t *testing.T) {
	setup()
	defer tearDown()
	c := context.NewContext(nil)

	k, x1 := NewX(c, "1")
	if cnt := s.Count(c); cnt != 0 {
		t.Errorf(`Before put; s.Count(c) = %v; want %v`, cnt, 0)
	}
	_, err := s.Put(c, k, x1)
	if err != nil {
		t.Errorf("err: %v; want: %v.", err, nil)
	}
	if cnt := s.Count(c); cnt != 1 {
		t.Errorf(`After put; s.Count(c): %v; want %v`, cnt, 1)
	}
}
Пример #23
0
// CurrentUserIDByEmail returns the userId of the requesting user. Or the userID
// associated with the provided email.
func CurrentUserIDByEmail(r *http.Request, emailAddress string) (string, error) {
	// TODO: User merge if the session UserID is different then the email UserID
	// search session
	sessID, _ := CurrentUserID(r)
	if sessID != "" {
		// TODO: maybe confirm that the UserID exists?
		// There are case where the session may have an incorrect UserID.
		return sessID, nil
	}
	// search by email
	c := context.NewContext(r)
	e, err := email.Get(c, emailAddress)
	if err != nil {
		return "", err
	}
	return e.UserID, nil
}
Пример #24
0
func TestCreateFromPerson(t *testing.T) {
	c := context.NewContext(nil)
	defer tearDown()

	var err error
	var u *User
	var u2 *User
	var e *email.Email

	// Round #1 New User with email & password
	// Save it.
	if u, err = CreateFromPerson(c, p1); err != nil {
		t.Errorf(`err: %v, want nil`, err)
	}

	// Check User
	// Get from ds to confirm save
	if u, err = Get(c, u.Key.StringID()); err != nil {
		t.Errorf(`err: %v, want nil`, err)
	}
	if u.Email != p1.Email {
		t.Errorf(`u.Email: %v, want %v`, u.Email, p1.Email)
	}
	if u.Person.ID != u.Key.StringID() {
		t.Errorf(`u.Person.ID: %v, want %v`, u.Person.ID, u.Key.StringID())
	}
	// Check Email
	if e, err = email.Get(c, u.Email); err != nil {
		t.Errorf(`err: %v, want nil`, err)
	}
	if e.UserID != u.Key.StringID() {
		t.Errorf(`u.UserID: %v, want %v`, e.UserID, u.Key.StringID())
	}

	// Round #2 Existing User with email & password
	// Get it
	if u2, err = UpdateFromPerson(c, u.Person); err != nil {
		t.Errorf(`err: %v, want nil`, err)
	}

	if u2.Key.StringID() != u.Key.StringID() {
		t.Errorf(`u2.Key.StringID: %v, want %v`, u2.Key.StringID(), u.Key.StringID())
	}
}
Пример #25
0
func TestPutMulti(t *testing.T) {
	setup()
	defer tearDown()
	c := context.NewContext(nil)

	if cnt := s.Count(c); cnt != 0 {
		t.Errorf(`Before Put; s.Count(c): %v; want %v`, cnt, 0)
	}
	k1, x1 := NewX(c, "X1")
	k2, x2 := NewX(c, "X2")
	k3, x3 := NewX(c, "X3")
	keys := []*datastore.Key{k1, k2, k3}
	xs := []*X{x1, x2, x3}

	keys, err := s.PutMulti(c, keys, xs)
	if err != nil {
		t.Errorf("err: %v; want: %v.", err, nil)
	}
	if cnt := s.Count(c); cnt != 3 {
		t.Errorf(`After Put; s.Count(c): %v; want %v`, cnt, 3)
	}
}
Пример #26
0
func TestDeleteMulti(t *testing.T) {
	setup()
	c := context.NewContext(nil)
	defer tearDown()
	var x interface{}
	// Put As
	x = []*A{
		&A{S: "a", I: 1, B: []byte{}, T: now},
		&A{S: "a", I: 1, B: []byte{}, T: now},
	}
	key := []*datastore.Key{
		datastore.NewKey(c, "A", "1", 0, nil),
		datastore.NewKey(c, "A", "2", 0, nil),
	}
	key, _ = PutMulti(c, key, x)
	// Delete As
	err := DeleteMulti(c, key)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	// Test Store for absence of values
	x = []*A{&A{}, &A{}}
	err = memory.GetMulti(c, key, x)
	if reflect.TypeOf(err) != reflect.TypeOf(dserrors.MultiError{}) {
		t.Errorf(`err = %s; expected %s`, reflect.TypeOf(err), reflect.TypeOf(dserrors.MultiError{}))
	}
	err = memcache.GetMulti(c, key, x)
	if reflect.TypeOf(err) != reflect.TypeOf(dserrors.MultiError{}) {
		t.Errorf(`err = %s; expected %s`, reflect.TypeOf(err), reflect.TypeOf(dserrors.MultiError{}))
	}
	// TODO(kylefinley) add this test back.
	// err = dsds.GetMulti(c, key, x)
	// if reflect.TypeOf(err) != reflect.TypeOf(dserrors.MultiError{}) {
	// 	t.Errorf(`err = %s; expected %s`, reflect.TypeOf(err), reflect.TypeOf(dserrors.MultiError{}))
	// }
}
Пример #27
0
func TestPutGetMulti(t *testing.T) {
	setup()
	c := context.NewContext(nil)
	defer tearDown()
	// Put As
	key := []*datastore.Key{
		datastore.NewKey(c, "A", "1", 0, nil),
		datastore.NewKey(c, "A", "2", 0, nil),
	}
	x := []*A{
		&A{S: "a", I: 1, B: []byte{}, T: now},
		&A{S: "a", I: 1, B: []byte{}, T: now},
	}
	key, err := PutMulti(c, key, x)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	// Test Store for values
	x = []*A{&A{}, &A{}}
	err = dsds.GetMulti(c, key, x)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
}
Пример #28
0
func TestGet(t *testing.T) {
	c := context.NewContext(nil)
	defer tearDown()

	// Save it.

	u := New()
	u.Email = "*****@*****.**"
	u.Key = datastore.NewKey(c, "User", "", 0, nil)
	err := u.Put(c)
	if err != nil {
		t.Errorf(`err: %q, want nil`, err)
	}

	// Get it.

	u2, err := Get(c, u.Key.StringID())
	if err != nil {
		t.Errorf(`err: %v, want nil`, err)
	}
	if u2.Email != "*****@*****.**" {
		t.Errorf(`u2.Email: %v, want "*****@*****.**"`, u2.Email)
	}
}
Пример #29
0
func TestPutGet(t *testing.T) {
	setup()
	c := context.NewContext(nil)
	defer tearDown()
	var x interface{}
	// Put A
	x = &A{S: "a", I: 1, B: []byte{}, T: now}
	key := datastore.NewKey(c, "A", "1", 0, nil)
	key, err := Put(c, key, x)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	// Test Store for values
	x = new(A)
	err = memory.Get(c, key, x)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	err = memcache.Get(c, key, x)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	err = dsds.Get(c, key, x)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	// Put B
	x = &B{S: "a", I: 1, B: []byte{}, T: now}
	key = datastore.NewKey(c, "B", "1", 0, nil)
	key, err = Put(c, key, x)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	// Test Store for values
	x = new(B)
	err = memory.Get(c, key, x)
	if err != dserrors.ErrNoSuchEntity {
		t.Errorf(`err = %s; expected %s`, err, dserrors.ErrNoSuchEntity)
	}
	err = memcache.Get(c, key, x)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	err = dsds.Get(c, key, x)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	// Put C
	x = &C{S: "a", I: 1, B: []byte{}, T: now}
	key = datastore.NewKey(c, "C", "1", 0, nil)
	key, err = Put(c, key, x)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
	x = new(C)
	// Test Store for values
	err = memory.Get(c, key, x)
	if err != dserrors.ErrNoSuchEntity {
		t.Errorf(`err = %s; expected %s`, err, dserrors.ErrNoSuchEntity)
	}
	err = memcache.Get(c, key, x)
	if err != dserrors.ErrNoSuchEntity {
		t.Errorf(`err = %s; expected %s`, err, dserrors.ErrNoSuchEntity)
	}
	err = dsds.Get(c, key, x)
	if err != nil {
		t.Errorf(`err = %s; expected nil`, err)
	}
}
Пример #30
0
// Scenario #2:
// - No User session
// - Yes Email Saved
// - Yes Profile Saved
func TestAuthenticate_Scenario2(t *testing.T) {
	pro := setup()
	defer tearDown()

	var pf *profile.Profile
	var uRL string
	var err error
	var v url.Values
	var r *http.Request

	c := context.NewContext(nil)
	w := httptest.NewRecorder()

	// Profile Not found
	v = url.Values{}
	v.Set("Email", "*****@*****.**")
	v.Set("Password.Current", "secret1")
	r = createRequest(v)
	// Check.
	if pf, uRL, err = pro.Authenticate(w, r); uRL != "" || err != ErrProfileNotFound {
		t.Errorf(`url: %v, want: ""`, uRL)
		t.Errorf(`err: %v, want: %v`, err, ErrProfileNotFound)
	}

	// Setup.
	pf = profile.New("Password", "")
	pf.UserID = "1"
	pf.ID = "1"
	passHash, _ := GenerateFromPassword([]byte("secret1"))
	pf.Auth = passHash
	pf.SetKey(c)
	pf.Person = &person.Person{
		Name: &person.PersonName{
			GivenName:  "Barack",
			FamilyName: "Obama",
		},
	}
	_ = pf.Put(c)
	e := email.New()
	e.UserID = "1"
	e.SetKey(c, "*****@*****.**")
	_ = e.Put(c)

	// 1. Login
	// a. Correct password.
	v = url.Values{}
	v.Set("Email", "*****@*****.**")
	v.Set("Password.Current", "secret1")
	v.Set("Name.GivenName", "Berry")
	r = createRequest(v)
	// Check.
	if pf, uRL, err = pro.Authenticate(w, r); uRL != "" || err != nil {
		t.Errorf(`url: %v, want: ""`, uRL)
		t.Fatalf(`err: %v, want: %v`, err, nil)
	}
	if x := pf.Person.Name.GivenName; x != "Barack" {
		t.Errorf(`.Person should not be updated on login`)
	}
	// b. In-Correct password.
	v = url.Values{}
	v.Set("Email", "*****@*****.**")
	v.Set("Password.Current", "fakepass")
	r = createRequest(v)
	// Check.
	if _, _, err = pro.Authenticate(w, r); err != ErrPasswordMismatch {
		t.Errorf(`err: %v, want: %v`, err, ErrPasswordMismatch)
	}
	// 2. Update
	// a. Correct password.
	v = url.Values{}
	v.Set("Email", "*****@*****.**")
	v.Set("Password.Current", "secret1")
	v.Set("Password.New", "secret2")
	v.Set("Name.GivenName", "Berry")
	r = createRequest(v)
	// Check.
	if pf, uRL, err = pro.Authenticate(w, r); uRL != "" || err != nil {
		t.Errorf(`url: %v, want: ""`, uRL)
		t.Errorf(`err: %v, want: %v`, err, nil)
	}
	if x := pf.Person.Name.GivenName; x != "Berry" {
		t.Errorf(`pf.Person should be updated on update`)
	}
	if x := pf.UserID; x != "1" {
		t.Errorf(`pf.UserID: %v, want %v`, x, "1")
	}
	if err := CompareHashAndPassword(pf.Auth, []byte("secret2")); err != nil {
		t.Errorf(`Password was not changed`)
	}
	// b. In-Correct password.
	v = url.Values{}
	v.Set("Email", "*****@*****.**")
	v.Set("Password.Current", "fakepass")
	v.Set("Password.New", "hacked")
	v.Set("Name.GivenName", "Bob")
	r = createRequest(v)
	// Check.
	if _, _, err = pro.Authenticate(w, r); err != ErrPasswordMismatch {
		t.Errorf(`err: %v, want: %v`, err, ErrPasswordMismatch)
	}
	// 2. Create - Should login user
	// a. Correct password.
	v = url.Values{}
	v.Set("Email", "*****@*****.**")
	v.Set("Password.New", "secret1")
	v.Set("Name.GivenName", "Bob1")
	r = createRequest(v)
	// Check.
	if pf, uRL, err = pro.Authenticate(w, r); uRL != "" || err != nil {
		t.Errorf(`url: %v, want: ""`, uRL)
		t.Errorf(`err: %v, want: %v`, err, nil)
	}
	if x := pf.Person.Name.GivenName; x != "Bob1" {
		t.Errorf(`.Person should be updated on update`)
	}
	if x := pf.UserID; x != "1" {
		t.Errorf(`pf.UserID: %v, want %v`, x, "1")
	}
	if err := CompareHashAndPassword(pf.Auth, []byte("secret1")); err != nil {
		t.Errorf(`Password was not changed`)
	}
	// b. In-Correct password.
	v = url.Values{}
	v.Set("Email", "*****@*****.**")
	v.Set("Password.New", "fakepass")
	v.Set("Name.GivenName", "Bob2")
	r = createRequest(v)
	// Check.
	if _, _, err = pro.Authenticate(w, r); err != ErrPasswordMismatch {
		t.Errorf(`err: %v, want: %v`, err, ErrPasswordMismatch)
	}
}