reuse http url password for p2phttp url when on same host

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.
This commit is contained in:
Joey Hess 2024-11-19 15:27:26 -04:00
parent 3510072883
commit b8a717a617
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
6 changed files with 55 additions and 4 deletions

View file

@ -17,6 +17,10 @@ git-annex (10.20241032) UNRELEASED; urgency=medium
versioned S3 bucket. versioned S3 bucket.
* git-remote-annex: Fix cloning from a special remote on a crippled * git-remote-annex: Fix cloning from a special remote on a crippled
filesystem. 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 <id@joeyh.name> Mon, 11 Nov 2024 12:26:00 -0400 -- Joey Hess <id@joeyh.name> Mon, 11 Nov 2024 12:26:00 -0400

View file

@ -37,6 +37,7 @@ import Annex.Concurrent
import Utility.Url (BasicAuth(..)) import Utility.Url (BasicAuth(..))
import Utility.HumanTime import Utility.HumanTime
import Utility.STM import Utility.STM
import qualified Git
import qualified Git.Credential as Git import qualified Git.Credential as Git
import Servant hiding (BasicAuthData(..)) import Servant hiding (BasicAuthData(..))
@ -83,8 +84,19 @@ p2pHttpClientVersions
-> (String -> Annex a) -> (String -> Annex a)
-> ClientAction a -> ClientAction a
-> Annex (Maybe 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 #ifdef WITH_SERVANT
p2pHttpClientVersions allowedversion rmt fallback clientaction = p2pHttpClientVersions' allowedversion rmt rmtrepo fallback clientaction =
case p2pHttpBaseUrl <$> remoteAnnexP2PHttpUrl (gitconfig rmt) of case p2pHttpBaseUrl <$> remoteAnnexP2PHttpUrl (gitconfig rmt) of
Nothing -> error "internal" Nothing -> error "internal"
Just baseurl -> do Just baseurl -> do
@ -139,9 +151,13 @@ p2pHttpClientVersions allowedversion rmt fallback clientaction =
++ " " ++ ++ " " ++
decodeBS (statusMessage (responseStatusCode resp)) 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" Nothing -> error "internal"
Just url -> url
credauth cred = do credauth cred = do
ba <- Git.credentialBasicAuth cred ba <- Git.credentialBasicAuth cred
@ -159,7 +175,7 @@ p2pHttpClientVersions allowedversion rmt fallback clientaction =
M.insert (Git.CredentialBaseURL credentialbaseurl) cred cc M.insert (Git.CredentialBaseURL credentialbaseurl) cred cc
Nothing -> noop Nothing -> noop
#else #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." "This remote uses an annex+http url, but this version of git-annex is not built with support for that."
#endif #endif

View file

@ -15,6 +15,9 @@ import Network.URI
import System.FilePath.Posix as P import System.FilePath.Posix as P
import Servant.Client (BaseUrl(..), Scheme(..)) import Servant.Client (BaseUrl(..), Scheme(..))
import Text.Read import Text.Read
import Data.Char
import qualified Git
import qualified Git.Url
#endif #endif
defaultP2PHttpProtocolPort :: Int defaultP2PHttpProtocolPort :: Int
@ -79,3 +82,15 @@ unavailableP2PHttpUrl p = p
#ifdef WITH_SERVANT #ifdef WITH_SERVANT
{ p2pHttpBaseUrl = (p2pHttpBaseUrl p) { baseUrlHost = "!dne!" } } { p2pHttpBaseUrl = (p2pHttpBaseUrl p) { baseUrlHost = "!dne!" } }
#endif #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

View file

@ -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 "annex+http://example.com/git-annex/". The annex+http url is
served by this server, and uses port 9417 by default. 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 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 convenient way to download the content of any key, by using the path
"/git-annex/$uuid/$key". For example: "/git-annex/$uuid/$key". For example:

View file

@ -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 operations. This allows using [[git-annex-p2phttp]] to serve a
git-annex repository over http. git-annex repository over http.
When this and the `remote.<name>.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.<name>.annex-uuid` * `remote.<name>.annex-uuid`
git-annex caches UUIDs of remote repositories here. git-annex caches UUIDs of remote repositories here.

View file

@ -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 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]] [[!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]]