<a id="strategies"></a>

# Strategies

Different strategies are defined to encapsulate the different frameworks
capabilities under a common API to reuse as much code as possible.

<a id="description"></a>

## 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.

<a id="implementing-a-new-strategy"></a>

## Implementing a new Strategy

The following methods must be defined on strategies sub-classes.

Request:

```default
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:

```default
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')
```

Settings:

```default
def get_setting(self, name):
    """Return value for given setting name"""
    raise NotImplementedError('Implement in subclass')
```

Responses:

```default
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')
```

<a id="effective-pipeline-request-data"></a>

## 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.

<a id="migrating-to-social-auth-core-6-and-social-auth-app-django-7"></a>

## Migrating to social-auth-core 6 and social-auth-app-django 7

* Rename custom `request_data()` overrides to `get_request_data()`. Keep
  framework extraction, validation, and application-specific defaults in that
  hook; allow the inherited `request_data()` method to handle replay.
* Replace pipeline `request` parameters and `kwargs['request']` reads with
  `strategy.request_data()` for effective parameters, or `strategy.request`
  for a native framework request. Pipeline steps no longer receive an automatic
  `request` argument.
* Upgrade framework adapters together with social-auth-core. Adapters that
  override the old hook must migrate before using core 6.

Partial request data is stored separately from pipeline arguments. Existing
partials with a request mapping in `kwargs['request']` are converted when
loaded, so upgrading does not require a database schema migration or discarding
pending authentication flows.

Partials are bound to their authentication or disconnect pipeline. Legacy
disconnect partials without a pipeline type must restart the disconnect flow
so its permission checks run.
