Repository: conda/conda

Issue:
Problem: when building a package the http auth credentials are lost in 4.4.2
This is most likely introduced by 4.4.2 - has not existed before!

We are using channels that have http auth enabled. Our channel urls look like this: `https://user:password@host.com/path/to/channel/`. Conda in all versions works fine with this. After updating to conda 4.4.2, our conda-build calls fail with:

```
conda.exceptions.CondaHTTPError: HTTP 401 UNAUTHORIZED for url https://host.com/path/to/channel/
```

Downgrading to 4.4.1 resolves the problem. We saw this error on all platforms (win/linux).

There are two interesting observations:
- conda still works with auth, just the conda-build process does not
- the error message indicates, that the credentials get lost. When a _wrong_ password is specified, then the credentials are usually printed alongside: `conda.exceptions.CondaHTTPError: HTTP 401 UNAUTHORIZED for url https://user:wrong_password@host.com/path/to/channel/`. That leaves the impression that the auth info get lost/dropped somewhere

@kalefranz @msarahan  I'm not 100% sure whether this is a conda or conda-build bug - but i think its introduced by conda 4.4.2...




Discussion:
> Downgrading to 4.4.1 resolves the problem.

Can you confirm that 4.4.1 indeed works for you, or is it the latest in 4.3, 4.3.31, that works?
I explicitly tried well combinations with 4.4.2, 4.4.1 and 4.3.31 with CB 3.1.3 and 3.2.0.

The result is that all 4.4.2 do  work with the above problem, all the others work. The CB version has no influence on the result.

correction:

The result is that all 4.4.2 do **not**  work with the above problem, all the others are fine. The CB version has no influence on the result...
... this problem still persists, the last working conda version was 4.4.1... Is there  anything we could do to assist in solving this bug?
Confirming this problem still exists on conda 4.4.7. @kalefranz any update on this? 
I have the same problem. I found out that the problem is in
https://github.com/conda/conda/blob/7cb5f66dd46727ce8f16b969e084555e6221cfc5/conda/plan.py#L524-L528, which was introduced after 4.4.1.
`Channel(url).canonical_name` (line 526) strips away the credentials, and a new channel is created using the stripped url (line 527). Btw., this is probably an issue in the code lines 519 to 523 as well.

As far as I can see it, `Channel.canonical_name` needs to be updated to include credentials (after all, they appear to be part of the channel name as defined in condarc). Indeed, replacing https://github.com/conda/conda/blob/7cb5f66dd46727ce8f16b969e084555e6221cfc5/conda/models/channel.py#L160-L161
with
```python
    if self.scheme:
            if self.auth:
                return "%s://%s@%s" % (self.scheme, self.auth, join_url(self.location, self.name))
            else:
                return "%s://%s" % (self.scheme, join_url(self.location, self.name))
```
gets rid of the problem, at least in a quick test. I hope, this does not leak the credentials anywhere now.

Resolving patch:
diff --git a/conda/plan.py b/conda/plan.py
--- a/conda/plan.py
+++ b/conda/plan.py
@@ -521,11 +521,13 @@ def install_actions(prefix, index, specs, force=False, only_names=None, always_c
         channels = IndexedSet(Channel(cn) for cn in channel_names)
         subdirs = IndexedSet(basename(url) for url in channel_priority_map)
     else:
+        # a hack for when conda-build calls this function without giving channel_priority_map
         if LAST_CHANNEL_URLS:
             channel_priority_map = prioritize_channels(LAST_CHANNEL_URLS)
-            channel_names = IndexedSet(Channel(url).canonical_name for url in channel_priority_map)
-            channels = IndexedSet(Channel(cn) for cn in channel_names)
-            subdirs = IndexedSet(basename(url) for url in channel_priority_map)
+            channels = IndexedSet(Channel(url) for url in channel_priority_map)
+            subdirs = IndexedSet(
+                subdir for subdir in (c.subdir for c in channels) if subdir
+            ) or context.subdirs
         else:
             channels = subdirs = None
 


Test patch: