Пример #1
0
// UpdateUser does the following:
//  - Search for an existing user - session -> Profile -> email address
//  - Creates a User or appends the AuthID to the Requesting user's account
//  - Adds the admin role to the User if they are a GAE Admin.
func (p *Profile) UpdateUser(w http.ResponseWriter, r *http.Request) (u *user.User, err error) {

	c := context.NewContext(r)
	if p.Key == nil {
		if p.ProviderName == "" && p.ID == "" {
			return nil, errors.New("auth: key not set")
		}
		p.SetKey(c)
	}
	var saveUser bool // flag indicating that the user needs to be saved.

	// Find the UserID
	// if the AuthProfile doesn't have a UserID look it up. And populate the
	// UserID from the saved profile.
	if p.UserID == "" {
		if p2, err := Get(c, p.Key.StringID()); err == nil {
			p.UserID = p2.UserID
		}
	}
	// look up the UserID in the session
	currentUserID, _ := user.CurrentUserID(r)
	if currentUserID != "" {
		if p.UserID == "" {
			p.UserID = currentUserID
		} else {
			// TODO: User merge
		}
	}

	// If we still don't have a UserID create a new user
	if p.UserID == "" {
		// Create User
		u = user.New()
		// Allocation an new ID
		if err = u.SetKey(c); err != nil {
			return nil, err
		}
		saveUser = true
	} else {
		if u, err = user.Get(c, p.UserID); err != nil {
			// if user is not found we have some type of syncing problem.
			c.Criticalf(`auth: userID: %v was saved to Profile / Session, but was not found in the datastore`, p.UserID)
			return nil, err
		}
	}
	// Add AuthID
	if err = u.AddAuthID(p.Key.StringID()); err == nil {
		saveUser = true
	}
	if p.Person.Email != "" {
		if _, err := u.AddEmail(c, p.Person.Email, 0); err == nil {
			saveUser = true
		}
	}
	// If current user is an admin in GAE add role to User
	if aeuser.IsAdmin(c) {
		// Save the roll to the session
		_ = user.CurrentUserSetRole(w, r, "admin", true)
		// Add the role to the user's roles.
		if err = u.AddRole("admin"); err == nil {
			saveUser = true
		}
	}
	if saveUser {
		if err = u.Put(c); err != nil {
			return nil, err
		}
	}
	p.UserID = u.Key.StringID()
	return u, nil
}
Пример #2
0
func Test_CreateAndLogin(t *testing.T) {
	setup()
	defer teardown()
	c := context.NewContext(nil)

	up := profile.New("Example", "example.com")
	r, _ := http.NewRequest("GET", "http://localhost:8080/-/auth/example4", nil)
	w := httptest.NewRecorder()

	// Round 1: No User | No Profile

	// Confirm.

	q := datastore.NewQuery("User")
	if cnt, _ := q.Count(c); cnt != 0 {
		t.Errorf(`User cnt: %v, want 0`, cnt)
	}
	q = datastore.NewQuery("Profile")
	if cnt, _ := q.Count(c); cnt != 0 {
		t.Errorf(`Profile cnt: %v, want 0`, cnt)
	}
	u, err := user.Current(r)
	if err != user.ErrNoLoggedInUser {
		t.Errorf(`err: %v, want %v`, err, user.ErrNoLoggedInUser)
	}

	// Create.

	up.ID = "1"
	up.ProviderName = "Example"
	up.SetKey(c)
	u, err = CreateAndLogin(w, r, up)
	if err != nil {
		t.Errorf(`err: %v, want nil`, err)
	}

	if u.Key.StringID() != "1" {
		t.Errorf(`u.Key.StringID(): %v, want 1`, u.Key.StringID())
	}
	if up.Key.StringID() != "example|1" {
		t.Errorf(`up.Key.StringID(): %v, want "example|1"`, up.Key.StringID())
	}
	if up.UserID != u.Key.StringID() {
		t.Errorf(`up.UserID: %v, want %v`, up.UserID, u.Key.StringID())
	}

	// Confirm Profile.

	rup, err := profile.Get(c, "example|1")
	if err != nil {
		t.Errorf(`err: %v, want nil`, err)
	}
	if rup.ID != "1" {
		t.Errorf(`rup.ID: %v, want "1"`, rup.ID)
	}
	if rup.Key.StringID() != "example|1" {
		t.Errorf(`rup.Key.StringID(): %v, want "example|1"`, rup.Key.StringID())
	}
	if rup.UserID != u.Key.StringID() {
		t.Errorf(`rup.UserID: %v, want %v`, rup.UserID, u.Key.StringID())
	}

	// Confirm User.

	ru, err := user.Get(c, "1")
	if err != nil {
		t.Fatalf(`err: %v, want nil`, err)
	}
	if ru.AuthIDs[0] != "example|1" {
		t.Errorf(`ru.AuthIDs[0]: %v, want "example|1"`, ru.AuthIDs[0])
	}
	if ru.Key.StringID() != "1" {
		t.Errorf(`ru.Key.StringID(): %v, want 1`, ru.Key.StringID())
	}
	q2 := datastore.NewQuery("User")
	q4 := datastore.NewQuery("AuthProfile")

	// Confirm Logged in User.

	u, err = user.Current(r)
	if err != nil {
		t.Errorf(`err: %v, want %v`, err, nil)
	}
	if u.Key.StringID() != "1" {
		t.Errorf(`u.Key.StringID(): %v, want 1`, u.Key.StringID())
	}
	if len(u.AuthIDs) != 1 {
		t.Errorf(`len(u.AuthIDs): %v, want 1`, len(u.AuthIDs))
		t.Errorf(`u.AuthIDs: %v`, u.AuthIDs)
		t.Errorf(`u: %v`, u)
	}

	// Round 2: Logged in User | Second Profile

	// Create.

	up = profile.New("AnotherExample", "anotherexample.com")
	up.ID = "2"
	up.SetKey(c)
	u, err = CreateAndLogin(w, r, up)
	if err != nil {
		t.Errorf(`err: %v, want nil`, err)
	}

	// Confirm Profile.

	rup, err = profile.Get(c, "anotherexample|2")
	if err != nil {
		t.Errorf(`err: %v, want nil`, err)
	}
	if rup.ID != "2" {
		t.Errorf(`rup.ID: %v, want "2"`, rup.ID)
	}
	if rup.Key.StringID() != "anotherexample|2" {
		t.Errorf(`rup.Key.StringID(): %v, want "anotherexample|2"`, rup.Key.StringID())
	}
	if rup.UserID != u.Key.StringID() {
		t.Errorf(`rup.UserID: %v, want %v`, rup.UserID, u.Key.StringID())
	}

	// Confirm Logged in User hasn't changed.

	u, err = user.Current(r)
	if err != nil {
		t.Errorf(`err: %v, want %v`, err, nil)
	}
	if u.Key.StringID() != "1" {
		t.Errorf(`u.Key.StringID(): %v, want 1`, u.Key.StringID())
	}
	if len(u.AuthIDs) != 2 {
		t.Errorf(`len(u.AuthIDs): %v, want 2`, len(u.AuthIDs))
		t.Errorf(`u.AuthIDs: %v`, u.AuthIDs)
		t.Errorf(`u: %v`, u)
	}
	if u.AuthIDs[0] != "example|1" {
		t.Errorf(`u.AuthIDs[0]: %v, want "example|1"`, u.AuthIDs[0])
	}
	if u.AuthIDs[1] != "anotherexample|2" {
		t.Errorf(`u.AuthIDs[1]: %v, want "anotherexample|2"`, u.AuthIDs[1])
	}

	// Confirm Counts

	q2 = datastore.NewQuery("User")
	if cnt, _ := q2.Count(c); cnt != 1 {
		t.Errorf(`User cnt: %v, want 1`, cnt)
	}
	q4 = datastore.NewQuery("AuthProfile")

	// Round 3: Logged out User | Existing Profile

	err = user.Logout(w, r)
	if err != nil {
		t.Errorf(`err: %v, want nil`, err)
	}

	// Confirm Logged out User.

	u, err = user.Current(r)
	if err != user.ErrNoLoggedInUser {
		t.Errorf(`err: %q, want %q`, err, user.ErrNoLoggedInUser)
	}

	// Login.

	up = profile.New("Example", "example.com")
	up.ID = "1"
	up.SetKey(c)
	u, err = CreateAndLogin(w, r, up)
	if err != nil {
		t.Errorf(`err: %v, want nil`, err)
	}

	// Confirm.

	q2 = datastore.NewQuery("User")
	if cnt, _ := q2.Count(c); cnt != 1 {
		t.Errorf(`User cnt: %v, want 1`, cnt)
	}
	q4 = datastore.NewQuery("AuthProfile")
	if cnt, _ := q4.Count(c); cnt != 2 {
		t.Errorf(`Profile cnt: %v, want 1`, cnt)
	}

	// Confirm Logged in User hasn't changed.

	u, err = user.Current(r)
	if err != nil {
		t.Errorf(`err: %v, want %v`, err, nil)
	}
	if u.Key.StringID() != "1" {
		t.Errorf(`u.Key.StringID(): %v, want "1"`, u.Key.StringID())
	}
	if len(u.AuthIDs) != 2 {
		t.Errorf(`len(u.AuthIDs): %v, want 2`, len(u.AuthIDs))
		t.Errorf(`u.AuthIDs: %s`, u.AuthIDs)
		t.Errorf(`u: %v`, u)
	}
}