diff --git a/CHANGELOG b/CHANGELOG index 7e523186c6..249ed77549 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,10 @@ git-annex (10.20241032) UNRELEASED; urgency=medium versioned S3 bucket. * git-remote-annex: Fix cloning from a special remote on a crippled filesystem. + * When remote.name.annexUrl is an annex+http(s) url, that + uses the same hostname as remote.name.url, which is itself a http(s) + url, they are assumed to share a username and password. This avoids + unnecessary duplicate password prompts. -- Joey Hess Mon, 11 Nov 2024 12:26:00 -0400 diff --git a/P2P/Http/Client.hs b/P2P/Http/Client.hs index d047eca7a0..c708908a19 100644 --- a/P2P/Http/Client.hs +++ b/P2P/Http/Client.hs @@ -37,6 +37,7 @@ import Annex.Concurrent import Utility.Url (BasicAuth(..)) import Utility.HumanTime import Utility.STM +import qualified Git import qualified Git.Credential as Git import Servant hiding (BasicAuthData(..)) @@ -83,8 +84,19 @@ p2pHttpClientVersions -> (String -> Annex a) -> ClientAction a -> Annex (Maybe a) +p2pHttpClientVersions allowedversion rmt fallback clientaction = do + rmtrepo <- getRepo rmt + p2pHttpClientVersions' allowedversion rmt rmtrepo fallback clientaction + +p2pHttpClientVersions' + :: (ProtocolVersion -> Bool) + -> Remote + -> Git.Repo + -> (String -> Annex a) + -> ClientAction a + -> Annex (Maybe a) #ifdef WITH_SERVANT -p2pHttpClientVersions allowedversion rmt fallback clientaction = +p2pHttpClientVersions' allowedversion rmt rmtrepo fallback clientaction = case p2pHttpBaseUrl <$> remoteAnnexP2PHttpUrl (gitconfig rmt) of Nothing -> error "internal" Just baseurl -> do @@ -139,9 +151,13 @@ p2pHttpClientVersions allowedversion rmt fallback clientaction = ++ " " ++ decodeBS (statusMessage (responseStatusCode resp)) - credentialbaseurl = case p2pHttpUrlString <$> remoteAnnexP2PHttpUrl (gitconfig rmt) of + credentialbaseurl = case remoteAnnexP2PHttpUrl (gitconfig rmt) of + Just p2phttpurl + | isP2PHttpSameHost p2phttpurl rmtrepo -> + Git.repoLocation rmtrepo + | otherwise -> + p2pHttpUrlString p2phttpurl Nothing -> error "internal" - Just url -> url credauth cred = do ba <- Git.credentialBasicAuth cred @@ -159,7 +175,7 @@ p2pHttpClientVersions allowedversion rmt fallback clientaction = M.insert (Git.CredentialBaseURL credentialbaseurl) cred cc Nothing -> noop #else -p2pHttpClientVersions _ _ fallback () = Just <$> fallback +p2pHttpClientVersions _ _ _ fallback () = Just <$> fallback "This remote uses an annex+http url, but this version of git-annex is not built with support for that." #endif diff --git a/P2P/Http/Url.hs b/P2P/Http/Url.hs index 9e1af2c8dc..b7ec6d22fe 100644 --- a/P2P/Http/Url.hs +++ b/P2P/Http/Url.hs @@ -15,6 +15,9 @@ import Network.URI import System.FilePath.Posix as P import Servant.Client (BaseUrl(..), Scheme(..)) import Text.Read +import Data.Char +import qualified Git +import qualified Git.Url #endif defaultP2PHttpProtocolPort :: Int @@ -79,3 +82,15 @@ unavailableP2PHttpUrl p = p #ifdef WITH_SERVANT { p2pHttpBaseUrl = (p2pHttpBaseUrl p) { baseUrlHost = "!dne!" } } #endif + +#ifdef WITH_SERVANT +-- When a p2phttp url is on the same host as a git repo, which also uses +-- http, the same username+password is assumed to be used for both. +isP2PHttpSameHost :: P2PHttpUrl -> Git.Repo -> Bool +isP2PHttpSameHost u repo + | not (Git.repoIsHttp repo) = False + | otherwise = + Just (map toLower $ baseUrlHost (p2pHttpBaseUrl u)) + == + (map toLower <$> (Git.Url.host repo)) +#endif diff --git a/doc/git-annex-p2phttp.mdwn b/doc/git-annex-p2phttp.mdwn index 802c52d929..3d10f62198 100644 --- a/doc/git-annex-p2phttp.mdwn +++ b/doc/git-annex-p2phttp.mdwn @@ -20,6 +20,12 @@ as usual, and `remote.name.annexUrl` set to an annex+http url such as "annex+http://example.com/git-annex/". The annex+http url is served by this server, and uses port 9417 by default. +Note that, when `remote.name.url` and `remote.name.annexUrl` +contain the same hostname, they are assumed by git-annex to +support the same users and passwords. So, git-annex will use +the password for the `remote.name.url` to log into the +`remote.name.annexUrl`. + As well as serving the git-annex HTTP API, this server provides a convenient way to download the content of any key, by using the path "/git-annex/$uuid/$key". For example: diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn index 178ad146d3..a082c97647 100644 --- a/doc/git-annex.mdwn +++ b/doc/git-annex.mdwn @@ -1569,6 +1569,13 @@ Remotes are configured using these settings in `.git/config`. git operations. This allows using [[git-annex-p2phttp]] to serve a git-annex repository over http. + When this and the `remote..url` contain the same hostname, + and this is an annex+http(s) url, and that is also a http(s) url, + git-annex assumes that the same username and password can be used + for both urls. When password cacheing is configured, this allows + you to only be prompted once for a password when using both git and + git-annex. See gitcredentials(7) for how to set up password caching. + * `remote..annex-uuid` git-annex caches UUIDs of remote repositories here. diff --git a/doc/todo/p2phttp__58___reuse_credentials_for_repos_on_one_host.mdwn b/doc/todo/p2phttp__58___reuse_credentials_for_repos_on_one_host.mdwn index da46f5b7f1..cbef6aebca 100644 --- a/doc/todo/p2phttp__58___reuse_credentials_for_repos_on_one_host.mdwn +++ b/doc/todo/p2phttp__58___reuse_credentials_for_repos_on_one_host.mdwn @@ -13,3 +13,6 @@ I see some ways to address this: 3. Perhaps most elegantly: make p2phttp support serving multiple repositories, so that repositories could share the same annexurl and therefore share credentials [[!tag projects/INM7]] + +> I have implemented reuse of the remote.name.url password for +> remote.name.annexurl when they are on the same host. [[done]] --[[Joey]]