You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by ke...@apache.org on 2019/11/18 21:46:20 UTC

[allura] 05/11: [#8340] various admin/auth tests and dead code removal (url for editing custom groups no longer used)

This is an automated email from the ASF dual-hosted git repository.

kentontaylor pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 4547f6d956839821247071f6744454c6ee16b4ba
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Tue Nov 12 17:57:43 2019 -0500

    [#8340] various admin/auth tests and dead code removal (url for editing custom groups no longer used)
---
 Allura/allura/ext/admin/admin_main.py              |  90 ---------------
 .../allura/ext/admin/templates/project_group.html  |   4 -
 Allura/allura/ext/admin/widgets.py                 |  17 ---
 Allura/allura/tests/functional/test_admin.py       |  23 +---
 Allura/allura/tests/functional/test_auth.py        | 125 +++++++++++++++------
 Allura/allura/tests/functional/test_site_admin.py  |   9 ++
 .../allura/tests/functional/test_trovecategory.py  |  19 +++-
 7 files changed, 123 insertions(+), 164 deletions(-)

diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index d63b734..b7a9ce8 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -61,7 +61,6 @@ class W:
     label_edit = ffw.LabelEdit()
     group_card = aw.GroupCard()
     permission_card = aw.PermissionCard()
-    group_settings = aw.GroupSettings()
     new_group_settings = aw.NewGroupSettings()
     screenshot_admin = aw.ScreenshotAdmin()
     screenshot_list = ProjectScreenshots(draggable=True)
@@ -1162,57 +1161,11 @@ class GroupsController(BaseController):
         return dict()
 
     @without_trailing_slash
-    @expose()
-    @require_post()
-    @h.vardec
-    def update(self, card=None, **kw):
-        for pr in card:
-            group = M.ProjectRole.query.get(_id=ObjectId(pr['id']))
-            assert group.project == c.project, 'Security violation'
-            user_ids = pr.get('value', [])
-            new_users = pr.get('new', [])
-            if isinstance(user_ids, basestring):
-                user_ids = [user_ids]
-            if isinstance(new_users, basestring):
-                new_users = [new_users]
-            # Handle new users in groups
-            user_added = False
-            for username in new_users:
-                user = M.User.by_username(username.strip())
-                if not user:
-                    flash('User %s not found' % username, 'error')
-                    redirect('.')
-                if not user._id:
-                    continue  # never add anon users to groups
-                M.AuditLog.log('add user %s to %s', username, group.name)
-                M.ProjectRole.by_user(
-                    user, upsert=True).roles.append(group._id)
-                user_added = True
-            # Make sure we aren't removing all users from the Admin group
-            if group.name == u'Admin' and not (user_ids or user_added):
-                flash('You must have at least one user with the Admin role.',
-                      'warning')
-                redirect('.')
-            # Handle users removed from groups
-            user_ids = set(
-                uid and ObjectId(uid)
-                for uid in user_ids)
-            for role in M.ProjectRole.query.find(dict(user_id={'$ne': None}, roles=group._id)):
-                if role.user_id and role.user_id not in user_ids:
-                    role.roles = [
-                        rid for rid in role.roles if rid != group._id]
-                    M.AuditLog.log('remove user %s from %s',
-                                   role.user.username, group.name)
-        g.post_event('project_updated')
-        redirect('.')
-
-    @without_trailing_slash
     @expose('jinja:allura.ext.admin:templates/project_group.html')
     def new(self):
         c.form = W.new_group_settings
         return dict(
             group=None,
-            show_settings=True,
             action="create")
 
     @expose()
@@ -1228,49 +1181,6 @@ class GroupsController(BaseController):
         g.post_event('project_updated')
         redirect('.')
 
-    @expose()
-    def _lookup(self, name, *remainder):
-        return GroupController(name), remainder
-
-
-class GroupController(BaseController):
-    def __init__(self, name):
-        self._group = M.ProjectRole.query.get(_id=ObjectId(name))
-
-    @with_trailing_slash
-    @expose('jinja:allura.ext.admin:templates/project_group.html')
-    def index(self, **kw):
-        if self._group.name in ('Admin', 'Developer', 'Member'):
-            show_settings = False
-            action = None
-        else:
-            show_settings = True
-            action = self._group.settings_href + 'update'
-        c.form = W.group_settings
-        return dict(
-            group=self._group,
-            show_settings=show_settings,
-            action=action)
-
-    @expose()
-    @h.vardec
-    @require_post()
-    @validate(W.group_settings)
-    def update(self, _id=None, delete=None, name=None, **kw):
-        pr = M.ProjectRole.by_name(name)
-        if pr and pr._id != _id._id:
-            flash('%s already exists' % name, 'error')
-            redirect('..')
-        if delete:
-            _id.delete()
-            M.AuditLog.log('delete group %s', _id.name)
-            flash('%s deleted' % name)
-            redirect('..')
-        M.AuditLog.log('update group name %s=>%s', _id.name, name)
-        _id.name = name
-        flash('%s updated' % name)
-        redirect('..')
-
 
 class AuditController(BaseController):
     @with_trailing_slash
diff --git a/Allura/allura/ext/admin/templates/project_group.html b/Allura/allura/ext/admin/templates/project_group.html
index 927b776..a84c095 100644
--- a/Allura/allura/ext/admin/templates/project_group.html
+++ b/Allura/allura/ext/admin/templates/project_group.html
@@ -16,8 +16,4 @@
        specific language governing permissions and limitations
        under the License.
 -#}
-{% if show_settings %}
 {{c.form.display(value=group, action=action)}}
-{% else %}
-<p>No settings available for reserved groups</p>
-{% endif %}
diff --git a/Allura/allura/ext/admin/widgets.py b/Allura/allura/ext/admin/widgets.py
index 4c877e5..d27f8fa 100644
--- a/Allura/allura/ext/admin/widgets.py
+++ b/Allura/allura/ext/admin/widgets.py
@@ -114,23 +114,6 @@ class PermissionCard(CardField):
         return role._id
 
 
-class GroupSettings(ff.CsrfForm):
-    submit_text = None
-
-    @property
-    def hidden_fields(self):
-        f = super(GroupSettings, self).hidden_fields
-        f.append(ew.HiddenField(name='_id', validator=V.Ming(M.ProjectRole)))
-        return f
-
-    class fields(ew_core.NameList):
-        name = ew.InputField(label='Name')
-
-    class buttons(ew_core.NameList):
-        save = ew.SubmitButton(label='Save')
-        delete = ew.SubmitButton(label='Delete Group')
-
-
 class NewGroupSettings(ff.AdminFormResponsive):
     submit_text = 'Save'
 
diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index 004fe73..3b2c4df 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -662,9 +662,6 @@ class TestProjectAdmin(TestController):
         users = dev_holder.find('ul', {'class': 'users'}).findAll(
             'li', {'class': 'deleter'})
         assert 'test-user' in users[0]['data-user']
-        # Make sure we can open role page for builtin role
-        r = self.app.get('/admin/groups/' + developer_id +
-                         '/', validate_chunk=True)
 
     def test_new_admin_subscriptions(self):
         """Newly added admin must be subscribed to all the tools in the project"""
@@ -810,33 +807,21 @@ class TestProjectAdmin(TestController):
         role_holder = r.html.find('table', {'id': 'usergroup_admin'}).findAll('tr')[4]
         assert 'RoleNew1' in str(role_holder)
         role_id = role_holder['data-group']
-        r = self.app.get('/admin/groups/' + role_id + '/', validate_chunk=True)
-        r = self.app.post('/admin/groups/' + str(role_id) + '/update', params={'_id': role_id, 'name': 'Developer'})
-        assert 'error' in self.webflash(r)
-        assert 'already exists' in self.webflash(r)
-
-        with audits('update group name RoleNew1=>rleNew2'):
-            r = self.app.post('/admin/groups/' + str(role_id) + '/update',
-                              params={'_id': role_id, 'name': 'rleNew2'}).follow()
-        assert 'RoleNew1' not in r
-        assert 'rleNew2' in r
 
         # add test-user to role
         role_holder = r.html.find('table', {'id': 'usergroup_admin'}).findAll('tr')[4]
-        rleNew2_id = role_holder['data-group']
-        with audits('add user test-user to rleNew2'):
+        with audits('add user test-user to RoleNew1'):
             r = self.app.post('/admin/groups/add_user', params={
-                'role_id': rleNew2_id,
+                'role_id': role_id,
                 'username': 'test-user'})
 
-        with audits('delete group rleNew2'):
+        with audits('delete group RoleNew1'):
             r = self.app.post('/admin/groups/delete_group', params={
-                'group_name': 'rleNew2'})
+                'group_name': 'RoleNew1'})
         assert 'deleted' in self.webflash(r)
         r = self.app.get('/admin/groups/', status=200)
         roles = [str(t) for t in r.html.findAll('td', {'class': 'group'})]
         assert 'RoleNew1' not in roles
-        assert 'rleNew2' not in roles
 
         # make sure can still access homepage after one of user's roles were
         # deleted
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index a7c6893..307460f 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -197,6 +197,37 @@ class TestAuth(TestController):
 
             # changing password covered in TestPasswordExpire
 
+    def test_login_disabled(self):
+        u = M.User.query.get(username='test-user')
+        u.disabled = True
+        r = self.app.get('/auth/', extra_environ={'username': '*anonymous'})
+        f = r.forms[0]
+        encoded = self.app.antispam_field_names(f)
+        f[encoded['username']] = 'test-user'
+        f[encoded['password']] = 'foo'
+        with audits('Failed login', user=True):
+            r = f.submit(extra_environ={'username': '*anonymous'})
+
+    def test_login_pending(self):
+        u = M.User.query.get(username='test-user')
+        u.pending = True
+        r = self.app.get('/auth/', extra_environ={'username': '*anonymous'})
+        f = r.forms[0]
+        encoded = self.app.antispam_field_names(f)
+        f[encoded['username']] = 'test-user'
+        f[encoded['password']] = 'foo'
+        with audits('Failed login', user=True):
+            r = f.submit(extra_environ={'username': '*anonymous'})
+
+    def test_login_overlay(self):
+        r = self.app.get('/auth/login_fragment/', extra_environ={'username': '*anonymous'})
+        f = r.forms[0]
+        encoded = self.app.antispam_field_names(f)
+        f[encoded['username']] = 'test-user'
+        f[encoded['password']] = 'foo'
+        with audits('Successful login', user=True):
+            r = f.submit(extra_environ={'username': '*anonymous'})
+
     def test_logout(self):
         self.app.extra_environ = {'disable_auth_magic': 'True'}
         nav_pattern = ('nav', {'class': 'nav-main'})
@@ -1645,6 +1676,10 @@ To update your password on %s, please visit the following URL:
                                                  })
         assert_in('Unable to process reset, please try again', r.follow().body)
 
+    def test_hash_invalid(self):
+        r = self.app.get('/auth/forgotten_password/123412341234', status=302)
+        assert_in('Unable to process reset, please try again', r.follow().body)
+
     @patch('allura.lib.plugin.AuthenticationProvider')
     def test_provider_disabled(self, AP):
         user = M.User.query.get(username='test-admin')
@@ -1729,9 +1764,15 @@ class TestOAuth(TestController):
         r = self.app.post('/auth/oauth/register',
                           params={'application_name': 'oautstapp', 'application_description': 'Oauth rulez',
                                   '_session_id': self.app.cookies['_session_id'],
-                                  }).follow()
+                                  }, status=302)
+        r = self.app.get('/auth/oauth/')
         assert_equal(r.forms[1].action, 'generate_access_token')
-        r.forms[1].submit()
+        r = r.forms[1].submit(extra_environ={'username': 'test-user'})  # not the right user
+        assert_in("Invalid app ID", self.webflash(r))                   # gets an error
+        r = self.app.get('/auth/oauth/')                                # do it again
+        r = r.forms[1].submit()                                         # as correct user
+        assert_equal('', self.webflash(r))
+
         r = self.app.get('/auth/oauth/')
         assert 'Bearer Token:' in r
         assert_not_equal(
@@ -1744,37 +1785,55 @@ class TestOAuth(TestController):
         assert_equal(
             M.OAuthAccessToken.for_user(M.User.by_username('test-admin')), [])
 
-    @mock.patch('allura.controllers.rest.oauth.Server')
-    @mock.patch('allura.controllers.rest.oauth.Request')
-    def test_interactive(self, Request, Server):
-        M.OAuthConsumerToken.consumer = mock.Mock()
-        user = M.User.by_username('test-admin')
-        M.OAuthConsumerToken(
-            api_key='api_key',
-            user_id=user._id,
-            description='ctok_desc',
-        )
-        ThreadLocalORMSession.flush_all()
-        Request.from_request.return_value = {
-            'oauth_consumer_key': 'api_key',
-            'oauth_callback': 'http://my.domain.com/callback',
-        }
-        r = self.app.post('/rest/oauth/request_token', params={})
-        rtok = parse_qs(r.body)['oauth_token'][0]
-        r = self.app.post('/rest/oauth/authorize',
-                          params={'oauth_token': rtok})
-        r = r.forms[0].submit('yes')
-        assert r.location.startswith('http://my.domain.com/callback')
-        pin = parse_qs(urlparse(r.location).query)['oauth_verifier'][0]
-        Request.from_request.return_value = {
-            'oauth_consumer_key': 'api_key',
-            'oauth_token': rtok,
-            'oauth_verifier': pin,
-        }
-        r = self.app.get('/rest/oauth/access_token')
-        atok = parse_qs(r.body)
-        assert_equal(len(atok['oauth_token']), 1)
-        assert_equal(len(atok['oauth_token_secret']), 1)
+    def test_interactive(self):
+        with mock.patch('allura.controllers.rest.oauth.Server') as Server, \
+                mock.patch('allura.controllers.rest.oauth.Request') as Request:   # these are the oauth2 libs
+            #M.OAuthConsumerToken.consumer = mock.Mock()
+            user = M.User.by_username('test-admin')
+            M.OAuthConsumerToken(
+                api_key='api_key',
+                user_id=user._id,
+                description='ctok_desc',
+            )
+            ThreadLocalORMSession.flush_all()
+            Request.from_request.return_value = {
+                'oauth_consumer_key': 'api_key',
+                'oauth_callback': 'http://my.domain.com/callback',
+            }
+            r = self.app.post('/rest/oauth/request_token', params={})
+            rtok = parse_qs(r.body)['oauth_token'][0]
+            r = self.app.post('/rest/oauth/authorize',
+                              params={'oauth_token': rtok})
+            r = r.forms[0].submit('yes')
+            assert r.location.startswith('http://my.domain.com/callback')
+            pin = parse_qs(urlparse(r.location).query)['oauth_verifier'][0]
+            Request.from_request.return_value = {
+                'oauth_consumer_key': 'api_key',
+                'oauth_token': rtok,
+                'oauth_verifier': pin,
+            }
+            r = self.app.get('/rest/oauth/access_token')
+            atok = parse_qs(r.body)
+            assert_equal(len(atok['oauth_token']), 1)
+            assert_equal(len(atok['oauth_token_secret']), 1)
+
+        # now use the tokens & secrets to make a full OAuth request:
+        oauth_secret = atok['oauth_token_secret'][0]
+        oauth_token = atok['oauth_token'][0]
+        consumer = oauth2.Consumer('api_key', oauth_secret)
+        M.OAuthConsumerToken.consumer = consumer
+        access_token = oauth2.Token(oauth_token, oauth_secret)
+        oauth_client = oauth2.Client(consumer, access_token)
+        # use the oauth2 lib, but intercept the request and then send it to self.app.get
+        with mock.patch('oauth2.httplib2.Http.request', name='hl2req') as oa2_req:
+            oauth_client.request('http://localhost/rest/p/test/', 'GET')
+            oa2url = oa2_req.call_args[0][1]
+            oa2url = oa2url.replace('http://localhost', '')
+            print(oa2url)
+            oa2kwargs = oa2_req.call_args[1]
+        self.app.get(oa2url, headers=oa2kwargs['headers'], status=200)
+        self.app.get(oa2url.replace('oauth_signature=', 'removed='), headers=oa2kwargs['headers'], status=401)
+
 
     @mock.patch('allura.controllers.rest.oauth.Server')
     @mock.patch('allura.controllers.rest.oauth.Request')
diff --git a/Allura/allura/tests/functional/test_site_admin.py b/Allura/allura/tests/functional/test_site_admin.py
index d7eebc6..8b23c1e 100644
--- a/Allura/allura/tests/functional/test_site_admin.py
+++ b/Allura/allura/tests/functional/test_site_admin.py
@@ -137,6 +137,15 @@ class TestSiteAdmin(TestController):
             url, extra_environ=dict(username='*anonymous'), status=302)
         r = self.app.get(url)
         assert 'math.ceil' in r, r
+        assert 'ready' in r, r
+
+        # test resubmit too
+        M.MonQTask.run_ready()
+        r = self.app.get(url)
+        assert 'complete' in r, r
+        r = r.forms['resubmit-task-form'].submit()
+        r = r.follow()
+        assert 'ready' in r, r
 
     def test_task_new(self):
         r = self.app.get('/nf/admin/task_manager/new')
diff --git a/Allura/allura/tests/functional/test_trovecategory.py b/Allura/allura/tests/functional/test_trovecategory.py
index 4bb6eed..346a9f1 100644
--- a/Allura/allura/tests/functional/test_trovecategory.py
+++ b/Allura/allura/tests/functional/test_trovecategory.py
@@ -18,7 +18,7 @@ from bs4 import BeautifulSoup
 import mock
 
 from tg import config
-from nose.tools import assert_equals, assert_true
+from nose.tools import assert_equals, assert_true, assert_in
 from ming.orm import session
 
 from allura import model as M
@@ -133,3 +133,20 @@ class TestTroveCategoryController(TestController):
         </ul>
         """.strip(), 'html.parser')
         assert_equals(str(expected), str(rendered_tree))
+
+    def test_delete(self):
+        self.create_some_cats()
+        session(M.TroveCategory).flush()
+        assert_equals(5, M.TroveCategory.query.find().count())
+
+        r = self.app.get('/categories/1')
+        form = r.forms[0]
+        r = form.submit()
+        assert_in("This category contains at least one sub-category, therefore it can't be removed",
+                  self.webflash(r))
+
+        r = self.app.get('/categories/2')
+        form = r.forms[0]
+        r = form.submit()
+        assert_in("Category removed", self.webflash(r))
+        assert_equals(4, M.TroveCategory.query.find().count())
\ No newline at end of file