strategy.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # coding=utf-8
  2. from django.conf import settings
  3. from django.http import HttpResponse, HttpRequest
  4. from django.db.models import Model
  5. from django.contrib.contenttypes.models import ContentType
  6. from django.contrib.auth import authenticate
  7. from django.shortcuts import redirect, resolve_url
  8. from django.template import TemplateDoesNotExist, loader, engines
  9. from django.utils.crypto import get_random_string
  10. from django.utils.encoding import force_text
  11. from django.utils.functional import Promise
  12. from django.utils.translation import get_language
  13. from social_core.strategy import BaseStrategy, BaseTemplateStrategy
  14. from .compat import get_request_port
  15. def render_template_string(request, html, context=None):
  16. """Take a template in the form of a string and render it for the
  17. given context"""
  18. template = engines['django'].from_string(html)
  19. return template.render(context=context, request=request)
  20. class DjangoTemplateStrategy(BaseTemplateStrategy):
  21. def render_template(self, tpl, context):
  22. template = loader.get_template(tpl)
  23. return template.render(context=context, request=self.strategy.request)
  24. def render_string(self, html, context):
  25. return render_template_string(self.strategy.request, html, context)
  26. class DjangoStrategy(BaseStrategy):
  27. DEFAULT_TEMPLATE_STRATEGY = DjangoTemplateStrategy
  28. def __init__(self, storage, request=None, tpl=None):
  29. self.request = request
  30. self.session = request.session if request else {}
  31. super(DjangoStrategy, self).__init__(storage, tpl)
  32. def get_setting(self, name):
  33. value = getattr(settings, name)
  34. # Force text on URL named settings that are instance of Promise
  35. if name.endswith('_URL'):
  36. if isinstance(value, Promise):
  37. value = force_text(value)
  38. value = resolve_url(value)
  39. return value
  40. def request_data(self, merge=True):
  41. if not self.request:
  42. return {}
  43. if merge:
  44. data = self.request.GET.copy()
  45. data.update(self.request.POST)
  46. elif self.request.method == 'POST':
  47. data = self.request.POST
  48. else:
  49. data = self.request.GET
  50. return data
  51. def request_host(self):
  52. if self.request:
  53. return self.request.get_host()
  54. def request_is_secure(self):
  55. """Is the request using HTTPS?"""
  56. return self.request.is_secure()
  57. def request_path(self):
  58. """path of the current request"""
  59. return self.request.path
  60. def request_port(self):
  61. """Port in use for this request"""
  62. return get_request_port(request=self.request)
  63. def request_get(self):
  64. """Request GET data"""
  65. return self.request.GET.copy()
  66. def request_post(self):
  67. """Request POST data"""
  68. return self.request.POST.copy()
  69. def redirect(self, url):
  70. return redirect(url)
  71. def html(self, content):
  72. return HttpResponse(content, content_type='text/html;charset=UTF-8')
  73. def render_html(self, tpl=None, html=None, context=None):
  74. if not tpl and not html:
  75. raise ValueError('Missing template or html parameters')
  76. context = context or {}
  77. try:
  78. template = loader.get_template(tpl)
  79. return template.render(context=context, request=self.request)
  80. except (TypeError, TemplateDoesNotExist):
  81. return render_template_string(self.request, html, context)
  82. def authenticate(self, backend, *args, **kwargs):
  83. kwargs['strategy'] = self
  84. kwargs['storage'] = self.storage
  85. kwargs['backend'] = backend
  86. return authenticate(*args, **kwargs)
  87. def clean_authenticate_args(self, request, *args, **kwargs):
  88. # pipelines don't want a positional request argument
  89. kwargs['request'] = request
  90. return args, kwargs
  91. def session_get(self, name, default=None):
  92. return self.session.get(name, default)
  93. def session_set(self, name, value):
  94. self.session[name] = value
  95. if hasattr(self.session, 'modified'):
  96. self.session.modified = True
  97. def session_pop(self, name):
  98. return self.session.pop(name, None)
  99. def session_setdefault(self, name, value):
  100. return self.session.setdefault(name, value)
  101. def build_absolute_uri(self, path=None):
  102. if self.request:
  103. return self.request.build_absolute_uri(path)
  104. else:
  105. return path
  106. def random_string(self, length=12, chars=BaseStrategy.ALLOWED_CHARS):
  107. return get_random_string(length, chars)
  108. def to_session_value(self, val):
  109. """Converts values that are instance of Model to a dictionary
  110. with enough information to retrieve the instance back later."""
  111. if isinstance(val, Model):
  112. val = {
  113. 'pk': val.pk,
  114. 'ctype': ContentType.objects.get_for_model(val).pk
  115. }
  116. return val
  117. def from_session_value(self, val):
  118. """Converts back the instance saved by self._ctype function."""
  119. if isinstance(val, dict) and 'pk' in val and 'ctype' in val:
  120. ctype = ContentType.objects.get_for_id(val['ctype'])
  121. ModelClass = ctype.model_class()
  122. val = ModelClass.objects.get(pk=val['pk'])
  123. return val
  124. def get_language(self):
  125. """Return current language"""
  126. return get_language()