1
1
{-# LANGUAGE DeriveDataTypeable, TypeFamilies, TemplateHaskell, RankNTypes,
2
- NamedFieldPuns, RecordWildCards, RecursiveDo, BangPatterns #-}
2
+ NamedFieldPuns, RecordWildCards, RecursiveDo, BangPatterns, OverloadedStrings #-}
3
3
module Distribution.Server.Features.UserDetails (
4
4
initUserDetailsFeature ,
5
5
UserDetailsFeature (.. ),
@@ -11,11 +11,14 @@ module Distribution.Server.Features.UserDetails (
11
11
import Distribution.Server.Framework
12
12
import Distribution.Server.Framework.BackupDump
13
13
import Distribution.Server.Framework.BackupRestore
14
+ import Distribution.Server.Framework.Templating
14
15
15
16
import Distribution.Server.Features.Users
17
+ import Distribution.Server.Features.Upload
16
18
import Distribution.Server.Features.Core
17
19
18
20
import Distribution.Server.Users.Types
21
+ import Distribution.Server.Util.Validators (guardValidLookingEmail , guardValidLookingName )
19
22
20
23
import Data.SafeCopy (base , deriveSafeCopy )
21
24
@@ -250,23 +253,31 @@ userDetailsToCSV backuptype (UserDetailsTable tbl)
250
253
initUserDetailsFeature :: ServerEnv
251
254
-> IO (UserFeature
252
255
-> CoreFeature
256
+ -> UploadFeature
253
257
-> IO UserDetailsFeature )
254
- initUserDetailsFeature ServerEnv {serverStateDir} = do
258
+ initUserDetailsFeature ServerEnv {serverStateDir, serverTemplatesDir, serverTemplatesMode } = do
255
259
-- Canonical state
256
260
usersDetailsState <- userDetailsStateComponent serverStateDir
257
261
258
262
-- TODO: link up to user feature to delete
259
263
260
- return $ \ users core -> do
261
- let feature = userDetailsFeature usersDetailsState users core
264
+ templates <-
265
+ loadTemplates serverTemplatesMode
266
+ [serverTemplatesDir, serverTemplatesDir </> " UserDetails" ]
267
+ [ " user-details-form.html" ]
268
+
269
+ return $ \ users core upload -> do
270
+ let feature = userDetailsFeature templates usersDetailsState users core upload
262
271
return feature
263
272
264
273
265
- userDetailsFeature :: StateComponent AcidState UserDetailsTable
274
+ userDetailsFeature :: Templates
275
+ -> StateComponent AcidState UserDetailsTable
266
276
-> UserFeature
267
277
-> CoreFeature
278
+ -> UploadFeature
268
279
-> UserDetailsFeature
269
- userDetailsFeature userDetailsState UserFeature {.. } CoreFeature {.. }
280
+ userDetailsFeature templates userDetailsState UserFeature {.. } CoreFeature {.. } UploadFeature {uploadersGroup }
270
281
= UserDetailsFeature {.. }
271
282
272
283
where
@@ -286,7 +297,9 @@ userDetailsFeature userDetailsState UserFeature{..} CoreFeature{..}
286
297
, (PUT , " set the name and contact details of a user account" )
287
298
, (DELETE , " delete the name and contact details of a user account" )
288
299
]
289
- , resourceGet = [ (" json" , handlerGetUserNameContact) ]
300
+ , resourceGet = [ (" json" , handlerGetUserNameContact)
301
+ , (" html" , handlerGetUserNameContactHtml)
302
+ ]
290
303
, resourcePut = [ (" json" , handlerPutUserNameContact) ]
291
304
, resourceDelete = [ (" " , handlerDeleteUserNameContact) ]
292
305
}
@@ -314,6 +327,30 @@ userDetailsFeature userDetailsState UserFeature{..} CoreFeature{..}
314
327
315
328
-- Request handlers
316
329
--
330
+ handlerGetUserNameContactHtml :: DynamicPath -> ServerPartE Response
331
+ handlerGetUserNameContactHtml dpath = do
332
+ (uid, uinfo) <- lookupUserNameFull =<< userNameInPath dpath
333
+ template <- getTemplate templates " user-details-form.html"
334
+ udetails <- queryUserDetails uid
335
+ showConfirmationOfSave <- not . null <$> queryString (lookBSs " showConfirmationOfSave" )
336
+ let
337
+ emailTxt = maybe " " accountContactEmail udetails
338
+ nameTxt = maybe " " accountName udetails
339
+ cacheControl
340
+ [Private ]
341
+ (etagFromHash
342
+ ( emailTxt
343
+ , nameTxt
344
+ , showConfirmationOfSave
345
+ )
346
+ )
347
+ ok . toResponse $
348
+ template
349
+ [ " username" $= display (userName uinfo)
350
+ , " contactEmailAddress" $= emailTxt
351
+ , " name" $= nameTxt
352
+ , " showConfirmationOfSave" $= showConfirmationOfSave
353
+ ]
317
354
318
355
handlerGetUserNameContact :: DynamicPath -> ServerPartE Response
319
356
handlerGetUserNameContact dpath = do
@@ -333,7 +370,10 @@ userDetailsFeature userDetailsState UserFeature{..} CoreFeature{..}
333
370
handlerPutUserNameContact dpath = do
334
371
uid <- lookupUserName =<< userNameInPath dpath
335
372
guardAuthorised_ [IsUserId uid, InGroup adminGroup]
373
+ void $ guardAuthorisedWhenInAnyGroup [uploadersGroup, adminGroup]
336
374
NameAndContact name email <- expectAesonContent
375
+ guardValidLookingName name
376
+ guardValidLookingEmail email
337
377
updateState userDetailsState (SetUserNameContact uid name email)
338
378
noContent $ toResponse ()
339
379
0 commit comments