providers/oauth2: accept token as post param
This commit is contained in:
		| @ -1,6 +1,8 @@ | |||||||
| """Proxy and Outpost e2e tests""" | """Proxy and Outpost e2e tests""" | ||||||
|  | from sys import platform | ||||||
| from time import sleep | from time import sleep | ||||||
| from typing import Any, Dict, Optional | from typing import Any, Dict, Optional | ||||||
|  | from unittest.case import skipUnless | ||||||
|  |  | ||||||
| from docker.client import DockerClient, from_env | from docker.client import DockerClient, from_env | ||||||
| from docker.models.containers import Container | from docker.models.containers import Container | ||||||
| @ -14,6 +16,7 @@ from passbook.outposts.models import Outpost, OutpostDeploymentType, OutpostType | |||||||
| from passbook.providers.proxy.models import ProxyProvider | from passbook.providers.proxy.models import ProxyProvider | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @skipUnless(platform.startswith("linux"), "requires local docker") | ||||||
| class TestProviderProxy(SeleniumTestCase): | class TestProviderProxy(SeleniumTestCase): | ||||||
|     """Proxy and Outpost e2e tests""" |     """Proxy and Outpost e2e tests""" | ||||||
|  |  | ||||||
|  | |||||||
| @ -17,7 +17,6 @@ from docker.models.containers import Container | |||||||
| from selenium import webdriver | from selenium import webdriver | ||||||
| from selenium.webdriver.common.desired_capabilities import DesiredCapabilities | from selenium.webdriver.common.desired_capabilities import DesiredCapabilities | ||||||
| from selenium.webdriver.remote.webdriver import WebDriver | from selenium.webdriver.remote.webdriver import WebDriver | ||||||
| from selenium.webdriver.support import expected_conditions as ec |  | ||||||
| from selenium.webdriver.support.ui import WebDriverWait | from selenium.webdriver.support.ui import WebDriverWait | ||||||
| from structlog import get_logger | from structlog import get_logger | ||||||
|  |  | ||||||
| @ -91,7 +90,7 @@ class SeleniumTestCase(StaticLiveServerTestCase): | |||||||
|     def wait_for_url(self, desired_url): |     def wait_for_url(self, desired_url): | ||||||
|         """Wait until URL is `desired_url`.""" |         """Wait until URL is `desired_url`.""" | ||||||
|         self.wait.until( |         self.wait.until( | ||||||
|             ec.url_to_be(desired_url), |             lambda driver: driver.current_url == desired_url, | ||||||
|             f"URL {self.driver.current_url} doesn't match expected URL {desired_url}", |             f"URL {self.driver.current_url} doesn't match expected URL {desired_url}", | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  | |||||||
| @ -3,6 +3,8 @@ from django.apps.registry import Apps | |||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
| from django.db.backends.base.schema import BaseDatabaseSchemaEditor | from django.db.backends.base.schema import BaseDatabaseSchemaEditor | ||||||
|  |  | ||||||
|  | import passbook.core.models | ||||||
|  |  | ||||||
|  |  | ||||||
| def create_default_admin_group(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): | def create_default_admin_group(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): | ||||||
|     db_alias = schema_editor.connection.alias |     db_alias = schema_editor.connection.alias | ||||||
| @ -42,9 +44,6 @@ class Migration(migrations.Migration): | |||||||
|         ), |         ), | ||||||
|         migrations.RunPython(create_default_admin_group), |         migrations.RunPython(create_default_admin_group), | ||||||
|         migrations.AlterModelManagers( |         migrations.AlterModelManagers( | ||||||
|             name='user', |             name="user", managers=[("objects", passbook.core.models.UserManager()),], | ||||||
|             managers=[ |  | ||||||
|                 ('objects', passbook.core.models.UserManager()), |  | ||||||
|             ], |  | ||||||
|         ), |         ), | ||||||
|     ] |     ] | ||||||
|  | |||||||
| @ -6,18 +6,39 @@ from django.db import migrations, models | |||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ('passbook_providers_oauth2', '0002_oauth2provider_sub_mode'), |         ("passbook_providers_oauth2", "0002_oauth2provider_sub_mode"), | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     operations = [ |     operations = [ | ||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='oauth2provider', |             model_name="oauth2provider", | ||||||
|             name='client_type', |             name="client_type", | ||||||
|             field=models.CharField(choices=[('confidential', 'Confidential'), ('public', 'Public')], default='confidential', help_text='Confidential clients are capable of maintaining the confidentiality\n    of their credentials. Public clients are incapable.', max_length=30, verbose_name='Client Type'), |             field=models.CharField( | ||||||
|  |                 choices=[("confidential", "Confidential"), ("public", "Public")], | ||||||
|  |                 default="confidential", | ||||||
|  |                 help_text="Confidential clients are capable of maintaining the confidentiality\n    of their credentials. Public clients are incapable.", | ||||||
|  |                 max_length=30, | ||||||
|  |                 verbose_name="Client Type", | ||||||
|  |             ), | ||||||
|         ), |         ), | ||||||
|         migrations.AlterField( |         migrations.AlterField( | ||||||
|             model_name='oauth2provider', |             model_name="oauth2provider", | ||||||
|             name='response_type', |             name="response_type", | ||||||
|             field=models.TextField(choices=[('code', 'code (Authorization Code Flow)'), ('code_adfs', 'code (ADFS Compatibility Mode, sends id_token as access_token)'), ('id_token', 'id_token (Implicit Flow)'), ('id_token token', 'id_token token (Implicit Flow)'), ('code token', 'code token (Hybrid Flow)'), ('code id_token', 'code id_token (Hybrid Flow)'), ('code id_token token', 'code id_token token (Hybrid Flow)')], default='code', help_text='Response Type required by the client.'), |             field=models.TextField( | ||||||
|  |                 choices=[ | ||||||
|  |                     ("code", "code (Authorization Code Flow)"), | ||||||
|  |                     ( | ||||||
|  |                         "code_adfs", | ||||||
|  |                         "code (ADFS Compatibility Mode, sends id_token as access_token)", | ||||||
|  |                     ), | ||||||
|  |                     ("id_token", "id_token (Implicit Flow)"), | ||||||
|  |                     ("id_token token", "id_token token (Implicit Flow)"), | ||||||
|  |                     ("code token", "code token (Hybrid Flow)"), | ||||||
|  |                     ("code id_token", "code id_token (Hybrid Flow)"), | ||||||
|  |                     ("code id_token token", "code id_token token (Hybrid Flow)"), | ||||||
|  |                 ], | ||||||
|  |                 default="code", | ||||||
|  |                 help_text="Response Type required by the client.", | ||||||
|  |             ), | ||||||
|         ), |         ), | ||||||
|     ] |     ] | ||||||
|  | |||||||
| @ -70,7 +70,10 @@ class ResponseTypes(models.TextChoices): | |||||||
|     """Response Type required by the client.""" |     """Response Type required by the client.""" | ||||||
|  |  | ||||||
|     CODE = "code", _("code (Authorization Code Flow)") |     CODE = "code", _("code (Authorization Code Flow)") | ||||||
|     CODE_ADFS = "code_adfs", _("code (ADFS Compatibility Mode, sends id_token as access_token)") |     CODE_ADFS = ( | ||||||
|  |         "code_adfs", | ||||||
|  |         _("code (ADFS Compatibility Mode, sends id_token as access_token)"), | ||||||
|  |     ) | ||||||
|     ID_TOKEN = "id_token", _("id_token (Implicit Flow)") |     ID_TOKEN = "id_token", _("id_token (Implicit Flow)") | ||||||
|     ID_TOKEN_TOKEN = "id_token token", _("id_token token (Implicit Flow)") |     ID_TOKEN_TOKEN = "id_token token", _("id_token token (Implicit Flow)") | ||||||
|     CODE_TOKEN = "code token", _("code token (Hybrid Flow)") |     CODE_TOKEN = "code token", _("code token (Hybrid Flow)") | ||||||
|  | |||||||
| @ -61,11 +61,12 @@ def extract_access_token(request: HttpRequest) -> str: | |||||||
|     auth_header = request.META.get("HTTP_AUTHORIZATION", "") |     auth_header = request.META.get("HTTP_AUTHORIZATION", "") | ||||||
|  |  | ||||||
|     if re.compile(r"^[Bb]earer\s{1}.+$").match(auth_header): |     if re.compile(r"^[Bb]earer\s{1}.+$").match(auth_header): | ||||||
|         access_token = auth_header.split()[1] |         return auth_header.split()[1] | ||||||
|     else: |     if "access_token" in request.POST: | ||||||
|         access_token = request.GET.get("access_token", "") |         return request.POST.get("access_token") | ||||||
|  |     if "access_token" in request.GET: | ||||||
|     return access_token |         return request.GET.get("access_token") | ||||||
|  |     return "" | ||||||
|  |  | ||||||
|  |  | ||||||
| def extract_client_auth(request: HttpRequest) -> Tuple[str, str]: | def extract_client_auth(request: HttpRequest) -> Tuple[str, str]: | ||||||
|  | |||||||
| @ -17,7 +17,8 @@ from passbook.providers.oauth2.errors import TokenError, UserAuthError | |||||||
| from passbook.providers.oauth2.models import ( | from passbook.providers.oauth2.models import ( | ||||||
|     AuthorizationCode, |     AuthorizationCode, | ||||||
|     OAuth2Provider, |     OAuth2Provider, | ||||||
|     RefreshToken, ResponseTypes, |     RefreshToken, | ||||||
|  |     ResponseTypes, | ||||||
| ) | ) | ||||||
| from passbook.providers.oauth2.utils import TokenResponse, extract_client_auth | from passbook.providers.oauth2.utils import TokenResponse, extract_client_auth | ||||||
|  |  | ||||||
|  | |||||||
| @ -6605,8 +6605,8 @@ definitions: | |||||||
|       client_type: |       client_type: | ||||||
|         title: Client Type |         title: Client Type | ||||||
|         description: |- |         description: |- | ||||||
|           <b>Confidential</b> clients are capable of maintaining the confidentiality |           Confidential clients are capable of maintaining the confidentiality | ||||||
|               of their credentials. <b>Public</b> clients are incapable. |               of their credentials. Public clients are incapable. | ||||||
|         type: string |         type: string | ||||||
|         enum: |         enum: | ||||||
|           - confidential |           - confidential | ||||||
| @ -6626,6 +6626,7 @@ definitions: | |||||||
|         type: string |         type: string | ||||||
|         enum: |         enum: | ||||||
|           - code |           - code | ||||||
|  |           - code_adfs | ||||||
|           - id_token |           - id_token | ||||||
|           - id_token token |           - id_token token | ||||||
|           - code token |           - code token | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer