Skip to content
This repository was archived by the owner on Feb 6, 2024. It is now read-only.

Commit a039ce9

Browse files
committed
infra: Handle username conflict
1 parent e457d93 commit a039ce9

File tree

2 files changed

+27
-19
lines changed

2 files changed

+27
-19
lines changed

infra/handler/app/Test.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ testUsersGet = withPristineDB $ \conn -> do
206206
}
207207
dbCreateUser iface someUserId someUser >>= \case
208208
Left () -> error "Encountered error"
209-
Right () -> pure ()
209+
Right _ -> pure ()
210210

211211
dbGetAllUsers iface >>= \case
212212
[Item userId user] ->
@@ -226,7 +226,7 @@ testUsersGetByUserId = withPristineDB $ \conn -> do
226226
}
227227
dbCreateUser iface someUserId someUser >>= \case
228228
Left () -> error "Encountered error"
229-
Right () -> pure ()
229+
Right _ -> pure ()
230230

231231
dbGetUserById iface someUserId >>= \case
232232
Just (Item userId user) ->
@@ -246,7 +246,7 @@ testUsersDelete = withPristineDB $ \conn -> do
246246
}
247247
dbCreateUser iface someUserId someUser >>= \case
248248
Left () -> error "Encountered error"
249-
Right () -> pure ()
249+
Right _ -> pure ()
250250

251251
dbDeleteUser iface someUserId >>= \case
252252
Left () -> error "couldn't delete"
@@ -263,7 +263,7 @@ testUsersCreate = withPristineDB $ \conn -> do
263263
}
264264
dbCreateUser iface someUserId someUser >>= \case
265265
Left () -> error "Encountered error"
266-
Right () -> pure ()
266+
Right _ -> pure ()
267267

268268
testUsersUpdate :: IO ()
269269
testUsersUpdate = withPristineDB $ \conn -> do
@@ -277,7 +277,7 @@ testUsersUpdate = withPristineDB $ \conn -> do
277277

278278
dbCreateUser iface someUserId someUser >>= \case
279279
Left () -> error "Encountered error"
280-
Right () -> pure ()
280+
Right _ -> pure ()
281281

282282
let someUser' = User
283283
{ userFirebaseId = someFirebaseId

infra/handler/src/DeckGo/Handler.hs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -596,9 +596,10 @@ usersPost conn fuid uinfo = do
596596
{ Servant.errBody = BL.fromStrict $ T.encodeUtf8 e }
597597
Right user -> pure user
598598
liftIO (dbCreateUser iface userId user) >>= \case
599-
Left () -> Servant.throwError $ Servant.err409
600-
{ Servant.errBody = Aeson.encode (Item userId user) }
601-
Right () -> pure $ Item userId user
599+
Left () ->
600+
Servant.throwError $ Servant.err409
601+
{ Servant.errBody = Aeson.encode (Item userId user) }
602+
Right user' -> pure $ Item userId user'
602603

603604
userInfoToUser :: UserInfo -> Either T.Text User
604605
userInfoToUser uinfo = User <$>
@@ -618,7 +619,7 @@ emailToUsername t = case T.breakOn "@" t of
618619
c | isAscii c && isAlphaNum c -> T.singleton c
619620
| otherwise -> ""
620621

621-
usersPostSession :: UserId -> User -> HS.Session (Either () ())
622+
usersPostSession :: UserId -> User -> HS.Session (Either () User)
622623
usersPostSession uid u = do
623624
HS.sql "BEGIN"
624625
liftIO $ putStrLn "Creating user in DB"
@@ -628,19 +629,27 @@ usersPostSession uid u = do
628629
case userUsername u of
629630
Just uname -> do
630631
liftIO $ putStrLn "Creating username"
632+
let success unam = do
633+
liftIO $ putStrLn "User created successfully"
634+
HS.sql "COMMIT"
635+
pure $ Right $ u { userUsername = Just unam }
631636
HS.statement (uname, uid) usersPostStatement' >>= \case
632-
1 -> do
633-
liftIO $ putStrLn "User created successfully"
634-
HS.sql "COMMIT"
635-
pure $ Right ()
637+
1 -> success uname
636638
_ -> do
637639
liftIO $ putStrLn "Couldn't create username"
638-
HS.sql "ROLLBACK"
639-
pure $ Left ()
640+
rand <- liftIO $ randomText 4 ['0' .. '9' ]
641+
let uname' = Username $ unUsername uname <> rand
642+
liftIO $ putStrLn $ "Retrying with username " <> (T.unpack $ unUsername uname')
643+
HS.statement (uname', uid) usersPostStatement' >>= \case
644+
1 -> success uname'
645+
_ -> do
646+
liftIO $ putStrLn "Couldn't create username again"
647+
HS.sql "ROLLBACK"
648+
pure $ Left ()
640649
Nothing -> do
641650
liftIO $ putStrLn "No username"
642651
HS.sql "COMMIT"
643-
pure $ Right ()
652+
pure $ Right u
644653
_ -> do
645654
liftIO $ putStrLn "Couldn't create exactly one user"
646655
HS.sql "ROLLBACK"
@@ -662,12 +671,11 @@ usersPostStatement = Statement sql encoder decoder True
662671
contramap (unFirebaseId . userFirebaseId . view _2) (HE.param HE.text)
663672
decoder = HD.rowsAffected
664673

665-
-- TODO: deal with conflict error
666674
usersPostStatement' :: Statement (Username, UserId) Int64
667675
usersPostStatement' = Statement sql encoder decoder True
668676
where
669677
sql = BS8.unwords
670-
[ "UPDATE account SET username = $1 WHERE id = $2" ]
678+
[ "UPDATE account SET username = $1 WHERE id = $2 AND NOT EXISTS (SELECT 1 FROM account WHERE username = $1)" ]
671679
encoder =
672680
contramap
673681
(unUsername . view _1)
@@ -835,7 +843,7 @@ instance Aeson.FromJSON PresResponse where
835843
data DbInterface = DbInterface
836844
{ dbGetAllUsers :: IO [Item UserId User]
837845
, dbGetUserById :: UserId -> IO (Maybe (Item UserId User))
838-
, dbCreateUser :: UserId -> User -> IO (Either () ())
846+
, dbCreateUser :: UserId -> User -> IO (Either () User)
839847
, dbUpdateUser :: UserId -> User -> IO UserUpdateResult
840848
, dbDeleteUser :: UserId -> IO (Either () ())
841849

0 commit comments

Comments
 (0)