示例#1
0
def browserid_login(request):
    """Multi-mode BrowserID authentication form processor.

    Handles login and register browserid verification. If
    the mode is login, we are done. If the mode is register
    then we start new profile flow. Also handles corner cases.

    Login and register sasl-browserid verification steps are very similar
    and the corner cases blur the lines, so this is best as one
    url.

    We use the form from django-browserid, but since the LDAP server
    does the BrowserID auth behind the scenes, we don't use it's auth code
    nor it's views.
    """
    form = ModalBrowserIdForm(data=request.POST)
    if form.is_valid():
        assertion = form.cleaned_data['assertion']
        store_assertion(request, assertion)
        mode = form.cleaned_data['mode']
        user = auth.authenticate(request=request, assertion=assertion)
        if user:
            auth.login(request, user)
            return redirect('profile', request.user.unique_id)
        else:
            url = absolutify("%s?link=%s" % (reverse('register'), mode))
            return redirect(url)
    else:
        msg = _('Sorry, but there were problems with the info you submitted. '
                'Please review the form, correct any errors, and try again.')
        messages.warning(request, msg)
        log.warning("Form didn't validate %s" % str(request.POST))
        return redirect('home')
示例#2
0
    def authenticate(self, request=None, assertion=None):
        """Authentication based on BrowserID assertion.

        ``django.contrib.auth`` backend that is SASL and BrowserID
        savy. Uses session to maintain assertion over multiple
        requests.
        """
        if not (request and assertion):
            return None
        store_assertion(request, assertion)

        directory = UserSession(request)
        with statsd.timer('larper.sasl_bind_time'):
            (registered, details) = _get_registered_user(directory, request)

        if registered:
            person = directory.get_by_unique_id(details)
            defaults = dict(username=person.username,
                            first_name=person.first_name,
                            last_name=person.last_name,
                            email=person.username)
            user, created = User.objects.get_or_create(username=person.username,
                                                       defaults=defaults)
            if created:
                user.set_unusable_password()
                user.save()
            return user
        return None
示例#3
0
def _get_registered_user(directory, request):
    """Checks the directory for a registered user.

    Function returns a tuple of registered and details.
    Registered is True if a user is found and False otherwise.
    If registered is True then details contains info about
    the known user.

    The statsd timer ``larper.sasl_bind_time`` allows IT to detect
    timeouts between ldap and https://browserid.org/verify. If this
    counter gets large, check DNS routes between slapd servers and
    browserid.org.

    The statsd counter
    ``browserid.unknown_error_checking_registered_user``
    allows IT to detect a problem with the backend auth system.
    """
    registered = False
    details = None
    try:
        (registered, details) = directory.registered_user()
        if registered:
            request.session['unique_id'] = details
        else:
            request.session['verified_email'] = details
    except Exception, e:
        # Look at syslogs on slapd hosts to investigate unknown issues
        messages.error(request,
                       _("We're Sorry, but Something Went Wrong!"))
        statsd.incr('browserid.unknown_error_checking_registered_user')
        log.error("Unknown error, clearing session assertion [%s]", e)
        store_assertion(request, None)
示例#4
0
def browserid_login(request):
    """Multi-mode BrowserID authentication form processor.

    Handles login and register browserid verification. If
    the mode is login, we are done. If the mode is register
    then we start new profile flow. Also handles corner cases.

    Login and register sasl-browserid verification steps are very similar
    and the corner cases blur the lines, so this is best as one
    url.

    We use the form from django-browserid, but since the LDAP server
    does the BrowserID auth behind the scenes, we don't use it's auth code
    nor it's views.
    """
    form = ModalBrowserIdForm(data=request.POST)
    if form.is_valid():
        assertion = form.cleaned_data['assertion']
        store_assertion(request, assertion)
        mode = form.cleaned_data['mode']
        user = auth.authenticate(request=request, assertion=assertion)
        if user:
            auth.login(request, user)
            return redirect('profile', request.user.unique_id)
        else:
            url = absolutify("%s?link=%s" % (reverse('register'), mode))
            return redirect(url)
    else:
        msg = _('Sorry, but there were problems with the info you submitted. '
                'Please review the form, correct any errors, and try again.')
        messages.warning(request, msg)
        log.warning("Form didn't validate %s" % str(request.POST))
        return redirect('home')
示例#5
0
def _get_registered_user(directory, request):
    """Checks the directory for a registered user.

    Function returns a tuple of registered and details.
    Registered is True if a user is found and False otherwise.
    If registered is True then details contains info about
    the known user.

    The statsd timer ``larper.sasl_bind_time`` allows IT to detect
    timeouts between ldap and https://browserid.org/verify. If this
    counter gets large, check DNS routes between slapd servers and
    browserid.org.

    The statsd counter
    ``browserid.unknown_error_checking_registered_user``
    allows IT to detect a problem with the backend auth system.
    """
    registered = False
    details = None
    try:
        (registered, details) = directory.registered_user()
        if registered:
            request.session['unique_id'] = details
        else:
            request.session['verified_email'] = details
    except Exception, e:
        # Look at syslogs on slapd hosts to investigate unknown issues
        messages.error(request, _("We're Sorry, but Something Went Wrong!"))
        statsd.incr('browserid.unknown_error_checking_registered_user')
        log.error("Unknown error, clearing session assertion [%s]", e)
        store_assertion(request, None)
示例#6
0
    def authenticate(self, request=None, assertion=None):
        """Authentication based on BrowserID assertion.

        ``django.contrib.auth`` backend that is SASL and BrowserID
        savy. Uses session to maintain assertion over multiple
        requests.
        """
        if not (request and assertion):
            return None
        store_assertion(request, assertion)

        directory = UserSession(request)
        with statsd.timer('larper.sasl_bind_time'):
            (registered, details) = _get_registered_user(directory, request)

        if registered:
            person = directory.get_by_unique_id(details)
            defaults = dict(username=person.username,
                            first_name=person.first_name,
                            last_name=person.last_name,
                            email=person.username)
            user, created = User.objects.get_or_create(
                username=person.username, defaults=defaults)
            if created:
                user.set_unusable_password()
                user.save()
            return user
        return None
示例#7
0
    def test_connection_pooling(self):
        # Don't use _mock_request, nor TestLarper since we want full control
        # over the request to find pooling bugs
        rf = RequestFactory()
        request = rf.get('/en-US')
        request.session = {}
        request.user = MockUser('*****@*****.**', '7f3a67u000001')

        larper.store_assertion(request, 'abcdefghijklmnop')

        R = larper.READ
        W = larper.WRITE

        directory = UserSession.connect(request)
        self.assertFalse(hasattr(request, 'larper_conns'))

        regi = RegistrarSession.connect(request)
        self.assertFalse(hasattr(request, 'larper_conns'))

        regi_W_conn = regi._ensure_conn(W)
        regi_W_conn2 = regi._ensure_conn(W)

        self.assertIs(regi_W_conn, regi_W_conn2)
        self.assertTrue(hasattr(request, 'larper_conns'))
        self.assertEqual(len(request.larper_conns[R].keys()), 0)
        self.assertEqual(len(request.larper_conns[W].keys()), 1)

        dir_W_conn = directory._ensure_conn(W)
        dir_W_conn2 = directory._ensure_conn(W)

        self.assertIs(dir_W_conn, dir_W_conn2)
        self.assertEqual(len(request.larper_conns[R].keys()), 0)
        self.assertEqual(len(request.larper_conns[W].keys()), 2)

        dir_R_conn = directory._ensure_conn(R)

        admin = AdminSession.connect(request)
        admin_R_conn = admin._ensure_conn(R)
        admin_R_conn2 = admin._ensure_conn(R)
        admin_W_conn = admin._ensure_conn(W)

        self.assertIs(admin_R_conn, admin_R_conn2)
        self.assertIsNot(admin_R_conn, admin_W_conn)

        for conn in (regi_W_conn, dir_R_conn, admin_R_conn, admin_W_conn):
            # nor is it dir_R_conn2 or admin_R_conn2
            self.assertIsNot(dir_W_conn, conn)

        self.assertEqual(len(request.larper_conns[R].keys()), 2)
        self.assertEqual(len(request.larper_conns[W].keys()), 3)

        directory.disconnect(request)

        self.assertEqual(len(request.larper_conns[R].keys()), 0)
        self.assertEqual(len(request.larper_conns[W].keys()), 0)
示例#8
0
    def test_connection_pooling(self):
        # Don't use _mock_request, nor TestLarper since we want full control
        # over the request to find pooling bugs
        rf = RequestFactory()
        request = rf.get('/en-US')
        request.session = {}
        request.user = MockUser('*****@*****.**', '7f3a67u000001')

        larper.store_assertion(request, 'abcdefghijklmnop')

        R = larper.READ
        W = larper.WRITE

        directory = UserSession.connect(request)
        self.assertFalse(hasattr(request, 'larper_conns'))

        regi = RegistrarSession.connect(request)
        self.assertFalse(hasattr(request, 'larper_conns'))

        regi_W_conn = regi._ensure_conn(W)
        regi_W_conn2 = regi._ensure_conn(W)

        self.assertIs(regi_W_conn, regi_W_conn2)
        self.assertTrue(hasattr(request, 'larper_conns'))
        self.assertEqual(len(request.larper_conns[R].keys()), 0)
        self.assertEqual(len(request.larper_conns[W].keys()), 1)

        dir_W_conn = directory._ensure_conn(W)
        dir_W_conn2 = directory._ensure_conn(W)

        self.assertIs(dir_W_conn, dir_W_conn2)
        self.assertEqual(len(request.larper_conns[R].keys()), 0)
        self.assertEqual(len(request.larper_conns[W].keys()), 2)

        dir_R_conn = directory._ensure_conn(R)

        admin = AdminSession.connect(request)
        admin_R_conn = admin._ensure_conn(R)
        admin_R_conn2 = admin._ensure_conn(R)
        admin_W_conn = admin._ensure_conn(W)

        self.assertIs(admin_R_conn, admin_R_conn2)
        self.assertIsNot(admin_R_conn, admin_W_conn)

        for conn in (regi_W_conn, dir_R_conn, admin_R_conn, admin_W_conn):
            # nor is it dir_R_conn2 or admin_R_conn2
            self.assertIsNot(dir_W_conn, conn)

        self.assertEqual(len(request.larper_conns[R].keys()), 2)
        self.assertEqual(len(request.larper_conns[W].keys()), 3)

        directory.disconnect(request)

        self.assertEqual(len(request.larper_conns[R].keys()), 0)
        self.assertEqual(len(request.larper_conns[W].keys()), 0)
示例#9
0
def _mock_request(path, username='******',
                  unique_id='7f3a67u000001', assertion='abcdefghijklmnop'):
    global requests
    rf = RequestFactory()
    # mock authenticated user
    request = rf.get(path)
    request.session = {}
    request.user = MockUser(username, unique_id)
    larper.store_assertion(request, assertion)
    requests.append(request)
    return request
示例#10
0
def _mock_request(path,
                  username='******',
                  unique_id='7f3a67u000001',
                  assertion='abcdefghijklmnop'):
    global requests
    rf = RequestFactory()
    # mock authenticated user
    request = rf.get(path)
    request.session = {}
    request.user = MockUser(username, unique_id)
    larper.store_assertion(request, assertion)
    requests.append(request)
    return request