p2phttp combining unauth and auth options
p2phttp: Support serving unauthenticated users while requesting authentication for operations that need it. Eg, --unauth-readonly can be combined with --authenv. Drop locking currently needs authentication so it will prompt for that. That still needs to be addressed somehow.
This commit is contained in:
parent
4e59828f4c
commit
0629219617
5 changed files with 67 additions and 15 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
git-annex (10.20240928) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
* p2phttp: Support serving unauthenticated users while requesting
|
||||||
|
authentication for operations that need it. Eg, --unauth-readonly
|
||||||
|
can be combined with --authenv.
|
||||||
|
|
||||||
|
-- Joey Hess <id@joeyh.name> Thu, 17 Oct 2024 11:02:17 -0400
|
||||||
|
|
||||||
git-annex (10.20240927) upstream; urgency=medium
|
git-annex (10.20240927) upstream; urgency=medium
|
||||||
|
|
||||||
* Detect when a preferred content expression contains "not present",
|
* Detect when a preferred content expression contains "not present",
|
||||||
|
|
|
@ -128,10 +128,15 @@ seek o = getAnnexWorkerPool $ \workerpool ->
|
||||||
|
|
||||||
mkGetServerMode :: M.Map Auth P2P.ServerMode -> Options -> GetServerMode
|
mkGetServerMode :: M.Map Auth P2P.ServerMode -> Options -> GetServerMode
|
||||||
mkGetServerMode _ o _ Nothing
|
mkGetServerMode _ o _ Nothing
|
||||||
| wideOpenOption o = Just P2P.ServeReadWrite
|
| wideOpenOption o =
|
||||||
| unauthAppendOnlyOption o = Just P2P.ServeAppendOnly
|
ServerMode P2P.ServeReadWrite False
|
||||||
| unauthReadOnlyOption o = Just P2P.ServeReadOnly
|
| unauthAppendOnlyOption o =
|
||||||
| otherwise = Nothing
|
ServerMode P2P.ServeAppendOnly canauth
|
||||||
|
| unauthReadOnlyOption o =
|
||||||
|
ServerMode P2P.ServeReadOnly canauth
|
||||||
|
| otherwise = CannotServeRequests
|
||||||
|
where
|
||||||
|
canauth = authEnvOption o || authEnvHttpOption o
|
||||||
mkGetServerMode authenv o issecure (Just auth) =
|
mkGetServerMode authenv o issecure (Just auth) =
|
||||||
case (issecure, authEnvOption o, authEnvHttpOption o) of
|
case (issecure, authEnvOption o, authEnvHttpOption o) of
|
||||||
(Secure, True, _) -> checkauth
|
(Secure, True, _) -> checkauth
|
||||||
|
@ -139,9 +144,10 @@ mkGetServerMode authenv o issecure (Just auth) =
|
||||||
_ -> noauth
|
_ -> noauth
|
||||||
where
|
where
|
||||||
checkauth = case M.lookup auth authenv of
|
checkauth = case M.lookup auth authenv of
|
||||||
Just servermode -> Just servermode
|
Just servermode -> ServerMode servermode False
|
||||||
Nothing -> noauth
|
Nothing -> noauth
|
||||||
noauth = mkGetServerMode authenv o issecure Nothing
|
noauth = mkGetServerMode authenv noautho issecure Nothing
|
||||||
|
noautho = o { authEnvOption = False, authEnvHttpOption = False }
|
||||||
|
|
||||||
getAuthEnv :: IO (M.Map Auth P2P.ServerMode)
|
getAuthEnv :: IO (M.Map Auth P2P.ServerMode)
|
||||||
getAuthEnv = do
|
getAuthEnv = do
|
||||||
|
|
|
@ -52,8 +52,14 @@ data P2PHttpServerState = P2PHttpServerState
|
||||||
|
|
||||||
type AnnexWorkerPool = TMVar (WorkerPool (Annex.AnnexState, Annex.AnnexRead))
|
type AnnexWorkerPool = TMVar (WorkerPool (Annex.AnnexState, Annex.AnnexRead))
|
||||||
|
|
||||||
-- Nothing when the server is not allowed to serve any requests.
|
type GetServerMode = IsSecure -> Maybe Auth -> ServerMode
|
||||||
type GetServerMode = IsSecure -> Maybe Auth -> Maybe P2P.ServerMode
|
|
||||||
|
data ServerMode
|
||||||
|
= ServerMode
|
||||||
|
{ serverMode :: P2P.ServerMode
|
||||||
|
, authenticationAllowed :: Bool
|
||||||
|
}
|
||||||
|
| CannotServeRequests
|
||||||
|
|
||||||
mkP2PHttpServerState :: AcquireP2PConnection -> AnnexWorkerPool -> GetServerMode -> IO P2PHttpServerState
|
mkP2PHttpServerState :: AcquireP2PConnection -> AnnexWorkerPool -> GetServerMode -> IO P2PHttpServerState
|
||||||
mkP2PHttpServerState acquireconn annexworkerpool getservermode = P2PHttpServerState
|
mkP2PHttpServerState acquireconn annexworkerpool getservermode = P2PHttpServerState
|
||||||
|
@ -143,13 +149,23 @@ checkAuthActionClass
|
||||||
-> (P2P.ServerMode -> Handler a)
|
-> (P2P.ServerMode -> Handler a)
|
||||||
-> Handler a
|
-> Handler a
|
||||||
checkAuthActionClass st sec auth actionclass go =
|
checkAuthActionClass st sec auth actionclass go =
|
||||||
case (getServerMode st sec auth, actionclass) of
|
case (sm, actionclass) of
|
||||||
(Just P2P.ServeReadWrite, _) -> go P2P.ServeReadWrite
|
(ServerMode { serverMode = P2P.ServeReadWrite }, _) ->
|
||||||
(Just P2P.ServeAppendOnly, RemoveAction) -> throwError err403
|
go P2P.ServeReadWrite
|
||||||
(Just P2P.ServeAppendOnly, _) -> go P2P.ServeAppendOnly
|
(ServerMode { serverMode = P2P.ServeAppendOnly }, RemoveAction) ->
|
||||||
(Just P2P.ServeReadOnly, ReadAction) -> go P2P.ServeReadOnly
|
throwError $ forbiddenWithoutAuth sm
|
||||||
(Just P2P.ServeReadOnly, _) -> throwError err403
|
(ServerMode { serverMode = P2P.ServeAppendOnly }, _) ->
|
||||||
(Nothing, _) -> throwError basicAuthRequired
|
go P2P.ServeAppendOnly
|
||||||
|
(ServerMode { serverMode = P2P.ServeReadOnly }, ReadAction) ->
|
||||||
|
go P2P.ServeReadOnly
|
||||||
|
(ServerMode { serverMode = P2P.ServeReadOnly }, _) ->
|
||||||
|
throwError $ forbiddenWithoutAuth sm
|
||||||
|
(CannotServeRequests, _) -> throwError basicAuthRequired
|
||||||
|
where
|
||||||
|
sm = getServerMode st sec auth
|
||||||
|
|
||||||
|
forbiddenAction :: ServerError
|
||||||
|
forbiddenAction = err403
|
||||||
|
|
||||||
basicAuthRequired :: ServerError
|
basicAuthRequired :: ServerError
|
||||||
basicAuthRequired = err401 { errHeaders = [(h, v)] }
|
basicAuthRequired = err401 { errHeaders = [(h, v)] }
|
||||||
|
@ -157,6 +173,11 @@ basicAuthRequired = err401 { errHeaders = [(h, v)] }
|
||||||
h = "WWW-Authenticate"
|
h = "WWW-Authenticate"
|
||||||
v = "Basic realm=\"git-annex\", charset=\"UTF-8\""
|
v = "Basic realm=\"git-annex\", charset=\"UTF-8\""
|
||||||
|
|
||||||
|
forbiddenWithoutAuth :: ServerMode -> ServerError
|
||||||
|
forbiddenWithoutAuth sm
|
||||||
|
| authenticationAllowed sm = basicAuthRequired
|
||||||
|
| otherwise = forbiddenAction
|
||||||
|
|
||||||
data ConnectionParams = ConnectionParams
|
data ConnectionParams = ConnectionParams
|
||||||
{ connectionProtocolVersion :: P2P.ProtocolVersion
|
{ connectionProtocolVersion :: P2P.ProtocolVersion
|
||||||
, connectionServerUUID :: UUID
|
, connectionServerUUID :: UUID
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
[[!comment format=mdwn
|
||||||
|
username="joey"
|
||||||
|
subject="""comment 6"""
|
||||||
|
date="2024-10-17T15:07:12Z"
|
||||||
|
content="""
|
||||||
|
I've implemented combining --unauth-readonly (or --unauth-appendonly) with
|
||||||
|
--authenv/--authenv-http.
|
||||||
|
|
||||||
|
Read-only drop locking in that configuration still needs to be addressed, it
|
||||||
|
does prompt for authentication currently.
|
||||||
|
"""]]
|
|
@ -116,10 +116,16 @@ convenient way to download the content of any key, by using the path
|
||||||
Allows unauthenticated users to read the repository, but not make
|
Allows unauthenticated users to read the repository, but not make
|
||||||
modifications to it.
|
modifications to it.
|
||||||
|
|
||||||
|
This can be combined with `--authenv` or `--authenv-http` to allow
|
||||||
|
anonymous readonly access, and authenticated write access.
|
||||||
|
|
||||||
* `--unauth-appendonly`
|
* `--unauth-appendonly`
|
||||||
|
|
||||||
Allows unauthenticated users to read the repository, and store data in
|
Allows unauthenticated users to read the repository, and store data in
|
||||||
it, but not remove data from it.
|
it, but not remove data from it.
|
||||||
|
|
||||||
|
This can be combined with `--authenv` or `--authenv-http` to allow
|
||||||
|
anonymous appendonly access, and authenticated remove access.
|
||||||
|
|
||||||
* `--wideopen`
|
* `--wideopen`
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue