providers/oauth2: accept token as post param
This commit is contained in:
parent
818f417fd8
commit
4b39c71de0
|
@ -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