test_pagure_lib_git_auth_paguregitauth.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2019-2019 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. Patrick Uiterwijk <patrick@puiterwijk.org>
  7. """
  8. from __future__ import unicode_literals, absolute_import
  9. import json
  10. import os
  11. import sys
  12. from mock import Mock
  13. sys.path.insert(
  14. 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
  15. )
  16. import pagure.lib.query
  17. import tests
  18. from pagure.config import config as pagure_config
  19. from pagure.lib.repo import PagureRepo
  20. class PagureLibGitAuthPagureGitAuthtests(tests.Modeltests):
  21. """ Tests for pagure.lib.git_auth PagureGitAuth dynamic ACL """
  22. config_values = {"authbackend": "pagure"}
  23. def setUp(self):
  24. super(PagureLibGitAuthPagureGitAuthtests, self).setUp()
  25. tests.create_projects(self.session)
  26. tests.create_tokens(self.session)
  27. tests.create_tokens_acl(self.session)
  28. self.create_project_full("acltest")
  29. project = pagure.lib.query._get_project(self.session, "acltest")
  30. # Create non-push deploy key
  31. non_push_dkey = pagure.lib.model.SSHKey(
  32. project_id=project.id,
  33. pushaccess=False,
  34. public_ssh_key="\n foo bar",
  35. ssh_short_key="\n foo bar",
  36. ssh_search_key="\n foo bar",
  37. creator_user_id=1, # pingou
  38. )
  39. self.session.add(non_push_dkey)
  40. # Create push deploy key
  41. push_dkey = pagure.lib.model.SSHKey(
  42. project_id=project.id,
  43. pushaccess=True,
  44. public_ssh_key="\n bar foo",
  45. ssh_short_key="\n bar foo",
  46. ssh_search_key="\n bar foo",
  47. creator_user_id=1, # pingou
  48. )
  49. self.session.add(push_dkey)
  50. self.session.commit()
  51. def create_fork(self):
  52. # Create fork
  53. headers = {"Authorization": "token aaabbbcccddd"}
  54. data = {"repo": "acltest"}
  55. output = self.app.post("/api/0/fork/", data=data, headers=headers)
  56. self.assertEqual(output.status_code, 200)
  57. data = json.loads(output.get_data(as_text=True))
  58. self.assertDictEqual(
  59. data, {"message": 'Repo "acltest" cloned to "pingou/acltest"'}
  60. )
  61. CASES = (
  62. # Internal push
  63. {
  64. "internal": True,
  65. "username": "foo",
  66. "project_pr_only": False,
  67. "global_pr_only": False,
  68. "project": {"name": "acltest"},
  69. "repotype": "main",
  70. "expected_messages": ["Internal push allowed"],
  71. "expected_result": True,
  72. },
  73. # Globally PR required push: PR merges are always internal
  74. {
  75. "internal": False,
  76. "username": "foo",
  77. "project_pr_only": False,
  78. "global_pr_only": True,
  79. "project": {"name": "acltest"},
  80. "repotype": "main",
  81. "expected_messages": ["Pull request required"],
  82. "expected_result": False,
  83. },
  84. # GLobally PR required, push is to fork
  85. {
  86. "internal": False,
  87. "username": "foo",
  88. "project_pr_only": False,
  89. "global_pr_only": True,
  90. "project": {"name": "acltest", "user": "pingou"},
  91. "repotype": "main",
  92. "expected_messages": ["Has commit access: False"],
  93. "expected_result": False,
  94. },
  95. # PR required push: PR merges are always internal
  96. {
  97. "internal": False,
  98. "username": "foo",
  99. "project_pr_only": True,
  100. "global_pr_only": False,
  101. "project": {"name": "acltest"},
  102. "repotype": "main",
  103. "expected_messages": ["Pull request required"],
  104. "expected_result": False,
  105. },
  106. # PR required for main repo, but not for ticket
  107. {
  108. "internal": False,
  109. "username": "foo",
  110. "project_pr_only": True,
  111. "global_pr_only": False,
  112. "project": {"name": "acltest"},
  113. "repotype": "ticket",
  114. "expected_messages": ["Has commit access: False"],
  115. "expected_result": False,
  116. },
  117. # Non-push deploy key
  118. {
  119. "internal": False,
  120. "username": "deploykey_acltest_1",
  121. "project_pr_only": False,
  122. "global_pr_only": False,
  123. "project": {"name": "acltest"},
  124. "repotype": "main",
  125. "expected_messages": [
  126. "Deploykey used. Push access: False",
  127. "Has commit access: False",
  128. ],
  129. "expected_result": False,
  130. },
  131. # Push deploy key
  132. {
  133. "internal": False,
  134. "username": "deploykey_acltest_2",
  135. "project_pr_only": False,
  136. "global_pr_only": False,
  137. "project": {"name": "acltest"},
  138. "repotype": "main",
  139. "expected_messages": [
  140. "Deploykey used. Push access: True",
  141. "Has commit access: True",
  142. ],
  143. "expected_result": True,
  144. },
  145. # Non-committer
  146. {
  147. "internal": False,
  148. "username": "foo",
  149. "project_pr_only": False,
  150. "global_pr_only": False,
  151. "project": {"name": "acltest"},
  152. "repotype": "main",
  153. "expected_messages": ["Has commit access: False"],
  154. "expected_result": False,
  155. },
  156. # Committer
  157. {
  158. "internal": False,
  159. "username": "pingou",
  160. "project_pr_only": False,
  161. "global_pr_only": False,
  162. "project": {"name": "acltest"},
  163. "repotype": "main",
  164. "expected_messages": ["Has commit access: True"],
  165. "expected_result": True,
  166. },
  167. )
  168. def test_cases(self):
  169. self.create_fork()
  170. ga = pagure.lib.git_auth.PagureGitAuth()
  171. ga.info = Mock()
  172. casenum = 0
  173. for case in self.CASES:
  174. casenum += 1
  175. print("Case %d: %s" % (casenum, case))
  176. project = pagure.lib.query._get_project(
  177. self.session, **case["project"]
  178. )
  179. # Set global PR setting
  180. pagure_config["PR_ONLY"] = case["global_pr_only"]
  181. # Set per-project PR setting
  182. curset = project.settings
  183. curset["pull_request_access_only"] = case["project_pr_only"]
  184. project.settings = curset
  185. self.session.commit()
  186. result = ga.check_acl(
  187. session=self.session,
  188. project=project,
  189. username=case["username"],
  190. refname="refs/heads/master",
  191. pull_request=None,
  192. repotype=case["repotype"],
  193. is_internal=case["internal"],
  194. )
  195. print("Result: %s" % result)
  196. self.assertEqual(
  197. result,
  198. case["expected_result"],
  199. "Expected result not met in case %s" % case,
  200. )
  201. print("Correct result")
  202. self.assertListEqual(
  203. case["expected_messages"],
  204. [info_call[0][0] for info_call in ga.info.call_args_list],
  205. )
  206. print("Correct messages")
  207. ga.info.reset_mock()