Repository: jazzband/django-oauth-toolkit

Issue:
Is documentation correct about OIDC_ISS_ENDPOINT?
The [OIDC_ISS_ENDPOINT](https://django-oauth-toolkit.readthedocs.io/en/latest/settings.html#oidc-iss-endpoint) documentation states that discovery is at `OIDC_ISS_ENDPOINT + /.well-known/openid-configuration/`. That would indicate that one should include the mount point of the `oauth2_provider.urls` right?

But `ConnectDiscoveryInfoView` uses `reverse` to get the path of the  `oauth2_provider:authorize`, `oauth2_provider:token`, `oauth2_provider:user-info`, `oauth2_provider:jwks-info` which results in the doubling of the mount point info.

So a if `oauth2_provider.urls` is mounted at `/some-initial-path/o` all the endpoints, except `issuer`, included in the response has doubled the mount point information. So if the `OIDC_ISS_ENDPOINT` is `http://localhost:8001/some-initial-path/o` the issuer will be `http://localhost:8001/some-initial-path/o` but `authorization_endpoint` will be `http://localhost:8001/some-initial-path/o/some-initial-path/o/authorize/`. Same pattern for `token_endpoint`, `userinfo_endpoint`, and `jwks_uri` 

Looking at the tests, there seems to be a little ambivalence about the topic. See below
https://github.com/jazzband/django-oauth-toolkit/blob/9d2aac2480b2a1875eb52612661992f73606bade/tests/test_oidc_views.py#L15

`test_get_connect_discovery_info` expects a url without a path and `test_get_connect_discovery_info_without_issuer_url` expects a url with a path `/o` (the default `oauth2` path?).

Anyways - I'm confused. Can anyone clarify if `OIDC_ISS_ENDPOINT` should just be the root url of the Django app or if it should include the mount point of the `oauth2_provider.urls`?

EDIT:
It looks as if the OIDC specification mentions [this](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig). The correct pattern should follow the `django_oauth_toolkit` documentation. So `OIDC_ISS_ENDPOINT ` + `/.well-known/openid-configuration` should resolve.
If this is true, then the test `test_get_connect_discovery_info` should expect `http://localhost/o` instead of `http://localhost` as `issuer` - I think.

EDIT2:
If `OIDC_ISS_ENDPOINT ` is defined, couldn't it be located somewhere else (another domain) than where `ConnectDiscoveryInfoView` is located? If yes, isn't it then a mistake to base the location of `authorization_endpoint`, `token_endpoint`, `userinfo_endpoint`, and `jwks_uri` on the use of `reverse` for the url patterns on the same host where `ConnectDiscoveryInfoView` is located.
Why not just hardcode the endpoints to `OIDC_ISS_ENDPOINT` + `{/authorize/, /token/, /userinfo/, o/.well-known/jwks.json}`?
Or urlparse `OIDC_ISS_ENDPOINT` and use the scheme + netloc + reverse of all the endpoints to fill the output of `ConnectDiscoveryInfoView`. 


Discussion:

Resolving patch:
diff --git a/oauth2_provider/views/oidc.py b/oauth2_provider/views/oidc.py
--- a/oauth2_provider/views/oidc.py
+++ b/oauth2_provider/views/oidc.py
@@ -1,4 +1,5 @@
 import json
+from urllib.parse import urlparse
 
 from django.http import HttpResponse, JsonResponse
 from django.urls import reverse
@@ -32,12 +33,15 @@ def get(self, request, *args, **kwargs):
             )
             jwks_uri = request.build_absolute_uri(reverse("oauth2_provider:jwks-info"))
         else:
-            authorization_endpoint = "{}{}".format(issuer_url, reverse("oauth2_provider:authorize"))
-            token_endpoint = "{}{}".format(issuer_url, reverse("oauth2_provider:token"))
+            parsed_url = urlparse(oauth2_settings.OIDC_ISS_ENDPOINT)
+            host = parsed_url.scheme + "://" + parsed_url.netloc
+            authorization_endpoint = "{}{}".format(host, reverse("oauth2_provider:authorize"))
+            token_endpoint = "{}{}".format(host, reverse("oauth2_provider:token"))
             userinfo_endpoint = oauth2_settings.OIDC_USERINFO_ENDPOINT or "{}{}".format(
-                issuer_url, reverse("oauth2_provider:user-info")
+                host, reverse("oauth2_provider:user-info")
             )
-            jwks_uri = "{}{}".format(issuer_url, reverse("oauth2_provider:jwks-info"))
+            jwks_uri = "{}{}".format(host, reverse("oauth2_provider:jwks-info"))
+
         signing_algorithms = [Application.HS256_ALGORITHM]
         if oauth2_settings.OIDC_RSA_PRIVATE_KEY:
             signing_algorithms = [Application.RS256_ALGORITHM, Application.HS256_ALGORITHM]


Test patch:
diff --git a/tests/presets.py b/tests/presets.py
--- a/tests/presets.py
+++ b/tests/presets.py
@@ -9,8 +9,8 @@
 DEFAULT_SCOPES_RO = {"DEFAULT_SCOPES": ["read"]}
 OIDC_SETTINGS_RW = {
     "OIDC_ENABLED": True,
-    "OIDC_ISS_ENDPOINT": "http://localhost",
-    "OIDC_USERINFO_ENDPOINT": "http://localhost/userinfo/",
+    "OIDC_ISS_ENDPOINT": "http://localhost/o",
+    "OIDC_USERINFO_ENDPOINT": "http://localhost/o/userinfo/",
     "OIDC_RSA_PRIVATE_KEY": settings.OIDC_RSA_PRIVATE_KEY,
     "SCOPES": {
         "read": "Reading scope",
diff --git a/tests/test_oidc_views.py b/tests/test_oidc_views.py
--- a/tests/test_oidc_views.py
+++ b/tests/test_oidc_views.py
@@ -12,10 +12,10 @@
 class TestConnectDiscoveryInfoView(TestCase):
     def test_get_connect_discovery_info(self):
         expected_response = {
-            "issuer": "http://localhost",
+            "issuer": "http://localhost/o",
             "authorization_endpoint": "http://localhost/o/authorize/",
             "token_endpoint": "http://localhost/o/token/",
-            "userinfo_endpoint": "http://localhost/userinfo/",
+            "userinfo_endpoint": "http://localhost/o/userinfo/",
             "jwks_uri": "http://localhost/o/.well-known/jwks.json",
             "response_types_supported": [
                 "code",