// CurrentUserHasRole checks for the presents of a role listed under the current user. // The role is retrieved from the users session to save on lookups. func CurrentUserHasRole(w http.ResponseWriter, r *http.Request, role string) bool { // Confirm we have a user. if id, err := CurrentUserID(r); id != "" || err != nil { return false } c := context.NewContext(r) store, err := session.GetStore(c) if err != nil { c.Criticalf("user: There was an error retrieving the session store Error: %v", err) return false } // 1st Check the session. s, err := store.Get(r, "user|roles") if err != nil { c.Criticalf("user: There was an error retrieving the session Error: %v", err) return false } if s.Values[role] == true { return true } // 2nd Check the ds. u, err := Current(r) if err != nil { return false } if u.HasRole(role) { // Set the role to true in the session to avoid this look up in the future. if err = CurrentUserSetRole(w, r, role, true); err != nil { return false } return true } return false }
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") } }
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) } }
func TestGetStore(t *testing.T) { setup() defer teardown() r, _ := http.NewRequest("GET", "http://localhost:8080/", nil) w := httptest.NewRecorder() c := context.NewContext(r) // create the store tStore, err := GetStore(c) if err != nil { t.Errorf(`err getting store: %q, want nil`, err) } // Get or Create a new session using the store s, err := tStore.Get(r, "t1") if err != nil { t.Errorf(`err getting session: %q, want nil`, err) } // Confirm api s.Values["val1"] = "example value" err = s.Save(r, w) if err != nil { t.Errorf(`err saving session: %q, want nil`, err) } }
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") } }
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) } }
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) } // Confirm. if cnt := s.Count(c); cnt != 0 { t.Errorf(`After delete; Count: %v; want %v`, cnt, 0) } // 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) } }
// 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 }
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) }
func TestGet(t *testing.T) { setup() defer tearDown() c := context.NewContext(nil) // Put. k, x := NewX(c, "1") _, err := s.Put(c, k, x) // Get. r := new(X) err = s.Get(c, k, r) if err != nil { t.Errorf("err: %v; want: %v.", err, nil) } // Confirm. CheckX(c, t, r, "1") // Get 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) } }
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) } }
// 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 }
func account(w http.ResponseWriter, r *http.Request) { m := tmplMap() c := context.NewContext(r) if u, err := user.Current(r); err == nil { m["User"] = u c.Debugf("User: %v", u) c.Debugf("User.Person: %v", u.Person) } if err := accountTmpl.Execute(w, m); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } }
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 }
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) } }
// 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 }
// 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 }
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 }
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") }
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)") } }
// CurrentUserSetID adds the provided userId to the current users session/cookie func CurrentUserSetID(w http.ResponseWriter, r *http.Request, userId string) error { c := context.NewContext(r) store, err := session.GetStore(c) if err != nil { c.Criticalf("user: There was an error retrieving the session store Error: %v", err) } s, err := store.Get(r, "user") if err != nil { c.Criticalf("user: There was an error retrieving the session Error: %v", err) return err } s.Values["userid"] = userId return s.Save(r, w) }
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`) } }
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) } }
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 }
// CurrentUserID returns the userId of the requesting user. func CurrentUserID(r *http.Request) (string, error) { c := context.NewContext(r) store, err := session.GetStore(c) if err != nil { c.Criticalf("user: There was an error retrieving the session store Error: %v", err) } s, err := store.Get(r, "user") if err != nil { c.Criticalf("user: There was an error retrieving the session Error: %v", err) } if err != nil { return "", err } id, _ := s.Values["userid"].(string) return id, err }
// 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 }
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) } }
// 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 }
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) } }
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()) } }