diff --git a/doc/usage/tips_tricks.rst b/doc/usage/tips_tricks.rst index 4319085..4fc9ba9 100644 --- a/doc/usage/tips_tricks.rst +++ b/doc/usage/tips_tricks.rst @@ -39,3 +39,24 @@ will get the emails printed to the console instead of being sent. The admin of the instance can then access the URL to manually validate the account from there. This is generally used for development where we don't need to send any emails. + + +Filter an user's projects by their access +----------------------------------------- + +When watching an user's page, the list of all the project that user is +involved in is presented regardless of whether the user has ticket, commit, +admin access or is the main admin of the project. + +You can specify an ``acl=`` argument to the url to filter the list of +project by access. + + +.. note:: This also works for your home page when you are logged in + + +Examples: +~~~~~~~~~ +https://pagure.io/user/pingou?acl=main admin +https://pagure.io/user/pingou?acl=admin +https://pagure.io/user/pingou?acl=commit diff --git a/pagure/ui/app.py b/pagure/ui/app.py index 74b140e..21b7d3e 100644 --- a/pagure/ui/app.py +++ b/pagure/ui/app.py @@ -87,6 +87,8 @@ def index_auth(): """ user = _get_user(username=flask.g.fas_user.username) + acl = flask.request.args.get('acl', '').strip().lower() or None + repopage = flask.request.args.get('repopage', 1) try: repopage = int(repopage) @@ -108,14 +110,29 @@ def index_auth(): username=flask.g.fas_user.username, exclude_groups=APP.config.get('EXCLUDE_GROUP_INDEX'), fork=False, private=flask.g.fas_user.username) - - repos_length = pagure.lib.search_projects( - SESSION, - username=flask.g.fas_user.username, - exclude_groups=APP.config.get('EXCLUDE_GROUP_INDEX'), - fork=False, - count=True, - private=flask.g.fas_user.username) + if repos and acl: + if acl == 'commit': + repos = [ + repo + for repo in repos + if user in repo.committers + or user.username == repo.user.username + ] + elif acl == 'admin': + repos = [ + repo + for repo in repos + if user in repo.admins + or user.username == repo.user.username + ] + elif acl == 'main admin': + repos = [ + repo + for repo in repos + if user.username == repo.user.username + ] + + repos_length = len(repos) forks = pagure.lib.search_projects( SESSION, @@ -123,12 +140,7 @@ def index_auth(): fork=True, private=flask.g.fas_user.username) - forks_length = pagure.lib.search_projects( - SESSION, - username=flask.g.fas_user.username, - fork=True, - count=True, - private=flask.g.fas_user.username) + forks_length = len(forks) watch_list = pagure.lib.user_watch_list( SESSION, @@ -316,6 +328,8 @@ def view_user(username): """ user = _get_user(username=username) + acl = flask.request.args.get('acl', '').strip().lower() or None + repopage = flask.request.args.get('repopage', 1) try: repopage = int(repopage) @@ -348,13 +362,30 @@ def view_user(username): start=repo_start, limit=limit, private=private) - repos_length = pagure.lib.search_projects( - SESSION, - username=username, - fork=False, - exclude_groups=APP.config.get('EXCLUDE_GROUP_INDEX'), - count=True, - private=private) + + if repos and acl: + if acl == 'commit': + repos = [ + repo + for repo in repos + if user in repo.committers + or user.username == repo.user.username + ] + elif acl == 'admin': + repos = [ + repo + for repo in repos + if user in repo.admins + or user.username == repo.user.username + ] + elif acl == 'main admin': + repos = [ + repo + for repo in repos + if user.username == repo.user.username + ] + + repos_length = len(repos) forks = pagure.lib.search_projects( SESSION, @@ -363,12 +394,7 @@ def view_user(username): start=fork_start, limit=limit, private=private) - forks_length = pagure.lib.search_projects( - SESSION, - username=username, - fork=True, - count=True, - private=private) + forks_length = len(forks) total_page_repos = int(ceil(repos_length / float(limit))) total_page_forks = int(ceil(forks_length / float(limit))) @@ -412,7 +438,7 @@ def view_user_requests(username): @APP.route('/user/<username>/issues') def view_user_issues(username): """ - Shows the issues created or assigned to the + Shows the issues created or assigned to the specified user. diff --git a/tests/test_pagure_flask_ui_app.py b/tests/test_pagure_flask_ui_app.py index eb5729b..56d5f36 100644 --- a/tests/test_pagure_flask_ui_app.py +++ b/tests/test_pagure_flask_ui_app.py @@ -43,58 +43,6 @@ class PagureFlaskApptests(tests.Modeltests): pagure.ui.filters.SESSION = self.session pagure.ui.repo.SESSION = self.session - @patch.dict('pagure.APP.config', {'HTML_TITLE': 'Pagure HTML title set'}) - def test_index_html_title(self): - """ Test the index endpoint with a set html title. """ - - output = self.app.get('/') - self.assertEqual(output.status_code, 200) - self.assertIn( - '<title>Home - Pagure HTML title set</title>', - output.data) - - def test_index(self): - """ Test the index endpoint. """ - - output = self.app.get('/') - self.assertEqual(output.status_code, 200) - self.assertIn('<title>Home - Pagure</title>', output.data) - self.assertIn( - '<h2 class="m-b-1">All Projects ' - '<span class="label label-default">0</span></h2>', output.data) - - tests.create_projects(self.session) - - output = self.app.get('/?page=abc') - self.assertEqual(output.status_code, 200) - self.assertIn( - '<h2 class="m-b-1">All Projects ' - '<span class="label label-default">3</span></h2>', output.data) - - # Add a 3rd project with a long description - item = pagure.lib.model.Project( - user_id=2, # foo - name='test3', - description='test project #3 with a very long description', - hook_token='aaabbbeeefff', - ) - self.session.add(item) - self.session.commit() - - user = tests.FakeUser(username='foo') - with tests.user_set(pagure.APP, user): - output = self.app.get('/?repopage=abc&forkpage=def') - self.assertIn( - 'Projects <span class="label label-default">1</span>', - output.data) - self.assertIn( - 'Forks <span class="label label-default">0</span>', - output.data) - self.assertEqual( - output.data.count('<p>No group found</p>'), 1) - self.assertEqual( - output.data.count('<div class="card-header">'), 6) - def test_watch_list(self): ''' Test for watch list of a user ''' @@ -1656,5 +1604,6 @@ class PagureFlaskApptests(tests.Modeltests): output = self.app.get('/settings/token/new') self.assertEqual(output.status_code, 302) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/tests/test_pagure_flask_ui_app_index.py b/tests/test_pagure_flask_ui_app_index.py new file mode 100644 index 0000000..3d8220a --- /dev/null +++ b/tests/test_pagure_flask_ui_app_index.py @@ -0,0 +1,441 @@ +# -*- coding: utf-8 -*- + +""" + (c) 2017 - Copyright Red Hat Inc + + Authors: + Pierre-Yves Chibon <pingou@pingoured.fr> + +""" + +__requires__ = ['SQLAlchemy >= 0.8'] +import pkg_resources + +import datetime +import unittest +import shutil +import sys +import os + +import six +import json +import pygit2 +from mock import patch, MagicMock + +sys.path.insert(0, os.path.join(os.path.dirname( + os.path.abspath(__file__)), '..')) + +import pagure.lib +import tests + + +class PagureFlaskAppIndextests(tests.Modeltests): + """ Tests for the index page of flask app controller of pagure """ + + def setUp(self): + """ Set up the environnment, ran before every tests. """ + super(PagureFlaskAppIndextests, self).setUp() + + pagure.APP.config['TESTING'] = True + pagure.SESSION = self.session + pagure.ui.SESSION = self.session + pagure.ui.app.SESSION = self.session + pagure.ui.filters.SESSION = self.session + pagure.ui.repo.SESSION = self.session + + @patch.dict('pagure.APP.config', {'HTML_TITLE': 'Pagure HTML title set'}) + def test_index_html_title(self): + """ Test the index endpoint with a set html title. """ + + output = self.app.get('/') + self.assertEqual(output.status_code, 200) + self.assertIn( + '<title>Home - Pagure HTML title set</title>', + output.data) + + def test_index_logged_out(self): + """ Test the index endpoint when logged out. """ + + output = self.app.get('/') + self.assertEqual(output.status_code, 200) + self.assertIn('<title>Home - Pagure</title>', output.data) + self.assertIn( + '<h2 class="m-b-1">All Projects ' + '<span class="label label-default">0</span></h2>', output.data) + + tests.create_projects(self.session) + + output = self.app.get('/?page=abc') + self.assertEqual(output.status_code, 200) + self.assertIn( + '<h2 class="m-b-1">All Projects ' + '<span class="label label-default">3</span></h2>', output.data) + + def test_index_logged_in(self): + """ Test the index endpoint when logged in. """ + tests.create_projects(self.session) + + # Add a 3rd project with a long description + item = pagure.lib.model.Project( + user_id=2, # foo + name='test3', + description='test project #3 with a very long description', + hook_token='aaabbbeeefff', + ) + self.session.add(item) + self.session.commit() + + user = tests.FakeUser(username='foo') + with tests.user_set(pagure.APP, user): + output = self.app.get('/?repopage=abc&forkpage=def') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">1</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + def test_index_commit_access_while_admin(self): + """ Test the index endpoint filter for commit access only when user + is an admin. """ + tests.create_projects(self.session) + + # Add a 3rd project just for foo + item = pagure.lib.model.Project( + user_id=2, # foo + name='test3', + description='test project #3 with a very long description', + hook_token='aaabbbeeefff', + ) + self.session.add(item) + self.session.commit() + + user = tests.FakeUser(username='foo') + with tests.user_set(pagure.APP, user): + # Before + output = self.app.get('/?acl=commit') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">1</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + # Add foo to test with admin level + project = pagure.lib._get_project(self.session, 'test') + msg = pagure.lib.add_user_to_project( + self.session, + project=project, + new_user='foo', + user='pingou', + access='admin') + self.session.commit() + self.assertEqual(msg, 'User added') + + # After + output = self.app.get('/?acl=commit') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">2</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + def test_index_commit_access_while_commit(self): + """ Test the index endpoint filter for commit access only when user + is an committer. """ + tests.create_projects(self.session) + + # Add a 3rd project just for foo + item = pagure.lib.model.Project( + user_id=2, # foo + name='test3', + description='test project #3 with a very long description', + hook_token='aaabbbeeefff', + ) + self.session.add(item) + self.session.commit() + + user = tests.FakeUser(username='foo') + with tests.user_set(pagure.APP, user): + # Before + output = self.app.get('/?acl=commit') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">1</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + # Add foo to test with commit level + project = pagure.lib._get_project(self.session, 'test') + msg = pagure.lib.add_user_to_project( + self.session, + project=project, + new_user='foo', + user='pingou', + access='commit') + self.session.commit() + self.assertEqual(msg, 'User added') + + # After + output = self.app.get('/?acl=commit') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">2</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + def test_index_commit_access_while_ticket(self): + """ Test the index endpoint filter for commit access only when user + is has ticket access. """ + tests.create_projects(self.session) + + # Add a 3rd project just for foo + item = pagure.lib.model.Project( + user_id=2, # foo + name='test3', + description='test project #3 with a very long description', + hook_token='aaabbbeeefff', + ) + self.session.add(item) + self.session.commit() + + user = tests.FakeUser(username='foo') + with tests.user_set(pagure.APP, user): + # Before + output = self.app.get('/?acl=ticket') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">1</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + # Add foo to test with ticket level + project = pagure.lib._get_project(self.session, 'test') + msg = pagure.lib.add_user_to_project( + self.session, + project=project, + new_user='foo', + user='pingou', + access='ticket') + self.session.commit() + self.assertEqual(msg, 'User added') + + # After - projects with ticket access aren't shown + output = self.app.get('/?acl=ticket') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">1</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + def test_index_admin_access_while_commit(self): + """ Test the index endpoint filter for admin access only when user + is an admin. """ + tests.create_projects(self.session) + + # Add a 3rd project just for foo + item = pagure.lib.model.Project( + user_id=2, # foo + name='test3', + description='test project #3 with a very long description', + hook_token='aaabbbeeefff', + ) + self.session.add(item) + self.session.commit() + + user = tests.FakeUser(username='foo') + with tests.user_set(pagure.APP, user): + # Before + output = self.app.get('/?acl=admin') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">1</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + # Add foo to test with commit level + project = pagure.lib._get_project(self.session, 'test') + msg = pagure.lib.add_user_to_project( + self.session, + project=project, + new_user='foo', + user='pingou', + access='admin') + self.session.commit() + self.assertEqual(msg, 'User added') + + # After + output = self.app.get('/?acl=admin') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">2</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + def test_index_admin_access_while_commit(self): + """ Test the index endpoint filter for admin access only when user + is an committer. """ + tests.create_projects(self.session) + + # Add a 3rd project just for foo + item = pagure.lib.model.Project( + user_id=2, # foo + name='test3', + description='test project #3 with a very long description', + hook_token='aaabbbeeefff', + ) + self.session.add(item) + self.session.commit() + + user = tests.FakeUser(username='foo') + with tests.user_set(pagure.APP, user): + # Before + output = self.app.get('/?acl=admin') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">1</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + # Add foo to test with commit level + project = pagure.lib._get_project(self.session, 'test') + msg = pagure.lib.add_user_to_project( + self.session, + project=project, + new_user='foo', + user='pingou', + access='commit') + self.session.commit() + self.assertEqual(msg, 'User added') + + # After + output = self.app.get('/?acl=admin') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">1</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + def test_index_main_admin_access_while_commit(self): + """ Test the index endpoint filter for main admin access only when + user is an committer. """ + tests.create_projects(self.session) + + # Add a 3rd project just for foo + item = pagure.lib.model.Project( + user_id=2, # foo + name='test3', + description='test project #3 with a very long description', + hook_token='aaabbbeeefff', + ) + self.session.add(item) + self.session.commit() + + user = tests.FakeUser(username='foo') + with tests.user_set(pagure.APP, user): + # Before + output = self.app.get('/?acl=main admin') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">1</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + # Add foo to test with commit level + project = pagure.lib._get_project(self.session, 'test') + msg = pagure.lib.add_user_to_project( + self.session, + project=project, + new_user='foo', + user='pingou', + access='commit') + self.session.commit() + self.assertEqual(msg, 'User added') + + # After + output = self.app.get('/?acl=main admin') + self.assertEqual(output.status_code, 200) + self.assertIn( + 'Projects <span class="label label-default">1</span>', + output.data) + self.assertIn( + 'Forks <span class="label label-default">0</span>', + output.data) + self.assertEqual( + output.data.count('<p>No group found</p>'), 1) + self.assertEqual( + output.data.count('<div class="card-header">'), 6) + + +if __name__ == '__main__': + unittest.main(verbosity=2)