Back to index

moin  1.9.0~rc2
oid.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - OpenID preferences
00004 
00005     @copyright: 2007     MoinMoin:JohannesBerg
00006     @license: GNU GPL, see COPYING for details.
00007 """
00008 
00009 from MoinMoin import wikiutil, user
00010 from MoinMoin.widget import html
00011 from MoinMoin.userprefs import UserPrefBase
00012 from MoinMoin.support.python_compatibility import hash_new
00013 
00014 try:
00015     from MoinMoin.auth.openidrp import OpenIDAuth
00016     from MoinMoin.util.moinoid import MoinOpenIDStore
00017     from openid.consumer import consumer
00018     from openid.yadis.discover import DiscoveryFailure
00019     from openid.fetchers import HTTPFetchingError
00020     _openid_disabled = False
00021 except ImportError:
00022     _openid_disabled = True
00023 
00024 
00025 class Settings(UserPrefBase):
00026     def __init__(self, request):
00027         """ Initialize OpenID settings form. """
00028         UserPrefBase.__init__(self, request)
00029         self.request = request
00030         self._ = request.getText
00031         self.cfg = request.cfg
00032         _ = self._
00033         self.title = _("OpenID settings")
00034         openid_auth = False
00035         if not _openid_disabled:
00036             for authm in self.request.cfg.auth:
00037                 if isinstance(authm, OpenIDAuth):
00038                     openid_auth = True
00039                     break
00040         if not openid_auth:
00041             self.allowed = lambda: False
00042 
00043     def _handle_remove(self):
00044         _ = self.request.getText
00045         if not hasattr(self.request.user, 'openids'):
00046             return
00047         openids = self.request.user.openids[:]
00048         for oid in self.request.user.openids:
00049             name = "rm-%s" % hash_new('sha1', oid).hexdigest()
00050             if name in self.request.form:
00051                 openids.remove(oid)
00052         if not openids and len(self.request.cfg.auth) == 1:
00053             return 'error', _("Cannot remove all OpenIDs.")
00054         self.request.user.openids = openids
00055         self.request.user.save()
00056         return 'info', _("The selected OpenIDs have been removed.")
00057 
00058     def _handle_add(self):
00059         _ = self.request.getText
00060         request = self.request
00061 
00062         openid_id = request.form.get('openid_identifier', '')
00063         if not openid_id:
00064             return 'error', _("No OpenID given.")
00065 
00066         if (hasattr(self.request.user, 'openids') and
00067             openid_id in request.user.openids):
00068             return 'error', _("OpenID is already present.")
00069 
00070         oidconsumer = consumer.Consumer(request.session,
00071                                         MoinOpenIDStore(self.request))
00072         try:
00073             oidreq = oidconsumer.begin(openid_id)
00074         except HTTPFetchingError:
00075             return 'error', _('Failed to resolve OpenID.')
00076         except DiscoveryFailure:
00077             return 'error', _('OpenID discovery failure, not a valid OpenID.')
00078         else:
00079             if oidreq is None:
00080                 return 'error', _("No OpenID given.") # ??
00081 
00082             qstr = {'action': 'userprefs',
00083                     'handler': 'oid',
00084                     'oid.return': '1'}
00085             return_to = request.getQualifiedURL(request.page.url(request, qstr))
00086             trust_root = request.url_root
00087             if oidreq.shouldSendRedirect():
00088                 redirect_url = oidreq.redirectURL(trust_root, return_to)
00089                 request.http_redirect(redirect_url)
00090             else:
00091                 form_html = oidreq.formMarkup(trust_root, return_to,
00092                     form_tag_attrs={'id': 'openid_message'})
00093                 request.session['openid.prefs.form_html'] = form_html
00094 
00095 
00096     def _handle_oidreturn(self):
00097         request = self.request
00098         _ = request.getText
00099 
00100         oidconsumer = consumer.Consumer(request.session,
00101                                         MoinOpenIDStore(request))
00102         query = {}
00103         for key in request.form:
00104             query[key] = request.form[key]
00105         qstr = {'action': 'userprefs',
00106                 'handler': 'oid',
00107                 'oid.return': '1'}
00108         return_to = request.getQualifiedURL(request.page.url(request, qstr))
00109         info = oidconsumer.complete(query, return_to)
00110         if info.status == consumer.FAILURE:
00111             return 'error', _('OpenID error: %s.') % info.message
00112         elif info.status == consumer.CANCEL:
00113             return 'info', _('Verification canceled.')
00114         elif info.status == consumer.SUCCESS:
00115             if not hasattr(self.request.user, 'openids'):
00116                 request.user.openids = []
00117 
00118             if info.identity_url in request.user.openids:
00119                 return 'error', _("OpenID is already present.")
00120 
00121             if user.getUserIdByOpenId(request, info.identity_url):
00122                 return 'error', _("This OpenID is already used for another account.")
00123 
00124             # all fine
00125             request.user.openids.append(info.identity_url)
00126             request.user.save()
00127             return 'info', _("OpenID added successfully.")
00128         else:
00129             return 'error', _('OpenID failure.')
00130 
00131 
00132     def handle_form(self):
00133         _ = self._
00134         form = self.request.form
00135 
00136         if self.request.values.has_key('oid.return'):
00137             return self._handle_oidreturn()
00138 
00139         if form.has_key('cancel'):
00140             return
00141 
00142         if self.request.method != 'POST':
00143             return
00144 
00145         if form.has_key('remove'):
00146             return self._handle_remove()
00147 
00148         if form.has_key('add'):
00149             return self._handle_add()
00150 
00151         return
00152 
00153     def _make_form(self):
00154         action = "%s%s" % (self.request.script_root, self.request.path)
00155         _form = html.FORM(action=action)
00156         _form.append(html.INPUT(type="hidden", name="action", value="userprefs"))
00157         _form.append(html.INPUT(type="hidden", name="handler", value="oid"))
00158         return _form
00159 
00160     def _make_row(self, label, cell, **kw):
00161         """ Create a row in the form table.
00162         """
00163         self._table.append(html.TR().extend([
00164             html.TD(**kw).extend([html.B().append(label), '   ']),
00165             html.TD().extend(cell),
00166         ]))
00167 
00168     def _oidlist(self):
00169         _ = self.request.getText
00170         form = self._make_form()
00171         for oid in self.request.user.openids:
00172             name = "rm-%s" % hash_new('sha1', oid).hexdigest()
00173             form.append(html.INPUT(type="checkbox", name=name, id=name))
00174             form.append(html.LABEL(for_=name).append(html.Text(oid)))
00175             form.append(html.BR())
00176         self._make_row(_("Current OpenIDs"), [form], valign='top')
00177         label = _("Remove selected")
00178         form.append(html.BR())
00179         form.append(html.INPUT(type="submit", name="remove", value=label))
00180 
00181     def _addoidform(self):
00182         _ = self.request.getText
00183         form = self._make_form()
00184         # go back to this page
00185         form.append(html.INPUT(type="hidden", name="sub", value="oid"))
00186         label = _("Add OpenID")
00187         form.append(html.INPUT(type="text", size="32",
00188                                name="openid_identifier",
00189                                id="openididentifier"))
00190         form.append(html.BR())
00191         form.append(html.INPUT(type="submit", name="add", value=label))
00192         self._make_row(_('Add OpenID'), [form])
00193 
00194     def create_form(self):
00195         """ Create the complete HTML form code. """
00196         _ = self._
00197 
00198         ret = html.P()
00199         # Use the user interface language and direction
00200         lang_attr = self.request.theme.ui_lang_attr()
00201         ret.append(html.Raw('<div %s>' % lang_attr))
00202         self._table = html.TABLE(border="0")
00203         ret.append(self._table)
00204         ret.append(html.Raw("</div>"))
00205 
00206         request = self.request
00207 
00208         if 'openid.prefs.form_html' in request.session:
00209             txt = _('OpenID verification requires that you click this button:')
00210             # create JS to automatically submit the form if possible
00211             submitjs = """<script type="text/javascript">
00212 <!--//
00213 document.getElementById("openid_message").submit();
00214 //-->
00215 </script>
00216 """
00217             oidhtml = request.session['openid.prefs.form_html']
00218             del request.session['openid.prefs.form_html']
00219             return ''.join([txt, oidhtml, submitjs])
00220 
00221         if hasattr(request.user, 'openids') and request.user.openids:
00222             self._oidlist()
00223         self._addoidform()
00224 
00225         form = self._make_form()
00226         label = _("Cancel")
00227         form.append(html.INPUT(type="submit", name='cancel', value=label))
00228         self._make_row('', [form])
00229         return unicode(ret)