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.
* 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 <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.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

View file

@ -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

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
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:

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