def approved(self, identity, openidreq, server_url=None):
        # TODO: If simple registration is implemented, this needs
        #       to do something like the following:
        #
        #       sreg_data = { fill this dict with real values }
        #       sreq_req = sreg.SRegRequest.fromOpenIDRequest(openidreq.message)
        #       # do something with the request to see what values are required?
        #       sreg_resp = sreg.SRegResponse.extractResponse(openidreq, sreg_data)
        #       sreg_resp.addToOpenIDResponse(reply.fields)

        request = self.request

        # obtain the endpoint if not overridden by an identity endpoint
        page_url = request.getQualifiedURL(
                         request.page.url(request, querystr={'action': 'serveopenid'}))
        endpoint_changed = server_url != page_url

        # prepare the response
        reply = openidreq.answer(True, identity=identity, server_url=server_url or page_url)

        # if the endpoint has changed, perhaps reflecting an identity-specific
        # endpoint, remove any association handle in use, working around any
        # association-related issues in relying parties (such as python-openid)
        if openidreq.assoc_handle and endpoint_changed:
            store = MoinOpenIDStore(request)
            signatory = server.Signatory(store)
            reply.fields.setArg(OPENID_NS, "invalidate_handle", openidreq.assoc_handle)
            signatory.invalidate(openidreq.assoc_handle, dumb=False)
        return reply
Exemple #2
0
    def _handle_oidreturn(self):
        request = self.request
        _ = request.getText

        oidconsumer = consumer.Consumer(request.session,
                                        MoinOpenIDStore(request))
        query = {}
        for key in request.values:
            query[key] = request.values[key]
        qstr = {'action': 'userprefs',
                'handler': 'oid',
                'oid.return': '1'}
        return_to = request.getQualifiedURL(request.page.url(request, qstr))
        info = oidconsumer.complete(query, return_to)
        if info.status == consumer.FAILURE:
            return 'error', _('OpenID error: %s.') % info.message
        elif info.status == consumer.CANCEL:
            return 'info', _('Verification canceled.')
        elif info.status == consumer.SUCCESS:
            if not hasattr(self.request.user, 'openids'):
                request.user.openids = []

            if info.identity_url in request.user.openids:
                return 'error', _("OpenID is already present.")

            if user.getUserIdByOpenId(request, info.identity_url):
                return 'error', _("This OpenID is already used for another account.")

            # all fine
            request.user.openids.append(info.identity_url)
            request.user.save()
            return 'info', _("OpenID added successfully.")
        else:
            return 'error', _('OpenID failure.')
Exemple #3
0
    def _handle_verify_continuation(self, request):
        _ = request.getText
        oidconsumer = consumer.Consumer(request.session,
                                        MoinOpenIDStore(request))
        query = {}
        for key in request.values.keys():
            query[key] = request.values.get(key)
        current_url = get_multistage_continuation_url(request, self.name,
                                                      {'oidstage': '1'})
        info = oidconsumer.complete(query, current_url)
        if info.status == consumer.FAILURE:
            logging.debug(_("OpenID error: %s.") % info.message)
            return CancelLogin(_('OpenID error: %s.') % info.message)
        elif info.status == consumer.CANCEL:
            logging.debug(_("OpenID verification canceled."))
            return CancelLogin(_('Verification canceled.'))
        elif info.status == consumer.SUCCESS:
            logging.debug(_("OpenID success. id: %s") % info.identity_url)
            request.session['openid.id'] = info.identity_url
            request.session['openid.info'] = info

            # try to find user object
            uid = user.getUserIdByOpenId(request, info.identity_url)
            if uid:
                u = user.User(request,
                              id=uid,
                              auth_method=self.name,
                              auth_username=info.identity_url,
                              auth_attribs=self.auth_attribs)
            else:
                u = None

            # create or update the user according to the registration data
            u = self._handle_user_data(request, u)
            if u:
                return ContinueLogin(u)

            # if no user found, then we need to ask for a username,
            # possibly associating an existing account.
            logging.debug("OpenID: No user found, prompting for username")
            #request.session['openid.id'] = info.identity_url
            return MultistageFormLogin(self._get_account_name)
        else:
            logging.debug(_("OpenID failure"))
            return CancelLogin(_('OpenID failure.'))
Exemple #4
0
    def _handle_add(self):
        _ = self.request.getText
        request = self.request

        openid_id = request.form.get('openid_identifier', '')
        if not openid_id:
            return 'error', _("No OpenID given.")

        if (hasattr(self.request.user, 'openids')
                and openid_id in request.user.openids):
            return 'error', _("OpenID is already present.")

        oidconsumer = consumer.Consumer(request.session,
                                        MoinOpenIDStore(self.request))
        try:
            oidreq = oidconsumer.begin(openid_id)
        except HTTPFetchingError:
            return 'error', _('Failed to resolve OpenID.')
        except DiscoveryFailure:
            return 'error', _('OpenID discovery failure, not a valid OpenID.')
        else:
            if oidreq is None:
                return 'error', _("No OpenID given.")  # ??

            qstr = {'action': 'userprefs', 'handler': 'oid', 'oid.return': '1'}
            return_to = request.getQualifiedURL(request.page.url(
                request, qstr))
            trust_root = request.url_root
            if oidreq.shouldSendRedirect():
                redirect_url = oidreq.redirectURL(trust_root, return_to)
                request.http_redirect(redirect_url)
            else:
                form_html = oidreq.formMarkup(
                    trust_root,
                    return_to,
                    form_tag_attrs={'id': 'openid_message'})
                request.session['openid.prefs.form_html'] = form_html
    def handle(self):
        _ = self._
        request = self.request
        form = request.values

        username = request.page.page_name
        if 'openid.user' in request.page.pi:
            username = request.page.pi['openid.user']


        if not request.cfg.openid_server_enabled:
            # since we didn't put any openid.server into
            # the page to start with, this is someone trying
            # to abuse us. No need to give a nice error
            request.makeForbidden(403, '')
            return

        server_url = request.getQualifiedURL(
                         request.page.url(request, querystr={'action': 'serveopenid'}))

        yadis_type = form.get('yadis')
        if yadis_type == 'ep':
            return self.serveYadisEP(server_url)
        elif yadis_type == 'idp':
            return self.serveYadisIDP(server_url)

        # if the identity is set it must match the server URL
        # sort of arbitrary, but we have to have some restriction
        identity = form.get('openid.identity')
        if identity == IDENTIFIER_SELECT:
            identity, server_url = self._make_identity()
            if not identity:
                return self._sorry_no_identity()
            username = request.user.name
        elif identity is not None:
            if not self._verify_endpoint_identity(identity):
                request.makeForbidden(403, 'verification failed')
                return

        if 'openid.user' in request.page.pi:
            username = request.page.pi['openid.user']

        store = MoinOpenIDStore(request)
        openidsrv = server.Server(store, op_endpoint=server_url)

        answer = None
        if 'dontapprove' in form:
            answer = self.handle_response(False, username, identity)
            if answer is None:
                return
        elif form.has_key('approve'):
            answer = self.handle_response(True, username, identity)
            if answer is None:
                return
        else:
            query = {}
            for key in form:
                query[key] = form[key]
            try:
                openidreq = openidsrv.decodeRequest(query)
            except Exception, e:
                request.makeForbidden(403, 'OpenID decode error: %r' % e)
                return

            if openidreq is None:
                request.makeForbidden(403, 'no request')
                return

            if request.user.valid and username != request.user.name:
                answer = openidreq.answer(False, identity=identity, server_url=server_url)
            elif openidreq.mode in ["checkid_immediate", "checkid_setup"]:
                answer = self.handleCheckIDRequest(identity, username, openidreq, server_url)
                if answer is None:
                    return
            else:
                answer = openidsrv.handleRequest(openidreq)
Exemple #6
0
    def login(self, request, user_obj, **kw):
        continuation = kw.get('multistage')

        if continuation:
            return self._handle_continuation(request)

        # openid is designed to work together with other auths
        if user_obj and user_obj.valid:
            return ContinueLogin(user_obj)

        openid_id = kw.get('openid_identifier')

        # nothing entered? continue...
        if not self._forced_service and not openid_id:
            return ContinueLogin(user_obj)

        _ = request.getText

        # user entered something but the session can't be stored
        if not request.cfg.cookie_lifetime[0]:
            return ContinueLogin(
                user_obj,
                _('Anonymous sessions need to be enabled for OpenID login.'))

        oidconsumer = consumer.Consumer(request.session,
                                        MoinOpenIDStore(request))

        try:
            fserv = self._forced_service
            if fserv:
                if isinstance(fserv, str) or isinstance(fserv, unicode):
                    oidreq = oidconsumer.begin(fserv)
                else:
                    oidreq = oidconsumer.beginWithoutDiscovery(fserv)
            else:
                oidreq = oidconsumer.begin(openid_id)
        except HTTPFetchingError:
            return ContinueLogin(None, _('Failed to resolve OpenID.'))
        except DiscoveryFailure:
            return ContinueLogin(
                None, _('OpenID discovery failure, not a valid OpenID.'))
        else:
            if oidreq is None:
                return ContinueLogin(None, _('No OpenID.'))

            self._modify_request(oidreq, request.cfg)

            return_to = get_multistage_continuation_url(
                request, self.name, {'oidstage': '1'})
            trust_root = request.url_root
            if oidreq.shouldSendRedirect():
                redirect_url = oidreq.redirectURL(trust_root, return_to)
                return MultistageRedirectLogin(redirect_url)
            else:
                form_html = oidreq.formMarkup(
                    trust_root,
                    return_to,
                    form_tag_attrs={'id': 'openid_message'})
                mcall = lambda request, form:\
                    self._openid_form(request, form, form_html)
                ret = MultistageFormLogin(mcall)
                return ret