86c033c2978b58504d64d6f29a560f6a52eba7ff
[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         key *datastore.Key
15 }
16
17 type dbUser struct {
18         ID string
19 }
20
21 func NewUser(ctx context.Context, email string) (*User, error) {
22         err := datastore.RunInTransaction(ctx, func(ctx legacy_context.Context) error {
23                 key := datastore.NewKey(ctx, "User", email, 0, nil)
24                 if err := datastore.Get(ctx, key, &dbUser{}); err != datastore.ErrNoSuchEntity {
25                         return err // may be nil
26                 }
27
28                 _, err := datastore.Put(ctx, key, &dbUser{
29                         ID: uuid.New().String(),
30                 })
31                 return err
32         }, nil)
33         if err != nil {
34                 return nil, err
35         }
36
37         return &User{
38                 key: datastore.NewKey(ctx, "User", email, 0, nil),
39         }, nil
40 }
41
42 func UserByID(ctx context.Context, id string) (*User, error) {
43         q := datastore.NewQuery("User").Filter("ID=", id).KeysOnly()
44         keys, err := q.GetAll(ctx, nil)
45         if err != nil {
46                 return nil, fmt.Errorf("datastore.Query.GetAll(): %v", err)
47         }
48         if len(keys) != 1 {
49                 return nil, fmt.Errorf("len(keys) = %d, want 1", len(keys))
50         }
51
52         return &User{
53                 key: keys[0],
54         }, nil
55 }
56
57 func (u *User) ID(ctx context.Context) (string, error) {
58         var db dbUser
59         if err := datastore.Get(ctx, u.key, &db); err != nil {
60                 return "", err
61         }
62
63         return db.ID, nil
64 }
65
66 func (u *User) Token(ctx context.Context, svc string) (*oauth2.Token, error) {
67         key := datastore.NewKey(ctx, "Token", svc, 0, u.key)
68
69         var tok oauth2.Token
70         if err := datastore.Get(ctx, key, &tok); err != nil {
71                 return nil, err
72         }
73
74         return &tok, nil
75 }
76
77 func (u *User) SetToken(ctx context.Context, svc string, tok *oauth2.Token) error {
78         key := datastore.NewKey(ctx, "Token", "Fitbit", 0, u.key)
79         _, err := datastore.Put(ctx, key, tok)
80         return err
81 }