Repository: goauthentik/authentik

Issue:
Certificate requires private key to be used for LDAP server verification in 2023.8.1
**Describe the bug**
CA Certificates that don't have private keys seem to be not showing up in the list of certificates for the configuration of TLS verification for LDAP sources

**To Reproduce**
Steps to reproduce the behavior:

1. Import the CA certificate of an LDAP server
2. Configure an LDAP source for that LDAP server
3. During configuration, try to select the CA certificate imported earlier as "TLS Verification Certificate"
4. In the list of certificates, only those with a private key are visible. I obviously don't have the private key of the CA, and I wouldn't want to import it here even if I had it, for security reasons.

**Expected behavior**
Certificates without private key can be selected if the purpose is only to validate remote servers.

**Screenshots**

![image](https://github.com/goauthentik/authentik/assets/359918/e8f96bde-086f-4a2e-b09c-cd59ab3e5d0c)
![image](https://github.com/goauthentik/authentik/assets/359918/24aabdfe-5f49-4b78-8d4a-3541717e968c)

**Logs**
N/A

**Version and Deployment (please complete the following information):**

-   authentik version: 2023.8.1
-   Deployment: docker-compose

**Additional context**
N/A



Discussion:
Seems to be a regression for the bug fixed in #4376.
Confirmed working in 2023.6.2, so seems to be specifically related to 2023.8.*

Resolving patch:
diff --git a/authentik/crypto/api.py b/authentik/crypto/api.py
--- a/authentik/crypto/api.py
+++ b/authentik/crypto/api.py
@@ -189,6 +189,8 @@ class CertificateKeyPairFilter(FilterSet):
 
     def filter_has_key(self, queryset, name, value):  # pragma: no cover
         """Only return certificate-key pairs with keys"""
+        if not value:
+            return queryset
         return queryset.exclude(key_data__exact="")
 
     class Meta:


Test patch:
diff --git a/authentik/crypto/tests.py b/authentik/crypto/tests.py
--- a/authentik/crypto/tests.py
+++ b/authentik/crypto/tests.py
@@ -128,8 +128,26 @@ def test_list(self):
         response = self.client.get(
             reverse(
                 "authentik_api:certificatekeypair-list",
-            )
-            + f"?name={cert.name}"
+            ),
+            data={"name": cert.name},
+        )
+        self.assertEqual(200, response.status_code)
+        body = loads(response.content.decode())
+        api_cert = [x for x in body["results"] if x["name"] == cert.name][0]
+        self.assertEqual(api_cert["fingerprint_sha1"], cert.fingerprint_sha1)
+        self.assertEqual(api_cert["fingerprint_sha256"], cert.fingerprint_sha256)
+
+    def test_list_has_key_false(self):
+        """Test API List with has_key set to false"""
+        cert = create_test_cert()
+        cert.key_data = ""
+        cert.save()
+        self.client.force_login(create_test_admin_user())
+        response = self.client.get(
+            reverse(
+                "authentik_api:certificatekeypair-list",
+            ),
+            data={"name": cert.name, "has_key": False},
         )
         self.assertEqual(200, response.status_code)
         body = loads(response.content.decode())
@@ -144,8 +162,8 @@ def test_list_without_details(self):
         response = self.client.get(
             reverse(
                 "authentik_api:certificatekeypair-list",
-            )
-            + f"?name={cert.name}&include_details=false"
+            ),
+            data={"name": cert.name, "include_details": False},
         )
         self.assertEqual(200, response.status_code)
         body = loads(response.content.decode())
@@ -168,8 +186,8 @@ def test_certificate_download(self):
             reverse(
                 "authentik_api:certificatekeypair-view-certificate",
                 kwargs={"pk": keypair.pk},
-            )
-            + "?download",
+            ),
+            data={"download": True},
         )
         self.assertEqual(200, response.status_code)
         self.assertIn("Content-Disposition", response)
@@ -189,8 +207,8 @@ def test_private_key_download(self):
             reverse(
                 "authentik_api:certificatekeypair-view-private-key",
                 kwargs={"pk": keypair.pk},
-            )
-            + "?download",
+            ),
+            data={"download": True},
         )
         self.assertEqual(200, response.status_code)
         self.assertIn("Content-Disposition", response)
@@ -200,7 +218,7 @@ def test_used_by(self):
         self.client.force_login(create_test_admin_user())
         keypair = create_test_cert()
         provider = OAuth2Provider.objects.create(
-            name="test",
+            name=generate_id(),
             client_id="test",
             client_secret=generate_key(),
             authorization_flow=create_test_flow(),