@@ -26,6 +26,7 @@ func (d *Backend) User(ctx context.Context, username string) (proto.User, error)
26
26
var m models.User
27
27
var pks []ssh.PublicKey
28
28
var hl models.Handle
29
+ var ems []proto.UserEmail
29
30
if err := d .db .TransactionContext (ctx , func (tx * db.Tx ) error {
30
31
var err error
31
32
m , err = d .store .FindUserByUsername (ctx , tx , username )
@@ -38,6 +39,15 @@ func (d *Backend) User(ctx context.Context, username string) (proto.User, error)
38
39
return err
39
40
}
40
41
42
+ emails , err := d .store .ListUserEmails (ctx , tx , m .ID )
43
+ if err != nil {
44
+ return err
45
+ }
46
+
47
+ for _ , e := range emails {
48
+ ems = append (ems , & userEmail {e })
49
+ }
50
+
41
51
hl , err = d .store .GetHandleByUserID (ctx , tx , m .ID )
42
52
return err
43
53
}); err != nil {
@@ -53,6 +63,7 @@ func (d *Backend) User(ctx context.Context, username string) (proto.User, error)
53
63
user : m ,
54
64
publicKeys : pks ,
55
65
handle : hl ,
66
+ emails : ems ,
56
67
}, nil
57
68
}
58
69
@@ -61,6 +72,7 @@ func (d *Backend) UserByID(ctx context.Context, id int64) (proto.User, error) {
61
72
var m models.User
62
73
var pks []ssh.PublicKey
63
74
var hl models.Handle
75
+ var ems []proto.UserEmail
64
76
if err := d .db .TransactionContext (ctx , func (tx * db.Tx ) error {
65
77
var err error
66
78
m , err = d .store .GetUserByID (ctx , tx , id )
@@ -73,6 +85,15 @@ func (d *Backend) UserByID(ctx context.Context, id int64) (proto.User, error) {
73
85
return err
74
86
}
75
87
88
+ emails , err := d .store .ListUserEmails (ctx , tx , m .ID )
89
+ if err != nil {
90
+ return err
91
+ }
92
+
93
+ for _ , e := range emails {
94
+ ems = append (ems , & userEmail {e })
95
+ }
96
+
76
97
hl , err = d .store .GetHandleByUserID (ctx , tx , m .ID )
77
98
return err
78
99
}); err != nil {
@@ -88,6 +109,7 @@ func (d *Backend) UserByID(ctx context.Context, id int64) (proto.User, error) {
88
109
user : m ,
89
110
publicKeys : pks ,
90
111
handle : hl ,
112
+ emails : ems ,
91
113
}, nil
92
114
}
93
115
@@ -98,6 +120,7 @@ func (d *Backend) UserByPublicKey(ctx context.Context, pk ssh.PublicKey) (proto.
98
120
var m models.User
99
121
var pks []ssh.PublicKey
100
122
var hl models.Handle
123
+ var ems []proto.UserEmail
101
124
if err := d .db .TransactionContext (ctx , func (tx * db.Tx ) error {
102
125
var err error
103
126
m , err = d .store .FindUserByPublicKey (ctx , tx , pk )
@@ -110,6 +133,15 @@ func (d *Backend) UserByPublicKey(ctx context.Context, pk ssh.PublicKey) (proto.
110
133
return err
111
134
}
112
135
136
+ emails , err := d .store .ListUserEmails (ctx , tx , m .ID )
137
+ if err != nil {
138
+ return err
139
+ }
140
+
141
+ for _ , e := range emails {
142
+ ems = append (ems , & userEmail {e })
143
+ }
144
+
113
145
hl , err = d .store .GetHandleByUserID (ctx , tx , m .ID )
114
146
return err
115
147
}); err != nil {
@@ -125,6 +157,7 @@ func (d *Backend) UserByPublicKey(ctx context.Context, pk ssh.PublicKey) (proto.
125
157
user : m ,
126
158
publicKeys : pks ,
127
159
handle : hl ,
160
+ emails : ems ,
128
161
}, nil
129
162
}
130
163
@@ -134,6 +167,7 @@ func (d *Backend) UserByAccessToken(ctx context.Context, token string) (proto.Us
134
167
var m models.User
135
168
var pks []ssh.PublicKey
136
169
var hl models.Handle
170
+ var ems []proto.UserEmail
137
171
token = HashToken (token )
138
172
139
173
if err := d .db .TransactionContext (ctx , func (tx * db.Tx ) error {
@@ -156,6 +190,15 @@ func (d *Backend) UserByAccessToken(ctx context.Context, token string) (proto.Us
156
190
return err
157
191
}
158
192
193
+ emails , err := d .store .ListUserEmails (ctx , tx , m .ID )
194
+ if err != nil {
195
+ return err
196
+ }
197
+
198
+ for _ , e := range emails {
199
+ ems = append (ems , & userEmail {e })
200
+ }
201
+
159
202
hl , err = d .store .GetHandleByUserID (ctx , tx , m .ID )
160
203
return err
161
204
}); err != nil {
@@ -171,6 +214,7 @@ func (d *Backend) UserByAccessToken(ctx context.Context, token string) (proto.Us
171
214
user : m ,
172
215
publicKeys : pks ,
173
216
handle : hl ,
217
+ emails : ems ,
174
218
}, nil
175
219
}
176
220
@@ -228,7 +272,7 @@ func (d *Backend) AddPublicKey(ctx context.Context, username string, pk ssh.Publ
228
272
// It implements backend.Backend.
229
273
func (d * Backend ) CreateUser (ctx context.Context , username string , opts proto.UserOptions ) (proto.User , error ) {
230
274
if err := d .db .TransactionContext (ctx , func (tx * db.Tx ) error {
231
- return d .store .CreateUser (ctx , tx , username , opts .Admin , opts .PublicKeys )
275
+ return d .store .CreateUser (ctx , tx , username , opts .Admin , opts .PublicKeys , opts . Emails )
232
276
}); err != nil {
233
277
return nil , db .WrapError (err )
234
278
}
@@ -335,10 +379,60 @@ func (d *Backend) SetPassword(ctx context.Context, username string, rawPassword
335
379
)
336
380
}
337
381
382
+ // AddUserEmail adds an email to a user.
383
+ func (d * Backend ) AddUserEmail (ctx context.Context , user proto.User , email string ) error {
384
+ return db .WrapError (
385
+ d .db .TransactionContext (ctx , func (tx * db.Tx ) error {
386
+ return d .store .AddUserEmail (ctx , tx , user .ID (), email , false )
387
+ }),
388
+ )
389
+ }
390
+
391
+ // ListUserEmails lists the emails of a user.
392
+ func (d * Backend ) ListUserEmails (ctx context.Context , user proto.User ) ([]proto.UserEmail , error ) {
393
+ var ems []proto.UserEmail
394
+ if err := d .db .TransactionContext (ctx , func (tx * db.Tx ) error {
395
+ emails , err := d .store .ListUserEmails (ctx , tx , user .ID ())
396
+ if err != nil {
397
+ return err
398
+ }
399
+
400
+ for _ , e := range emails {
401
+ ems = append (ems , & userEmail {e })
402
+ }
403
+
404
+ return nil
405
+ }); err != nil {
406
+ return nil , db .WrapError (err )
407
+ }
408
+
409
+ return ems , nil
410
+ }
411
+
412
+ // RemoveUserEmail deletes an email for a user.
413
+ // The deleted email must not be the primary email.
414
+ func (d * Backend ) RemoveUserEmail (ctx context.Context , user proto.User , email string ) error {
415
+ return db .WrapError (
416
+ d .db .TransactionContext (ctx , func (tx * db.Tx ) error {
417
+ return d .store .RemoveUserEmail (ctx , tx , user .ID (), email )
418
+ }),
419
+ )
420
+ }
421
+
422
+ // SetUserPrimaryEmail sets the primary email of a user.
423
+ func (d * Backend ) SetUserPrimaryEmail (ctx context.Context , user proto.User , email string ) error {
424
+ return db .WrapError (
425
+ d .db .TransactionContext (ctx , func (tx * db.Tx ) error {
426
+ return d .store .SetUserPrimaryEmail (ctx , tx , user .ID (), email )
427
+ }),
428
+ )
429
+ }
430
+
338
431
type user struct {
339
432
user models.User
340
433
publicKeys []ssh.PublicKey
341
434
handle models.Handle
435
+ emails []proto.UserEmail
342
436
}
343
437
344
438
var _ proto.User = (* user )(nil )
@@ -371,3 +465,29 @@ func (u *user) Password() string {
371
465
372
466
return ""
373
467
}
468
+
469
+ // Emails implements proto.User.
470
+ func (u * user ) Emails () []proto.UserEmail {
471
+ return u .emails
472
+ }
473
+
474
+ type userEmail struct {
475
+ email models.UserEmail
476
+ }
477
+
478
+ var _ proto.UserEmail = (* userEmail )(nil )
479
+
480
+ // Email implements proto.UserEmail.
481
+ func (e * userEmail ) Email () string {
482
+ return e .email .Email
483
+ }
484
+
485
+ // ID implements proto.UserEmail.
486
+ func (e * userEmail ) ID () int64 {
487
+ return e .email .ID
488
+ }
489
+
490
+ // IsPrimary implements proto.UserEmail.
491
+ func (e * userEmail ) IsPrimary () bool {
492
+ return e .email .IsPrimary
493
+ }
0 commit comments