This project has tools for managing trusted user agents. For example, you might allow the user to indicate whether they are using a public or private computer and implement different policies for each. Or you might be using a two-factor authentication scheme, allowing the users to bypass the second factor on machines that they designate as trusted. This uses Django 1.4’s signed cookie facility and operates independently of sessions.
Short list of features:
- request.agent.is_trusted tells you whether the request came from a trusted agent.
- APIs to trust or revoke the agent that made a given request.
- Global, per-user, and per-agent settings can set the duration of agent trust as well as an inactivity timeout.
- Supports session-scoped agent trust for consistency of authorization policies.
- Revoke all of a user’s previously trusted agents at any time.
The mechanisms by which a user is allowed to designate trusted agents is left entirely to clients of this library. For an application of this API using one-time passwords, see django-otp-agents, part of the django-otp suite.
django-agent-trust requires at least Python 2.6 and Django 1.4. It also depends on django.contrib.auth.
A view can determine whether it’s being requested from a trusted agent by checking request.agent.is_trusted. Agent trust is tied to authenticated users; each user gets a different cookie, so multiple users can maintain separate trust settings on your site using the same machine/browser. Anonymous users always have untrusted agents.
AgentMiddleware installs an object on requests that will tell you whether the requesting user agent has been marked trusted and at what time:
Objects of this class will be attached to requests as request.agent. This is not a database model; it will be serialized into a signed cookie. These objects are immutable and should never be instantiated directly. Use the APIs below to manipulate trust.
True if this agent has been marked as trusted.
True if this agent is only trusted for the current session.
The datetime at which this agent was last explicitly trusted, if any.
The datetime at which trust in this agent expires. None if the agent is not trusted or does not expire.
You may optionally install an included context processor to propagate these objects to template contexts:
A context processor that sets the template context variable agent to the value of request.agent.
Agent trust may be persistent or scoped to a session. Of course, the point of the library is the former, but the latter is included to enable more consistent authorization polices. For example, if you ask the user whether they are on a public or shared device, you might set session-scoped trust for public agents and persistent trust for private agents. Your authorization policy can then refer solely to agent trust: for public agents, this will be synonymous with authentication; for private agents, trust will persist across login sessions. Persistent trust is typically implemented with two-factor authentication, where the second factor is used to establish the trusted agent.
You can update the status of the current agent with the following APIs:
Mark the requesting agent as trusted for the currently logged-in user. This does nothing for anonymous users.
Mark the requesting agent as trusted in the context of the current session; when the session ends, the agent’s trust will be revoked. This replaces any agent trust that already exists. All expiration settings and future revocations still apply. This does nothing for anonymous users.
|Parameters:||request (HttpRequest) – The current request.|
Revoke trust in the requesting agent for the currently logged-in user.
|Parameters:||request (HttpRequest) – The current request.|
Similar to login_required(), but requires request.agent.is_trusted to be true. This will frequently be used in conjunction with login_required, unless you’re allowing trusted agents to bypass authentication.
The default value for login_url is AGENT_LOGIN_URL.
django-agent-trust supports two types of trust expiration: simple expiration based on the original trust date and expiration from inactivity. Simple expiration can be managed on three levels: a global setting, a per-user setting, and a setting on the agent itself. Inactivity timeouts can be managed globally and per-user. If any time expirations are specified at multiple levels, the most restrictive takes precedence. All expiration settings are measured in days, although fractional days are permitted.
Agent trust settings for a single user.
FloatField: The number of days this user’s agents will remain trusted. None for no limit. Default is None.
FloatField: The number of days that may elapse between requests from one of this user’s agents before trust is revoked. None for no limit. Default is None.
A custom duration can be set on an individual agent at the time that it is trusted by trust_agent().
The domain to use for agent cookies or None to use a standard domain.
A prefix for agent cookies. This can be anything.
The path set on the agent cookies. This should either match the URL path of your Django installation or be a parent of that path.
Whether to use a secure cookie for the agent cookies. If this is set to True, the cookie will be marked as “secure,” which means browsers may ensure that the cookie is only sent under an HTTPS connection.
The URL where requests are redirected for login when using the trusted_agent_required() decorator.
The number of days an agent will remain trusted. This can be None to impose no limit.
The number of days allowed between requests before an agent’s trust is revoked. This can not be None (all cookies expire eventually), but you can always set it to a very large number.
Copyright (c) 2012, Peter Sagerson All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.