]> git.parisson.com Git - django-social-auth.git/commitdiff
Fix expiration calculation, add django backward compatibility code. Refs #381
authorMatías Aguirre <matiasaguirre@gmail.com>
Tue, 3 Jul 2012 19:43:30 +0000 (16:43 -0300)
committerMatías Aguirre <matiasaguirre@gmail.com>
Tue, 3 Jul 2012 19:43:30 +0000 (16:43 -0300)
social_auth/models.py
social_auth/utils.py
social_auth/views.py

index 87ce08a30c527385eeab9d6bc6e52d12b3a57f03..28a58c1f348969e86435d1a2f439e6fc41c42b97 100644 (file)
@@ -1,9 +1,10 @@
 """Social auth models"""
-from datetime import datetime
+import time
+from datetime import datetime, date, timedelta
 from django.db import models
-from django.utils.timezone import utc
+
 from social_auth.fields import JSONField
-from social_auth.utils import setting
+from social_auth.utils import setting, utc
 
 
 # If User class is overridden, it *must* provide the following fields
@@ -48,17 +49,30 @@ class UserSocialAuth(models.Model):
             return {}
 
     def expiration_datetime(self):
-        """Return saved session expiration seconds if any. Is returned in
-        the form of timezone-aware datetime. None is returned if there's no
-        value stored or it's malformed.
+        """Return provider session live seconds. Returns a timedelta ready to
+        use with session.set_expiry().
+
+        If provider returns a timestamp instead of session seconds to live, the
+        timedelta is inferred from current time (using UTC timezone). None is
+        returned if there's no value stored or it's invalid.
         """
-        if self.extra_data:
-            name = setting('SOCIAL_AUTH_EXPIRATION', 'expires')
+        name = setting('SOCIAL_AUTH_EXPIRATION', 'expires')
+        if self.extra_data and name in self.extra_data:
             try:
-                return datetime.utcfromtimestamp(self.extra_data.get(name)).replace(tzinfo=utc)
+                expires = int(self.extra_data.get(name))
             except (ValueError, TypeError):
-                pass
-        return None
+                return None
+
+            now = datetime.now()
+            now_timestamp = time.mktime(now.timetuple())
+
+            # Detect if expires is a timestamp
+            if expires > now_timestamp:  # expires is a datetime
+                return datetime.utcfromtimestamp(expires) \
+                               .replace(tzinfo=utc) - \
+                       now.replace(tzinfo=utc)
+            else:  # expires is a timedelta
+                return timedelta(seconds=expires)
 
 
 class Nonce(models.Model):
index 7542b054927b9b084932905d3642177a7262df2d..8c383253a498d66e84cff445ae6772ad2b120b20 100644 (file)
@@ -1,11 +1,34 @@
 import urlparse
 import logging
 from collections import defaultdict
+from datetime import timedelta, tzinfo
 
 from django.conf import settings
 from django.db.models import Model
 from django.contrib.contenttypes.models import ContentType
 
+try:
+    from django.utils.timezone import utc as django_utc
+except ImportError:  # django < 1.4
+    class UTC(tzinfo):
+        """UTC implementation taken from django 1.4."""
+        def __repr__(self):
+            return '<UTC>'
+
+        def utcoffset(self, dt):
+            return timedelta(0)
+
+        def tzname(self, dt):
+            return 'UTC'
+
+        def dst(self, dt):
+            return timedelta(0)
+
+    django_utc = None
+
+
+utc = django_utc
+
 
 def sanitize_log_data(secret, data=None, leave_characters=4):
     """
index 8f4bc3cfc452b44885c6f84a39310e76e6ec20c2..fc4966bc6fdce71de3053cec7f07a494216d2f95 100644 (file)
@@ -117,9 +117,10 @@ def complete_process(request, backend, *args, **kwargs):
                 # Set session expiration date if present and not disabled by
                 # setting. Use last social-auth instance for current provider,
                 # users can associate several accounts with a same provider.
-                if social_user.expiration_datetime():
+                expiration = social_user.expiration_datetime()
+                if expiration:
                     try:
-                        request.session.set_expiry(social_user.expiration_datetime())
+                        request.session.set_expiry(expiration)
                     except OverflowError:
                         # Handle django time zone overflow, set default expiry.
                         request.session.set_expiry(None)