8465c2ce582b982686ea379bc462b12685efc972
[kraftakt.git] / app / user.go
1 package app
2
3 import (
4         "context"
5         "fmt"
6
7         "github.com/google/uuid"
8         legacy_context "golang.org/x/net/context"
9         "golang.org/x/oauth2"
10         "google.golang.org/appengine/datastore"
11 )
12
13 type User struct {
14         Email string
15         key   *datastore.Key
16 }
17
18 type dbUser struct {
19         ID string
20 }
21
22 func NewUser(ctx context.Context, email string) (*User, error) {
23         err := datastore.RunInTransaction(ctx, func(ctx legacy_context.Context) error {
24                 key := datastore.NewKey(ctx, "User", email, 0, nil)
25                 if err := datastore.Get(ctx, key, &dbUser{}); err != datastore.ErrNoSuchEntity {
26                         return err // may be nil
27                 }
28
29                 _, err := datastore.Put(ctx, key, &dbUser{
30                         ID: uuid.New().String(),
31                 })
32                 return err
33         }, nil)
34         if err != nil {
35                 return nil, err
36         }
37
38         return &User{
39                 Email: email,
40                 key:   datastore.NewKey(ctx, "User", email, 0, nil),
41         }, nil
42 }
43
44 func UserByID(ctx context.Context, id string) (*User, error) {
45         q := datastore.NewQuery("User").Filter("ID=", id).KeysOnly()
46         keys, err := q.GetAll(ctx, nil)
47         if err != nil {
48                 return nil, fmt.Errorf("datastore.Query.GetAll(): %v", err)
49         }
50         if len(keys) != 1 {
51                 return nil, fmt.Errorf("len(keys) = %d, want 1", len(keys))
52         }
53
54         return &User{
55                 Email: keys[0].StringID(),
56                 key:   keys[0],
57         }, nil
58 }
59
60 func (u *User) ID(ctx context.Context) (string, error) {
61         var db dbUser
62         if err := datastore.Get(ctx, u.key, &db); err != nil {
63                 return "", err
64         }
65
66         return db.ID, nil
67 }
68
69 func (u *User) Token(ctx context.Context, svc string) (*oauth2.Token, error) {
70         key := datastore.NewKey(ctx, "Token", svc, 0, u.key)
71
72         var tok oauth2.Token
73         if err := datastore.Get(ctx, key, &tok); err != nil {
74                 return nil, err
75         }
76
77         return &tok, nil
78 }
79
80 func (u *User) SetToken(ctx context.Context, svc string, tok *oauth2.Token) error {
81         key := datastore.NewKey(ctx, "Token", "Fitbit", 0, u.key)
82         _, err := datastore.Put(ctx, key, tok)
83         return err
84 }