Skip to content

Commit

Permalink
Merge pull request #74 from blag/custom-auth-code-templates
Browse files Browse the repository at this point in the history
  • Loading branch information
Colin-b authored Feb 12, 2024
2 parents e928e2b + 67797d1 commit 8a1abd7
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 27 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ with httpx.Client() as client:
| `timeout` | Maximum amount of seconds to wait for a code or a token to be received once requested. | Optional | 60 |
| `success_display_time` | In case a code is successfully received, this is the maximum amount of milliseconds the success page will be displayed in your browser. | Optional | 1 |
| `failure_display_time` | In case received code is not valid, this is the maximum amount of milliseconds the failure page will be displayed in your browser. | Optional | 5000 |
| `success_template` | HTML content to render to the browser upon successfully receiving an authorization code from the authorization server. Will be formatted with `text` and `display_time` parameters. | Optional | |
| `failure_template` | HTML content to render to the browser upon successfully receiving an authorization code from the authorization server. Will be formatted with `text` and `display_time` parameters. | Optional | |
| `header_name` | Name of the header field used to send token. | Optional | Authorization |
| `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} |
| `response_type` | Value of the response_type query parameter if not already provided in authorization URL. | Optional | code |
Expand Down Expand Up @@ -137,6 +139,8 @@ with httpx.Client() as client:
| `timeout` | Maximum amount of seconds to wait for a token to be received once requested. | Optional | 60 |
| `success_display_time` | In case a token is successfully received, this is the maximum amount of milliseconds the success page will be displayed in your browser. | Optional | 1 |
| `failure_display_time` | In case received token is not valid, this is the maximum amount of milliseconds the failure page will be displayed in your browser. | Optional | 5000 |
| `success_template` | HTML content to render to the browser upon successfully receiving an authorization code from the authorization server. Will be formatted with `text` and `display_time` parameters. | Optional | |
| `failure_template` | HTML content to render to the browser upon successfully receiving an authorization code from the authorization server. Will be formatted with `text` and `display_time` parameters. | Optional | |
| `header_name` | Name of the header field used to send token. | Optional | Authorization |
| `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} |
| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | |
Expand Down Expand Up @@ -181,6 +185,8 @@ with httpx.Client() as client:
| `timeout` | Maximum amount of seconds to wait for a token to be received once requested. | Optional | 60 |
| `success_display_time` | In case a token is successfully received, this is the maximum amount of milliseconds the success page will be displayed in your browser. | Optional | 1 |
| `failure_display_time` | In case received token is not valid, this is the maximum amount of milliseconds the failure page will be displayed in your browser. | Optional | 5000 |
| `success_template` | HTML content to render to the browser upon successfully receiving an authorization code from the authorization server. Will be formatted with `text` and `display_time` parameters. | Optional | |
| `failure_template` | HTML content to render to the browser upon successfully receiving an authorization code from the authorization server. Will be formatted with `text` and `display_time` parameters. | Optional | |
| `header_name` | Name of the header field used to send token. | Optional | Authorization |
| `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} |
| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | |
Expand Down Expand Up @@ -212,6 +218,8 @@ with httpx.Client() as client:
| `timeout` | Maximum amount of seconds to wait for a code or a token to be received once requested. | Optional | 60 |
| `success_display_time` | In case a code is successfully received, this is the maximum amount of milliseconds the success page will be displayed in your browser. | Optional | 1 |
| `failure_display_time` | In case received code is not valid, this is the maximum amount of milliseconds the failure page will be displayed in your browser. | Optional | 5000 |
| `success_template` | HTML content to render to the browser upon successfully receiving an authorization code from the authorization server. Will be formatted with `text` and `display_time` parameters. | Optional | |
| `failure_template` | HTML content to render to the browser upon successfully receiving an authorization code from the authorization server. Will be formatted with `text` and `display_time` parameters. | Optional | |
| `header_name` | Name of the header field used to send token. | Optional | Authorization |
| `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} |
| `response_type` | Value of the response_type query parameter if not already provided in authorization URL. | Optional | code |
Expand Down Expand Up @@ -270,6 +278,8 @@ with httpx.Client() as client:
| `timeout` | Maximum amount of seconds to wait for a token to be received once requested. | Optional | 60 |
| `success_display_time` | In case a token is successfully received, this is the maximum amount of milliseconds the success page will be displayed in your browser. | Optional | 1 |
| `failure_display_time` | In case received token is not valid, this is the maximum amount of milliseconds the failure page will be displayed in your browser. | Optional | 5000 |
| `success_template` | HTML content to render to the browser upon successfully receiving an authorization code from the authorization server. Will be formatted with `text` and `display_time` parameters. | Optional | |
| `failure_template` | HTML content to render to the browser upon successfully receiving an authorization code from the authorization server. Will be formatted with `text` and `display_time` parameters. | Optional | |
| `header_name` | Name of the header field used to send token. | Optional | Authorization |
| `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} |
| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | |
Expand Down
30 changes: 30 additions & 0 deletions httpx_auth/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,10 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs):
:param failure_display_time: In case received code is not valid,
this is the maximum amount of milliseconds the failure page will be displayed in your browser.
Display the page for 5 seconds by default.
:param success_template: HTML content to render to the browser upon successfully receiving an
authorization code from the authorization server. Will be formatted with 'text' and 'display_time' parameters.
:param failure_template: HTML content to render to the browser upon failing to receive an
authorization code from the authorization server. Will be formatted with 'text' and 'display_time' parameters.
:param header_name: Name of the header field used to send token.
Token will be sent in Authorization header field by default.
:param header_value: Format used to send the token value.
Expand Down Expand Up @@ -389,6 +393,9 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs):
if not self.token_url:
raise Exception("Token URL is mandatory.")

success_template = kwargs.pop("success_template", None)
failure_template = kwargs.pop("failure_template", None)

BrowserAuth.__init__(self, kwargs)

self.header_name = kwargs.pop("header_name", None) or "Authorization"
Expand Down Expand Up @@ -438,6 +445,8 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs):
self.success_display_time,
self.failure_display_time,
self.redirect_uri_port,
reception_success_template=success_template,
reception_failure_template=failure_template,
)

# As described in https://tools.ietf.org/html/rfc6749#section-4.1.3
Expand Down Expand Up @@ -514,6 +523,10 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs):
:param failure_display_time: In case received code is not valid,
this is the maximum amount of milliseconds the failure page will be displayed in your browser.
Display the page for 5 seconds by default.
:param success_template: HTML content to render to the browser upon successfully receiving an
authorization code from the authorization server. Will be formatted with 'text' and 'display_time' parameters.
:param failure_template: HTML content to render to the browser upon failing to receive an
authorization code from the authorization server. Will be formatted with 'text' and 'display_time' parameters.
:param header_name: Name of the header field used to send token.
Token will be sent in Authorization header field by default.
:param header_value: Format used to send the token value.
Expand Down Expand Up @@ -543,6 +556,9 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs):
if not self.token_url:
raise Exception("Token URL is mandatory.")

success_template = kwargs.pop("success_template", None)
failure_template = kwargs.pop("failure_template", None)

BrowserAuth.__init__(self, kwargs)

self.client = kwargs.pop("client", None)
Expand Down Expand Up @@ -601,6 +617,8 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs):
self.success_display_time,
self.failure_display_time,
self.redirect_uri_port,
reception_success_template=success_template,
reception_failure_template=failure_template,
)

# As described in https://tools.ietf.org/html/rfc6749#section-4.1.3
Expand Down Expand Up @@ -1043,6 +1061,10 @@ def __init__(self, instance: str, client_id: str, **kwargs):
:param failure_display_time: In case received token is not valid,
this is the maximum amount of milliseconds the failure page will be displayed in your browser.
Display the page for 5 seconds by default.
:param success_template: HTML content to render to the browser upon successfully receiving an
authorization code from the authorization server. Will be formatted with 'text' and 'display_time' parameters.
:param failure_template: HTML content to render to the browser upon failing to receive an
authorization code from the authorization server. Will be formatted with 'text' and 'display_time' parameters.
:param header_name: Name of the header field used to send token.
Token will be sent in Authorization header field by default.
:param header_value: Format used to send the token value.
Expand Down Expand Up @@ -1104,6 +1126,10 @@ def __init__(
:param failure_display_time: In case received token is not valid,
this is the maximum amount of milliseconds the failure page will be displayed in your browser.
Display the page for 5 seconds by default.
:param success_template: HTML content to render to the browser upon successfully receiving an
authorization code from the authorization server. Will be formatted with 'text' and 'display_time' parameters.
:param failure_template: HTML content to render to the browser upon failing to receive an
authorization code from the authorization server. Will be formatted with 'text' and 'display_time' parameters.
:param header_name: Name of the header field used to send token.
Token will be sent in Authorization header field by default.
:param header_value: Format used to send the token value.
Expand Down Expand Up @@ -1162,6 +1188,10 @@ def __init__(self, instance: str, client_id: str, **kwargs):
:param failure_display_time: In case received token is not valid,
this is the maximum amount of milliseconds the failure page will be displayed in your browser.
Display the page for 5 seconds by default.
:param success_template: HTML content to render to the browser upon successfully receiving an
authorization code from the authorization server. Will be formatted with 'text' and 'display_time' parameters.
:param failure_template: HTML content to render to the browser upon failing to receive an
authorization code from the authorization server. Will be formatted with 'text' and 'display_time' parameters.
:param header_name: Name of the header field used to send token.
Token will be sent in Authorization header field by default.
:param header_value: Format used to send the token value.
Expand Down
62 changes: 44 additions & 18 deletions httpx_auth/oauth2_authentication_responses_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import parse_qs, urlparse
from socket import socket
from typing import Optional

import httpx

Expand Down Expand Up @@ -91,26 +92,16 @@ def send_html(self, html_content: str) -> None:
logger.debug("HTML content sent to client.")

def success_page(self, text: str) -> str:
return f"""<body onload="window.open('', '_self', ''); window.setTimeout(close, {self.server.grant_details.reception_success_display_time})" style="
color: #4F8A10;
background-color: #DFF2BF;
font-size: xx-large;
display: flex;
align-items: center;
justify-content: center;">
<div style="border: 1px solid;">{text}</div>
</body>"""
return self.server.grant_details.success_page_template.format(
display_time=self.server.grant_details.reception_success_display_time,
text=text,
)

def error_page(self, text: str) -> str:
return f"""<body onload="window.open('', '_self', ''); window.setTimeout(close, {self.server.grant_details.reception_failure_display_time})" style="
color: #D8000C;
background-color: #FFBABA;
font-size: xx-large;
display: flex;
align-items: center;
justify-content: center;">
<div style="border: 1px solid;">{text}</div>
</body>"""
return self.server.grant_details.failure_page_template.format(
display_time=self.server.grant_details.reception_failure_display_time,
text=text,
)

def fragment_redirect_page(self) -> str:
"""Return a page with JS that calls back the server on the url
Expand All @@ -137,6 +128,33 @@ def log_message(self, format: str, *args) -> None:


class GrantDetails:
DEFAULT_SUCCESS_TEMPLATE = """
<!DOCTYPE html>
<html>
<body onload="window.open('', '_self', ''); window.setTimeout(close, {display_time})"
style="color: #4F8A10;
background-color: #DFF2BF;
font-size: xx-large;
display: flex;
align-items: center;
justify-content: center;">
<div style="border: 1px solid; padding: 8px;">{text}</div>
</body>
</html>"""
DEFAULT_FAILURE_TEMPLATE = """
<!DOCTYPE html>
<html>
<body onload="window.open('', '_self', ''); window.setTimeout(close, {display_time})"
style="color: #D8000C;
background-color: #FFBABA;
font-size: xx-large;
display: flex;
align-items: center;
justify-content: center;">
<div style="border: 1px solid; padding: 8px;">{text}</div>
</body>
</html>"""

def __init__(
self,
url: str,
Expand All @@ -145,10 +163,18 @@ def __init__(
reception_success_display_time: int,
reception_failure_display_time: int,
redirect_uri_port: int,
reception_success_template: Optional[str] = None,
reception_failure_template: Optional[str] = None,
):
self.url = url
self.name = name
self.reception_timeout = reception_timeout
self.success_page_template = (
reception_success_template or GrantDetails.DEFAULT_SUCCESS_TEMPLATE
)
self.failure_page_template = (
reception_failure_template or GrantDetails.DEFAULT_FAILURE_TEMPLATE
)
self.reception_success_display_time = reception_success_display_time
self.reception_failure_display_time = reception_failure_display_time
self.redirect_uri_port = redirect_uri_port
Expand Down
Loading

0 comments on commit 8a1abd7

Please sign in to comment.