3 from django.utils.html import escape
 
   4 from django.http import get_host
 
   6 from forum.authentication.base import AuthenticationConsumer, InvalidAuthentication
 
   9 from openid.yadis import xri
 
  10 from openid.consumer.consumer import Consumer, SUCCESS, CANCEL, FAILURE, SETUP_NEEDED
 
  11 from openid.consumer.discover import DiscoveryFailure
 
  12 from openid.extensions.sreg import SRegRequest, SRegResponse
 
  13 from openid.extensions.ax import FetchRequest as AXFetchRequest, AttrInfo, FetchResponse as AXFetchResponse
 
  14 from django.utils.translation import ugettext as _
 
  16 from store import OsqaOpenIDStore
 
  18 class OpenIdAbstractAuthConsumer(AuthenticationConsumer):
 
  21         'username': 'http://axschema.org/namePerson/friendly',
 
  22         'email': 'http://axschema.org/contact/email',
 
  23         #'web': 'http://axschema.org/contact/web/default',
 
  24         #'firstname': 'http://axschema.org/namePerson/first',
 
  25         #'lastname': 'http://axschema.org/namePerson/last',
 
  26         #'birthdate': 'http://axschema.org/birthDate',
 
  32             "nickname": "username"
 
  36     def get_user_url(self, request):
 
  38             return request.POST['openid_identifier']
 
  40             raise NotImplementedError()
 
  42     def prepare_authentication_request(self, request, redirect_to):
 
  43         if not redirect_to.startswith('http://') or redirect_to.startswith('https://'):
 
  44                     redirect_to =  get_url_host(request) + redirect_to
 
  46         user_url = self.get_user_url(request)
 
  48         if xri.identifierScheme(user_url) == 'XRI' and getattr(
 
  49             settings, 'OPENID_DISALLOW_INAMES', False
 
  51             raise InvalidAuthentication('i-names are not supported')
 
  53         consumer = Consumer(request.session, OsqaOpenIDStore())
 
  56             auth_request = consumer.begin(user_url)
 
  57         except DiscoveryFailure:
 
  58             raise InvalidAuthentication(_('Sorry, but your input is not a valid OpenId'))
 
  60         sreg = getattr(self, 'sreg_attributes', False)
 
  65             for k, attr_dic in sreg.items():
 
  67                     s.policy_url = attr_dic
 
  70                 for attr_name in attr_dic.keys():
 
  71                     s.requestField(field_name=attr_name, required=(k == "required"))
 
  73             auth_request.addExtension(s)
 
  75         ax_schema = getattr(self, 'dataype2ax_schema', False)
 
  77         if ax_schema and request.session.get('force_email_request', True):
 
  78             axr = AXFetchRequest()
 
  79             for data_type, schema in ax_schema.items():
 
  80                 if isinstance(schema, tuple):
 
  81                     axr.add(AttrInfo(schema[0], 1, True, schema[1]))
 
  83                     axr.add(AttrInfo(schema, 1, True, data_type))
 
  85             auth_request.addExtension(axr)
 
  88             settings, 'OPENID_TRUST_ROOT', get_url_host(request) + '/'
 
  91         return auth_request.redirectURL(trust_root, redirect_to)
 
  93     def process_authentication_request(self, request):
 
  94         consumer = Consumer(request.session, OsqaOpenIDStore())
 
  97             (k.encode('utf8'), v.encode('utf8')) for k, v in request.GET.items()
 
 100         #for i in query_dict.items():
 
 103         url = get_url_host(request) + request.path
 
 104         openid_response = consumer.complete(query_dict, url)
 
 106         if openid_response.status == SUCCESS:
 
 110             sreg_attrs = getattr(self, 'sreg_attributes', False)
 
 113                 sreg_response = SRegResponse.fromSuccessResponse(openid_response)
 
 117                     [all_attrs.update(d) for k,d in sreg_attrs.items() if k != "policy_url"]
 
 119                     for attr_name, local_name in all_attrs.items():
 
 120                         if attr_name in sreg_response:
 
 121                             consumer_data[local_name] = sreg_response[attr_name]
 
 123             ax_schema = getattr(self, 'dataype2ax_schema', False)
 
 126                 ax = AXFetchResponse.fromSuccessResponse(openid_response)
 
 129                     axargs = ax.getExtensionArgs()
 
 131                     ax_schema2data_type = dict([(s, t) for t, s in ax_schema.items()])
 
 133                     available_types = dict([
 
 134                         (ax_schema2data_type[s], re.sub('^type\.', '', n))
 
 135                         for n, s in axargs.items() if s in ax_schema2data_type
 
 138                     for t, s in available_types.items():
 
 139                         if not t in consumer_data:
 
 140                             if axargs.get("value.%s.1" % s, None):
 
 141                                 consumer_data[t] = axargs["value.%s.1" % s]
 
 143             request.session['auth_consumer_data'] = consumer_data
 
 146             return request.GET['openid.identity']
 
 147         elif openid_response.status == CANCEL:
 
 148             raise InvalidAuthentication(_('The OpenId authentication request was canceled'))
 
 149         elif openid_response.status == FAILURE:
 
 150             raise InvalidAuthentication(_('The OpenId authentication failed: ') + openid_response.message)
 
 151         elif openid_response.status == SETUP_NEEDED:
 
 152             raise InvalidAuthentication(_('Setup needed'))
 
 154             raise InvalidAuthentication(_('The OpenId authentication failed with an unknown status: ') + openid_response.status)
 
 156     def get_user_data(self, key):
 
 159 def get_url_host(request):
 
 160     if request.is_secure():
 
 164     host = escape(get_host(request))
 
 165     return '%s://%s' % (protocol, host)
 
 167 def get_full_url(request):
 
 168     return get_url_host(request) + request.get_full_path()