Source code for django_agent_trust.models

from __future__ import unicode_literals

from datetime import datetime, timedelta
from time import mktime

import django.conf
from django.db import models
from django.utils import six

from .conf import settings


SESSION_TOKEN_KEY = 'django-agent-trust-token'


[docs]class AgentSettings(models.Model): """ Agent trust settings for a single user. .. attribute:: user *OneToOneField*: The :class:`~django.contrib.auth.models.User` (or custom user model) this belongs to. .. attribute:: trust_days *FloatField*: The number of days this user's agents will remain trusted. ``None`` for no limit. Default is ``None``. .. attribute:: inactivity_days *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``. """ user = models.OneToOneField(getattr(django.conf.settings, 'AUTH_USER_MODEL', 'auth.User')) trust_days = models.FloatField(blank=True, null=True, default=None, help_text="The number of days a agent will remain trusted.") inactivity_days = models.FloatField(blank=True, null=True, default=None, help_text="The number of days allowed between requests before a agent's trust is revoked.") serial = models.IntegerField(default=0, help_text="Increment this to revoke all previously trusted agents.") def __str__(self): if six.PY3: return self.__unicode__() else: return unicode(self).encode('utf-8') def __unicode__(self): username = self.user.get_username() if hasattr(self.user, 'get_username') else self.user.username return u"AgentSettings: {0}".format(username)
[docs]class Agent(object): """ 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. """ def __init__(self, user, is_trusted, trusted_at, trust_days, serial, session): self._user = user self._is_trusted = is_trusted self._trusted_at = trusted_at.replace(microsecond=0) if (trusted_at is not None) else None self._trust_days = trust_days self._serial = serial self._session = session @classmethod def untrusted_agent(cls, user): return cls(user, False, None, None, -1, None) @classmethod def trusted_agent(cls, user, trust_days=None): if user.is_anonymous(): raise ValueError("Can't create a trusted agent for an anonymous user.") return cls(user, True, datetime.now(), trust_days, user.agentsettings.serial, None) @classmethod def session_agent(cls, user, token): if user.is_anonymous(): raise ValueError("Can't create a trusted agent for an anonymous user.") return cls(user, True, datetime.now(), None, user.agentsettings.serial, token) @property def user(self): return self._user @property
[docs] def is_trusted(self): """ ``True`` if this agent has been marked as trusted. """ return self._is_trusted
@property
[docs] def is_session(self): """ ``True`` if this agent is only trusted for the current session. """ return (self._session is not None)
@property
[docs] def trusted_at(self): """ The datetime at which this agent was last explicitly trusted, if any. """ return self._trusted_at
@property def trust_days(self): return self._trust_days @property def serial(self): return self._serial @property def session(self): return self._session @property
[docs] def trust_expiration(self): """ The datetime at which trust in this agent expires. ``None`` if the agent is not trusted or does not expire. """ if not hasattr(self, '_trust_expiration'): self._trust_expiration = self._get_trust_expiration() return self._trust_expiration
def _get_trust_expiration(self): if (not self.is_trusted) or (self.trusted_at is None): return None prefs = [d for d in [settings.AGENT_TRUST_DAYS, self.user.agentsettings.trust_days, self.trust_days] if d is not None] if len(prefs) > 0: expiration = self.trusted_at + timedelta(days=min(prefs)) else: expiration = None return expiration def to_jsonable(self): return { 'username': self.user.get_username() if hasattr(self.user, 'get_username') else self.user.username, 'is_trusted': self.is_trusted, 'trusted_at': self._trusted_at_timestamp(), 'trust_days': self.trust_days, 'serial': self.serial, 'session': self.session, } def _trusted_at_timestamp(self): if self.trusted_at is not None: timestamp = int(mktime(self.trusted_at.timetuple())) else: timestamp = None return timestamp @classmethod def from_jsonable(cls, jsonable, user): is_trusted = jsonable.get('is_trusted', False) trusted_at = jsonable.get('trusted_at', None) trust_days = jsonable.get('trust_days', None) serial = jsonable.get('serial', -1) session = jsonable.get('session', None) if trusted_at is not None: trusted_at = datetime.fromtimestamp(trusted_at) return cls(user, is_trusted, trusted_at, trust_days, serial, session)