Skip to content

Commit 856a143

Browse files
committed
Do a bunch of error handling
1 parent 18e58f5 commit 856a143

File tree

2 files changed

+40
-15
lines changed

2 files changed

+40
-15
lines changed

share-api/src/Share/Web/Authentication.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
module Share.Web.Authentication
77
( cookieSessionTTL,
88
requireAuthenticatedUser,
9+
requireAuthenticatedUser',
910
UnauthenticatedError (..),
1011
pattern MaybeAuthedUserID,
1112
pattern AuthenticatedUser,
@@ -39,3 +40,7 @@ instance ToServerError UnauthenticatedError where
3940
requireAuthenticatedUser :: Maybe Session -> WebApp UserId
4041
requireAuthenticatedUser (AuthenticatedUser uid) = pure uid
4142
requireAuthenticatedUser _ = Errors.respondError UnauthenticatedError
43+
44+
requireAuthenticatedUser' :: Maybe UserId -> WebApp UserId
45+
requireAuthenticatedUser' (Just uid) = pure uid
46+
requireAuthenticatedUser' _ = Errors.respondError UnauthenticatedError

share-api/src/Share/Web/UCM/HistoryComments/Impl.hs

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
module Share.Web.UCM.HistoryComments.Impl (server) where
22

3-
import Conduit (ConduitT)
3+
import Control.Monad.Except
4+
import Control.Monad.Trans.Maybe
45
import Data.Either (partitionEithers)
5-
import Data.Void
66
import Network.WebSockets.Connection
7-
import Servant
87
import Share.IDs
8+
import Share.IDs qualified as IDs
99
import Share.Postgres qualified as PG
10+
import Share.Postgres.Queries qualified as PGQ
11+
import Share.Postgres.Users.Queries qualified as UserQ
1012
import Share.Prelude
11-
import Share.Utils.Servant.Streaming qualified as Streaming
1213
import Share.Web.App (WebApp, WebAppServer)
14+
import Share.Web.Authentication qualified as AuthN
15+
import Share.Web.Authorization qualified as AuthZ
1316
import Share.Web.Errors (Unimplemented (Unimplemented), reportError, respondError)
14-
import Share.Web.UCM.HistoryComments.Queries (insertHistoryComments)
1517
import Share.Web.UCM.HistoryComments.Queries qualified as Q
1618
import Unison.Server.HistoryComments.API qualified as HistoryComments
17-
import Unison.Server.HistoryComments.Types (DownloadCommentsRequest (DownloadCommentsRequest), HistoryCommentChunk (..), UploadCommentsResponse)
19+
import Unison.Server.HistoryComments.Types (DownloadCommentsRequest (DownloadCommentsRequest), HistoryCommentChunk (..), UploadCommentsResponse (..))
1820
import Unison.Server.Types
19-
import Unison.Util.Servant.CBOR
2021
import Unison.Util.Websockets
2122
import UnliftIO
2223

@@ -54,23 +55,42 @@ fetchChunk size action = do
5455
go size
5556

5657
uploadHistoryCommentsStreamImpl :: Maybe UserId -> BranchRef -> Connection -> WebApp ()
57-
uploadHistoryCommentsStreamImpl mayUserId branchRef conn = do
58-
authZ <- error "AUTH CHECK HERE"
59-
projectId <- error "Process Branch Ref"
60-
result <- withQueues @HistoryCommentChunk @_ wsMessageBufferSize wsMessageBufferSize conn \Queues {receive} -> do
61-
let loop :: WebApp ()
58+
uploadHistoryCommentsStreamImpl mayCallerUserId br@(BranchRef branchRef) conn = do
59+
callerUserId <- AuthN.requireAuthenticatedUser' mayCallerUserId
60+
result <- withQueues @UploadCommentsResponse @HistoryCommentChunk wsMessageBufferSize wsMessageBufferSize conn \q@(Queues {receive}) -> runExceptT $ do
61+
projectBranchSH@ProjectBranchShortHand {userHandle, projectSlug, contributorHandle} <- case IDs.fromText @ProjectBranchShortHand branchRef of
62+
Left err -> handleErrInQueue q (UploadCommentsGenericFailure $ IDs.toText err)
63+
Right pbsh -> pure pbsh
64+
let projectSH = ProjectShortHand {userHandle, projectSlug}
65+
mayInfo <- runMaybeT $ mapMaybeT PG.runTransaction $ do
66+
project <- MaybeT $ PGQ.projectByShortHand projectSH
67+
branch <- MaybeT $ PGQ.branchByProjectBranchShortHand projectBranchSH
68+
contributorUser <- MaybeT $ for contributorHandle UserQ.userByHandle
69+
pure (project, branch, contributorUser)
70+
(project, branch, contributorUser) <- maybe (handleErrInQueue q $ UploadCommentsProjectBranchNotFound br) pure $ mayInfo
71+
authZ <-
72+
lift (AuthZ.checkUploadToProjectBranchCodebase callerUserId project.projectId contributorUser.user_id) >>= \case
73+
Left _authErr -> handleErrInQueue q (UploadCommentsNotAuthorized br)
74+
Right authZ -> pure authZ
75+
projectId <- error "Process Branch Ref"
76+
let loop :: ExceptT UploadCommentsResponse WebApp ()
6277
loop = do
6378
(chunk, closed) <- atomically $ fetchChunk insertCommentBatchSize do
6479
receive <&> fmap \case
65-
HistoryCommentErrorChunk err -> (Left err)
80+
HistoryCommentErrorChunk err -> (Left $ UploadCommentsGenericFailure err)
6681
chunk -> (Right chunk)
6782
let (errs, chunks) = partitionEithers chunk
68-
for_ errs reportError
6983
PG.runTransaction $ Q.insertHistoryComments authZ projectId chunks
84+
for errs $ \err -> handleErrInQueue q err
7085
when (not closed) loop
7186
loop
7287
case result of
7388
Left err -> reportError err
74-
Right () -> pure ()
89+
Right (Left err) -> reportError err
90+
Right (Right ()) -> pure ()
7591
where
7692
insertCommentBatchSize = 100
93+
handleErrInQueue :: forall o x. Queues UploadCommentsResponse o -> UploadCommentsResponse -> ExceptT UploadCommentsResponse WebApp x
94+
handleErrInQueue Queues {send} e = do
95+
_ <- atomically $ send e
96+
throwError e

0 commit comments

Comments
 (0)