1717module DeckGo.Handler where
1818
1919-- TODO: double check what is returned on 200 from DynamoDB
20- -- TODO: check user is in DB
2120-- TODO: check permissions
2221-- TODO: created_at, updated_at
2322-- TODO: TTL on anonymous users
23+ -- TODO: enforce uniqueness on deck_name (per user)
24+ -- TODO: improve swagger description
2425
2526import Control.Lens hiding ((.=) )
2627import Control.Monad
@@ -90,11 +91,11 @@ newtype Username = Username { unUsername :: T.Text }
9091 deriving newtype (Aeson.FromJSON , Aeson.ToJSON )
9192
9293data User = User
93- { userFirebaseId :: FirebaseId -- TODO: enforce uniqueness
94+ { userFirebaseId :: FirebaseId
9495 , userAnonymous :: Bool
9596 } deriving (Show , Eq )
9697
97- newtype UserId = UserId { unUserId :: T. Text }
98+ newtype UserId = UserId { unUserId :: FirebaseId }
9899 deriving newtype
99100 ( Aeson. FromJSON
100101 , Aeson. ToJSON
@@ -171,7 +172,7 @@ newtype Deckname = Deckname { unDeckname :: T.Text }
171172
172173data Deck = Deck
173174 { deckSlides :: [SlideId ]
174- , deckDeckname :: Deckname -- TODO: enforce uniqueness
175+ , deckDeckname :: Deckname
175176 , deckOwnerId :: UserId
176177 } deriving (Show , Eq )
177178
@@ -323,7 +324,7 @@ usersGet env = do
323324usersGetUserId :: Aws. Env -> UserId -> Servant. Handler (Item UserId User )
324325usersGetUserId env userId = do
325326 res <- runAWS env $ Aws. send $ DynamoDB. getItem " Users" &
326- DynamoDB. giKey .~ HMS. singleton " UserId " (userIdToAttributeValue userId)
327+ DynamoDB. giKey .~ HMS. singleton " UserFirebaseId " (userIdToAttributeValue userId)
327328 case res of
328329 Right getItemResponse -> do
329330 case getItemResponse ^. DynamoDB. girsResponseStatus of
@@ -347,18 +348,26 @@ usersGetUserId env userId = do
347348 Servant. throwError Servant. err500
348349
349350usersPost :: Aws. Env -> Firebase. UserId -> User -> Servant. Handler (Item UserId User )
350- usersPost env _uid user = do
351+ usersPost env fuid user = do
351352
352- userId <- liftIO $ UserId <$> newId
353+ let userId = UserId (userFirebaseId user)
354+
355+ when (Firebase. unUserId fuid /= unFirebaseId (userFirebaseId user)) $ do
356+ Servant. throwError Servant. err403
353357
354358 res <- runAWS env $ Aws. send $ DynamoDB. putItem " Users" &
355- DynamoDB. piItem .~ userToItem userId user
359+ DynamoDB. piItem .~ userToItem userId user &
360+ DynamoDB. piConditionExpression .~ Just " attribute_not_exists(UserFirebaseId)"
356361
357362 case res of
358363 Right {} -> pure ()
359- Left e -> do
360- liftIO $ print e
361- Servant. throwError Servant. err500
364+ Left e -> case e ^? DynamoDB. _ConditionalCheckFailedException of
365+ Just _e -> do
366+ u <- usersGetUserId env userId
367+ Servant. throwError Servant. err409 { Servant. errBody = Aeson. encode u }
368+ Nothing -> do
369+ liftIO $ print e
370+ Servant. throwError Servant. err500
362371
363372 pure $ Item userId user
364373
@@ -367,7 +376,7 @@ usersPut env _ userId user = do
367376
368377 res <- runAWS env $ Aws. send $ DynamoDB. updateItem " Users" &
369378 DynamoDB. uiUpdateExpression .~
370- Just " SET UserDecks = :s, UserUsername = :n, UserFirebaseId = :i " &
379+ Just " SET UserDecks = :s, UserUsername = :n" &
371380 DynamoDB. uiExpressionAttributeValues .~ userToItem' user &
372381 DynamoDB. uiReturnValues .~ Just DynamoDB. UpdatedNew &
373382 DynamoDB. uiKey .~ HMS. singleton " UserId"
@@ -385,7 +394,7 @@ usersDelete :: Aws.Env -> Firebase.UserId -> UserId -> Servant.Handler ()
385394usersDelete env _ userId = do
386395
387396 res <- runAWS env $ Aws. send $ DynamoDB. deleteItem " Users" &
388- DynamoDB. diKey .~ HMS. singleton " UserId "
397+ DynamoDB. diKey .~ HMS. singleton " UserFirebaseId "
389398 (userIdToAttributeValue userId)
390399
391400 case res of
@@ -588,31 +597,29 @@ slidesDelete env slideId = do
588597-- USERS
589598
590599userToItem :: UserId -> User -> HMS. HashMap T. Text DynamoDB. AttributeValue
591- userToItem userId User {userFirebaseId, userAnonymous} =
592- HMS. singleton " UserId" (userIdToAttributeValue userId) <>
593- HMS. singleton " UserFirebaseId" (userFirebaseIdToAttributeValue userFirebaseId) <>
600+ userToItem userId User {userAnonymous} =
601+ HMS. singleton " UserFirebaseId" (userIdToAttributeValue userId) <>
594602 HMS. singleton " UserAnonymous" (userAnonymousToAttributeValue userAnonymous)
595603
596604userToItem' :: User -> HMS. HashMap T. Text DynamoDB. AttributeValue
597- userToItem' User {userFirebaseId, userAnonymous} =
598- HMS. singleton " :i" (userFirebaseIdToAttributeValue userFirebaseId) <>
605+ userToItem' User {userAnonymous} =
599606 HMS. singleton " :a" (userAnonymousToAttributeValue userAnonymous)
600607
601608itemToUser :: HMS. HashMap T. Text DynamoDB. AttributeValue -> Maybe (Item UserId User )
602609itemToUser item = do
603- userId <- HMS. lookup " UserId " item >>= userIdFromAttributeValue
604- userFirebaseId <- HMS. lookup " UserFirebaseId " item >>= userFirebaseIdFromAttributeValue
610+ userId <- HMS. lookup " UserFirebaseId " item >>= userIdFromAttributeValue
611+ let userFirebaseId = unUserId userId
605612 userAnonymous <- HMS. lookup " UserAnonymous" item >>= userAnonymousFromAttributeValue
606613 pure $ Item userId User {.. }
607614
608615-- USER ATTRIBUTES
609616
610617userIdToAttributeValue :: UserId -> DynamoDB. AttributeValue
611- userIdToAttributeValue (UserId userId) =
618+ userIdToAttributeValue (UserId ( FirebaseId userId) ) =
612619 DynamoDB. attributeValue & DynamoDB. avS .~ Just userId
613620
614621userIdFromAttributeValue :: DynamoDB. AttributeValue -> Maybe UserId
615- userIdFromAttributeValue attr = UserId <$> attr ^. DynamoDB. avS
622+ userIdFromAttributeValue attr = ( UserId . FirebaseId ) <$> attr ^. DynamoDB. avS
616623
617624userNameToAttributeValue :: Username -> DynamoDB. AttributeValue
618625userNameToAttributeValue (Username username) =
@@ -693,11 +700,11 @@ deckSlidesFromAttributeValue attr =
693700 traverse slideIdFromAttributeValue (attr ^. DynamoDB. avL)
694701
695702deckOwnerIdToAttributeValue :: UserId -> DynamoDB. AttributeValue
696- deckOwnerIdToAttributeValue (UserId deckOwnerId) =
703+ deckOwnerIdToAttributeValue (UserId ( FirebaseId deckOwnerId) ) =
697704 DynamoDB. attributeValue & DynamoDB. avS .~ Just deckOwnerId
698705
699706deckOwnerIdFromAttributeValue :: DynamoDB. AttributeValue -> Maybe UserId
700- deckOwnerIdFromAttributeValue attr = UserId <$> attr ^. DynamoDB. avS
707+ deckOwnerIdFromAttributeValue attr = ( UserId . FirebaseId ) <$> attr ^. DynamoDB. avS
701708
702709-- SLIDES
703710
0 commit comments