Back to index

moin  1.9.0~rc2
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes
MoinMoin.action.serveopenid.MoinOpenIDServer Class Reference

List of all members.

Public Member Functions

def __init__
def serveYadisEP
def serveYadisIDP
def handleCheckIDRequest
def handle
def handle_response
def approved
def user_trusts_url
def show_decide_page

Public Attributes

 request
 cfg

Private Member Functions

def _verify_endpoint_identity
def _make_identity
def _sorry_no_identity

Private Attributes

 _

Detailed Description

Definition at line 26 of file serveopenid.py.


Constructor & Destructor Documentation

def MoinMoin.action.serveopenid.MoinOpenIDServer.__init__ (   self,
  pagename,
  request 
)

Definition at line 27 of file serveopenid.py.

00027 
00028     def __init__(self, pagename, request):
00029         self.request = request
00030         self._ = request.getText
00031         self.cfg = request.cfg


Member Function Documentation

Definition at line 161 of file serveopenid.py.

00161 
00162     def _make_identity(self):
00163         page = wikiutil.getHomePage(self.request)
00164         if page:
00165             server_url = self.request.getQualifiedURL(
00166                              page.url(self.request, querystr={'action': 'serveopenid'}))
00167             identity = self.request.getQualifiedURL(page.url(self.request))
00168             return identity, server_url
00169         return None, None

Here is the caller graph for this function:

Definition at line 387 of file serveopenid.py.

00387 
00388     def _sorry_no_identity(self):
00389         request = self.request
00390         _ = self._
00391 
00392         request.theme.send_title(_("OpenID not served"), pagename=request.page.page_name)
00393         # Start content (important for RTL support)
00394         request.write(request.formatter.startContent("content"))
00395 
00396         request.write(request.formatter.paragraph(1))
00397         request.write(_('''
00398 Unfortunately you have not created your homepage yet. Therefore,
00399 we cannot serve an OpenID for you. Please create your homepage first
00400 and then reload this page or click the button below to cancel this
00401 verification.'''))
00402         request.write(request.formatter.paragraph(0))
00403 
00404         form = html.FORM(method='POST', action=request.page.url(request))
00405         form.append(html.INPUT(type='hidden', name='action', value='serveopenid'))
00406 
00407         nonce = randomString(32, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
00408         form.append(html.INPUT(type='hidden', name='nonce', value=nonce))
00409         request.session['openidserver.nonce'] = nonce
00410 
00411         form.append(html.INPUT(type='submit', name='dontapprove', value=_("Cancel")))
00412 
00413         request.write(unicode(form))
00414 
00415         request.write(request.formatter.endContent())
00416         request.theme.send_footer(request.page.page_name)
00417         request.theme.send_closing_html()

Here is the caller graph for this function:

   Verify that the given identity matches the current endpoint.

   We always serve out /UserName?action=... for the UserName
   OpenID and this is pure paranoia to make sure it is that way
   on incoming data.

   Also verify that the given identity is allowed to have an OpenID.

Definition at line 105 of file serveopenid.py.

00105 
00106     def _verify_endpoint_identity(self, identity):
00107         """
00108            Verify that the given identity matches the current endpoint.
00109 
00110            We always serve out /UserName?action=... for the UserName
00111            OpenID and this is pure paranoia to make sure it is that way
00112            on incoming data.
00113 
00114            Also verify that the given identity is allowed to have an OpenID.
00115         """
00116         request = self.request
00117         cfg = request.cfg
00118 
00119         # we can very well split on the last slash since usernames
00120         # must not contain slashes
00121         base, received_name = rsplit(identity, '/', 1)
00122         check_name = received_name
00123 
00124         if received_name == '':
00125             pg = wikiutil.getFrontPage(request)
00126             if pg:
00127                 received_name = pg.page_name
00128                 check_name = received_name
00129                 if 'openid.user' in pg.pi:
00130                     received_name = pg.pi['openid.user']
00131 
00132         # some sanity checking
00133         # even if someone goes to http://johannes.sipsolutions.net/
00134         # we'll serve out http://johannes.sipsolutions.net/JohannesBerg?action=serveopenid
00135         # (if JohannesBerg is set as page_front_page)
00136         # For the #OpenIDUser PI, we need to allow the page that includes the PI,
00137         # hence use check_name here (see above for how it is assigned)
00138         fullidentity = '/'.join([base, check_name])
00139         thisurl = request.getQualifiedURL(request.page.url(request))
00140         if not thisurl == fullidentity:
00141             return False
00142 
00143         # again, we never put an openid.server link on this page...
00144         # why are they here?
00145         openid_group_name = cfg.openid_server_restricted_users_group
00146         if openid_group_name and received_name not in request.groups.get(openid_group_name, []):
00147             return False
00148 
00149         return True

Here is the caller graph for this function:

def MoinMoin.action.serveopenid.MoinOpenIDServer.approved (   self,
  identity,
  openidreq,
  server_url = None 
)

Definition at line 288 of file serveopenid.py.

00288 
00289     def approved(self, identity, openidreq, server_url=None):
00290         # TODO: If simple registration is implemented, this needs
00291         #       to do something like the following:
00292         #
00293         #       sreg_data = { fill this dict with real values }
00294         #       sreq_req = sreg.SRegRequest.fromOpenIDRequest(openidreq.message)
00295         #       # do something with the request to see what values are required?
00296         #       sreg_resp = sreg.SRegResponse.extractResponse(openidreq, sreg_data)
00297         #       sreg_resp.addToOpenIDResponse(reply.fields)
00298 
00299         reply = openidreq.answer(True, identity=identity, server_url=server_url)
00300         return reply

Here is the caller graph for this function:

Definition at line 170 of file serveopenid.py.

00170 
00171     def handle(self):
00172         _ = self._
00173         request = self.request
00174         form = request.form
00175 
00176         username = request.page.page_name
00177         if 'openid.user' in request.page.pi:
00178             username = request.page.pi['openid.user']
00179 
00180 
00181         if not request.cfg.openid_server_enabled:
00182             # since we didn't put any openid.server into
00183             # the page to start with, this is someone trying
00184             # to abuse us. No need to give a nice error
00185             request.makeForbidden(403, '')
00186             return
00187 
00188         server_url = request.getQualifiedURL(
00189                          request.page.url(request, querystr={'action': 'serveopenid'}))
00190 
00191         yadis_type = form.get('yadis')
00192         if yadis_type == 'ep':
00193             return self.serveYadisEP(server_url)
00194         elif yadis_type == 'idp':
00195             return self.serveYadisIDP(server_url)
00196 
00197         # if the identity is set it must match the server URL
00198         # sort of arbitrary, but we have to have some restriction
00199         identity = form.get('openid.identity')
00200         if identity == IDENTIFIER_SELECT:
00201             identity, server_url = self._make_identity()
00202             if not identity:
00203                 return self._sorry_no_identity()
00204             username = request.user.name
00205         elif identity is not None:
00206             if not self._verify_endpoint_identity(identity):
00207                 request.makeForbidden(403, 'verification failed')
00208                 return
00209 
00210         if 'openid.user' in request.page.pi:
00211             username = request.page.pi['openid.user']
00212 
00213         store = MoinOpenIDStore(request)
00214         openidsrv = server.Server(store, op_endpoint=server_url)
00215 
00216         answer = None
00217         if 'dontapprove' in form:
00218             answer = self.handle_response(False, username, identity)
00219             if answer is None:
00220                 return
00221         elif form.has_key('approve'):
00222             answer = self.handle_response(True, username, identity)
00223             if answer is None:
00224                 return
00225         else:
00226             query = {}
00227             for key in form:
00228                 query[key] = form[key]
00229             try:
00230                 openidreq = openidsrv.decodeRequest(query)
00231             except Exception, e:
00232                 request.makeForbidden(403, 'OpenID decode error: %r' % e)
00233                 return
00234 
00235             if openidreq is None:
00236                 request.makeForbidden(403, 'no request')
00237                 return
00238 
00239             if request.user.valid and username != request.user.name:
00240                 answer = openidreq.answer(False, identity=identity, server_url=server_url)
00241             elif openidreq.mode in ["checkid_immediate", "checkid_setup"]:
00242                 answer = self.handleCheckIDRequest(identity, username, openidreq, server_url)
00243                 if answer is None:
00244                     return
00245             else:
00246                 answer = openidsrv.handleRequest(openidreq)
00247         webanswer = openidsrv.encodeResponse(answer)
00248         request.status = '%d OpenID status' % webanswer.code
00249         for hdr in webanswer.headers:
00250             request.headers.add(hdr, webanswer.headers[hdr])
00251         request.write(webanswer.body)
00252         raise MoinMoinFinish

Here is the call graph for this function:

def MoinMoin.action.serveopenid.MoinOpenIDServer.handle_response (   self,
  positive,
  username,
  identity 
)

Definition at line 253 of file serveopenid.py.

00253 
00254     def handle_response(self, positive, username, identity):
00255         request = self.request
00256         form = request.form
00257 
00258         # check form submission nonce, use None for stored value default
00259         # since it cannot be sent from the user
00260         session_nonce = self.request.session.get('openidserver.nonce')
00261         if session_nonce is not None:
00262             del self.request.session['openidserver.nonce']
00263         # use empty string if nothing was sent
00264         form_nonce = form.get('nonce', '')
00265         if session_nonce != form_nonce:
00266             self.request.makeForbidden(403, 'invalid nonce')
00267             return None
00268 
00269         openidreq = request.session.get('openidserver.request')
00270         if not openidreq:
00271             request.makeForbidden(403, 'no response request')
00272             return None
00273         del request.session['openidserver.request']
00274 
00275         if (not positive or
00276             not request.user.valid or
00277             request.user.name != username):
00278             return openidreq.answer(False)
00279 
00280 
00281         if form.get('remember', 'no') == 'yes':
00282             if not hasattr(request.user, 'openid_trusted_roots'):
00283                 request.user.openid_trusted_roots = []
00284             request.user.openid_trusted_roots.append(strbase64(openidreq.trust_root))
00285             request.user.save()
00286         dummyidentity, server_url = self._make_identity()
00287         return self.approved(identity, openidreq, server_url=server_url)

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.action.serveopenid.MoinOpenIDServer.handleCheckIDRequest (   self,
  identity,
  username,
  openidreq,
  server_url 
)

Definition at line 150 of file serveopenid.py.

00150 
00151     def handleCheckIDRequest(self, identity, username, openidreq, server_url):
00152         if self.user_trusts_url(openidreq.trust_root):
00153             return self.approved(identity, openidreq, server_url=server_url)
00154 
00155         if openidreq.immediate:
00156             return openidreq.answer(False, identity=identity, server_url=server_url)
00157 
00158         self.request.session['openidserver.request'] = openidreq
00159         self.show_decide_page(identity, username, openidreq)
00160         return None

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 32 of file serveopenid.py.

00032 
00033     def serveYadisEP(self, endpoint_url):
00034         request = self.request
00035         request.content_type = 'application/xrds+xml'
00036 
00037         user_url = request.getQualifiedURL(request.page.url(request))
00038         self.request.write("""\
00039 <?xml version="1.0" encoding="UTF-8"?>
00040 <xrds:XRDS
00041     xmlns:xrds="xri://$xrds"
00042     xmlns="xri://$xrd*($v*2.0)">
00043   <XRD>
00044 
00045     <Service priority="0">
00046       <Type>%(type10)s</Type>
00047       <URI>%(uri)s</URI>
00048       <LocalID>%(id)s</LocalID>
00049     </Service>
00050 
00051     <Service priority="0">
00052       <Type>%(type11)s</Type>
00053       <URI>%(uri)s</URI>
00054       <LocalID>%(id)s</LocalID>
00055     </Service>
00056 
00057     <!-- older version of the spec draft -->
00058     <Service priority="0">
00059       <Type>http://openid.net/signon/2.0</Type>
00060       <URI>%(uri)s</URI>
00061       <LocalID>%(id)s</LocalID>
00062     </Service>
00063 
00064     <Service priority="0">
00065       <Type>%(type20)s</Type>
00066       <URI>%(uri)s</URI>
00067       <LocalID>%(id)s</LocalID>
00068     </Service>
00069 
00070   </XRD>
00071 </xrds:XRDS>
""" % {

Here is the caller graph for this function:

Definition at line 79 of file serveopenid.py.

00079 
00080     def serveYadisIDP(self, endpoint_url):
00081         request = self.request
00082         request.content_type = 'application/xrds+xml'
00083 
00084         user_url = request.getQualifiedURL(request.page.url(request))
00085         self.request.write("""\
00086 <?xml version="1.0" encoding="UTF-8"?>
00087 <xrds:XRDS
00088     xmlns:xrds="xri://$xrds"
00089     xmlns="xri://$xrd*($v*2.0)">
00090   <XRD>
00091 
00092     <Service priority="0">
00093       <Type>%(typeidp)s</Type>
00094       <URI>%(uri)s</URI>
00095       <LocalID>%(id)s</LocalID>
00096     </Service>
00097 
00098   </XRD>
00099 </xrds:XRDS>
""" % {

Here is the caller graph for this function:

def MoinMoin.action.serveopenid.MoinOpenIDServer.show_decide_page (   self,
  identity,
  username,
  openidreq 
)

Definition at line 307 of file serveopenid.py.

00307 
00308     def show_decide_page(self, identity, username, openidreq):
00309         request = self.request
00310         _ = self._
00311 
00312         if not request.user.valid or username != request.user.name:
00313             request.makeForbidden(403, _('''You need to manually go to your OpenID provider wiki
00314 and log in before you can use your OpenID. MoinMoin will
00315 never allow you to enter your password here.
00316 
00317 Once you have logged in, simply reload this page.'''))
00318             return
00319 
00320         request.theme.send_title(_("OpenID Trust verification"), pagename=request.page.page_name)
00321         # Start content (important for RTL support)
00322         request.write(request.formatter.startContent("content"))
00323 
00324         request.write(request.formatter.paragraph(1))
00325         request.write(_('The site %s has asked for your identity.') % openidreq.trust_root)
00326         request.write(request.formatter.paragraph(0))
00327         request.write(request.formatter.paragraph(1))
00328         request.write(_('''
00329 If you approve, the site represented by the trust root below will be
00330 told that you control the identity URL %s. (If you are using a delegated
00331 identity, the site will take care of reversing the
00332 delegation on its own.)''') % openidreq.identity)
00333         request.write(request.formatter.paragraph(0))
00334 
00335         form = html.FORM(method='POST', action=request.page.url(request))
00336         form.append(html.INPUT(type='hidden', name='action', value='serveopenid'))
00337         form.append(html.INPUT(type='hidden', name='openid.identity', value=openidreq.identity))
00338         form.append(html.INPUT(type='hidden', name='openid.return_to', value=openidreq.return_to))
00339         form.append(html.INPUT(type='hidden', name='openid.trust_root', value=openidreq.trust_root))
00340         form.append(html.INPUT(type='hidden', name='openid.mode', value=openidreq.mode))
00341         form.append(html.INPUT(type='hidden', name='name', value=username))
00342 
00343         nonce = randomString(32, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
00344         form.append(html.INPUT(type='hidden', name='nonce', value=nonce))
00345         request.session['openidserver.nonce'] = nonce
00346 
00347         table = html.TABLE()
00348         form.append(table)
00349 
00350         tr = html.TR()
00351         table.append(tr)
00352         tr.append(html.TD().append(html.STRONG().append(html.Text(_('Trust root')))))
00353         tr.append(html.TD().append(html.Text(openidreq.trust_root)))
00354 
00355         tr = html.TR()
00356         table.append(tr)
00357         tr.append(html.TD().append(html.STRONG().append(html.Text(_('Identity URL')))))
00358         tr.append(html.TD().append(html.Text(identity)))
00359 
00360         tr = html.TR()
00361         table.append(tr)
00362         tr.append(html.TD().append(html.STRONG().append(html.Text(_('Name')))))
00363         tr.append(html.TD().append(html.Text(username)))
00364 
00365         tr = html.TR()
00366         table.append(tr)
00367         tr.append(html.TD().append(html.STRONG().append(html.Text(_('Remember decision')))))
00368         td = html.TD()
00369         tr.append(td)
00370         td.append(html.INPUT(type='checkbox', name='remember', value='yes'))
00371         td.append(html.Text(_('Remember this trust decision and don\'t ask again')))
00372 
00373         tr = html.TR()
00374         table.append(tr)
00375         tr.append(html.TD())
00376         td = html.TD()
00377         tr.append(td)
00378 
00379         td.append(html.INPUT(type='submit', name='approve', value=_("Approve")))
00380         td.append(html.INPUT(type='submit', name='dontapprove', value=_("Don't approve")))
00381 
00382         request.write(unicode(form))
00383 
00384         request.write(request.formatter.endContent())
00385         request.theme.send_footer(request.page.page_name)
00386         request.theme.send_closing_html()

Here is the caller graph for this function:

Definition at line 301 of file serveopenid.py.

00301 
00302     def user_trusts_url(self, trustroot):
00303         user = self.request.user
00304         if hasattr(user, 'openid_trusted_roots'):
00305             return strbase64(trustroot) in user.openid_trusted_roots
00306         return False

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 29 of file serveopenid.py.

Definition at line 30 of file serveopenid.py.

Definition at line 28 of file serveopenid.py.


The documentation for this class was generated from the following file: