Plain git tries the same credentials for multiple different repositories on the same host. I.e. with multiple different repositories on https://atris.fz-juelich.de/, if I push to one and supply my credentials, these will be saved omitting the actual repository path on the host and will be reused for any other repository that is also located on ATRIS.
Git-annex with p2phttp behaves differently. It saves the full URL to the p2phttp endpoint including the repository path, which means that two repositories using p2phttp will both ask for credentials and save them separate from each other.
This difference in behavior seems to stem from a difference in how git credential
handles schemes: if you ask it for credentials for http(s)
it will silently omit any supplied path and only match on scheme and host, while asking for annex+http(s)
matches on the full scheme, host and path.
There might be some situations in which one would want to associate the credentials with the full path, but in my case for forgejo-aneksajo all authentication is handled by Forgejo and users are global on that instance so per-repository credentials don't make much sense.
I see some ways to address this:
- Remove the path from the request to
git credential
on git-annex' side - Allow
remote.<name>.annexurl
to be set tohttp(s)://
URLs in addition toannex+http(s)://
, exploiting the difference in thegit credential
behavior - Perhaps most elegantly: make p2phttp support serving multiple repositories, so that repositories could share the same annexurl and therefore share credentials
I have implemented reuse of the remote.name.url password for remote.name.annexurl when they are on the same host. done --Joey
Just an addendum: in forgejo-aneksajo I've effectively implemented the third option by having one git-annex-p2phttp endpoint for all repositories, peaking at the request to get the repository UUID, starting the p2phttp server for that repository, and then forwarding the request. So, having to enter the credentials for every new repository is no longer a concern there, and https://git-annex.branchable.com/todo/p2phttp_serve_multiple_repositories/ would address this for standalone p2phttp.
What might still be nice though is trying to reuse the credentials of standard git operations for p2phttp. In the case of forgejo-aneksajo, git push/pull and annex-p2phttp operations use the same username/password or username/access-token combination for authentication, but git-annex will prompt for them twice due to the different URLs. This might be a bit hacky, but I think this would just work if git-annex allowed plain http(s):// URLs in addition to annex+http(s):// in the annexurl configuration, as the request to git credential would then match that of plain git operations.
Unfortunately, remote.foo.annexUrl is not limited to use for p2phttp. It existed before that and could be legitimately set to a http url when p2phttp is not being used.
I agree it would be good to try to reuse the credentials of the git url for p2phttp. That could be done by just querying git credential for the git url credentials, and trying to use them for the p2phttp url. If they don't work, use git credential to prompt for the p2phttp url credentials as it does now.
If the user had credential.helper configured, they would probably already have the git credentials cached, and if not, this would cache them for later use, so no harm done asking for them. But if credential.helper was not configured, there would be an extra and wholly unncessary password prompt.
So, I think it makes sense to only do this when credential.helper is configured. And when the hostname is the same in both the git url and the p2phttp url.
Hmm, I can imagine a situation where this behavior could be considered a security hole. Suppose A and B both have accounts on the same host. A is in charge of serving the git repositories. B is in charge of serving git-annex p2phttp. This would make git-annex prompt for a password to one of user A's git repositories, and send the password to user B. So B would be able to crack into the git repos.
That is pretty farfetched. But it begs the question: If the git repository and p2phttp are on the same host, why would they ever need 2 distinct passwords? If git-annex simply doesn't support that A/B split, then that security hole can't happen.
So, git-annex could simply, when the git url and p2phttp url have the same hostname, request the git credentials for the git url, rather than for the p2phttp url.
credential.useHttpPath is the relevant git config for this git-credential behavior.
I think it would be reasonable for git-annex to check if that is false, and if so, remove the path from the
git credential
request for an annex+http url.But I agree, it would be better, in the vast majority of cases, to have a single url endpoint that serves multiple repositories.
And for that matter, if someone is running git-annex p2phttp to serve 2 different repositories right now, they are probably making the two listen on different ports and so removing the path wouldn't help. They would have to be interposing another web server that mapped those ports to paths, like you have done with forgejo-aneksajo, for the path mangling to help.
So implementing p2phttp serve multiple repositories seems better than adding such path mangling.