@@ -382,7 +382,17 @@ usersPost env fuid user = do
382382 pure $ Item userId user
383383
384384usersPut :: Aws. Env -> Firebase. UserId -> UserId -> User -> Servant. Handler (Item UserId User )
385- usersPut env _ userId user = do
385+ usersPut env fuid userId user = do
386+
387+ when (Firebase. unUserId fuid /= unFirebaseId (unUserId userId)) $ do
388+ liftIO $ putStrLn $ unwords
389+ [ " User is trying to update another user:" , show (fuid, userId, user) ]
390+ Servant. throwError Servant. err404
391+
392+ when (Firebase. unUserId fuid /= unFirebaseId (userFirebaseId user)) $ do
393+ liftIO $ putStrLn $ unwords
394+ [ " Client used the wrong user ID on user" , show (fuid, userId, user) ]
395+ Servant. throwError Servant. err400
386396
387397 res <- runAWS env $ Aws. send $ DynamoDB. updateItem " Users" &
388398 DynamoDB. uiUpdateExpression .~
@@ -401,7 +411,10 @@ usersPut env _ userId user = do
401411 pure $ Item userId user
402412
403413usersDelete :: Aws. Env -> Firebase. UserId -> UserId -> Servant. Handler ()
404- usersDelete env _ userId = do
414+ usersDelete env fuid userId = do
415+
416+ when (Firebase. unUserId fuid /= unFirebaseId (unUserId userId)) $ do
417+ Servant. throwError Servant. err403
405418
406419 res <- runAWS env $ Aws. send $ DynamoDB. deleteItem " Users" &
407420 DynamoDB. diKey .~ HMS. singleton " UserFirebaseId"
@@ -416,15 +429,24 @@ usersDelete env _ userId = do
416429-- DECKS
417430
418431decksGet :: Aws. Env -> Firebase. UserId -> Maybe UserId -> Servant. Handler [Item DeckId Deck ]
419- decksGet env _uid mUserId = do
432+ decksGet env fuid mUserId = do
433+
434+ userId <- case mUserId of
435+ Nothing -> do
436+ liftIO $ putStrLn $ unwords
437+ [ " No user specified when GETting decks:" , show fuid ]
438+ Servant. throwError Servant. err400
439+ Just userId -> pure userId
440+
441+ when (Firebase. unUserId fuid /= unFirebaseId (unUserId userId)) $ do
442+ liftIO $ putStrLn $ unwords
443+ [ " Client asking for decks as another user" , show (fuid, userId) ]
444+ Servant. throwError Servant. err403
420445
421- let updateReq = case mUserId of
422- Nothing -> id
423- Just userId -> \ req -> req &
446+ res <- runAWS env $ Aws. send $ DynamoDB. scan " Decks" &
424447 DynamoDB. sFilterExpression .~ Just " DeckOwnerId = :o" &
425448 DynamoDB. sExpressionAttributeValues .~ HMS. singleton " :o" (userIdToAttributeValue userId)
426449
427- res <- runAWS env $ Aws. send $ updateReq $ DynamoDB. scan " Decks"
428450 case res of
429451 Right scanResponse ->
430452 case sequence $ scanResponse ^. DynamoDB. srsItems <&> itemToDeck of
@@ -437,10 +459,12 @@ decksGet env _uid mUserId = do
437459 Servant. throwError Servant. err500
438460
439461decksGetDeckId :: Aws. Env -> Firebase. UserId -> DeckId -> Servant. Handler (Item DeckId Deck )
440- decksGetDeckId env _ deckId = do
462+ decksGetDeckId env fuid deckId = do
463+
441464 res <- runAWS env $ Aws. send $ DynamoDB. getItem " Decks" &
442465 DynamoDB. giKey .~ HMS. singleton " DeckId" (deckIdToAttributeValue deckId)
443- case res of
466+
467+ deck@ Item {itemContent} <- case res of
444468 Right getItemResponse -> do
445469 case getItemResponse ^. DynamoDB. girsResponseStatus of
446470 200 -> pure ()
@@ -462,8 +486,24 @@ decksGetDeckId env _ deckId = do
462486 liftIO $ print e
463487 Servant. throwError Servant. err500
464488
489+ let ownerId = deckOwnerId itemContent
490+
491+ when (Firebase. unUserId fuid /= unFirebaseId (unUserId ownerId)) $ do
492+ liftIO $ putStrLn $ unwords $
493+ [ " Deck was found" , show deck, " but requester is not the owner" , show fuid ]
494+ Servant. throwError Servant. err404
495+
496+ pure deck
497+
465498decksPost :: Aws. Env -> Firebase. UserId -> Deck -> Servant. Handler (Item DeckId Deck )
466- decksPost env _ deck = do
499+ decksPost env fuid deck = do
500+
501+ let ownerId = deckOwnerId deck
502+
503+ when (Firebase. unUserId fuid /= unFirebaseId (unUserId ownerId)) $ do
504+ liftIO $ putStrLn $ unwords $
505+ [ " Deck was POSTed" , show deck, " but requester is not the owner" , show fuid ]
506+ Servant. throwError Servant. err400
467507
468508 deckId <- liftIO $ DeckId <$> newId
469509
@@ -479,7 +519,18 @@ decksPost env _ deck = do
479519 pure $ Item deckId deck
480520
481521decksPut :: Aws. Env -> Firebase. UserId -> DeckId -> Deck -> Servant. Handler (Item DeckId Deck )
482- decksPut env _ deckId deck = do
522+ decksPut env fuid deckId deck = do
523+
524+ getDeck env deckId >>= \ case
525+ Nothing -> do
526+ liftIO $ putStrLn $ unwords
527+ [ " Trying to PUT" , show deckId, " but deck doesn't exist." ]
528+ Servant. throwError Servant. err404
529+ Just Deck {deckOwnerId} -> do
530+ when (Firebase. unUserId fuid /= unFirebaseId (unUserId deckOwnerId)) $ do
531+ liftIO $ putStrLn $ unwords $
532+ [ " Deck was PUTed" , show deck, " but requester is not the owner" , show fuid ]
533+ Servant. throwError Servant. err404
483534
484535 res <- runAWS env $ Aws. send $ DynamoDB. updateItem " Decks" &
485536 DynamoDB. uiUpdateExpression .~ Just " SET DeckSlides = :s, DeckName = :n, DeckOwnerId = :o, DeckAttributes = :a" &
@@ -509,6 +560,44 @@ decksDelete env _ deckId = do
509560 liftIO $ print e
510561 Servant. throwError Servant. err500
511562
563+ -- | Reads a Deck from the database.
564+ --
565+ -- If the deck is not found, returns Nothing
566+ -- If the deck can't be parsed, throws a 500.
567+ -- If the response status is not 200, throws a 500.
568+ getDeck :: Aws. Env -> DeckId -> Servant. Handler (Maybe Deck )
569+ getDeck env deckId = do
570+
571+ res <- runAWS env $ Aws. send $ DynamoDB. getItem " Decks" &
572+ DynamoDB. giKey .~ HMS. singleton " DeckId" (deckIdToAttributeValue deckId)
573+
574+ mItem <- case res of
575+ Right r -> do
576+ case
577+ ( r ^. DynamoDB. girsResponseStatus
578+ , itemToDeck (r ^. DynamoDB. girsItem )) of
579+ (200 , Just deck) -> pure $ Just deck
580+ (200 , Nothing ) -> do
581+ liftIO $ putStrLn $ " Could not parse response: " <> show r
582+ Servant. throwError Servant. err500
583+ (404 , _) -> pure Nothing
584+ s -> do
585+ liftIO $
586+ putStrLn $ " Unkown response status: " <> show s <>
587+ " in response " <> show r
588+ Servant. throwError Servant. err500
589+ Left e -> do
590+ liftIO $ print e
591+ Servant. throwError Servant. err500
592+
593+ case mItem of
594+ Just Item {itemId = deckId', itemContent = deck} -> do
595+ when (deckId' /= deckId) $ do
596+ liftIO $ putStrLn $ " Mismatched deck IDs " <> show (deckId, deckId')
597+ Servant. throwError Servant. err500
598+ pure $ Just deck
599+ Nothing -> pure Nothing
600+
512601-- SLIDES
513602
514603slidesGet :: Aws. Env -> Firebase. UserId -> Servant. Handler [Item SlideId Slide ]
0 commit comments