]> git.parisson.com Git - django-social-auth.git/commitdiff
Merge branch 'estebistec'
authorMatías Aguirre <matiasaguirre@gmail.com>
Mon, 9 Jul 2012 04:47:37 +0000 (01:47 -0300)
committerMatías Aguirre <matiasaguirre@gmail.com>
Mon, 9 Jul 2012 04:47:37 +0000 (01:47 -0300)
Conflicts:
README.rst
doc/contributions.rst
social_auth/models.py

1  2 
README.rst
doc/configuration.rst
doc/contributions.rst
social_auth/backends/__init__.py
social_auth/backends/pipeline/associate.py
social_auth/db/base.py

diff --cc README.rst
index 292b1b60e1621b39b9c692f5c919361cbf13fe66,be4f2ed45a14e0cd26a5af5b0b751633f2f16f08..9abd2741fc7548d5a861146946eb7540d4bbc4c3
@@@ -1343,10 -1289,10 +1363,14 @@@ Attributions to whom deserves
  
    - Evernote support
  
 +- fmoga_ (Florian Moga)
 +
 +  - Mixcloud support
 +
+ - estebistec_ (Steven Cummings)
+   - Overrideable models feature
  
  Copyrights
  ----------
@@@ -1452,7 -1398,6 +1476,10 @@@ Base work is copyrighted by
  .. _Odnoklassniki OAuth: http://dev.odnoklassniki.ru/wiki/display/ok/The+OAuth+2.0+Protocol
  .. _authentication for VKontakte applications: http://www.ikrvss.ru/2011/11/08/django-social-auh-and-vkontakte-application/
  .. _Facebook Canvas Application Authentication: http://www.ikrvss.ru/2011/09/22/django-social-auth-and-facebook-canvas-applications/
 +.. _Mixcloud OAuth2: http://www.mixcloud.com/developers/documentation/#authorization 
 +.. _Mixcloud API: http://www.mixcloud.com/developers/documentation
 +.. _Mixcloud Developers: http://www.mixcloud.com/developers
 +.. _fmoga: https://github.com/fmoga
+ .. _MongoEngine: http://mongoengine.org
+ .. _MongoEngine Django integration: http://mongoengine-odm.readthedocs.org/en/latest/django.html
+ .. _estebistec: https://github.com/estebistec
Simple merge
index 97df20feb47a4dfaf90b03cc6d026406bdda5d33,bfba6e4f9d85af98bb22dda7d222c56980a12578..ae1cb09e08a162ff65e1e42766a322239c6e28e7
@@@ -61,9 -46,8 +61,11 @@@ niQo_ (Nicolas Quiénot
  hassek_ (Tomas Henriquez)
    * Evernote support
  
 +fmoga_ (Florian Moga)
 +  * Mixcloud support
 +
+ estebistec_ (Steven Cummings)
+   * Overrideable models feature
  
  .. _caioariede: https://github.com/caioariede
  .. _krvss: https://github.com/krvss
@@@ -80,7 -64,4 +82,8 @@@
  .. _python-oauth2: https://github.com/simplegeo/python-oauth2
  .. _niQo: https://github.com/niQo
  .. _hassek: https://github.com/hassek
 +.. _fmoga: https://github.com/fmoga
 +.. _revolunet: https://github.com/revolunet
 +.. _r4vi: https://github.com/r4vi
 +.. _danielgtaylor: https://github.com/danielgtaylor
+ .. _estebistec: https://github.com/estebistec
index 01711188e82e0bb68acc844c786de5676c9f4b2d,5acc43b26a25e4c68f99bf80e2a2cda1b3b646ce..fbf59eb944729e27a0ddb24c9badbd746fb9633f
@@@ -24,9 -24,9 +23,10 @@@ from django.contrib.auth.backends impor
  from django.utils import simplejson
  from django.utils.importlib import import_module
  
+ from social_auth.models import UserSocialAuth
  from social_auth.utils import setting, log, model_to_ctype, ctype_to_model, \
 -                              clean_partial_pipeline
 +                              clean_partial_pipeline, url_add_parameters, \
 +                              get_random_string, constant_time_compare
  from social_auth.store import DjangoOpenIDStore
  from social_auth.backends.exceptions import StopPipeline, AuthException, \
                                              AuthFailed, AuthCanceled, \
index 0000000000000000000000000000000000000000,333d3f92c2901f5b9f24226c4447fd275082f034..64885b60e8dd5518d177e16234fa9816b81a8425
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,160 +1,173 @@@
 -from datetime import datetime
+ """Models mixins for Social Auth"""
+ import base64
 -        """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.
++import time
++from datetime import datetime, timedelta
+ from django.utils.timezone import utc
+ from openid.association import Association as OIDAssociation
+ from social_auth.utils import setting
+ class UserSocialAuthMixin(object):
+     User = None
+     user = ''
+     provider = ''
+     def __unicode__(self):
+         """Return associated user unicode representation"""
+         return u'%s - %s' % (unicode(self.user), self.provider.title())
+     @property
+     def tokens(self):
+         """Return access_token stored in extra_data or None"""
+         # Make import here to avoid recursive imports :-/
+         from social_auth.backends import get_backends
+         backend = get_backends().get(self.provider)
+         if backend:
+             return backend.AUTH_BACKEND.tokens(self)
+         else:
+             return {}
+     def expiration_datetime(self):
 -        if self.extra_data:
 -            name = setting('SOCIAL_AUTH_EXPIRATION', 'expires')
++        """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.
+         """
 -                return datetime.utcfromtimestamp(self.extra_data.get(name))\
 -                               .replace(tzinfo=utc)
++        name = setting('SOCIAL_AUTH_EXPIRATION', 'expires')
++        if self.extra_data and name in self.extra_data:
+             try:
 -                pass
 -        return None
++                expires = int(self.extra_data.get(name))
+             except (ValueError, TypeError):
++                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)
+     @classmethod
+     def username_max_length(cls):
+         raise NotImplementedError('Implement in subclass')
+     @classmethod
+     def simple_user_exists(cls, *args, **kwargs):
+         """
+         Return True/False if a User instance exists with the given arguments.
+         Arguments are directly passed to filter() manager method.
+         """
+         return cls.User.objects.filter(*args, **kwargs).count() > 0
+     @classmethod
+     def create_user(cls, *args, **kwargs):
+         return cls.User.objects.create(*args, **kwargs)
+     @classmethod
+     def get_user(cls, pk):
+         try:
+             return cls.User.objects.get(pk=pk)
+         except cls.User.DoesNotExist:
+             return None
+     @classmethod
+     def get_user_by_email(cls, email):
+         return cls.User.objects.get(email=email)
+     @classmethod
+     def resolve_user_or_id(cls, user_or_id):
+         if isinstance(user_or_id, cls.User):
+             return user_or_id
+         return cls.User.objects.get(pk=user_or_id)
+     @classmethod
+     def get_social_auth(cls, provider, uid):
+         try:
+             return cls.objects.get(provider=provider, uid=uid)
+         except cls.DoesNotExist:
+             return None
+     @classmethod
+     def get_social_auth_for_user(cls, user):
+         return user.social_auth.all()
+     @classmethod
+     def create_social_auth(cls, user, uid, provider):
+         return cls.objects.create(user=user, uid=uid, provider=provider)
+     @classmethod
+     def store_association(cls, server_url, association):
+         from social_auth.models import Association
+         args = {'server_url': server_url, 'handle': association.handle}
+         try:
+             assoc = Association.objects.get(**args)
+         except Association.DoesNotExist:
+             assoc = Association(**args)
+         assoc.secret = base64.encodestring(association.secret)
+         assoc.issued = association.issued
+         assoc.lifetime = association.lifetime
+         assoc.assoc_type = association.assoc_type
+         assoc.save()
+     @classmethod
+     def get_oid_associations(cls, server_url, handle=None):
+         from social_auth.models import Association
+         args = {'server_url': server_url}
+         if handle is not None:
+             args['handle'] = handle
+         return sorted([
+                 (assoc.id,
+                  OIDAssociation(assoc.handle,
+                                 base64.decodestring(assoc.secret),
+                                 assoc.issued,
+                                 assoc.lifetime,
+                                 assoc.assoc_type))
+                 for assoc in Association.objects.filter(**args)
+         ], key=lambda x: x[1].issued, reverse=True)
+     @classmethod
+     def delete_associations(cls, ids_to_delete):
+         from social_auth.models import Association
+         Association.objects.filter(pk__in=ids_to_delete).delete()
+     @classmethod
+     def use_nonce(cls, server_url, timestamp, salt):
+         from social_auth.models import Nonce
+         return Nonce.objects.get_or_create(server_url=server_url,
+                                            timestamp=timestamp,
+                                            salt=salt)[1]
+ class NonceMixin(object):
+     """One use numbers"""
+     server_url = ''
+     timestamp = 0
+     salt = ''
+     def __unicode__(self):
+         """Unicode representation"""
+         return self.server_url
+ class AssociationMixin(object):
+     """OpenId account association"""
+     server_url = ''
+     handle = ''
+     secret = ''
+     issued = 0
+     lifetime = 0
+     assoc_type = ''
+     def __unicode__(self):
+         """Unicode representation"""
+         return '%s %s' % (self.handle, self.issued)