Strategies¶
Different strategies are defined to encapsulate the different frameworks capabilities under a common API to reuse as much code as possible.
Description¶
A strategy’s responsibility is to provide access to:
Request data and host information and URI building
Session access
Project settings
Response types (HTML and redirects)
HTML rendering
Different frameworks implement these features on different ways, thus the need for these interfaces.
Implementing a new Strategy¶
The following methods must be defined on strategies sub-classes.
Request:
def get_request_data(self, merge=True):
"""Return current framework request data (POST or GET)"""
raise NotImplementedError('Implement in subclass')
def request_host(self):
"""Return current host value"""
raise NotImplementedError('Implement in subclass')
def build_absolute_uri(self, path=None):
"""Build absolute URI with given (optional) path"""
raise NotImplementedError('Implement in subclass')
Session:
def session_get(self, name):
"""Return session value for given key"""
raise NotImplementedError('Implement in subclass')
def session_set(self, name, value):
"""Set session value for given key"""
raise NotImplementedError('Implement in subclass')
def session_pop(self, name):
"""Pop session value for given key"""
raise NotImplementedError('Implement in subclass')
get_session_id() and restore_session() have been removed from the
strategy interface. Callbacks must use the initiating browser’s session;
custom backends that used these methods need to migrate to browser-bound
correlation.
Settings:
def get_setting(self, name):
"""Return value for given setting name"""
raise NotImplementedError('Implement in subclass')
Responses:
def html(self, content):
"""Return HTTP response with given content"""
raise NotImplementedError('Implement in subclass')
def redirect(self, url):
"""Return a response redirect to the given URL"""
raise NotImplementedError('Implement in subclass')
def render_html(self, tpl=None, html=None, context=None):
"""Render given template or raw html with given context"""
raise NotImplementedError('Implement in subclass')
BaseStrategy.html_with_headers(content, headers) is a required strategy
hook for returning HTML with the specified HTTP headers. SAML POST callbacks
use it for a protected browser return page. Integrations must implement this
hook using their framework’s response API. A custom strategy without the hook
fails closed during SAML completion. The Django strategy implements it.
Effective pipeline request data¶
strategy.request holds the native framework request, when the integration
provides one. It is never replaced by saved partial-pipeline parameters.
strategy.get_request_data(merge=True) reads the current framework request.
With merge=False, it reads the data for the current request method, following
the framework integration’s existing behavior. Custom strategies implement this
hook instead of overriding request_data().
strategy.request_data(merge=True) returns the effective parameters for the
active pipeline. During a partial resume, this includes any confirmed data
replayed from an external validation link. Both values of merge return the
same effective mapping during replay, because saved data no longer has a
separate GET or POST origin. Use get_request_data(), request_get(), or
request_post() when the current framework request is required.
The effective mapping is scoped to execution of the resumed authentication or
disconnect pipeline. The previous mapping is restored when execution completes,
returns a response, or raises an exception. Nested executions restore the outer
mapping. Integration code can establish the same scope with
strategy.pipeline_request_data(data) as a context manager.