Repository: conan-io/conan

Issue:
Removing credentials from 'url' for SCM doesn't play well with SSH git repository hosting
- [x] I've read the [CONTRIBUTING guide](https://github.com/conan-io/conan/blob/develop/.github/CONTRIBUTING.md).
- [x] I've specified the Conan version, operating system version and any tool that can be relevant.
- [x] I've explained the steps to reproduce the error or the motivation/use case of the question/suggestion.

conan 1.12+, previous used version was 1.11

Once upon a time there was a pull request #4207 that changed URLs like `ssh://git@a.b.c.d:port/GROUP/repo.git` to `ssh://a.b.c.d:port/GROUP/repo.git` (i.e. without username) for SCM attribute.

Recently I updated to conan 1.18.5 and got a problem.

I'm pulling sources from a GitLab instance via SSH (I can't change it now to HTTP) and GitLab (I think git hosting services too) doesn't accept SSH connections without username.

So what options do I have now?
- Every user of package have to execute `git config --global url.ssh://git@a.b.c.d:port.insteadOf ssh://a.b.c.d:port`, i.e. add config to rewrite URL. It doesn't scale well.
- Every package developer must hardcode username 'git' in the scm attribute i.e.
```scm = {
        "type": "git",
        "username": "git",
        "url": "auto",
        "revision": "auto",
    }
```
It doesn't scale too and what if someone wants to use HTTPS and his name is not `git`?

For me as a user of conan it looks like a regression.

Could you suggest a scalable workaround or fix this issue?


Discussion:
Hi, I think that the problem is in the `auto` behavior: Conan reads the remotes and uses the URL like ``ssh://....``, but this is indeed a problem if you need to be authenticated to the server. I wonder if it would be safe to change the ``ssh`` protocol to ``https`` unconditionally.

This is something that has bitten me in the past exporting packages I'm developing in Github.
I will discuss this issue, maybe we can introduce a new entry in the dict to avoid removing the user credentials.
Unfortunately, I can't easily change SSH to HTTPS. So it will be very useful feature.
But, even if we enable an opt-out to not replace username/password, you will end with the `git@...` in the recipe, so you cannot easily change to HTTPs without changing the recipe (same issue).  Right?
Yes, exactly. That is why I'm asking for a suggestion and cannot provide my own solution.
A PR #4207 has strange test case with SSH: 
```python
    def test_ssh(self):
        # Here, for ssh, we don't want to remove the user ('git' in this example)
        self.assertEqual('git@github.com:conan-io/conan.git',
                         SCMBase._remove_credentials_url(
                             'git@github.com:conan-io/conan.git'))
```

I think, that the URI in invalid and should look like `ssh://git@github.com:2222/conan.git` according to https://www.iana.org/assignments/uri-schemes/prov/ssh because a SSH URI can't contain a text after the colon.
@lasote , you merged this PR #4207, what do you think about this test case?

Resolving patch:
diff --git a/conans/client/tools/scm.py b/conans/client/tools/scm.py
--- a/conans/client/tools/scm.py
+++ b/conans/client/tools/scm.py
@@ -78,6 +78,8 @@ def _remove_credentials_url(cls, url):
         netloc = parsed.hostname
         if parsed.port:
             netloc += ":{}".format(parsed.port)
+        if parsed.username and parsed.scheme == "ssh":
+            netloc = "{}@{}".format(parsed.username, netloc)
         replaced = parsed._replace(netloc=netloc)
         return replaced.geturl()
 


Test patch:
diff --git a/conans/test/unittests/client/tools/scm/test_scm_base.py b/conans/test/unittests/client/tools/scm/test_scm_base.py
--- a/conans/test/unittests/client/tools/scm/test_scm_base.py
+++ b/conans/test/unittests/client/tools/scm/test_scm_base.py
@@ -25,6 +25,15 @@ def test_http_with_port_number(self):
 
     def test_ssh(self):
         # Here, for ssh, we don't want to remove the user ('git' in this example)
+        # URL-like syntax
+        self.assertEqual('ssh://git@github.com:2222/conan-io/conan.git',
+                         SCMBase._remove_credentials_url(
+                             'ssh://git@github.com:2222/conan-io/conan.git'))
+        # URL-like syntax with a password
+        self.assertEqual('ssh://git@github.com:2222/conan-io/conan.git',
+                         SCMBase._remove_credentials_url(
+                             'ssh://git:password@github.com:2222/conan-io/conan.git'))
+        # scp-like syntax
         self.assertEqual('git@github.com:conan-io/conan.git',
                          SCMBase._remove_credentials_url(
                              'git@github.com:conan-io/conan.git'))