diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py index 3ba29c3..39db198 100644 --- a/pagure/lib/__init__.py +++ b/pagure/lib/__init__.py @@ -2195,18 +2195,31 @@ def search_projects( # No filtering is done if private == username i.e if the owner of the # project is viewing the project elif isinstance(private, basestring) and private != username: - projects = projects.filter( + # if we use the sqlalchemy.or_ in projects.filter, it will + # fail to find any projects assuming there are no rows in + # the ProjectUser table due to the way sqlalchemy creates + # nested selects from conditions; therefore we create the + # subquery explicitly on our own and do it right + subquery = session.query( + sqlalchemy.distinct(model.Project.id) + ).outerjoin( + model.ProjectUser + ).outerjoin( + model.User + ).filter( sqlalchemy.or_( model.Project.private == False, # noqa: E712 sqlalchemy.and_( model.User.user == private, - model.User.id == model.ProjectUser.user_id, - model.ProjectUser.project_id == model.Project.id, model.Project.private == True, ) ) ) + projects = projects.filter( + model.Project.id.in_(subquery) + ) + if fork is not None: if fork is True: projects = projects.filter( diff --git a/tests/test_pagure_lib.py b/tests/test_pagure_lib.py index 6bb5800..857c7f2 100644 --- a/tests/test_pagure_lib.py +++ b/tests/test_pagure_lib.py @@ -281,27 +281,31 @@ class PagureLibtests_search_projects(tests.Modeltests): name='private_test', description='Private test project #1', hook_token='aaabbbcccpp', + private=True, ) self.session.add(item) self.session.commit() + # non authenticated projects = pagure.lib.search_projects(self.session) - self.assertEqual(len(projects), 4) + self.assertEqual(len(projects), 3) self.assertEqual( [p.path for p in projects], - ['private_test.git', 'test.git', 'test2.git', + ['test.git', 'test2.git', 'somenamespace/test3.git'] ) + # non authenticated projects = pagure.lib.search_projects( self.session, username='pingou') - self.assertEqual(len(projects), 4) + self.assertEqual(len(projects), 3) self.assertEqual( [p.path for p in projects], - ['private_test.git', 'test.git', 'test2.git', + ['test.git', 'test2.git', 'somenamespace/test3.git'] ) + # authenticated as pingou projects = pagure.lib.search_projects( self.session, username='pingou', private='pingou') self.assertEqual(len(projects), 4) @@ -311,9 +315,15 @@ class PagureLibtests_search_projects(tests.Modeltests): 'somenamespace/test3.git'] ) + # authenticated as foo projects = pagure.lib.search_projects( self.session, username='pingou', private='foo') - self.assertEqual(len(projects), 0) + self.assertEqual(len(projects), 3) + self.assertEqual( + [p.path for p in projects], + ['test.git', 'test2.git', + 'somenamespace/test3.git'] + ) def test_search_projects_tags(self): """