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

Commit 014bd43

Browse files
committed
feat: generate acceptable usernames
1 parent 428e344 commit 014bd43

File tree

2 files changed

+32
-15
lines changed

2 files changed

+32
-15
lines changed

infra/handler/app/Test.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,15 +267,16 @@ main' = withServer $ \port -> do
267267

268268
let someUserInfo = UserInfo
269269
{ userInfoFirebaseId = someFirebaseId
270-
, userInfoEmail = Just "patrick" }
271-
someUser = userInfoToUser someUserInfo
270+
, userInfoEmail = Just "patrick@foo.com" }
271+
Right someUser = userInfoToUser someUserInfo
272272

273273
runClientM (usersPost' b someUserInfo) clientEnv >>= \case
274274
Left err -> error $ "Expected user, got error: " <> show err
275275
Right (Item userId user) ->
276276
if user == someUser && userId == someUserId then pure () else (error $ "Expected same user, got: " <> show user)
277277

278278
runClientM (usersPost' b someUserInfo) clientEnv >>= \case
279+
-- TODO: test that user is returned here, even on 409
279280
Left (FailureResponse resp) ->
280281
if HTTP.statusCode (responseStatusCode resp) == 409 then pure () else
281282
error $ "Got unexpected response: " <> show resp

infra/handler/src/DeckGo/Handler.hs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
module DeckGo.Handler where
2121

2222
-- TODO: created_at, updated_at
23+
-- TODO: nullable slide content
2324
-- TODO: improve swagger description
2425
-- TODO: feed API
2526

@@ -45,9 +46,11 @@ import Servant (Context ((:.)))
4546
import Servant.API
4647
import Servant.Auth.Firebase (Protected)
4748
import UnliftIO
49+
import Data.Char
4850
import qualified Data.Aeson as Aeson
4951
import qualified Data.Aeson.Types as Aeson
5052
import qualified Data.ByteString.Char8 as BS8
53+
import qualified Data.ByteString.Lazy as BSL
5154
import qualified Data.HashMap.Strict as HMS
5255
import qualified Data.Text as T
5356
import qualified Data.Text.Encoding as T
@@ -187,9 +190,6 @@ instance ToJSONObject User where
187190
, "firebase_uid" .= userFirebaseId user
188191
]
189192

190-
instance Aeson.ToJSON User where
191-
toJSON = Aeson.Object . toJSONObject
192-
193193
instance Aeson.ToJSON UserInfo where
194194
toJSON = Aeson.Object . toJSONObject
195195

@@ -472,19 +472,32 @@ usersPost conn fuid uinfo = do
472472
liftIO $ putStrLn "got DB interface"
473473

474474
let userId = UserId (userInfoFirebaseId uinfo)
475-
user = userInfoToUser uinfo
475+
user <- case userInfoToUser uinfo of
476+
Left e -> Servant.throwError Servant.err400
477+
{ Servant.errBody = BSL.fromStrict $ T.encodeUtf8 e }
478+
Right user -> pure user
476479
liftIO (dbCreateUser iface userId user) >>= \case
477480
Left () -> Servant.throwError $ Servant.err409
481+
{ Servant.errBody = Aeson.encode (Item userId user) }
478482
Right () -> pure $ Item userId user
479483

480-
userInfoToUser :: UserInfo -> User
481-
userInfoToUser uinfo = User
482-
{ userFirebaseId = userInfoFirebaseId uinfo
483-
, userUsername = emailToUsername <$> userInfoEmail uinfo
484-
}
485-
486-
emailToUsername :: T.Text -> Username
487-
emailToUsername = Username
484+
userInfoToUser :: UserInfo -> Either T.Text User
485+
userInfoToUser uinfo = User <$>
486+
pure (userInfoFirebaseId uinfo) <*>
487+
(traverse emailToUsername (userInfoEmail uinfo))
488+
489+
emailToUsername :: T.Text -> Either T.Text Username
490+
emailToUsername t = case T.breakOn "@" t of
491+
("", _) -> Left ("Invalid email: " <> t)
492+
(out', _) -> case dropBadChars (T.toLower out') of
493+
"" -> Left ("No valid char found: " <> out')
494+
out -> Right $ Username out
495+
where
496+
dropBadChars :: T.Text -> T.Text
497+
dropBadChars = T.concatMap
498+
$ \case
499+
c | isAscii c && isAlphaNum c -> T.singleton c
500+
| otherwise -> ""
488501

489502
usersPostSession :: UserId -> User -> HS.Session (Either () ())
490503
usersPostSession uid u = do
@@ -580,7 +593,10 @@ usersPut conn fuid userId uinfo = do
580593
Servant.throwError Servant.err400
581594

582595
iface <- liftIO $ getDbInterface conn
583-
let user = userInfoToUser uinfo
596+
user <- case userInfoToUser uinfo of
597+
Left e -> Servant.throwError Servant.err400
598+
{ Servant.errBody = BSL.fromStrict $ T.encodeUtf8 e }
599+
Right user -> pure user
584600
liftIO (dbUpdateUser iface userId user) >>= \case
585601
UserUpdateOk -> pure $ Item userId user -- TODO: check # of affected rows
586602
e -> do -- TODO: handle not found et al.

0 commit comments

Comments
 (0)