@@ -16,11 +16,13 @@ package admin
16
16
17
17
import (
18
18
"context"
19
+ "fmt"
19
20
"net/http"
20
21
21
22
"github.com/google/exposure-notifications-verification-server/pkg/controller"
22
23
"github.com/google/exposure-notifications-verification-server/pkg/database"
23
24
"github.com/gorilla/mux"
25
+ "github.com/jinzhu/gorm"
24
26
)
25
27
26
28
func (c * Controller ) HandleRealmsIndex () http.Handler {
@@ -199,3 +201,130 @@ func (c *Controller) renderEditRealm(ctx context.Context, w http.ResponseWriter,
199
201
m ["supportsPerRealmSigning" ] = c .db .SupportsPerRealmSigning ()
200
202
c .h .RenderHTML (w , "admin/realms/edit" , m )
201
203
}
204
+
205
+ func (c * Controller ) HandleRealmsJoin () http.Handler {
206
+ return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
207
+ ctx := r .Context ()
208
+ vars := mux .Vars (r )
209
+
210
+ session := controller .SessionFromContext (ctx )
211
+ if session == nil {
212
+ controller .MissingSession (w , r , c .h )
213
+ return
214
+ }
215
+ flash := controller .Flash (session )
216
+
217
+ user := controller .UserFromContext (ctx )
218
+ if user == nil {
219
+ controller .MissingUser (w , r , c .h )
220
+ return
221
+ }
222
+
223
+ realm , err := c .db .FindRealm (vars ["id" ])
224
+ if err != nil {
225
+ controller .InternalError (w , r , c .h , err )
226
+ return
227
+ }
228
+
229
+ user .Realms = append (user .Realms , realm )
230
+ user .AdminRealms = append (user .AdminRealms , realm )
231
+
232
+ // Do the membership update and audit entry in a transaction because we need
233
+ // both to succeed to continue.
234
+ if err := c .db .RawDB ().Transaction (func (tx * gorm.DB ) error {
235
+ // Save the user
236
+ if err := database .SaveUser (tx , user ); err != nil {
237
+ return fmt .Errorf ("failed to save user: %w" , err )
238
+ }
239
+
240
+ // Create the audit entry
241
+ audit := & database.AuditEntry {
242
+ UserID : user .ID ,
243
+ Action : "added user" ,
244
+ TargetType : "users" ,
245
+ TargetID : user .ID ,
246
+ SourceType : "realms" ,
247
+ SourceID : realm .ID ,
248
+ }
249
+ if err := database .SaveAuditEntry (tx , audit ); err != nil {
250
+ return fmt .Errorf ("failed to save audit: %w" , err )
251
+ }
252
+
253
+ return nil
254
+ }); err != nil {
255
+ flash .Error ("Failed to join %q: %v" , realm .Name , err )
256
+ controller .Back (w , r , c .h )
257
+ return
258
+ }
259
+
260
+ // Store the current realm on the session.
261
+ controller .StoreSessionRealm (session , realm )
262
+
263
+ flash .Alert ("Successfully joined %q" , realm .Name )
264
+ controller .Back (w , r , c .h )
265
+ })
266
+ }
267
+
268
+ func (c * Controller ) HandleRealmsLeave () http.Handler {
269
+ return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
270
+ ctx := r .Context ()
271
+ vars := mux .Vars (r )
272
+
273
+ session := controller .SessionFromContext (ctx )
274
+ if session == nil {
275
+ controller .MissingSession (w , r , c .h )
276
+ return
277
+ }
278
+ flash := controller .Flash (session )
279
+
280
+ user := controller .UserFromContext (ctx )
281
+ if user == nil {
282
+ controller .MissingUser (w , r , c .h )
283
+ return
284
+ }
285
+
286
+ realm , err := c .db .FindRealm (vars ["id" ])
287
+ if err != nil {
288
+ controller .InternalError (w , r , c .h , err )
289
+ return
290
+ }
291
+
292
+ user .RemoveRealm (realm )
293
+
294
+ // Do the membership update and audit entry in a transaction because we need
295
+ // both to succeed to continue.
296
+ if err := c .db .RawDB ().Transaction (func (tx * gorm.DB ) error {
297
+ // Save the user
298
+ if err := database .SaveUser (tx , user ); err != nil {
299
+ return fmt .Errorf ("failed to save user: %w" , err )
300
+ }
301
+
302
+ // Create the audit entry
303
+ audit := & database.AuditEntry {
304
+ UserID : user .ID ,
305
+ Action : "removed user" ,
306
+ TargetType : "users" ,
307
+ TargetID : user .ID ,
308
+ SourceType : "realms" ,
309
+ SourceID : realm .ID ,
310
+ }
311
+ if err := database .SaveAuditEntry (tx , audit ); err != nil {
312
+ return fmt .Errorf ("failed to save audit: %w" , err )
313
+ }
314
+
315
+ return nil
316
+ }); err != nil {
317
+ flash .Error ("Failed to leave %q: %v" , realm .Name , err )
318
+ controller .Back (w , r , c .h )
319
+ return
320
+ }
321
+
322
+ // If the currently-selected realm is the realm the admin just left, clear
323
+ // it.
324
+ if controller .RealmIDFromSession (session ) == realm .ID {
325
+ controller .ClearSessionRealm (session )
326
+ }
327
+ flash .Alert ("Successfully left %q" , realm .Name )
328
+ controller .Back (w , r , c .h )
329
+ })
330
+ }
0 commit comments