9 "github.com/google/uuid"
10 legacy_context "golang.org/x/net/context"
12 "google.golang.org/appengine/datastore"
13 "google.golang.org/appengine/log"
27 func NewUser(ctx context.Context, email string) (*User, error) {
29 err := datastore.RunInTransaction(ctx, func(ctx legacy_context.Context) error {
30 key := datastore.NewKey(ctx, "User", email, 0, nil)
33 err := datastore.Get(ctx, key, &u)
34 if err != nil && err != datastore.ErrNoSuchEntity {
42 id = uuid.New().String()
43 _, err = datastore.Put(ctx, key, &dbUser{
53 key: datastore.NewKey(ctx, "User", email, 0, nil),
59 func UserByID(ctx context.Context, id string) (*User, error) {
60 q := datastore.NewQuery("User").Filter("ID=", id).KeysOnly()
61 keys, err := q.GetAll(ctx, nil)
63 return nil, fmt.Errorf("datastore.Query.GetAll(): %v", err)
66 return nil, fmt.Errorf("len(keys) = %d, want 1", len(keys))
72 Email: keys[0].StringID(),
76 func (u *User) Token(ctx context.Context, svc string) (*oauth2.Token, error) {
77 key := datastore.NewKey(ctx, "Token", svc, 0, u.key)
80 if err := datastore.Get(ctx, key, &tok); err != nil {
87 func (u *User) SetToken(ctx context.Context, svc string, tok *oauth2.Token) error {
88 key := datastore.NewKey(ctx, "Token", svc, 0, u.key)
89 _, err := datastore.Put(ctx, key, tok)
93 func (u *User) DeleteToken(ctx context.Context, svc string) error {
94 key := datastore.NewKey(ctx, "Token", svc, 0, u.key)
95 return datastore.Delete(ctx, key)
98 func (u *User) OAuthClient(ctx context.Context, svc string, cfg *oauth2.Config) (*http.Client, error) {
99 key := datastore.NewKey(ctx, "Token", svc, 0, u.key)
102 if err := datastore.Get(ctx, key, &tok); err != nil {
106 src := cfg.TokenSource(ctx, &tok)
107 return oauth2.NewClient(ctx, &persistingTokenSource{
115 func (u *User) String() string {
119 type persistingTokenSource struct {
122 src oauth2.TokenSource
128 func (s *persistingTokenSource) Token() (*oauth2.Token, error) {
132 tok, err := s.src.Token()
137 if s.t.AccessToken != tok.AccessToken ||
138 s.t.TokenType != tok.TokenType ||
139 s.t.RefreshToken != tok.RefreshToken ||
140 !s.t.Expiry.Equal(tok.Expiry) {
141 if _, err := datastore.Put(s.ctx, s.key, tok); err != nil {
142 log.Errorf(s.ctx, "persisting OAuth token in datastore failed: %v", err)