implement serveRemove and send WWW-Authenticate header on auth failure
This commit is contained in:
parent
97d0fc9b65
commit
48f76cb3e8
4 changed files with 37 additions and 11 deletions
|
@ -67,7 +67,12 @@ optParser _ = Options
|
||||||
)
|
)
|
||||||
|
|
||||||
seek :: Options -> CommandSeek
|
seek :: Options -> CommandSeek
|
||||||
seek o = startConcurrency commandStages $
|
seek o = startConcurrency commandStages $ do
|
||||||
|
-- XXX remove this
|
||||||
|
when (isNothing (portOption o)) $ do
|
||||||
|
liftIO $ putStrLn "test begins"
|
||||||
|
testCheckPresent
|
||||||
|
giveup "TEST DONE"
|
||||||
withLocalP2PConnections $ \acquireconn -> liftIO $ do
|
withLocalP2PConnections $ \acquireconn -> liftIO $ do
|
||||||
authenv <- getAuthEnv
|
authenv <- getAuthEnv
|
||||||
st <- mkP2PHttpServerState acquireconn $
|
st <- mkP2PHttpServerState acquireconn $
|
||||||
|
|
21
P2P/Http.hs
21
P2P/Http.hs
|
@ -21,7 +21,7 @@ module P2P.Http (
|
||||||
import Annex.Common
|
import Annex.Common
|
||||||
import P2P.Http.Types
|
import P2P.Http.Types
|
||||||
import P2P.Http.State
|
import P2P.Http.State
|
||||||
import P2P.Protocol hiding (Offset, Bypass)
|
import P2P.Protocol hiding (Offset, Bypass, auth)
|
||||||
import P2P.IO
|
import P2P.IO
|
||||||
|
|
||||||
import Servant
|
import Servant
|
||||||
|
@ -181,9 +181,8 @@ serveCheckPresent st apiver (B64Key k) cu su bypass sec auth = do
|
||||||
$ \runst conn ->
|
$ \runst conn ->
|
||||||
liftIO $ runNetProto runst conn $ checkPresent k
|
liftIO $ runNetProto runst conn $ checkPresent k
|
||||||
case res of
|
case res of
|
||||||
Right (Right b) -> return (CheckPresentResult b)
|
Right b -> return (CheckPresentResult b)
|
||||||
Right (Left err) -> throwError $ err500 { errBody = encodeBL err }
|
Left err -> throwError $ err500 { errBody = encodeBL err }
|
||||||
Left err -> throwError $ err500 { errBody = encodeBL (describeProtoFailure err) }
|
|
||||||
|
|
||||||
clientCheckPresent
|
clientCheckPresent
|
||||||
:: ClientEnv
|
:: ClientEnv
|
||||||
|
@ -214,6 +213,7 @@ type RemoveAPI result
|
||||||
:> ClientUUID Required
|
:> ClientUUID Required
|
||||||
:> ServerUUID Required
|
:> ServerUUID Required
|
||||||
:> BypassUUIDs
|
:> BypassUUIDs
|
||||||
|
:> IsSecure
|
||||||
:> AuthHeader
|
:> AuthHeader
|
||||||
:> Post '[JSON] result
|
:> Post '[JSON] result
|
||||||
|
|
||||||
|
@ -226,9 +226,18 @@ serveRemove
|
||||||
-> B64UUID ClientSide
|
-> B64UUID ClientSide
|
||||||
-> B64UUID ServerSide
|
-> B64UUID ServerSide
|
||||||
-> [B64UUID Bypass]
|
-> [B64UUID Bypass]
|
||||||
|
-> IsSecure
|
||||||
-> Maybe Auth
|
-> Maybe Auth
|
||||||
-> Handler t
|
-> Handler t
|
||||||
serveRemove = undefined
|
serveRemove st resultmangle apiver (B64Key k) cu su bypass sec auth = do
|
||||||
|
res <- withP2PConnection apiver st cu su bypass sec auth RemoveAction
|
||||||
|
$ \runst conn ->
|
||||||
|
liftIO $ runNetProto runst conn $ remove Nothing k
|
||||||
|
case res of
|
||||||
|
(Right b, plus) -> return $ resultmangle $
|
||||||
|
RemoveResultPlus b (map B64UUID (fromMaybe [] plus))
|
||||||
|
(Left err, _) -> throwError $
|
||||||
|
err500 { errBody = encodeBL err }
|
||||||
|
|
||||||
clientRemove
|
clientRemove
|
||||||
:: ProtocolVersion
|
:: ProtocolVersion
|
||||||
|
@ -248,7 +257,7 @@ clientRemove (ProtocolVersion ver) k cu su bypass auth = case ver of
|
||||||
_ :<|> _ :<|> _ :<|> _ :<|>
|
_ :<|> _ :<|> _ :<|> _ :<|>
|
||||||
_ :<|> _ :<|> _ :<|> _ :<|>
|
_ :<|> _ :<|> _ :<|> _ :<|>
|
||||||
v3 :<|> v2 :<|> v1 :<|> v0 :<|> _ = client p2pHttpAPI
|
v3 :<|> v2 :<|> v1 :<|> v0 :<|> _ = client p2pHttpAPI
|
||||||
|
|
||||||
type RemoveBeforeAPI
|
type RemoveBeforeAPI
|
||||||
= KeyParam
|
= KeyParam
|
||||||
:> ClientUUID Required
|
:> ClientUUID Required
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
-}
|
-}
|
||||||
|
|
||||||
{-# LANGUAGE BangPatterns #-}
|
{-# LANGUAGE BangPatterns #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
module P2P.Http.State where
|
module P2P.Http.State where
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@ withP2PConnection
|
||||||
-> IsSecure
|
-> IsSecure
|
||||||
-> Maybe Auth
|
-> Maybe Auth
|
||||||
-> ActionClass
|
-> ActionClass
|
||||||
-> (RunState -> P2PConnection -> Handler a)
|
-> (RunState -> P2PConnection -> Handler (Either ProtoFailure a))
|
||||||
-> Handler a
|
-> Handler a
|
||||||
withP2PConnection apiver st cu su bypass sec auth actionclass connaction =
|
withP2PConnection apiver st cu su bypass sec auth actionclass connaction =
|
||||||
case (getServerMode st sec auth, actionclass) of
|
case (getServerMode st sec auth, actionclass) of
|
||||||
|
@ -58,7 +59,7 @@ withP2PConnection apiver st cu su bypass sec auth actionclass connaction =
|
||||||
(Just P2P.ServeAppendOnly, _) -> go P2P.ServeAppendOnly
|
(Just P2P.ServeAppendOnly, _) -> go P2P.ServeAppendOnly
|
||||||
(Just P2P.ServeReadOnly, ReadAction) -> go P2P.ServeReadOnly
|
(Just P2P.ServeReadOnly, ReadAction) -> go P2P.ServeReadOnly
|
||||||
(Just P2P.ServeReadOnly, _) -> throwError err403
|
(Just P2P.ServeReadOnly, _) -> throwError err403
|
||||||
(Nothing, _) -> throwError err401
|
(Nothing, _) -> throwError basicAuthRequired
|
||||||
where
|
where
|
||||||
go servermode = liftIO (acquireP2PConnection st cp) >>= \case
|
go servermode = liftIO (acquireP2PConnection st cp) >>= \case
|
||||||
Left (ConnectionFailed err) ->
|
Left (ConnectionFailed err) ->
|
||||||
|
@ -66,7 +67,7 @@ withP2PConnection apiver st cu su bypass sec auth actionclass connaction =
|
||||||
Left TooManyConnections ->
|
Left TooManyConnections ->
|
||||||
throwError err503
|
throwError err503
|
||||||
Right (runst, conn, releaseconn) ->
|
Right (runst, conn, releaseconn) ->
|
||||||
connaction runst conn
|
connaction' runst conn
|
||||||
`finally` liftIO releaseconn
|
`finally` liftIO releaseconn
|
||||||
where
|
where
|
||||||
cp = ConnectionParams
|
cp = ConnectionParams
|
||||||
|
@ -76,6 +77,17 @@ withP2PConnection apiver st cu su bypass sec auth actionclass connaction =
|
||||||
, connectionBypass = map fromB64UUID bypass
|
, connectionBypass = map fromB64UUID bypass
|
||||||
, connectionServerMode = servermode
|
, connectionServerMode = servermode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connaction' runst conn = connaction runst conn >>= \case
|
||||||
|
Right r -> return r
|
||||||
|
Left err -> throwError $
|
||||||
|
err500 { errBody = encodeBL (describeProtoFailure err) }
|
||||||
|
|
||||||
|
basicAuthRequired :: ServerError
|
||||||
|
basicAuthRequired = err401 { errHeaders = [(h, v)] }
|
||||||
|
where
|
||||||
|
h = "WWW-Authenticate"
|
||||||
|
v = "Basic realm=\"git-annex\", charset=\"UTF-8\""
|
||||||
|
|
||||||
-- Nothing when the server is not allowed to serve any requests.
|
-- Nothing when the server is not allowed to serve any requests.
|
||||||
type GetServerMode = IsSecure -> Maybe Auth -> Maybe P2P.ServerMode
|
type GetServerMode = IsSecure -> Maybe Auth -> Maybe P2P.ServerMode
|
||||||
|
|
|
@ -24,7 +24,7 @@ configuration of the HTTP server. When a request needs authentication,
|
||||||
it will fail with 401 Unauthorized.
|
it will fail with 401 Unauthorized.
|
||||||
|
|
||||||
Authentication is done using HTTP basic auth. The realm to use when
|
Authentication is done using HTTP basic auth. The realm to use when
|
||||||
authenticating is "git-annex".
|
authenticating is "git-annex". The charset is UTF-8.
|
||||||
|
|
||||||
When authentication is successful but does not allow a request to be
|
When authentication is successful but does not allow a request to be
|
||||||
performed, it will fail with 403 Forbidden.
|
performed, it will fail with 403 Forbidden.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue