diff --git a/e2e/test_provider_proxy.py b/e2e/test_provider_proxy.py
index bc90d3c8a..617b65178 100644
--- a/e2e/test_provider_proxy.py
+++ b/e2e/test_provider_proxy.py
@@ -1,6 +1,8 @@
"""Proxy and Outpost e2e tests"""
+from sys import platform
from time import sleep
from typing import Any, Dict, Optional
+from unittest.case import skipUnless
from docker.client import DockerClient, from_env
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
+@skipUnless(platform.startswith("linux"), "requires local docker")
class TestProviderProxy(SeleniumTestCase):
"""Proxy and Outpost e2e tests"""
diff --git a/e2e/utils.py b/e2e/utils.py
index 5592c6a68..f48d3aaa1 100644
--- a/e2e/utils.py
+++ b/e2e/utils.py
@@ -17,7 +17,6 @@ from docker.models.containers import Container
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.remote.webdriver import WebDriver
-from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from structlog import get_logger
@@ -91,7 +90,7 @@ class SeleniumTestCase(StaticLiveServerTestCase):
def wait_for_url(self, desired_url):
"""Wait until URL is `desired_url`."""
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}",
)
diff --git a/passbook/core/migrations/0009_group_is_superuser.py b/passbook/core/migrations/0009_group_is_superuser.py
index a69a3ebbb..cc7fcc497 100644
--- a/passbook/core/migrations/0009_group_is_superuser.py
+++ b/passbook/core/migrations/0009_group_is_superuser.py
@@ -3,6 +3,8 @@ from django.apps.registry import Apps
from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
+import passbook.core.models
+
def create_default_admin_group(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
@@ -42,9 +44,6 @@ class Migration(migrations.Migration):
),
migrations.RunPython(create_default_admin_group),
migrations.AlterModelManagers(
- name='user',
- managers=[
- ('objects', passbook.core.models.UserManager()),
- ],
+ name="user", managers=[("objects", passbook.core.models.UserManager()),],
),
]
diff --git a/passbook/providers/oauth2/migrations/0003_auto_20200916_2129.py b/passbook/providers/oauth2/migrations/0003_auto_20200916_2129.py
index b1d37983c..1f2f806ff 100644
--- a/passbook/providers/oauth2/migrations/0003_auto_20200916_2129.py
+++ b/passbook/providers/oauth2/migrations/0003_auto_20200916_2129.py
@@ -6,18 +6,39 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('passbook_providers_oauth2', '0002_oauth2provider_sub_mode'),
+ ("passbook_providers_oauth2", "0002_oauth2provider_sub_mode"),
]
operations = [
migrations.AlterField(
- model_name='oauth2provider',
- 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'),
+ model_name="oauth2provider",
+ 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(
- model_name='oauth2provider',
- 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.'),
+ model_name="oauth2provider",
+ 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.",
+ ),
),
]
diff --git a/passbook/providers/oauth2/models.py b/passbook/providers/oauth2/models.py
index 6f15f4282..8d904c83b 100644
--- a/passbook/providers/oauth2/models.py
+++ b/passbook/providers/oauth2/models.py
@@ -70,7 +70,10 @@ class ResponseTypes(models.TextChoices):
"""Response Type required by the client."""
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_TOKEN = "id_token token", _("id_token token (Implicit Flow)")
CODE_TOKEN = "code token", _("code token (Hybrid Flow)")
diff --git a/passbook/providers/oauth2/utils.py b/passbook/providers/oauth2/utils.py
index 6d5a18e30..909725a27 100644
--- a/passbook/providers/oauth2/utils.py
+++ b/passbook/providers/oauth2/utils.py
@@ -61,11 +61,12 @@ def extract_access_token(request: HttpRequest) -> str:
auth_header = request.META.get("HTTP_AUTHORIZATION", "")
if re.compile(r"^[Bb]earer\s{1}.+$").match(auth_header):
- access_token = auth_header.split()[1]
- else:
- access_token = request.GET.get("access_token", "")
-
- return access_token
+ return auth_header.split()[1]
+ if "access_token" in request.POST:
+ return request.POST.get("access_token")
+ if "access_token" in request.GET:
+ return request.GET.get("access_token")
+ return ""
def extract_client_auth(request: HttpRequest) -> Tuple[str, str]:
diff --git a/passbook/providers/oauth2/views/token.py b/passbook/providers/oauth2/views/token.py
index 84eb4262d..2ff9e4683 100644
--- a/passbook/providers/oauth2/views/token.py
+++ b/passbook/providers/oauth2/views/token.py
@@ -17,7 +17,8 @@ from passbook.providers.oauth2.errors import TokenError, UserAuthError
from passbook.providers.oauth2.models import (
AuthorizationCode,
OAuth2Provider,
- RefreshToken, ResponseTypes,
+ RefreshToken,
+ ResponseTypes,
)
from passbook.providers.oauth2.utils import TokenResponse, extract_client_auth
diff --git a/swagger.yaml b/swagger.yaml
index ac57ced14..523dd7575 100755
--- a/swagger.yaml
+++ b/swagger.yaml
@@ -6605,8 +6605,8 @@ definitions:
client_type:
title: Client Type
description: |-
- Confidential clients are capable of maintaining the confidentiality
- of their credentials. Public clients are incapable.
+ Confidential clients are capable of maintaining the confidentiality
+ of their credentials. Public clients are incapable.
type: string
enum:
- confidential
@@ -6626,6 +6626,7 @@ definitions:
type: string
enum:
- code
+ - code_adfs
- id_token
- id_token token
- code token