aboutsummaryrefslogtreecommitdiff
path: root/app/models/account.go
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/account.go')
-rw-r--r--app/models/account.go115
1 files changed, 115 insertions, 0 deletions
diff --git a/app/models/account.go b/app/models/account.go
new file mode 100644
index 0000000..0ae1821
--- /dev/null
+++ b/app/models/account.go
@@ -0,0 +1,115 @@
1package models
2
3import (
4 "context"
5 "fmt"
6 "time"
7
8 "code.crute.us/mcrute/golib/db/mongodb"
9)
10
11const accountCol = "accounts"
12
13type AccountStore interface {
14 List(context.Context) ([]*Account, error)
15 ListForUser(context.Context, *User) ([]*Account, error)
16 Get(context.Context, string) (*Account, error) // Error on not found
17 GetForUser(context.Context, string, *User) (*Account, error) // Error on not found
18 Put(context.Context, *Account) error
19 Delete(context.Context, *Account) error
20}
21
22type Account struct {
23 ShortName string `bson:"_id"`
24 AccountType string
25 AccountNumber int
26 Name string
27 ConsoleSessionDuration time.Duration
28 VaultMaterial string
29 DefaultRegion string
30 Users []string
31}
32
33func (a *Account) ConsoleSessionDurationSecs() int64 {
34 return int64(a.ConsoleSessionDuration.Seconds())
35}
36
37func (a *Account) CanAccess(u *User) bool {
38 if u.IsAdmin {
39 return true
40 }
41 // Linear search should be fine for now, these lists are pretty small
42 for _, n := range a.Users {
43 if n == u.Username {
44 return true
45 }
46 }
47 return false
48}
49
50type MongoDbAccountStore struct {
51 Db *mongodb.Mongo
52}
53
54// List returns all accounts in the system.
55func (s *MongoDbAccountStore) List(ctx context.Context) ([]*Account, error) {
56 var out []*Account
57 if err := s.Db.FindAll(ctx, accountCol, &out); err != nil {
58 return nil, err
59 }
60 return out, nil
61}
62
63// ListForUser returns all accounts for which the user has access. This is the
64// authorized version of List.
65//
66// Note this does not handle the case where a user is an admin but not
67// explicitly listed in the allowed users list for an account. For that case
68// just use List directly.
69func (s *MongoDbAccountStore) ListForUser(ctx context.Context, u *User) ([]*Account, error) {
70 var out []*Account
71 filter := mongodb.AnyInTopLevelArray("Users", u.Username)
72 if err := s.Db.FindAllByFilter(ctx, accountCol, filter, &out); err != nil {
73 return nil, err
74 }
75 return out, nil
76}
77
78func (s *MongoDbAccountStore) Get(ctx context.Context, id string) (*Account, error) {
79 var a Account
80 if err := s.Db.FindOneById(ctx, accountCol, id, &a); err != nil {
81 return nil, err
82 }
83 return &a, nil
84}
85
86// GetForUser returns an account if the user has access to this account,
87// otherwise it returns an error. This is the authorized version of Get.
88func (s *MongoDbAccountStore) GetForUser(ctx context.Context, id string, u *User) (*Account, error) {
89 a, err := s.Get(ctx, id)
90 if err != nil {
91 return nil, err
92 }
93
94 if !a.CanAccess(u) {
95 return nil, fmt.Errorf("User does not have access to account")
96 }
97
98 return a, nil
99}
100
101func (s *MongoDbAccountStore) Put(ctx context.Context, a *Account) error {
102 if err := s.Db.ReplaceOneById(ctx, accountCol, a.ShortName, a); err != nil {
103 return err
104 }
105 return nil
106}
107
108func (s *MongoDbAccountStore) Delete(ctx context.Context, a *Account) error {
109 if err := s.Db.DeleteOneById(ctx, accountCol, a.ShortName); err != nil {
110 return err
111 }
112 return nil
113}
114
115var _ AccountStore = (*MongoDbAccountStore)(nil)