diff options
Diffstat (limited to 'app/models/user.go')
-rw-r--r-- | app/models/user.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/app/models/user.go b/app/models/user.go new file mode 100644 index 0000000..0cbd92d --- /dev/null +++ b/app/models/user.go | |||
@@ -0,0 +1,99 @@ | |||
1 | package models | ||
2 | |||
3 | import ( | ||
4 | "context" | ||
5 | |||
6 | "code.crute.us/mcrute/golib/db/mongodb" | ||
7 | ) | ||
8 | |||
9 | const userCol = "users" | ||
10 | |||
11 | type UserStore interface { | ||
12 | List(context.Context) ([]*User, error) | ||
13 | Get(context.Context, string) (*User, error) // Error on not found | ||
14 | Put(context.Context, *User) error | ||
15 | Delete(context.Context, *User) error | ||
16 | } | ||
17 | |||
18 | type AuthToken struct { | ||
19 | Kind string | ||
20 | Token string | ||
21 | RefreshToken string | ||
22 | } | ||
23 | |||
24 | type User struct { | ||
25 | Username string `bson:"_id"` | ||
26 | IsAdmin bool | ||
27 | IsService bool | ||
28 | Keys map[string]*SessionKey // kid -> key | ||
29 | AuthTokens map[string]*AuthToken // kind -> token | ||
30 | } | ||
31 | |||
32 | // GCKeys garbage collects keys that are no longer valid | ||
33 | func (u *User) GCKeys() { | ||
34 | for k, v := range u.Keys { | ||
35 | if v.IsGarbage() { | ||
36 | delete(u.Keys, k) | ||
37 | } | ||
38 | } | ||
39 | } | ||
40 | |||
41 | // GetKey returns a key for a key ID. It will only return valid keys. | ||
42 | func (u *User) GetKey(kid string) *SessionKey { | ||
43 | if u.Keys != nil { | ||
44 | if k := u.Keys[kid]; k != nil && k.IsValid() { | ||
45 | return k | ||
46 | } | ||
47 | } | ||
48 | return nil | ||
49 | } | ||
50 | |||
51 | func (u *User) AddKey(k *SessionKey) { | ||
52 | if u.Keys == nil { | ||
53 | u.Keys = map[string]*SessionKey{} | ||
54 | } | ||
55 | u.Keys[k.KeyId] = k | ||
56 | } | ||
57 | |||
58 | func (u *User) AddToken(t *AuthToken) { | ||
59 | if u.AuthTokens == nil { | ||
60 | u.AuthTokens = map[string]*AuthToken{} | ||
61 | } | ||
62 | u.AuthTokens[t.Kind] = t | ||
63 | } | ||
64 | |||
65 | type MongoDbUserStore struct { | ||
66 | Db *mongodb.Mongo | ||
67 | } | ||
68 | |||
69 | func (s *MongoDbUserStore) List(ctx context.Context) ([]*User, error) { | ||
70 | var out []*User | ||
71 | if err := s.Db.FindAll(ctx, userCol, &out); err != nil { | ||
72 | return nil, err | ||
73 | } | ||
74 | return out, nil | ||
75 | } | ||
76 | |||
77 | func (s *MongoDbUserStore) Get(ctx context.Context, username string) (*User, error) { | ||
78 | var u User | ||
79 | if err := s.Db.FindOneById(ctx, userCol, username, &u); err != nil { | ||
80 | return nil, err | ||
81 | } | ||
82 | return &u, nil | ||
83 | } | ||
84 | |||
85 | func (s *MongoDbUserStore) Put(ctx context.Context, u *User) error { | ||
86 | if err := s.Db.ReplaceOneById(ctx, userCol, u.Username, u); err != nil { | ||
87 | return err | ||
88 | } | ||
89 | return nil | ||
90 | } | ||
91 | |||
92 | func (s *MongoDbUserStore) Delete(ctx context.Context, u *User) error { | ||
93 | if err := s.Db.DeleteOneById(ctx, userCol, u.Username); err != nil { | ||
94 | return err | ||
95 | } | ||
96 | return nil | ||
97 | } | ||
98 | |||
99 | var _ UserStore = (*MongoDbUserStore)(nil) | ||