예제 #1
0
    def test_parseExtensionArgsWithAuthLevels_openID1(self):
        request_args = {
            'preferred_auth_level_types': 'nist jisa',
        }
        expected_auth_levels = [pape.LEVELS_NIST, pape.LEVELS_JISA]
        self.req.parseExtensionArgs(request_args, is_openid1=True)
        self.assertEqual(self.req.preferred_auth_level_types, expected_auth_levels)

        self.req = pape.Request()
        self.req.parseExtensionArgs(request_args, is_openid1=False)
        self.assertEqual(self.req.preferred_auth_level_types, [])

        self.req = pape.Request()
        self.assertRaises(ValueError, self.req.parseExtensionArgs, request_args, is_openid1=False, strict=True)
예제 #2
0
def login():
    """Does the login via OpenID.  Has to call into `oid.try_login`
    to start the OpenID machinery.
    """
    # if we are already logged in, go back to were we came from
    if logged_in_user() is not None:
        return redirect(oid.get_next_url())
    if request.method == 'POST':
        openid = request.form.get('openid')
        if not re.findall('^https*://', openid):
            openid = 'http://' + openid
        if openid:
            pape_req = pape.Request([])
            x = oid.try_login(openid,
                              ask_for=['email', 'nickname'],
                              ask_for_optional=['fullname'],
                              extensions=[pape_req])
            return x
    form = LoginForm()
    if form.validate_on_submit():
        return redirect(oid.get_next_uril())

    msg = oid.fetch_error()
    if msg:
        flash(msg)
    elif fns_util.pu_time():
        flash('Please enter an openid')

    return render_template('login.html',
                           next=oid.get_next_url(),
                           error=oid.fetch_error(),
                           form=form,
                           version=version.__version__)
예제 #3
0
    def setup_request(self, params=None):
        """Setup request"""
        request = self.openid_request(params)
        # Request some user details. Use attribute exchange if provider
        # advertises support.
        if request.endpoint.supportsType(ax.AXMessage.ns_uri):
            fetch_request = ax.FetchRequest()
            # Mark all attributes as required, Google ignores optional ones
            for attr, alias in self.get_ax_attributes():
                fetch_request.add(ax.AttrInfo(attr, alias=alias,
                                              required=True))
        else:
            fetch_request = sreg.SRegRequest(
                optional=list(dict(self.get_sreg_attributes()).keys()))
        request.addExtension(fetch_request)

        # Add PAPE Extension for if configured
        preferred_policies = self.setting(
            'OPENID_PAPE_PREFERRED_AUTH_POLICIES')
        preferred_level_types = self.setting(
            'OPENID_PAPE_PREFERRED_AUTH_LEVEL_TYPES')
        max_age = self.setting('OPENID_PAPE_MAX_AUTH_AGE')
        if max_age is not None:
            try:
                max_age = int(max_age)
            except (ValueError, TypeError):
                max_age = None

        if max_age is not None or preferred_policies or preferred_level_types:
            pape_request = pape.Request(
                max_auth_age=max_age,
                preferred_auth_policies=preferred_policies,
                preferred_auth_level_types=preferred_level_types)
            request.addExtension(pape_request)
        return request
예제 #4
0
    def _update_authrequest(self, authrequest):
        """Update the authrequest with Attribute Exchange and optionally OAuth

        To optionally request OAuth, the request POST must include an ``oauth_scope``
        parameter that indicates what Google Apps should have access requested.

        """
        request_attributes = request.POST.get('ax_attributes', ax_attributes.keys())
        ax_request = ax.FetchRequest()
        for attr in request_attributes:
            ax_request.add(ax.AttrInfo(attributes[attr], required=True))
        authrequest.addExtension(ax_request)

        # Add PAPE request information. Setting max_auth_age to zero will force a login.
        requested_policies = []
        policy_prefix = 'policy_'
        for k, v in request.POST.iteritems():
            if k.startswith(policy_prefix):
                policy_attr = k[len(policy_prefix):]
                requested_policies.append(getattr(pape, policy_attr))

        pape_request = pape.Request(requested_policies,
                                    max_auth_age=request.POST.get('pape_max_auth_age',None))
        authrequest.addExtension(pape_request)

        oauth_request = OAuthRequest(consumer=self.consumer_key, scope=self.scope or 'http://www.google.com/m8/feeds/')
        authrequest.addExtension(oauth_request)

        if 'popup_mode' in request.POST:
            kw_args = {'mode': request.POST['popup_mode']}
            if 'popup_icon' in request.POST:
                kw_args['icon'] = request.POST['popup_icon']
            ui_request = UIRequest(**kw_args)
            authrequest.addExtension(ui_request)
        return None
예제 #5
0
def login_openid():
    if g.user is not None:
        return redirect(oid.get_next_url())

    openid = DEFAULT_STACKEXCHANGE_OPENID_ENDPOINT
    pape_req = pape.Request([])
    return oid.try_login(openid, ask_for=['nickname'], extensions=[pape_req])
예제 #6
0
    def setup_request(self, extra_params=None):
        """Setup request"""
        openid_request = self.openid_request(extra_params)
        # Request some user details. Use attribute exchange if provider
        # advertises support.
        if openid_request.endpoint.supportsType(ax.AXMessage.ns_uri):
            fetch_request = ax.FetchRequest()
            # Mark all attributes as required, Google ignores optional ones
            for attr, alias in (AX_SCHEMA_ATTRS + OLD_AX_ATTRS):
                fetch_request.add(ax.AttrInfo(attr, alias=alias,
                                              required=True))
        else:
            fetch_request = sreg.SRegRequest(optional=dict(SREG_ATTR).keys())
        openid_request.addExtension(fetch_request)

        # Add PAPE Extension for max_auth_age, if configured
        max_age = setting('SOCIAL_AUTH_OPENID_PAPE_MAX_AUTH_AGE')
        if max_age is not None:
            try:
                openid_request.addExtension(
                    pape.Request(max_auth_age=int(max_age)))
            except (ValueError, TypeError):
                pass

        return openid_request
예제 #7
0
    def login(self, return_url=None, cancel_url=None, groups=None):
        """Tries to log in a user.

        Sets the user information on :attr:`flask.g.fas_user`.
        Will set 0 to :attr:`flask.g.fas_session_id, for compatibility
        with flask_fas.

        :kwarg username: Not used, but accepted for compatibility with the
            flask_fas module
        :kwarg password: Not used, but accepted for compatibility with the
            flask_fas module
        :kwarg return_url: The URL to forward the user to after login
        :kwarg groups: A string or a list of group the user should belong
            to to be authentified.
        :returns: True if the user was succesfully authenticated.
        :raises: Might raise an redirect to the OpenID endpoint
        """
        if groups is None:
            groups = ['_FAS_ALL_GROUPS_']

        if return_url is None:
            return_url = flask.request.args.get('next', flask.request.url)
        session = {}
        oidconsumer = consumer.Consumer(session, None)
        try:
            request = oidconsumer.begin(self.app.config['FAS_OPENID_ENDPOINT'])
        except consumer.DiscoveryFailure:
            # VERY strange, as this means it could not discover an OpenID
            # endpoint at FAS_OPENID_ENDPOINT
            return 'discoveryfailure'
        if request is None:
            # Also very strange, as this means the discovered OpenID
            # endpoint is no OpenID endpoint
            return 'no-request'

        if isinstance(groups, basestring):
            groups = [groups]

        request.addExtension(
            sreg.SRegRequest(
                required=['nickname', 'fullname', 'email', 'timezone']))
        request.addExtension(pape.Request([]))
        request.addExtension(teams.TeamsRequest(requested=groups))
        request.addExtension(
            cla.CLARequest(requested=[cla.CLA_URI_FEDORA_DONE]))

        trust_root = self.normalize_url(flask.request.url_root)
        return_to = trust_root + '_flask_fas_openid_handler/'

        flask.session['FLASK_FAS_OPENID_RETURN_URL'] = return_url
        flask.session['FLASK_FAS_OPENID_CANCEL_URL'] = cancel_url
        if request.shouldSendRedirect():
            redirect_url = request.redirectURL(trust_root, return_to, False)
            return flask.redirect(redirect_url)
        else:
            return request.htmlMarkup(trust_root,
                                      return_to,
                                      form_tag_attrs={'id': 'openid_message'},
                                      immediate=False)
예제 #8
0
    def test_construct(self):
        self.failUnlessEqual([], self.req.preferred_auth_policies)
        self.failUnlessEqual(None, self.req.max_auth_age)
        self.failUnlessEqual('pape', self.req.ns_alias)

        req2 = pape.Request([pape.AUTH_MULTI_FACTOR], 1000)
        self.failUnlessEqual([pape.AUTH_MULTI_FACTOR], req2.preferred_auth_policies)
        self.failUnlessEqual(1000, req2.max_auth_age)
예제 #9
0
def login_begin(request, attribute_set='default'):
    """Begin an MojeID login request."""

    if mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR in request.session:
        del request.session[mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR]

    # create consumer, start login process
    consumer = MojeIDConsumer(DjangoOpenIDStore())
    openid_request = consumer.begin(create_service())

    # Request user details.
    attributes = get_attribute_query(attribute_set)
    # save settings set name for response handler
    request.session[SESSION_ATTR_SET_KEY] = attribute_set

    fetch_request = ax.FetchRequest()
    for attribute, required in attributes:
        fetch_request.add(attribute.generate_ax_attrinfo(required))

    if attributes:
        openid_request.addExtension(fetch_request)

    if mojeid_settings.MOJEID_LOGIN_METHOD != 'ANY' or \
            mojeid_settings.MOJEID_MAX_AUTH_AGE is not None:
        # set authentication method to OTP or CERT
        if mojeid_settings.MOJEID_LOGIN_METHOD == "OTP":
            auth_method = [pape.AUTH_MULTI_FACTOR]
        elif mojeid_settings.MOJEID_LOGIN_METHOD == "CERT":
            auth_method = [pape.AUTH_PHISHING_RESISTANT]
        else:
            auth_method = None

        pape_request = pape.Request(
            preferred_auth_policies=auth_method,
            max_auth_age=mojeid_settings.MOJEID_MAX_AUTH_AGE,
        )
        openid_request.addExtension(pape_request)

    # Construct the request completion URL
    return_to = request.build_absolute_uri(reverse(login_complete))

    # get 'next page' and save it to the session
    redirect_to = sanitise_redirect_url(OpenIDBackend.get_redirect_to(request))
    if redirect_to:
        request.session[mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR] = redirect_to

    # Realm should be always something like 'https://example.org/openid/'
    realm = getattr(settings, 'MOJEID_REALM', None)
    if not realm:
        realm = request.build_absolute_uri(reverse(top))

    # we always use POST request
    form_html = openid_request.htmlMarkup(
        realm, return_to, form_tag_attrs={'id': 'openid_message'})
    return HttpResponse(form_html, content_type='text/html; charset=UTF-8')
예제 #10
0
    def test_construct(self):
        self.assertEqual(self.req.preferred_auth_policies, [])
        self.assertIsNone(self.req.max_auth_age)
        self.assertEqual(self.req.ns_alias, 'pape')
        self.assertFalse(self.req.preferred_auth_level_types)

        bogus_levels = ['http://janrain.com/our_levels']
        req2 = pape.Request(
            [pape.AUTH_MULTI_FACTOR], 1000, bogus_levels)
        self.assertEqual(req2.preferred_auth_policies, [pape.AUTH_MULTI_FACTOR])
        self.assertEqual(req2.max_auth_age, 1000)
        self.assertEqual(req2.preferred_auth_level_types, bogus_levels)
예제 #11
0
def login():
    if g.user is not None:
        return redirect(oid.get_next_url())
    if request.method == 'POST':
        openid = "https://launchpad.net/~" + request.form.get('openid')
        if openid:
            pape_req = pape.Request([])
            return oid.try_login(openid, ask_for=['email', 'nickname'],
                                 ask_for_optional=['fullname'],
                                 extensions=[pape_req])
    return render_template('login.html', next=oid.get_next_url(),
                           error=oid.fetch_error())
예제 #12
0
    def render(self):
        # Reauthentication is called for by a query string parameter.
        reauth_qs = self.request.query_string_params.get('reauth', ['0'])
        do_reauth = int(reauth_qs[0])
        if self.account is not None and not do_reauth:
            return AlreadyLoggedInView(self.context, self.request)()

        # Allow unauthenticated users to have sessions for the OpenID
        # handshake to work.
        allowUnauthenticatedSession(self.request)
        consumer = self._getConsumer()
        openid_vhost = config.launchpad.openid_provider_vhost

        timeline_action = get_request_timeline(self.request).start(
            "openid-association-begin",
            allvhosts.configs[openid_vhost].rooturl,
            allow_nested=True)
        try:
            self.openid_request = consumer.begin(
                allvhosts.configs[openid_vhost].rooturl)
        finally:
            timeline_action.finish()
        self.openid_request.addExtension(
            sreg.SRegRequest(required=['email', 'fullname']))

        # Force the Open ID handshake to re-authenticate, using
        # pape extension's max_auth_age, if the URL indicates it.
        if do_reauth:
            self.openid_request.addExtension(pape.Request(max_auth_age=0))

        assert not self.openid_request.shouldSendRedirect(), (
            "Our fixed OpenID server should not need us to redirect.")
        # Once the user authenticates with the OpenID provider they will be
        # sent to the /+openid-callback page, where we log them in, but
        # once that's done they must be sent back to the URL they were when
        # they started the login process (i.e. the current URL without the
        # '+login' bit). To do that we encode that URL as a query arg in the
        # return_to URL passed to the OpenID Provider
        starting_url = urllib.urlencode([('starting_url',
                                          self.starting_url.encode('utf-8'))])
        trust_root = allvhosts.configs['mainsite'].rooturl
        return_to = urlappend(trust_root, '+openid-callback')
        return_to = "%s?%s" % (return_to, starting_url)
        form_html = self.openid_request.htmlMarkup(trust_root, return_to)

        # The consumer.begin() call above will insert rows into the
        # OpenIDAssociations table, but since this will be a GET request, the
        # transaction would be rolled back, so we need an explicit commit
        # here.
        transaction.commit()

        return form_html
예제 #13
0
def login():
    if g.user is not None:
        return redirect(oid.get_next_url())

    else:
        openid = "http://steamcommunity.com/openid"
        if openid:
            pape_req = pape.Request([])
            return oid.try_login(openid,
                                 ask_for=['email', 'nickname'],
                                 ask_for_optional=['fullname'],
                                 extensions=[pape_req])
    return render_template('/templates/register.html',
                           next=oid.get_next_url(),
                           error=oid.fetch_error())
예제 #14
0
def login():
    """Does the login via OpenID.  Has to call into `oid.try_login`
    to start the OpenID machinery.
    """
    # if we are already logged in, go back to were we came from
    if g.user is not None:
        return redirect(oid.get_next_url())
    if request.method == 'POST':
        openid = request.form.get('openid')
        if openid:
            pape_req = pape.Request([])
            return oid.try_login(openid, ask_for=['email', 'nickname'],
                                         ask_for_optional=['fullname'],
                                         extensions=[pape_req])
    return render_template('login.html', next=oid.get_next_url(),
                           error=oid.fetch_error())
    def _update_authrequest(self, authrequest):
        """Update the authrequest with the default extensions and attributes
        we ask for
        
        This method doesn't need to return anything, since the extensions
        should be added to the authrequest object itself.
        
        """
        # Add on the Attribute Exchange for those that support that
        request_attributes = self.get_argument('ax_attributes',
                                               ax_attributes.keys())
        ax_request = ax.FetchRequest()
        for attr in request_attributes:
            ax_request.add(ax.AttrInfo(attributes[attr], required=True))
        authrequest.addExtension(ax_request)

        # Form the Simple Reg request
        sreg_request = sreg.SRegRequest(optional=[
            'nickname', 'email', 'fullname', 'dob', 'gender', 'postcode',
            'country', 'language', 'timezone'
        ], )
        authrequest.addExtension(sreg_request)

        # Add PAPE request information. Setting max_auth_age to zero will force a login.
        requested_policies = []
        policy_prefix = 'policy_'
        #for k, v in request.POST.iteritems():
        #    if k.startswith(policy_prefix):
        #        policy_attr = k[len(policy_prefix):]
        #        requested_policies.append(getattr(pape, policy_attr))

        pape_request = pape.Request(requested_policies,
                                    max_auth_age=self.get_argument(
                                        'pape_max_auth_age', None))
        authrequest.addExtension(pape_request)
        popup_mode = self.get_argument('popup_mode', None)
        if popup_mode:
            kw_args = {'mode': popup_mode}
            popup_icon = self.get_argument('popup_icon')
            if 'popup_icon':
                kw_args['icon'] = popup_icon
            ui_request = UIRequest(**kw_args)
            authrequest.addExtension(ui_request)
        return None
def handle_initial_request(request):

    groups = ['sysadmin-releng', 'sysadmin-main']
    session = {}
    oidconsumer = consumer.Consumer(session, None)
    try:
        req = oidconsumer.begin('https://id.fedoraproject.org')
    except consumer.DiscoveryFailure:
        # VERY strange, as this means it could not discover an OpenID
        # endpoint at FAS_OPENID_ENDPOINT
        return 'discoveryfailure'
    if req is None:
        # Also very strange, as this means the discovered OpenID
        # endpoint is no OpenID endpoint
        return 'no-req'

    req.addExtension(sreg.SRegRequest(
        required=['nickname', 'fullname', 'email', 'timezone']))
    req.addExtension(pape.Request([]))
    req.addExtension(teams.TeamsRequest(requested=groups))
    req.addExtension(cla.CLARequest(
        requested=[cla.CLA_URI_FEDORA_DONE]))


    # Use the django HTTPRequest for this
    trust_root = request.build_absolute_uri('/')
    return_to = request.build_absolute_uri() + "?type=fas-openid"

    # Success or fail, redirect to the base.  ¯\_(ツ)_/¯
    return_url = cancel_url = request.build_absolute_uri('/')
    request.session['FAS_OPENID_RETURN_URL'] = return_url
    request.session['FAS_OPENID_CANCEL_URL'] = cancel_url

    # the django rest framework requires that we use the json route here
    return dict(form=req.htmlMarkup(trust_root, return_to,
        form_tag_attrs={'id': 'openid_message'}, immediate=False))
예제 #17
0
    def login(self):
                
        # Instantiate consumer
        self.store._log = self._log
        oi_consumer = consumer.Consumer(self.session, self.store)
        
        # handle realm and XRDS if there is only one query parameter
        if self.use_realm and len(self.params) == 1:
            realm_request = self.params.get(self.realm_param)
            xrds_request = self.params.get(self.xrds_param)                
        else:
            realm_request = None
            xrds_request = None
        
        # determine type of request
        if realm_request:
            #===================================================================
            # Realm HTML
            #===================================================================
            
            self._log(logging.INFO, 'Writing OpenID realm HTML to the response.')
            xrds_location = '{u}?{x}={x}'.format(u=self.url, x=self.xrds_param)
            self.write(REALM_HTML.format(xrds_location=xrds_location, body=self.realm_body))
            
        elif xrds_request:
            #===================================================================
            # XRDS XML
            #===================================================================
            
            self._log(logging.INFO, 'Writing XRDS XML document to the response.')
            self.set_header('Content-Type', 'application/xrds+xml')
            self.write(XRDS_XML.format(return_to=self.url))
        
        elif self.params.get('openid.mode'):
            #===================================================================
            # Phase 2 after redirect
            #===================================================================
            
            self._log(logging.INFO, 'Continuing OpenID authentication procedure after redirect.')
            
            # complete the authentication process
            response = oi_consumer.complete(self.params, self.url)            
            
            # on success
            if response.status == consumer.SUCCESS:
                
                data = {}
                
                # get user ID
                data['guid'] = response.getDisplayIdentifier()

                self._log(logging.INFO, 'Authentication successful.')
                
                # get user data from AX response
                ax_response = ax.FetchResponse.fromSuccessResponse(response)
                if ax_response and ax_response.data:
                    self._log(logging.INFO, 'Got AX data.')
                    ax_data = {}
                    # convert iterable values to their first item
                    for k, v in ax_response.data.iteritems():
                        if v and type(v) in (list, tuple):
                            ax_data[k] = v[0]
                    data['ax'] = ax_data
                
                
                # get user data from SREG response
                sreg_response = sreg.SRegResponse.fromSuccessResponse(response)
                if sreg_response and sreg_response.data:
                    self._log(logging.INFO, 'Got SREG data.')
                    data['sreg'] = sreg_response.data
                                
                
                # get data from PAPE response
                pape_response = pape.Response.fromSuccessResponse(response)
                if pape_response and pape_response.auth_policies:
                    self._log(logging.INFO, 'Got PAPE data.')
                    data['pape'] = pape_response.auth_policies
                
                # create user
                self._update_or_create_user(data)
                
                #===============================================================
                # We're done!
                #===============================================================
            
            elif response.status == consumer.CANCEL:
                raise CancellationError('User cancelled the verification of ID "{}"!'.format(response.getDisplayIdentifier()))
            
            elif response.status == consumer.FAILURE:
                raise FailureError(response.message)
            
        elif self.params.get(self.identifier_param):
            #===================================================================
            # Phase 1 before redirect
            #===================================================================
            
            self._log(logging.INFO, 'Starting OpenID authentication procedure.')
            
            # get AuthRequest object
            try:
                auth_request = oi_consumer.begin(self.identifier)
            except consumer.DiscoveryFailure as e:
                raise FailureError('Discovery failed for identifier {}!'.format(self.identifier),
                                   url=self.identifier,
                                   original_message=e.message)
            
            self._log(logging.INFO, 'Service discovery for identifier {} successful.'.format(self.identifier))
            
            # add SREG extension
            # we need to remove required fields from optional fields because addExtension then raises an error
            self.sreg = [i for i in self.sreg if i not in self.sreg_required]
            auth_request.addExtension(sreg.SRegRequest(optional=self.sreg,
                                                       required=self.sreg_required))
            
            # add AX extension
            ax_request = ax.FetchRequest()
            # set AX schemas
            for i in self.ax:
                required = i in self.ax_required
                ax_request.add(ax.AttrInfo(i, required=required))
            auth_request.addExtension(ax_request)
            
            # add PAPE extension
            auth_request.addExtension(pape.Request(self.pape))           
            
            # prepare realm and return_to URLs
            if self.use_realm:
                realm = return_to = '{u}?{r}={r}'.format(u=self.url, r=self.realm_param)
            else:
                realm = return_to = self.url
                        
            url = auth_request.redirectURL(realm, return_to)
            
            if auth_request.shouldSendRedirect():
                # can be redirected
                url = auth_request.redirectURL(realm, return_to)
                self._log(logging.INFO, 'Redirecting user to {}.'.format(url))
                self.redirect(url)
            else:
                # must be sent as POST
                # this writes a html post form with auto-submit
                self._log(logging.INFO, 'Writing an auto-submit HTML form to the response.')
                form = auth_request.htmlMarkup(realm, return_to, False, dict(id='openid_form'))
                self.write(form)
        else:
            raise OpenIDError('No identifier specified!')
예제 #18
0
        error_string = ''
        try:
            request = oidconsumer.begin(openid_url)
        except consumer.DiscoveryFailure, exc:
            error_string = 'Error in discovery: %s' % (urllib.quote(str(
                exc[0])))
        else:
            if request is None:
                error_string = 'No OpenID services found for <code>%s</code>' % (
                    urllib.quote(openid_url), )
            else:
                request.addExtension(
                    sreg.SRegRequest(required=['nickname'],
                                     optional=['fullname', 'email']))
                request.addExtension(
                    pape.Request([pape.AUTH_PHISHING_RESISTANT]))

                trust_root = self.server.base_url
                return_to = '%sopenidprocess?%s' % (self.server.base_url,
                                                    urllib.urlencode(params))

                if request.shouldSendRedirect():
                    redirect_url = request.redirectURL(trust_root,
                                                       return_to,
                                                       immediate=False)
                    self.redirect(redirect_url)
                    print 'redirect to', redirect_url
                else:
                    form_html = request.htmlMarkup(
                        trust_root,
                        return_to,
예제 #19
0
 def setUp(self):
     self.req = pape.Request()
예제 #20
0
class FAS(object):
    def __init__(self, app=None):
        self.app = app
        if self.app is not None:
            self._init_app(app)

    def _init_app(self, app):
        app.config.setdefault('FAS_OPENID_ENDPOINT',
                              'http://id.fedoraproject.org/')
        app.config.setdefault('FAS_OPENID_CHECK_CERT', True)

        if not self.app.config['FAS_OPENID_CHECK_CERT']:
            setDefaultFetcher(Urllib2Fetcher())

        @app.route('/_flask_fas_openid_handler/', methods=['GET', 'POST'])
        def flask_fas_openid_handler():
            return self._handle_openid_request()

        app.before_request(self._check_session)

    def _handle_openid_request(self):
        return_url = flask.session['FLASK_FAS_OPENID_RETURN_URL']
        cancel_url = flask.session['FLASK_FAS_OPENID_CANCEL_URL']
        base_url = self.normalize_url(flask.request.base_url)
        oidconsumer = consumer.Consumer(flask.session, None)
        info = oidconsumer.complete(flask.request.values, base_url)
        display_identifier = info.getDisplayIdentifier()

        if info.status == consumer.FAILURE and display_identifier:
            return 'FAILURE. display_identifier: %s' % display_identifier
        elif info.status == consumer.CANCEL:
            if cancel_url:
                return flask.redirect(cancel_url)
            return 'OpenID request was cancelled'
        elif info.status == consumer.SUCCESS:
            sreg_resp = sreg.SRegResponse.fromSuccessResponse(info)
            pape_resp = pape.Response.fromSuccessResponse(info)
            teams_resp = teams.TeamsResponse.fromSuccessResponse(info)
            cla_resp = cla.CLAResponse.fromSuccessResponse(info)
            user = {
                'fullname': '',
                'username': '',
                'email': '',
                'timezone': '',
                'cla_done': False,
                'groups': []
            }
            if not sreg_resp:
                # If we have no basic info, be gone with them!
                return flask.redirect(cancel_url)
            user['username'] = sreg_resp.get('nickname')
            user['fullname'] = sreg_resp.get('fullname')
            user['email'] = sreg_resp.get('email')
            user['timezone'] = sreg_resp.get('timezone')
            if cla_resp:
                user['cla_done'] = cla.CLA_URI_FEDORA_DONE in cla_resp.clas
            if teams_resp:
                user['groups'] = frozenset(
                    teams_resp.teams
                )  # The groups do not contain the cla_ groups
            flask.session['FLASK_FAS_OPENID_USER'] = user
            flask.session.modified = True
            return flask.redirect(return_url)
        else:
            return 'Strange state: %s' % info.status

    def _check_session(self):
        if not 'FLASK_FAS_OPENID_USER' in flask.session or flask.session[
                'FLASK_FAS_OPENID_USER'] is None:
            flask.g.fas_user = None
        else:
            user = flask.session['FLASK_FAS_OPENID_USER']
            # Add approved_memberships to provide backwards compatibility
            # New applications should only use g.fas_user.groups
            user['approved_memberships'] = []
            for group in user['groups']:
                membership = dict()
                membership['name'] = group
                user['approved_memberships'].append(Bunch.fromDict(membership))
            flask.g.fas_user = Bunch.fromDict(user)
        flask.g.fas_session_id = 0

    def login(self,
              username=None,
              password=None,
              return_url=None,
              cancel_url=None,
              groups=['_FAS_ALL_GROUPS_']):
        """Tries to log in a user.

        Sets the user information on :attr:`flask.g.fas_user`.
        Will set 0 to :attr:`flask.g.fas_session_id, for compatibility
        with flask_fas.

        :arg username: Not used, but accepted for compatibility with the
           flask_fas module
        :arg password: Not used, but accepted for compatibility with the
           flask_fas module
        :arg return_url: The URL to forward the user to after login
        :arg groups: A string or a list of group the user should belong to
           to be authentified.
        :returns: True if the user was succesfully authenticated.
        :raises: Might raise an redirect to the OpenID endpoint
        """
        if return_url is None:
            if 'next' in flask.request.args.values():
                return_url = flask.request.args.values['next']
            else:
                return_url = flask.request.url
        oidconsumer = consumer.Consumer(flask.session, None)
        try:
            request = oidconsumer.begin(self.app.config['FAS_OPENID_ENDPOINT'])
        except consumer.DiscoveryFailure, exc:
            # VERY strange, as this means it could not discover an OpenID endpoint at FAS_OPENID_ENDPOINT
            return 'discoveryfailure'
        if request is None:
            # Also very strange, as this means the discovered OpenID endpoint is no OpenID endpoint
            return 'no-request'

        if isinstance(groups, basestring):
            groups = [groups]

        request.addExtension(
            sreg.SRegRequest(
                required=['nickname', 'fullname', 'email', 'timezone']))
        request.addExtension(pape.Request([]))
        request.addExtension(teams.TeamsRequest(requested=groups))
        request.addExtension(
            cla.CLARequest(requested=[cla.CLA_URI_FEDORA_DONE]))

        trust_root = self.normalize_url(flask.request.url_root)
        return_to = trust_root + '_flask_fas_openid_handler/'

        flask.session['FLASK_FAS_OPENID_RETURN_URL'] = return_url
        flask.session['FLASK_FAS_OPENID_CANCEL_URL'] = cancel_url
        if request.shouldSendRedirect():
            redirect_url = request.redirectURL(trust_root, return_to, False)
            return flask.redirect(redirect_url)
        else:
            return request.htmlMarkup(trust_root,
                                      return_to,
                                      form_tag_attrs={'id': 'openid_message'},
                                      immediate=False)
예제 #21
0
def login_begin(request,
                template_name='openid/login.html',
                login_complete_view='openid-complete',
                form_class=OpenIDLoginForm,
                render_failure=default_render_failure,
                redirect_field_name=REDIRECT_FIELD_NAME):
    """Begin an OpenID login request, possibly asking for an identity URL."""
    data = get_request_data(request)
    redirect_to = data.get(redirect_field_name, '')

    # Get the OpenID URL to try.  First see if we've been configured
    # to use a fixed server URL.
    openid_url = getattr(settings, 'OPENID_SSO_SERVER_URL', None)

    if openid_url is None:
        if request.POST:
            login_form = form_class(data=request.POST)
            if login_form.is_valid():
                openid_url = login_form.cleaned_data['openid_identifier']
        else:
            login_form = form_class()

        # Invalid or no form data:
        if openid_url is None:
            context = RequestContext(request).flatten()
            context.update({
                'form': login_form,
                redirect_field_name: redirect_to,
            })
            return render(request, template_name, context)

    consumer = make_consumer(request)
    try:
        openid_request = consumer.begin(openid_url)
    except DiscoveryFailure as exc:
        return render_failure(request,
                              "OpenID discovery error: %s" % (str(exc), ),
                              status=500,
                              exception=exc)

    # Request some user details.  If the provider advertises support
    # for attribute exchange, use that.
    endpoint = openid_request.endpoint
    if endpoint.supportsType(ax.AXMessage.ns_uri):
        fetch_request = ax.FetchRequest()
        # We mark all the attributes as required, since Google ignores
        # optional attributes.  We request both the full name and
        # first/last components since some providers offer one but not
        # the other.
        for (attr, alias) in [
            ('http://axschema.org/contact/email', 'email'),
            ('http://axschema.org/namePerson', 'fullname'),
            ('http://axschema.org/namePerson/first', 'firstname'),
            ('http://axschema.org/namePerson/last', 'lastname'),
            ('http://axschema.org/namePerson/friendly', 'nickname'),
                # The myOpenID provider advertises AX support, but uses
                # attribute names from an obsolete draft of the
                # specification.  We request them for compatibility.
            ('http://schema.openid.net/contact/email', 'old_email'),
            ('http://schema.openid.net/namePerson', 'old_fullname'),
            ('http://schema.openid.net/namePerson/friendly', 'old_nickname')
        ]:
            fetch_request.add(ax.AttrInfo(attr, alias=alias, required=True))

        # conditionally require account_verified attribute
        verification_scheme_map = getattr(settings,
                                          'OPENID_VALID_VERIFICATION_SCHEMES',
                                          {})
        valid_schemes = verification_scheme_map.get(
            endpoint.server_url, verification_scheme_map.get(None, ()))
        if valid_schemes:
            # there are valid schemes configured for this endpoint, so
            # request account_verified status
            fetch_request.add(
                ax.AttrInfo(
                    'http://ns.login.ubuntu.com/2013/validation/account',
                    alias='account_verified',
                    required=True))

        openid_request.addExtension(fetch_request)
    else:
        sreg_required_fields = []
        sreg_required_fields.extend(
            getattr(settings, 'OPENID_SREG_REQUIRED_FIELDS', []))
        sreg_optional_fields = ['email', 'fullname', 'nickname']
        sreg_optional_fields.extend(
            getattr(settings, 'OPENID_SREG_EXTRA_FIELDS', []))
        sreg_optional_fields = [
            field for field in sreg_optional_fields
            if field not in sreg_required_fields
        ]
        openid_request.addExtension(
            sreg.SRegRequest(optional=sreg_optional_fields,
                             required=sreg_required_fields))

    if getattr(settings, 'OPENID_PHYSICAL_MULTIFACTOR_REQUIRED', False):
        preferred_auth = [
            pape.AUTH_MULTI_FACTOR_PHYSICAL,
        ]
        pape_request = pape.Request(preferred_auth_policies=preferred_auth)
        openid_request.addExtension(pape_request)

    # Request team info
    teams_mapping_auto = getattr(settings,
                                 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
    teams_mapping_auto_blacklist = getattr(
        settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST', [])
    launchpad_teams = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING', {})
    if teams_mapping_auto:
        # ignore launchpad teams. use all django-groups
        launchpad_teams = dict()
        all_groups = Group.objects.exclude(
            name__in=teams_mapping_auto_blacklist)
        for group in all_groups:
            launchpad_teams[group.name] = group.name

    if launchpad_teams:
        openid_request.addExtension(teams.TeamsRequest(launchpad_teams.keys()))

    # Construct the request completion URL, including the page we
    # should redirect to.
    return_to = request.build_absolute_uri(reverse(login_complete_view))
    if redirect_to:
        if '?' in return_to:
            return_to += '&'
        else:
            return_to += '?'
        # Django gives us Unicode, which is great.  We must encode URI.
        # urllib enforces str. We can't trust anything about the default
        # encoding inside  str(foo) , so we must explicitly make foo a str.
        return_to += urlencode(
            {redirect_field_name: redirect_to.encode("UTF-8")})

    return render_openid_request(request, openid_request, return_to)
예제 #22
0
    def login(self,
              username=None,
              password=None,
              return_url=None,
              cancel_url=None,
              groups=['_FAS_ALL_GROUPS_']):
        """
        Copied from the FAS Flask OpenID Auth Plugin with modifications to be
        compatible with a separate frontend application.
        """

        if return_url is None:
            if 'next' in flask.request.args.values():
                return_url = flask.request.args.values['next']
            else:
                return_url = flask.request.url_root

        return_to_same_app = self._check_safe_root(return_url)

        session = {}
        oidconsumer = consumer.Consumer(session, None)
        try:
            request = oidconsumer.begin(self.app.config['FAS_OPENID_ENDPOINT'])
        except consumer.DiscoveryFailure as exc:
            # VERY strange, as this means it could not discover an OpenID
            # endpoint at FAS_OPENID_ENDPOINT
            log.warn(exc)
            return 'discoveryfailure'
        if request is None:
            # Also very strange, as this means the discovered OpenID
            # endpoint is no OpenID endpoint
            return 'no-request'

        if isinstance(groups, six.string_types):
            groups = [groups]

        request.addExtension(
            sreg.SRegRequest(
                required=['nickname', 'fullname', 'email', 'timezone']))
        request.addExtension(pape.Request([]))
        request.addExtension(teams.TeamsRequest(requested=groups))
        request.addExtension(
            cla.CLARequest(requested=[cla.CLA_URI_FEDORA_DONE]))

        ax_req = ax.FetchRequest()
        ax_req.add(
            ax.AttrInfo(
                type_uri='http://fedoauth.org/openid/schema/GPG/keyid'))
        ax_req.add(
            ax.AttrInfo(type_uri='http://fedoauth.org/openid/schema/SSH/key',
                        count='unlimited'))
        request.addExtension(ax_req)

        trust_root = self.normalize_url(flask.request.url_root)
        return_to = trust_root + '_flask_fas_openid_handler/'
        flask.session['FLASK_FAS_OPENID_RETURN_URL'] = return_url
        flask.session['FLASK_FAS_OPENID_CANCEL_URL'] = cancel_url
        flask.session.modified = True

        if request_wants_json():
            output = request.getMessage(trust_root,
                                        return_to=return_to).toPostArgs()
            output['server_url'] = request.endpoint.server_url
            return flask.jsonify(output)
        elif request.shouldSendRedirect():
            redirect_url = request.redirectURL(trust_root, return_to, False)
            return flask.redirect(redirect_url)
        elif not return_to_same_app:
            return_to = os.environ['CLIENT_URL'] + '/_flask_fas_openid_handler/'
            redirect_url = request.redirectURL(os.environ['CLIENT_URL'],
                                               return_to, False)
            return redirect_url
        else:
            return request.htmlMarkup(trust_root,
                                      return_to,
                                      form_tag_attrs={'id': 'openid_message'},
                                      immediate=False)
예제 #23
0
                self._commit_oidsession(oidsession, req)
                # Then, ask the library to begin the authorization.
                # Here we find out the identity server that will verify the
                # user's identity, and get a token that allows us to
                # communicate securely with the identity server.

                requested_policies = []
                if self.pape_method:
                    requested_policies.append(self.pape_method)

                pape_method = req.args.get('pape_method')
                if pape_method:
                    requested_policies.append(pape_method)

                if requested_policies:
                    pape_request = pape.Request(requested_policies)
                    request.addExtension(pape_request)

                # Let the sreg policy be configurable
                sreg_opt = []
                sreg_req = []
                sreg_fields = ['fullname', 'email']
                if self.sreg_required:
                    sreg_req = sreg_fields
                else:
                    sreg_opt = sreg_fields
                if self.use_nickname_as_authname:
                    sreg_req.append('nickname')
                sreg_request = sreg.SRegRequest(optional=sreg_opt,
                                                required=sreg_req)
                request.addExtension(sreg_request)
예제 #24
0
            return
        except discover.XRDSError, e:
            self.report_error('Error parsing XRDS from provider.', e)
            return

        self.session.claimed_id = auth_request.endpoint.claimed_id
        self.session.server_url = auth_request.endpoint.server_url
        self.store_session()

        sreg_request = sreg.SRegRequest(
            optional=['nickname', 'fullname', 'email'])
        auth_request.addExtension(sreg_request)

        pape_request = pape.Request([
            pape.AUTH_MULTI_FACTOR,
            pape.AUTH_MULTI_FACTOR_PHYSICAL,
            pape.AUTH_PHISHING_RESISTANT,
        ])
        auth_request.addExtension(pape_request)

        parts = list(urlparse.urlparse(self.request.uri))
        parts[2] = 's/finish'
        parts[4] = 'session_id=%d' % self.session.key().id()
        parts[5] = ''
        return_to = urlparse.urlunparse(parts)
        realm = urlparse.urlunparse(parts[0:2] + [''] * 4)

        redirect_url = auth_request.redirectURL(realm, return_to)
        logging.debug('Redirecting to %s' % redirect_url)
        self.response.set_status(302)
        self.response.headers['Location'] = redirect_url
예제 #25
0
    def login(self,
              username=None,
              password=None,
              return_url=None,
              cancel_url=None,
              groups=['_FAS_ALL_GROUPS_']):
        """Tries to log in a user.

        Sets the user information on :attr:`flask.g.fas_user`.
        Will set 0 to :attr:`flask.g.fas_session_id, for compatibility
        with flask_fas.

        :kwarg username: Not used, but accepted for compatibility with the
            flask_fas module
        :kwarg password: Not used, but accepted for compatibility with the
            flask_fas module
        :kwarg return_url: The URL to forward the user to after login
        :kwarg groups: A string or a list of group the user should belong
            to to be authentified.
        :returns: True if the user was succesfully authenticated.
        :raises: Might raise an redirect to the OpenID endpoint
        """
        if return_url is None:
            if 'next' in flask.request.args.values():
                return_url = flask.request.args.values['next']
            else:
                return_url = flask.request.url_root
        # This makes sure that we only allow stuff where
        # ?next= value is in a safe root (the application
        # root)
        return_url = (self._check_safe_root(return_url)
                      or flask.request.url_root)
        session = {}
        oidconsumer = consumer.Consumer(session, None)
        try:
            request = oidconsumer.begin(self.app.config['FAS_OPENID_ENDPOINT'])
        except consumer.DiscoveryFailure as exc:
            # VERY strange, as this means it could not discover an OpenID
            # endpoint at FAS_OPENID_ENDPOINT
            log.warn(exc)
            return 'discoveryfailure'
        if request is None:
            # Also very strange, as this means the discovered OpenID
            # endpoint is no OpenID endpoint
            return 'no-request'

        if isinstance(groups, six.string_types):
            groups = [groups]
        # Some applications pass the group list as a set. Convert to a list in
        # case we need to append to it (see below).
        if isinstance(groups, set):
            groups = list(groups)
        # In the new AAA system, we know a user has signed the FPCA by looking
        # a group membership. We must therefore always request the
        # corresponding group.
        if "_FAS_ALL_GROUPS_" not in groups:
            groups.append("signed_fpca")

        request.addExtension(
            sreg.SRegRequest(
                required=['nickname', 'fullname', 'email', 'timezone']))
        request.addExtension(pape.Request([]))
        request.addExtension(teams.TeamsRequest(requested=groups))
        request.addExtension(
            cla.CLARequest(requested=[cla.CLA_URI_FEDORA_DONE]))

        ax_req = ax.FetchRequest()
        ax_req.add(
            ax.AttrInfo(
                type_uri='http://fedoauth.org/openid/schema/GPG/keyid'))
        ax_req.add(
            ax.AttrInfo(type_uri='http://fedoauth.org/openid/schema/SSH/key',
                        count='unlimited'))
        request.addExtension(ax_req)

        trust_root = self.normalize_url(flask.request.url_root)
        return_to = trust_root + '_flask_fas_openid_handler/'

        flask.session['FLASK_FAS_OPENID_RETURN_URL'] = return_url
        flask.session['FLASK_FAS_OPENID_CANCEL_URL'] = cancel_url

        if request_wants_json():
            output = request.getMessage(trust_root,
                                        return_to=return_to).toPostArgs()
            output['server_url'] = request.endpoint.server_url
            return flask.jsonify(output)
        elif request.shouldSendRedirect():
            redirect_url = request.redirectURL(trust_root, return_to, False)
            return flask.redirect(redirect_url)
        else:
            return request.htmlMarkup(trust_root,
                                      return_to,
                                      form_tag_attrs={'id': 'openid_message'},
                                      immediate=False)
예제 #26
0
 def requestPAPEDetails(self, request):
     pape_request = pape.Request([pape.AUTH_PHISHING_RESISTANT])
     request.addExtension(pape_request)
예제 #27
0
def begin(request,
          redirect_to=None,
          on_failure=None,
          template_name='openid_signin.html'):

    on_failure = on_failure or default_on_failure

    trust_root = getattr(settings, 'OPENID_TRUST_ROOT',
                         get_url_host(request) + '/')
    # foo derbis.
    redirect_to = redirect_to or getattr(
        settings,
        'OPENID_REDIRECT_TO',
        # If not explicitly set, assume current URL with complete/ appended
        get_full_url(request).split('?')[0] + 'complete/')
    # In case they were lazy...
    if not redirect_to.startswith('http://') or redirect_to.startswith(
            'https://'):
        redirect_to = get_url_host(request) + redirect_to

    if request.GET.get('next') and is_valid_next_url(request,
                                                     request.GET['next']):
        if '?' in redirect_to:
            join = '&'
        else:
            join = '?'
        redirect_to += join + urllib.urlencode({'next': request.GET['next']})

    user_url = request.REQUEST.get('openid_url', None)

    if not user_url:
        request_path = request.path
        if request.GET.get('next'):
            request_path += '?' + urllib.urlencode(
                {'next': request.GET['next']})

        return render(template_name, {'action': request_path},
                      context_instance=RequestContext(request))

    if xri.identifierScheme(user_url) == 'XRI' and getattr(
            settings, 'OPENID_DISALLOW_INAMES', False):
        return on_failure(request, _('i-names are not supported'))

    consumer = Consumer(request.session, DjangoOpenIDStore())

    try:
        auth_request = consumer.begin(user_url)
    except DiscoveryFailure:
        return on_failure(request, _('The OpenID was invalid'))

    sreg = getattr(settings, 'OPENID_SREG', False)

    if sreg:
        s = oidsreg.SRegRequest()
        for sarg in sreg:
            if sarg.lower().lstrip() == "policy_url":
                s.policy_url = sreg[sarg]
            else:
                for v in sreg[sarg].split(','):
                    s.requestField(
                        field_name=v.lower().lstrip(),
                        required=(sarg.lower().lstrip() == "required"))
        auth_request.addExtension(s)

    pape = getattr(settings, 'OPENID_PAPE', False)

    if pape:
        if openid.__version__ < '2.1.0':
            raise ImportError, 'For pape extension you need python-openid 2.1.0 or newer'
        p = oidpape.Request()
        for parg in pape:
            if parg.lower().strip() == 'policy_list':
                for v in pape[parg].split(','):
                    p.addPolicyURI(v)
            elif parg.lower().strip() == 'max_auth_age':
                p.max_auth_age = pape[parg]
        auth_request.addExtension(p)

    ax = getattr(settings, 'OPENID_AX', False)

    if ax:
        if openid.__version__ < '2.1.0':
            raise ImportError, 'For ax extension you need python-openid 2.1.0 or newer'
        axr = oidax.FetchRequest()
        for i in ax:
            axr.add(
                oidax.AttrInfo(i['type_uri'], i['count'], i['required'],
                               i['alias']))
        auth_request.addExtension(axr)

    redirect_url = auth_request.redirectURL(trust_root, redirect_to)
    return HttpResponseRedirect(redirect_url)
예제 #28
0
def main():
    #get query parameters
    params = cgi.FieldStorage()

    #check if an OpenID url was specified
    if not params.has_key('openid_url'):
        print_msg('Please enter an OpenID Identifier to verify.', 'text/plain')
    else:
        #capture OpenID url
        openid_url = params['openid_url'].value

        #create a base consumer object
        oidconsumer = consumer.Consumer({}, None)

        try:
            request = oidconsumer.begin(openid_url)
        except:
            print_msg('Error in discovery: ' + openid_url, 'text/plain')
        else:
            if request is None:
                print_msg('No OpenID services found', 'text/plain')
            else:
                #build trust root and url to return to
                trust_root = 'http://%s/' % (os.environ['HTTP_HOST'])
                return_to = 'http://%s/complete.py' % (os.environ['HTTP_HOST'])

                #simple registration extension request
                sreg_request = sreg.SRegRequest(required=['nickname'],
                                                optional=['fullname', 'email'])
                request.addExtension(sreg_request)

                #attribute exchange extension request
                ax_request = ax.FetchRequest()
                ax_request.add(
                    ax.AttrInfo('http://axschema.org/contact/email',
                                required=False,
                                alias='email'))
                ax_request.add(
                    ax.AttrInfo('http://axschema.org/namePerson',
                                required=False,
                                alias='fullname'))
                ax_request.add(
                    ax.AttrInfo('http://axschema.org/person/gender',
                                required=False,
                                alias='gender'))
                ax_request.add(
                    ax.AttrInfo('http://axschema.org/media/image/default',
                                required=False,
                                alias='picture'))
                request.addExtension(ax_request)

                #pape policy extension request
                if params.has_key('policy_phishing'):
                    pape_request = pape.Request([pape.AUTH_PHISHING_RESISTANT])
                    request.addExtension(pape_request)

                #openid v1 - send through redirect
                if request.shouldSendRedirect():
                    redirect_url = request.redirectURL(trust_root,
                                                       return_to,
                                                       immediate='immediate')
                    print "Location: " + redirect_url
                #openid v2 - use javascript form to send POST to server
                else:
                    form_html = request.htmlMarkup(
                        trust_root,
                        return_to,
                        form_tag_attrs={'id': 'openid_message'})

                    print_msg(form_html, 'text/html')
예제 #29
0
def startOpenID(request):
    """
    Start the OpenID authentication process.  Renders an
    authentication form and accepts its POST.

    * Renders an error message if OpenID cannot be initiated

    * Requests some Simple Registration data using the OpenID
      library's Simple Registration machinery

    * Generates the appropriate trust root and return URL values for
      this application (tweak where appropriate)

    * Generates the appropriate redirect based on the OpenID protocol
      version.
    """
    if request.POST:
        # Start OpenID authentication.
        openid_url = request.POST['openid_identifier']
        c = getConsumer(request)
        error = None

        try:
            auth_request = c.begin(openid_url)
        except DiscoveryFailure as e:
            # Some other protocol-level failure occurred.
            error = "OpenID discovery error: %s" % (str(e), )

        if error:
            # Render the page with an error.
            return renderIndexPage(request, error=error)

        # Add Simple Registration request information.  Some fields
        # are optional, some are required.  It's possible that the
        # server doesn't support sreg or won't return any of the
        # fields.
        sreg_request = sreg.SRegRequest(
            optional=['email', 'nickname'], required=['dob'])
        auth_request.addExtension(sreg_request)

        # Add Attribute Exchange request information.
        ax_request = ax.FetchRequest()
        # XXX - uses myOpenID-compatible schema values, which are
        # not those listed at axschema.org.
        ax_request.add(
            ax.AttrInfo('http://schema.openid.net/namePerson', required=True))
        ax_request.add(
            ax.AttrInfo(
                'http://schema.openid.net/contact/web/default',
                required=False,
                count=ax.UNLIMITED_VALUES))
        auth_request.addExtension(ax_request)

        # Add PAPE request information.  We'll ask for
        # phishing-resistant auth and display any policies we get in
        # the response.
        requested_policies = []
        policy_prefix = 'policy_'
        for k, v in list(request.POST.items()):
            if k.startswith(policy_prefix):
                policy_attr = k[len(policy_prefix):]
                if policy_attr in PAPE_POLICIES:
                    requested_policies.append(getattr(pape, policy_attr))

        if requested_policies:
            pape_request = pape.Request(requested_policies)
            auth_request.addExtension(pape_request)

        # Compute the trust root and return URL values to build the
        # redirect information.
        trust_root = util.getViewURL(request, startOpenID)
        return_to = util.getViewURL(request, finishOpenID)

        # Send the browser to the server either by sending a redirect
        # URL or by generating a POST form.
        if auth_request.shouldSendRedirect():
            url = auth_request.redirectURL(trust_root, return_to)
            return HttpResponseRedirect(url)
        else:
            # Beware: this renders a template whose content is a form
            # and some javascript to submit it upon page load.  Non-JS
            # users will have to click the form submit button to
            # initiate OpenID authentication.
            form_id = 'openid_message'
            form_html = auth_request.formMarkup(trust_root, return_to, False,
                                                {'id': form_id})
            return TemplateView(request, 'consumer/request_form.html',
                                {'html': form_html})

    return renderIndexPage(request)
예제 #30
0
        sreg_optional_fields = ['email', 'fullname', 'nickname']
        sreg_optional_fields.extend(
            getattr(settings, 'OPENID_SREG_EXTRA_FIELDS', []))
        sreg_optional_fields = [
            field for field in sreg_optional_fields
            if (not field in sreg_required_fields)
        ]
        openid_request.addExtension(
            sreg.SRegRequest(optional=sreg_optional_fields,
                             required=sreg_required_fields))

    if getattr(settings, 'OPENID_PHYSICAL_MULTIFACTOR_REQUIRED', False):
        preferred_auth = [
            pape.AUTH_MULTI_FACTOR_PHYSICAL,
        ]
        pape_request = pape.Request(preferred_auth_policies=preferred_auth)
        openid_request.addExtension(pape_request)

    # Request team info
    teams_mapping_auto = getattr(settings,
                                 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
    teams_mapping_auto_blacklist = getattr(
        settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST', [])
    launchpad_teams = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING', {})
    if teams_mapping_auto:
        #ignore launchpad teams. use all django-groups
        launchpad_teams = dict()
        all_groups = Group.objects.exclude(
            name__in=teams_mapping_auto_blacklist)
        for group in all_groups:
            launchpad_teams[group.name] = group.name