Repository: goauthentik/authentik

Issue:
OCI Registry Blueprint port ignored
**Describe the bug**
When I try to load blueprints from a registry running on a custom port (e.g. port 5050) the connection fails.

**To Reproduce**
Steps to reproduce the behavior:

1. Go to `Costomization > Blueprints`
2. Create a new `OCI Registry` Blueprint with a non default Port
3. Example `oci://larsl.dev:5050/larsl-net/authentik-config/blueprints/larsl-stages-base:latest`
4. A connection error occurs

**Expected behavior**
authentik connects on the port specified in the URL (5050). What happens according to the error message is that authentik uses port 443.

**Logs**
```
HTTPSConnectionPool(host='larsl.dev', port=443): Max retries exceeded with url: /v2/larsl-net/authentik-config/blueprints/larsl-stages-base/manifests/latest (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f2e26efa690>: Failed to establish a new connection: [Errno 111] Connection refused'))
```

**Version and Deployment (please complete the following information):**

-   authentik version: 2023.5.1
-   Deployment: docker-compose



Discussion:

Resolving patch:
diff --git a/authentik/blueprints/v1/oci.py b/authentik/blueprints/v1/oci.py
--- a/authentik/blueprints/v1/oci.py
+++ b/authentik/blueprints/v1/oci.py
@@ -39,11 +39,16 @@ def __init__(self, url: str) -> None:
         self.logger = get_logger().bind(url=self.sanitized_url)
 
         self.ref = "latest"
+        # Remove the leading slash of the path to convert it to an image name
         path = self.url.path[1:]
-        if ":" in self.url.path:
+        if ":" in path:
+            # if there's a colon in the path, use everything after it as a ref
             path, _, self.ref = path.partition(":")
+        base_url = f"https://{self.url.hostname}"
+        if self.url.port:
+            base_url += f":{self.url.port}"
         self.client = NewClient(
-            f"https://{self.url.hostname}",
+            base_url,
             WithUserAgent(authentik_user_agent()),
             WithUsernamePassword(self.url.username, self.url.password),
             WithDefaultName(path),


Test patch:
diff --git a/authentik/blueprints/tests/test_oci.py b/authentik/blueprints/tests/test_oci.py
--- a/authentik/blueprints/tests/test_oci.py
+++ b/authentik/blueprints/tests/test_oci.py
@@ -32,6 +32,29 @@ def test_successful(self):
                 "foo",
             )
 
+    def test_successful_port(self):
+        """Successful retrieval with custom port"""
+        with Mocker() as mocker:
+            mocker.get(
+                "https://ghcr.io:1234/v2/goauthentik/blueprints/test/manifests/latest",
+                json={
+                    "layers": [
+                        {
+                            "mediaType": OCI_MEDIA_TYPE,
+                            "digest": "foo",
+                        }
+                    ]
+                },
+            )
+            mocker.get("https://ghcr.io:1234/v2/goauthentik/blueprints/test/blobs/foo", text="foo")
+
+            self.assertEqual(
+                BlueprintInstance(
+                    path="oci://ghcr.io:1234/goauthentik/blueprints/test:latest"
+                ).retrieve(),
+                "foo",
+            )
+
     def test_manifests_error(self):
         """Test manifests request erroring"""
         with Mocker() as mocker: