@@ -293,7 +293,7 @@ from django.contrib.auth import authenticate
293293from django.contrib.sites.models import Site
294294from django.contrib.sites.shortcuts import get_current_site
295295from django.core.exceptions import PermissionDenied
296- from django.db import models
296+ ~~ from django.db import models
297297from django.utils.crypto import get_random_string
298298
299299import allauth.app_settings
@@ -312,60 +312,13 @@ from .adapter import get_adapter
312312from .fields import JSONField
313313
314314
315- class SocialAppManager (models .Manager ):
316- def get_current (self , provider , request = None ):
317- cache = {}
318- if request:
319- cache = getattr (request, ' _socialapp_cache' , {})
320- request._socialapp_cache = cache
321- app = cache.get(provider)
322- if not app:
323- site = get_current_site(request)
324- app = self .get(
325- sites__id = site.id,
326- provider = provider)
327- cache[provider] = app
328- return app
329-
330-
331- @python_2_unicode_compatible
332- class SocialApp (models .Model ):
333- objects = SocialAppManager()
334-
335- provider = models.CharField(verbose_name = _(' provider' ),
336- max_length = 30 ,
337- choices = providers.registry.as_choices())
338- name = models.CharField(verbose_name = _(' name' ),
339- max_length = 40 )
340- client_id = models.CharField(verbose_name = _(' client id' ),
341- max_length = 191 ,
342- help_text = _(' App ID, or consumer key' ))
343- secret = models.CharField(verbose_name = _(' secret key' ),
344- max_length = 191 ,
345- help_text = _(' API secret, client secret, or'
346- ' consumer secret' ))
347- key = models.CharField(verbose_name = _(' key' ),
348- max_length = 191 ,
349- blank = True ,
350- help_text = _(' Key' ))
351- # Most apps can be used across multiple domains, therefore we use
352- # a ManyToManyField. Note that Facebook requires an app per domain
353- # (unless the domains share a common base name).
354- # blank=True allows for disabling apps without removing them
355- sites = models.ManyToManyField(Site, blank = True )
356-
357- class Meta :
358- verbose_name = _(' social application' )
359- verbose_name_plural = _(' social applications' )
360-
361- def __str__ (self ):
362- return self .name
315+ # # ... source file abbreviated to get to ForeignKey examples ...
363316
364317
365318@python_2_unicode_compatible
366319class SocialAccount (models .Model ):
367- user = models.ForeignKey(allauth.app_settings.USER_MODEL ,
368- on_delete = models.CASCADE )
320+ ~~ user = models.ForeignKey(allauth.app_settings.USER_MODEL ,
321+ ~~ on_delete = models.CASCADE )
369322 provider = models.CharField(verbose_name = _(' provider' ),
370323 max_length = 30 ,
371324 choices = providers.registry.as_choices())
@@ -401,8 +354,8 @@ class SocialAccount(models.Model):
401354 def authenticate (self ):
402355 return authenticate(account = self )
403356
404- def __str__ (self ):
405- return force_str(self .user)
357+ ~~ def __str__ (self ):
358+ ~~ return force_str(self .user)
406359
407360 def get_profile_url (self ):
408361 return self .get_provider_account().get_profile_url()
@@ -419,8 +372,8 @@ class SocialAccount(models.Model):
419372
420373@python_2_unicode_compatible
421374class SocialToken (models .Model ):
422- app = models.ForeignKey(SocialApp, on_delete = models.CASCADE )
423- account = models.ForeignKey(SocialAccount, on_delete = models.CASCADE )
375+ ~~ app = models.ForeignKey(SocialApp, on_delete = models.CASCADE )
376+ ~~ account = models.ForeignKey(SocialAccount, on_delete = models.CASCADE )
424377 token = models.TextField(
425378 verbose_name = _(' token' ),
426379 help_text = _(
@@ -442,174 +395,7 @@ class SocialToken(models.Model):
442395 return self .token
443396
444397
445- class SocialLogin (object ):
446- """
447- Represents a social user that is in the process of being logged
448- in. This consists of the following information:
449-
450- `account` (`SocialAccount` instance): The social account being
451- logged in. Providers are not responsible for checking whether or
452- not an account already exists or not. Therefore, a provider
453- typically creates a new (unsaved) `SocialAccount` instance. The
454- `User` instance pointed to by the account (`account.user`) may be
455- prefilled by the provider for use as a starting point later on
456- during the signup process.
457-
458- `token` (`SocialToken` instance): An optional access token token
459- that results from performing a successful authentication
460- handshake.
461-
462- `state` (`dict`): The state to be preserved during the
463- authentication handshake. Note that this state may end up in the
464- url -- do not put any secrets in here. It currently only contains
465- the url to redirect to after login.
466-
467- `email_addresses` (list of `EmailAddress`): Optional list of
468- e-mail addresses retrieved from the provider.
469- """
470-
471- def __init__ (self , user = None , account = None , token = None ,
472- email_addresses = []):
473- if token:
474- assert token.account is None or token.account == account
475- self .token = token
476- self .user = user
477- self .account = account
478- self .email_addresses = email_addresses
479- self .state = {}
480-
481- def connect (self , request , user ):
482- self .user = user
483- self .save(request, connect = True )
484-
485- def serialize (self ):
486- serialize_instance = get_adapter().serialize_instance
487- ret = dict (account = serialize_instance(self .account),
488- user = serialize_instance(self .user),
489- state = self .state,
490- email_addresses = [serialize_instance(ea)
491- for ea in self .email_addresses])
492- if self .token:
493- ret[' token' ] = serialize_instance(self .token)
494- return ret
495-
496- @ classmethod
497- def deserialize (cls , data ):
498- deserialize_instance = get_adapter().deserialize_instance
499- account = deserialize_instance(SocialAccount, data[' account' ])
500- user = deserialize_instance(get_user_model(), data[' user' ])
501- if ' token' in data:
502- token = deserialize_instance(SocialToken, data[' token' ])
503- else :
504- token = None
505- email_addresses = []
506- for ea in data[' email_addresses' ]:
507- email_address = deserialize_instance(EmailAddress, ea)
508- email_addresses.append(email_address)
509- ret = cls ()
510- ret.token = token
511- ret.account = account
512- ret.user = user
513- ret.email_addresses = email_addresses
514- ret.state = data[' state' ]
515- return ret
516-
517- def save (self , request , connect = False ):
518- """
519- Saves a new account. Note that while the account is new,
520- the user may be an existing one (when connecting accounts)
521- """
522- assert not self .is_existing
523- user = self .user
524- user.save()
525- self .account.user = user
526- self .account.save()
527- if app_settings.STORE_TOKENS and self .token:
528- self .token.account = self .account
529- self .token.save()
530- if connect:
531- # TODO : Add any new email addresses automatically?
532- pass
533- else :
534- setup_user_email(request, user, self .email_addresses)
535-
536- @ property
537- def is_existing (self ):
538- """
539- Account is temporary, not yet backed by a database record.
540- """
541- return self .account.pk is not None
542-
543- def lookup (self ):
544- """
545- Lookup existing account, if any.
546- """
547- assert not self .is_existing
548- try :
549- a = SocialAccount.objects.get(provider = self .account.provider,
550- uid = self .account.uid)
551- # Update account
552- a.extra_data = self .account.extra_data
553- self .account = a
554- self .user = self .account.user
555- a.save()
556- # Update token
557- if app_settings.STORE_TOKENS and self .token:
558- assert not self .token.pk
559- try :
560- t = SocialToken.objects.get(account = self .account,
561- app = self .token.app)
562- t.token = self .token.token
563- if self .token.token_secret:
564- # only update the refresh token if we got one
565- # many oauth2 providers do not resend the refresh token
566- t.token_secret = self .token.token_secret
567- t.expires_at = self .token.expires_at
568- t.save()
569- self .token = t
570- except SocialToken.DoesNotExist:
571- self .token.account = a
572- self .token.save()
573- except SocialAccount.DoesNotExist:
574- pass
575-
576- def get_redirect_url (self , request ):
577- url = self .state.get(' next' )
578- return url
579-
580- @ classmethod
581- def state_from_request (cls , request ):
582- state = {}
583- next_url = get_next_redirect_url(request)
584- if next_url:
585- state[' next' ] = next_url
586- state[' process' ] = get_request_param(request, ' process' , ' login' )
587- state[' scope' ] = get_request_param(request, ' scope' , ' ' )
588- state[' auth_params' ] = get_request_param(request, ' auth_params' , ' ' )
589- return state
590-
591- @ classmethod
592- def stash_state (cls , request ):
593- state = cls .state_from_request(request)
594- verifier = get_random_string()
595- request.session[' socialaccount_state' ] = (state, verifier)
596- return verifier
597-
598- @ classmethod
599- def unstash_state (cls , request ):
600- if ' socialaccount_state' not in request.session:
601- raise PermissionDenied()
602- state, verifier = request.session.pop(' socialaccount_state' )
603- return state
604-
605- @ classmethod
606- def verify_and_unstash_state (cls , request , verifier ):
607- if ' socialaccount_state' not in request.session:
608- raise PermissionDenied()
609- state, verifier2 = request.session.pop(' socialaccount_state' )
610- if verifier != verifier2:
611- raise PermissionDenied()
612- return state
398+ # # ... source file continues with no further ForeignKey examples ...
613399
614400```
615401
0 commit comments