allura git commit: [#8128] show 2FA+HTTP checkout message when needed
Repository: allura Updated Branches: refs/heads/db/8128 6ac5a2c26 -> 9e0469d50 [#8128] show 2FA+HTTP checkout message when needed Project: http://git-wip-us.apache.org/repos/asf/allura/repo Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/9e0469d5 Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/9e0469d5 Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/9e0469d5 Branch: refs/heads/db/8128 Commit: 9e0469d50370c32bc641075c224be355a83de1c0 Parents: 6ac5a2c Author: Dave BrondsemaAuthored: Thu Sep 22 16:43:43 2016 -0400 Committer: Dave Brondsema Committed: Thu Sep 22 16:43:43 2016 -0400 -- Allura/allura/templates/repo/repo_master.html | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) -- http://git-wip-us.apache.org/repos/asf/allura/blob/9e0469d5/Allura/allura/templates/repo/repo_master.html -- diff --git a/Allura/allura/templates/repo/repo_master.html b/Allura/allura/templates/repo/repo_master.html index 1d94285..eb51f79 100644 --- a/Allura/allura/templates/repo/repo_master.html +++ b/Allura/allura/templates/repo/repo_master.html @@ -38,10 +38,16 @@ $('#access_urls .btn').click(function(evt){ evt.preventDefault(); var parent = $(this).parents('.btn-bar'); -$(parent).find('input').val($(this).attr('data-url')); +var checkout_cmd = $(this).attr('data-url'); +$(parent).find('input').val(checkout_cmd); $(parent).find('span').text($(this).attr('title')+' access'); $(this).parent().children('.btn').removeClass('active'); $(this).addClass('active'); +if (checkout_cmd.indexOf(' http://') !== -1 || checkout_cmd.indexOf(' https://') !== -1 ) { + $('#http-2fa-msg').show(); +} else { + $('#http-2fa-msg').hide(); +} }); $('#access_urls .btn').first().click(); @@ -110,6 +116,12 @@ class="selectText" value=""/> +{% if not c.user.is_anonymous() and c.user.get_pref('multifactor') and h.has_access(c.app, 'write') %} + +When using HTTP access with two-factor auth, you will need to enter your password and current token together as +the password (e.g. "p4ssw0Rd123456") + +{% endif %} {% endif %} {% endmacro %}
allura git commit: [#8131] use correct field name in LastCommitDoc queries
Repository: allura Updated Branches: refs/heads/db/8131 [created] d9c9df551 [#8131] use correct field name in LastCommitDoc queries Project: http://git-wip-us.apache.org/repos/asf/allura/repo Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/d9c9df55 Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/d9c9df55 Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/d9c9df55 Branch: refs/heads/db/8131 Commit: d9c9df551fb951ee0658bb360e8930251e997563 Parents: 7fb4022 Author: Dave BrondsemaAuthored: Thu Sep 22 15:29:15 2016 -0400 Committer: Dave Brondsema Committed: Thu Sep 22 15:29:15 2016 -0400 -- Allura/allura/scripts/refreshrepo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -- http://git-wip-us.apache.org/repos/asf/allura/blob/d9c9df55/Allura/allura/scripts/refreshrepo.py -- diff --git a/Allura/allura/scripts/refreshrepo.py b/Allura/allura/scripts/refreshrepo.py index fbec016..115e5a4 100644 --- a/Allura/allura/scripts/refreshrepo.py +++ b/Allura/allura/scripts/refreshrepo.py @@ -111,12 +111,12 @@ class RefreshRepo(ScriptTask): # delete LastCommitDocs i = M.repository.LastCommitDoc.m.find( -dict(commit_ids={'$in': ci_ids_chunk})).count() +dict(commit_id={'$in': ci_ids_chunk})).count() if i: log.info( "Deleting %i remaining LastCommitDoc docs, by repo id...", i) M.repository.LastCommitDoc.m.remove( -dict(commit_ids={'$in': ci_ids_chunk})) +dict(commit_id={'$in': ci_ids_chunk})) i = M.repository.CommitRunDoc.m.find( {"commit_ids": {"$in": ci_ids_chunk}}).count()
allura git commit: [#8130] invalidate other login sessions after setting up two-factor auth
Repository: allura Updated Branches: refs/heads/master e30522555 -> 7fb402233 [#8130] invalidate other login sessions after setting up two-factor auth Project: http://git-wip-us.apache.org/repos/asf/allura/repo Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/7fb40223 Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/7fb40223 Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/7fb40223 Branch: refs/heads/master Commit: 7fb4022335055d605b571f538cff5661df509fff Parents: e305225 Author: Dave BrondsemaAuthored: Tue Sep 20 16:44:01 2016 -0400 Committer: Dave Brondsema Committed: Tue Sep 20 16:44:01 2016 -0400 -- Allura/allura/controllers/auth.py | 3 +++ Allura/allura/lib/plugin.py | 16 +++- Allura/allura/tests/functional/test_auth.py | 10 ++ 3 files changed, 24 insertions(+), 5 deletions(-) -- http://git-wip-us.apache.org/repos/asf/allura/blob/7fb40223/Allura/allura/controllers/auth.py -- diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py index a5031d1..932f106 100644 --- a/Allura/allura/controllers/auth.py +++ b/Allura/allura/controllers/auth.py @@ -731,6 +731,8 @@ class PreferencesController(BaseController): h.auditlog_user('Set up multifactor TOTP') totp_service.set_secret_key(c.user, key) c.user.set_pref('multifactor', True) +c.user.set_tool_data('allura', multifactor_date=datetime.utcnow()) +c.user.set_tool_data('allura', pwd_reset_preserve_session=session.id) # other sessions will have to re-auth; preserve this one del session['totp_new_key'] session.save() tg.flash('Two factor authentication has now been set up.') @@ -754,6 +756,7 @@ class PreferencesController(BaseController): recovery = RecoveryCodeService.get() recovery.delete_all(c.user) c.user.set_pref('multifactor', False) +c.user.set_tool_data('allura', multifactor_date=None) tg.flash('Multifactor authentication has now been disabled.') email_body = g.jinja2_env.get_template('allura:templates/mail/twofactor_disabled.md').render(dict( user=c.user, http://git-wip-us.apache.org/repos/asf/allura/blob/7fb40223/Allura/allura/lib/plugin.py -- diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py index 7127120..4b2bf0a 100644 --- a/Allura/allura/lib/plugin.py +++ b/Allura/allura/lib/plugin.py @@ -118,11 +118,17 @@ class AuthenticationProvider(object): if user.disabled or user.pending: self.logout() return M.User.anonymous() -if not user.is_anonymous() and \ -self.get_last_password_updated(user) > datetime.utcfromtimestamp(self.session.created) and \ -user.get_tool_data('allura', 'pwd_reset_preserve_session') != self.session.id: -log.debug('Session logged out: due to user %s pwd change %s > %s', user.username, - self.get_last_password_updated(user), datetime.utcfromtimestamp(self.session.created)) +session_create_date = datetime.utcfromtimestamp(self.session.created) +if user.is_anonymous(): +sessions_need_reauth = False +elif self.get_last_password_updated(user) > session_create_date: +sessions_need_reauth = True +elif (user.get_tool_data('allura', 'multifactor_date') or datetime.min) > session_create_date: +sessions_need_reauth = True +else: +sessions_need_reauth = False +if sessions_need_reauth and user.get_tool_data('allura', 'pwd_reset_preserve_session') != self.session.id: +log.debug('Session logged out: due to user %s pwd change or multifactor enabled', user.username) self.logout() return M.User.anonymous() http://git-wip-us.apache.org/repos/asf/allura/blob/7fb40223/Allura/allura/tests/functional/test_auth.py -- diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py index 4ba27e3..b7b28be 100644 --- a/Allura/allura/tests/functional/test_auth.py +++ b/Allura/allura/tests/functional/test_auth.py @@ -2093,6 +2093,11 @@ class TestTwoFactor(TestController): assert_in('Password Confirmation', r) def test_enable_totp(self): +# create a separate session, for later use in the test +other_session = TestController() +other_session.setUp() +other_session.app.get('/auth/preferences/') + with out_audits(user=True): r
[3/3] allura git commit: Make this test run successfully on its own
Make this test run successfully on its own Project: http://git-wip-us.apache.org/repos/asf/allura/repo Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/8a70d6e4 Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/8a70d6e4 Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/8a70d6e4 Branch: refs/heads/db/parallel_test_improvements Commit: 8a70d6e45b33d35a95a01fe3c623a2d94557 Parents: 46dc9f9 Author: Dave BrondsemaAuthored: Thu Sep 22 10:16:04 2016 -0400 Committer: Dave Brondsema Committed: Thu Sep 22 10:16:04 2016 -0400 -- ForgeImporters/forgeimporters/tests/github/test_tasks.py | 1 + 1 file changed, 1 insertion(+) -- http://git-wip-us.apache.org/repos/asf/allura/blob/8a70d6e4/ForgeImporters/forgeimporters/tests/github/test_tasks.py -- diff --git a/ForgeImporters/forgeimporters/tests/github/test_tasks.py b/ForgeImporters/forgeimporters/tests/github/test_tasks.py index cf58644..b048407 100644 --- a/ForgeImporters/forgeimporters/tests/github/test_tasks.py +++ b/ForgeImporters/forgeimporters/tests/github/test_tasks.py @@ -23,6 +23,7 @@ from ...github import tasks @mock.patch.object(tasks, 'GitHubProjectExtractor') @mock.patch.object(tasks, 'ThreadLocalORMSession') @mock.patch.object(tasks, 'c') +@mock.patch.object(tasks, 'g', mock.MagicMock()) def test_import_project_info(c, session, ghpe): c.project = mock.Mock(name='project') c.user = mock.Mock(name='user')
[2/3] allura git commit: Split up pylint test into chunks that can be run with nose multiprocess; move pyflakes chunks into parallelized pattern
Split up pylint test into chunks that can be run with nose multiprocess; move pyflakes chunks into parallelized pattern Project: http://git-wip-us.apache.org/repos/asf/allura/repo Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/46dc9f9b Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/46dc9f9b Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/46dc9f9b Branch: refs/heads/db/parallel_test_improvements Commit: 46dc9f9bc0a026e0b555add0dbd5e90cea4a7462 Parents: 1969390 Author: Dave BrondsemaAuthored: Wed Sep 21 14:32:35 2016 -0400 Committer: Dave Brondsema Committed: Wed Sep 21 14:32:35 2016 -0400 -- AlluraTest/alluratest/test_syntax.py | 89 +-- 1 file changed, 50 insertions(+), 39 deletions(-) -- http://git-wip-us.apache.org/repos/asf/allura/blob/46dc9f9b/AlluraTest/alluratest/test_syntax.py -- diff --git a/AlluraTest/alluratest/test_syntax.py b/AlluraTest/alluratest/test_syntax.py index d29b00b..1db63c9 100644 --- a/AlluraTest/alluratest/test_syntax.py +++ b/AlluraTest/alluratest/test_syntax.py @@ -18,6 +18,7 @@ import os.path from subprocess import Popen, PIPE import sys +from itertools import izip_longest toplevel_dir = os.path.abspath(os.path.dirname(__file__) + "/../..") @@ -30,52 +31,17 @@ def run(cmd): sys.stderr.write(stderr) return proc.returncode -find_py = "find Allura Forge* -name '*.py'" -# a recepe from itertools doc -from itertools import izip_longest +find_py = "find Allura Forge* -name '*.py'" +# a recipe from itertools doc def grouper(n, iterable, fillvalue=None): "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n return izip_longest(fillvalue=fillvalue, *args) -def test_pyflakes(): -# skip some that aren't critical errors -skips = [ -'imported but unused', -'redefinition of unused', -'assigned to but never used', -'__version__', -] -proc = Popen(find_py, shell=True, cwd=toplevel_dir, - stdout=PIPE, stderr=PIPE) -(find_stdout, stderr) = proc.communicate() -sys.stderr.write(stderr) -assert proc.returncode == 0, proc.returncode - -# run pyflakes in batches, so it doesn't take tons of memory -error = False -all_files = [f for f in find_stdout.split('\n') - if '/migrations/' not in f and f.strip()] -for files in grouper(20, all_files, fillvalue=''): -cmd = "pyflakes " + \ -' '.join(files) + " | grep -v '" + \ -"' | grep -v '".join(skips) + "'" -# print 'Command was: %s' % cmd -retval = run(cmd) -if retval != 1: -print -# print 'Command was: %s' % cmd -print 'Returned %s' % retval -error = True - -if error: -raise Exception('pyflakes failure, see stdout') - - def test_no_local_tz_functions(): if run(find_py + " | xargs grep '\.now(' ") not in [1, 123]: raise Exception("These should use .utcnow()") @@ -104,6 +70,51 @@ def test_no_tabs(): if run(find_py + " | xargs grep ' ' ") not in [1, 123]: raise Exception('These should not use tab chars') -def test_linters(): -if run(find_py + ' | xargs pylint -E --disable=all --enable=exposed-api-needs-kwargs --load-plugins alluratest.pylint_checkers') != 0: + +def run_linter(files): +if run('pylint -E --disable=all --enable=exposed-api-needs-kwargs --load-plugins alluratest.pylint_checkers {}'.format(' '.join(files))) != 0: raise Exception('Custom Allura pylint errors found.') + + +def run_pyflakes(files): +# skip some that aren't critical errors +skips = [ +'imported but unused', +'redefinition of unused', +'assigned to but never used', +'__version__', +] +files = [f for f in files if '/migrations/' not in f] +cmd = "pyflakes " + ' '.join(files) + " | grep -v '" + "' | grep -v '".join(skips) + "'" +if run(cmd) != 1: +# print 'Command was: %s' % cmd +raise Exception('pyflakes failure, see stdout') + + +class TestLinters(object): +# this will get populated dynamically with test methods, see below +pass + + +# Dynamically generate many test methods, to run pylint & pyflakes commands in separate batches +# Can't use http://nose.readthedocs.io/en/latest/writing_tests.html#test-generators because nose doesn't run +# those in parallel +def create_many_lint_methods(): +proc = Popen(find_py, shell=True, cwd=toplevel_dir, stdout=PIPE, stderr=PIPE) +(find_stdout, stderr) = proc.communicate() +sys.stderr.write(stderr) +assert proc.returncode == 0, proc.returncode +py_files = find_stdout.split('\n') + +for i, files in
[1/3] allura git commit: Make these test classes runnable on their own (they happen to pass if other stuff runs first)
Repository: allura Updated Branches: refs/heads/db/parallel_test_improvements [created] 8a70d6e45 Make these test classes runnable on their own (they happen to pass if other stuff runs first) Project: http://git-wip-us.apache.org/repos/asf/allura/repo Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/1969390a Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/1969390a Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/1969390a Branch: refs/heads/db/parallel_test_improvements Commit: 1969390a5a4d2d2428b6e50244d3409bf6d1278c Parents: e305225 Author: Dave BrondsemaAuthored: Wed Sep 21 14:28:36 2016 -0400 Committer: Dave Brondsema Committed: Wed Sep 21 14:28:36 2016 -0400 -- .../forgeimporters/tests/forge/test_tracker.py | 13 ++--- .../forgeimporters/tests/github/test_tracker.py| 10 ++ 2 files changed, 20 insertions(+), 3 deletions(-) -- http://git-wip-us.apache.org/repos/asf/allura/blob/1969390a/ForgeImporters/forgeimporters/tests/forge/test_tracker.py -- diff --git a/ForgeImporters/forgeimporters/tests/forge/test_tracker.py b/ForgeImporters/forgeimporters/tests/forge/test_tracker.py index e985763..9be7743 100644 --- a/ForgeImporters/forgeimporters/tests/forge/test_tracker.py +++ b/ForgeImporters/forgeimporters/tests/forge/test_tracker.py @@ -17,8 +17,6 @@ from datetime import datetime from unittest import TestCase -from cgi import FieldStorage -from cStringIO import StringIO import mock from ming.odm import ThreadLocalORMSession @@ -29,11 +27,20 @@ from allura.tests.decorators import with_tracker from allura import model as M from forgeimporters.forge import tracker -from forgetracker import model as TM class TestTrackerImporter(TestCase): +def setUp(self): +super(TestTrackerImporter, self).setUp() +# every single test method here creates an importer and ToolImporterMeta uses 'g' +self.patcher_g = mock.patch('forgeimporters.base.g', mock.MagicMock()) +self.patcher_g.start() + +def tearDown(self): +super(TestTrackerImporter, self).tearDown() +self.patcher_g.stop() + @mock.patch.object(tracker, 'File') @mock.patch.object(tracker.h, 'make_app_admin_only') @mock.patch.object(tracker, 'g') http://git-wip-us.apache.org/repos/asf/allura/blob/1969390a/ForgeImporters/forgeimporters/tests/github/test_tracker.py -- diff --git a/ForgeImporters/forgeimporters/tests/github/test_tracker.py b/ForgeImporters/forgeimporters/tests/github/test_tracker.py index e02ac5a..fd7df5c 100644 --- a/ForgeImporters/forgeimporters/tests/github/test_tracker.py +++ b/ForgeImporters/forgeimporters/tests/github/test_tracker.py @@ -26,6 +26,16 @@ from forgeimporters.github.utils import GitHubMarkdownConverter class TestTrackerImporter(TestCase): +def setUp(self): +super(TestTrackerImporter, self).setUp() +# every single test method here creates an importer and ToolImporterMeta uses 'g' +self.patcher_g = mock.patch('forgeimporters.base.g', mock.MagicMock()) +self.patcher_g.start() + +def tearDown(self): +super(TestTrackerImporter, self).tearDown() +self.patcher_g.stop() + @mock.patch.object(tracker, 'g') @mock.patch.object(tracker, 'c') @mock.patch.object(tracker, 'ThreadLocalORMSession')