Repository: typesafehub/conductr-cli

Issue:
Unable to access non-default org and repo with bintray resolver
Note how the URL duplicates the org and file name, even when you don't specify an org.

 `conduct load typesafe/internal-bundle/typesafe-website`
 
 ```
 Retrieving https://dl.bintray.com/typesafe/internal-bundle/typesafe/typesafe-website/v1-075dbb07a7c6271164c2a429b06f5908bc3d416d18c5813d3d4d718aa6470f2e/typesafe-website-v1-075dbb07a7c6271164c2a429b06f5908bc3d416d18c5813d3d4d718aa6470f2e.zip
Error: Bundle not found: Unable to resolve bundle using typesafe/internal-bundle/typesafe-website
```

` conduct load internal-bundle/typesafe-website`

```
Resolving bundle typesafe/internal-bundle/typesafe-website
Retrieving https://dl.bintray.com/typesafe/internal-bundle/typesafe/typesafe-website/v1-d31c136feef7a7c0a43a0bdf4a2179491e40161ee3a7a37335bcda1c13c5612f/typesafe-website-v1-d31c136feef7a7c0a43a0bdf4a2179491e40161ee3a7a37335bcda1c13c5612f.zip
Error: Bundle not found: Unable to resolve bundle using internal-bundle/typesafe-website
```

Discussion:

Patch:
diff --git a/conductr_cli/resolvers/bintray_resolver.py b/conductr_cli/resolvers/bintray_resolver.py
index 8f892b1..cfb0ce9 100644
--- a/conductr_cli/resolvers/bintray_resolver.py
+++ b/conductr_cli/resolvers/bintray_resolver.py
@@ -10,6 +10,7 @@ import requests
 
 BINTRAY_API_BASE_URL = 'https://api.bintray.com'
 BINTRAY_DOWNLOAD_BASE_URL = 'https://dl.bintray.com'
+BINTRAY_DOWNLOAD_REALM = 'Bintray'
 BINTRAY_CREDENTIAL_FILE_PATH = '{}/.bintray/.credentials'.format(os.path.expanduser('~'))
 
 
@@ -22,7 +23,8 @@ def resolve_bundle(cache_dir, uri):
         bundle_download_url = bintray_download_url(bintray_username, bintray_password, org, repo, package_name,
                                                    compatibility_version, digest)
         if bundle_download_url:
-            return uri_resolver.resolve_bundle(cache_dir, bundle_download_url)
+            auth = (BINTRAY_DOWNLOAD_REALM, bintray_username, bintray_password) if bintray_username else None
+            return uri_resolver.resolve_bundle(cache_dir, bundle_download_url, auth)
         else:
             return False, None, None
     except MalformedBundleUriError:
diff --git a/conductr_cli/resolvers/uri_resolver.py b/conductr_cli/resolvers/uri_resolver.py
index 45a12df..8207d26 100644
--- a/conductr_cli/resolvers/uri_resolver.py
+++ b/conductr_cli/resolvers/uri_resolver.py
@@ -6,9 +6,10 @@ from conductr_cli import screen_utils
 import os
 import logging
 import shutil
+import urllib
 
 
-def resolve_bundle(cache_dir, uri):
+def resolve_bundle(cache_dir, uri, auth=None):
     log = logging.getLogger(__name__)
 
     if not os.path.exists(cache_dir):
@@ -23,7 +24,7 @@ def resolve_bundle(cache_dir, uri):
         if os.path.exists(tmp_download_path):
             os.remove(tmp_download_path)
 
-        download_bundle(log, bundle_url, tmp_download_path)
+        download_bundle(log, bundle_url, tmp_download_path, auth)
 
         shutil.move(tmp_download_path, cached_file)
         return True, bundle_name, cached_file
@@ -62,12 +63,22 @@ def cache_path(cache_dir, uri):
     return '{}/{}'.format(cache_dir, basename)
 
 
-def download_bundle(log, bundle_url, tmp_download_path):
+def download_bundle(log, bundle_url, tmp_download_path, auth):
     log.info('Retrieving {}'.format(bundle_url))
 
     parsed = urlparse(bundle_url, scheme='file')
     is_http_download = parsed.scheme == 'http' or parsed.scheme == 'https'
 
+    if is_http_download and auth:
+        realm, username, password = auth
+        authinfo = urllib.request.HTTPBasicAuthHandler()
+        authinfo.add_password(realm=realm,
+                              uri=bundle_url,
+                              user=username,
+                              passwd=password)
+        opener = urllib.request.build_opener(authinfo)
+        urllib.request.install_opener(opener)
+
     if log.is_progress_enabled() and is_http_download:
         urlretrieve(bundle_url, tmp_download_path, reporthook=show_progress(log))
     else:


Test patch:
diff --git a/conductr_cli/resolvers/test/test_bintray_resolver.py b/conductr_cli/resolvers/test/test_bintray_resolver.py
index cf68b72..2c8a77b 100644
--- a/conductr_cli/resolvers/test/test_bintray_resolver.py
+++ b/conductr_cli/resolvers/test/test_bintray_resolver.py
@@ -32,7 +32,8 @@ class TestResolveBundle(TestCase):
         parse_mock.assert_called_with('bundle-name:v1')
         bintray_download_url_mock.assert_called_with('username', 'password', 'typesafe', 'bundle', 'bundle-name', 'v1',
                                                      'digest')
-        resolve_bundle_mock.assert_called_with('/cache-dir', 'https://dl.bintray.com/download.zip')
+        resolve_bundle_mock.assert_called_with('/cache-dir', 'https://dl.bintray.com/download.zip',
+                                               ('Bintray', 'username', 'password'))
 
     def test_bintray_version_not_found(self):
         load_bintray_credentials_mock = MagicMock(return_value=('username', 'password'))