You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2019/11/18 17:34:05 UTC
[allura] 02/08: [#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.
brondsem pushed a commit to branch db/8340
in repository https://gitbox.apache.org/repos/asf/allura.git
commit fc378829bb0708215b694687a1a14b9be00b06dd
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