/ tests / GithubIntegration.py
GithubIntegration.py
  1  import time  # NOQA
  2  
  3  import requests  # NOQA
  4  from urllib3.exceptions import InsecureRequestWarning
  5  
  6  import github
  7  from github import Consts
  8  from github.Auth import AppInstallationAuth
  9  
 10  from . import Framework
 11  
 12  APP_ID = 243473
 13  PRIVATE_KEY = """
 14  -----BEGIN RSA PRIVATE KEY-----
 15  MIICXAIBAAKBgQC+5ePolLv6VcWLp2f17g6r6vHl+eoLuodOOfUl8JK+MVmvXbPa
 16  xDy0SS0pQhwTOMtB0VdSt++elklDCadeokhEoGDQp411o+kiOhzLxfakp/kewf4U
 17  HJnu4M/A2nHmxXVe2lzYnZvZHX5BM4SJo5PGdr0Ue2JtSXoAtYr6qE9maQIDAQAB
 18  AoGAFhOJ7sy8jG+837Clcihso+8QuHLVYTPaD+7d7dxLbBlS8NfaQ9Nr3cGUqm/N
 19  xV9NCjiGa7d/y4w/vrPwGh6UUsA+CvndwDgBd0S3WgIdWvAvHM8wKgNh/GBLLzhT
 20  Bg9BouRUzcT1MjAnkGkWqqCAgN7WrCSUMLt57TNleNWfX90CQQDjvVKTT3pOiavD
 21  3YcLxwkyeGd0VMvKiS4nV0XXJ97cGXs2GpOGXldstDTnF5AnB6PbukdFLHpsx4sW
 22  Hft3LRWnAkEA1pY15ke08wX6DZVXy7zuQ2izTrWSGySn7B41pn55dlKpttjHeutA
 23  3BEQKTFvMhBCphr8qST7Wf1SR9FgO0tFbwJAEhHji2yy96hUyKW7IWQZhrem/cP8
 24  p4Va9CQolnnDZRNgg1p4eiDiLu3dhLiJ547joXuWTBbLX/Y1Qvv+B+a74QJBAMCW
 25  O3WbMZlS6eK6//rIa4ZwN00SxDg8I8FUM45jwBsjgVGrKQz2ilV3sutlhIiH82kk
 26  m1Iq8LMJGYl/LkDJA10CQBV1C+Xu3ukknr7C4A/4lDCa6Xb27cr1HanY7i89A+Ab
 27  eatdM6f/XVqWp8uPT9RggUV9TjppJobYGT2WrWJMkYw=
 28  -----END RSA PRIVATE KEY-----
 29  """
 30  PUBLIC_KEY = """
 31  -----BEGIN PUBLIC KEY-----
 32  MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+5ePolLv6VcWLp2f17g6r6vHl
 33  +eoLuodOOfUl8JK+MVmvXbPaxDy0SS0pQhwTOMtB0VdSt++elklDCadeokhEoGDQ
 34  p411o+kiOhzLxfakp/kewf4UHJnu4M/A2nHmxXVe2lzYnZvZHX5BM4SJo5PGdr0U
 35  e2JtSXoAtYr6qE9maQIDAQAB
 36  -----END PUBLIC KEY-----
 37  """
 38  
 39  
 40  class GithubIntegration(Framework.BasicTestCase):
 41      def setUp(self):
 42          super().setUp()
 43          self.org_installation_id = 30614487
 44          self.repo_installation_id = 30614431
 45          self.user_installation_id = 30614431
 46  
 47      def testDeprecatedAppAuth(self):
 48          # Replay data copied from testGetInstallations to test authentication only
 49          with self.assertWarns(DeprecationWarning) as warning:
 50              github_integration = github.GithubIntegration(integration_id=APP_ID, private_key=PRIVATE_KEY)
 51          installations = github_integration.get_installations()
 52          self.assertEqual(len(list(installations)), 2)
 53          self.assertWarning(
 54              warning,
 55              "Arguments integration_id, private_key, jwt_expiry, jwt_issued_at and "
 56              "jwt_algorithm are deprecated, please use auth=github.Auth.AppAuth(...) "
 57              "instead",
 58          )
 59  
 60      def testRequiredAppAuth(self):
 61          # GithubIntegration requires AppAuth authentication.
 62          for auth in [self.oauth_token, self.jwt, self.login]:
 63              with self.assertRaises(AssertionError) as r:
 64                  github.GithubIntegration(auth=auth)
 65              self.assertEqual(
 66                  str(r.exception),
 67                  f"GithubIntegration requires github.Auth.AppAuth authentication, not {type(auth)}",
 68              )
 69  
 70      def testAppAuth(self):
 71          # Replay data copied from testDeprecatedAppAuth to test parity
 72          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
 73          github_integration = github.GithubIntegration(auth=auth)
 74          installations = github_integration.get_installations()
 75          self.assertEqual(len(list(installations)), 2)
 76  
 77      def testNoneAppAuth(self):
 78          with self.assertRaises(AssertionError):
 79              github.GithubIntegration(auth=None)
 80  
 81      def testGetInstallations(self):
 82          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
 83          github_integration = github.GithubIntegration(auth=auth)
 84          installations = github_integration.get_installations()
 85  
 86          self.assertEqual(len(list(installations)), 2)
 87          self.assertEqual(installations[0].id, self.org_installation_id)
 88          self.assertEqual(installations[1].id, self.repo_installation_id)
 89  
 90      def testGetGithubForInstallation(self):
 91          # with verify=False, urllib3.connectionpool rightly may issue an InsecureRequestWarning
 92          # we ignore InsecureRequestWarning from urllib3.connectionpool
 93          with self.ignoreWarning(category=InsecureRequestWarning, module="urllib3.connectionpool"):
 94              kwargs = dict(
 95                  auth=github.Auth.AppAuth(APP_ID, PRIVATE_KEY),
 96                  # http protocol used to deviate from default base url, recording data might require https
 97                  base_url="http://api.github.com",
 98                  timeout=Consts.DEFAULT_TIMEOUT + 10,
 99                  user_agent="PyGithub/Python-Test",
100                  per_page=Consts.DEFAULT_PER_PAGE + 10,
101                  verify=False,
102                  retry=3,
103                  pool_size=10,
104                  seconds_between_requests=100,
105                  seconds_between_writes=1000,
106              )
107  
108              # assert kwargs consists of ALL requester constructor arguments
109              self.assertEqual(kwargs.keys(), github.Requester.Requester.__init__.__annotations__.keys())
110  
111              github_integration = github.GithubIntegration(**kwargs)
112              g = github_integration.get_github_for_installation(36541767)
113  
114              self.assertIsInstance(g._Github__requester.auth, AppInstallationAuth)
115  
116              actual = g._Github__requester.kwargs
117              kwargs.update(auth=str(AppInstallationAuth))
118              actual.update(auth=str(type(actual["auth"])))
119              self.assertDictEqual(kwargs, actual)
120  
121              repo = g.get_repo("PyGithub/PyGithub")
122              self.assertEqual(repo.full_name, "PyGithub/PyGithub")
123  
124      def testGetAccessToken(self):
125          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
126          github_integration = github.GithubIntegration(auth=auth)
127  
128          # Get repo installation access token
129          repo_installation_authorization = github_integration.get_access_token(self.repo_installation_id)
130          self.assertEqual(
131              repo_installation_authorization.token,
132              "ghs_1llwuELtXN5HDOB99XhpcTXdJxbOuF0ZlSmj",
133          )
134          self.assertDictEqual(
135              repo_installation_authorization.permissions,
136              {"issues": "read", "metadata": "read"},
137          )
138          self.assertEqual(repo_installation_authorization.repository_selection, "selected")
139  
140          # Get org installation access token
141          org_installation_authorization = github_integration.get_access_token(self.org_installation_id)
142          self.assertEqual(
143              org_installation_authorization.token,
144              "ghs_V0xygF8yACXSDz5FM65QWV1BT2vtxw0cbgPw",
145          )
146          org_permissions = {
147              "administration": "write",
148              "issues": "write",
149              "metadata": "read",
150              "organization_administration": "read",
151          }
152          self.assertDictEqual(org_installation_authorization.permissions, org_permissions)
153          self.assertEqual(org_installation_authorization.repository_selection, "selected")
154  
155          # Get user installation access token
156          user_installation_authorization = github_integration.get_access_token(self.user_installation_id)
157          self.assertEqual(
158              user_installation_authorization.token,
159              "ghs_1llwuELtXN5HDOB99XhpcTXdJxbOuF0ZlSmj",
160          )
161          self.assertDictEqual(
162              user_installation_authorization.permissions,
163              {"issues": "read", "metadata": "read"},
164          )
165          self.assertEqual(user_installation_authorization.repository_selection, "selected")
166  
167      def testGetUserInstallation(self):
168          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
169          github_integration = github.GithubIntegration(auth=auth)
170          installation = github_integration.get_user_installation(username="ammarmallik")
171  
172          self.assertEqual(installation.id, self.user_installation_id)
173  
174      def testGetOrgInstallation(self):
175          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
176          github_integration = github.GithubIntegration(auth=auth)
177          installation = github_integration.get_org_installation(org="GithubApp-Test-Org")
178  
179          self.assertEqual(installation.id, self.org_installation_id)
180  
181      def testGetRepoInstallation(self):
182          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
183          github_integration = github.GithubIntegration(auth=auth)
184          installation = github_integration.get_repo_installation(owner="ammarmallik", repo="test-runner")
185  
186          self.assertEqual(installation.id, self.repo_installation_id)
187  
188      def testGetAppInstallation(self):
189          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
190          github_integration = github.GithubIntegration(auth=auth)
191          installation = github_integration.get_app_installation(installation_id=self.org_installation_id)
192  
193          self.assertEqual(installation.id, self.org_installation_id)
194  
195      def testGetInstallationNotFound(self):
196          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
197          github_integration = github.GithubIntegration(auth=auth)
198          with self.assertRaises(github.UnknownObjectException) as raisedexp:
199              github_integration.get_org_installation(org="GithubApp-Test-Org-404")
200  
201          self.assertEqual(raisedexp.exception.status, 404)
202  
203      def testGetInstallationWithExpiredJWT(self):
204          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
205          github_integration = github.GithubIntegration(auth=auth)
206          with self.assertRaises(github.GithubException) as raisedexp:
207              github_integration.get_org_installation(org="GithubApp-Test-Org")
208  
209          self.assertEqual(raisedexp.exception.status, 401)
210  
211      def testGetAccessTokenWithExpiredJWT(self):
212          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
213          github_integration = github.GithubIntegration(auth=auth)
214          with self.assertRaises(github.GithubException) as raisedexp:
215              github_integration.get_access_token(self.repo_installation_id)
216  
217          self.assertEqual(raisedexp.exception.status, 401)
218  
219      def testGetAccessTokenForNoInstallation(self):
220          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
221          github_integration = github.GithubIntegration(auth=auth)
222          with self.assertRaises(github.UnknownObjectException) as raisedexp:
223              github_integration.get_access_token(40432121)
224  
225          self.assertEqual(raisedexp.exception.status, 404)
226  
227      def testGetAccessTokenWithInvalidPermissions(self):
228          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
229          github_integration = github.GithubIntegration(auth=auth)
230          with self.assertRaises(github.GithubException) as raisedexp:
231              github_integration.get_access_token(self.repo_installation_id, permissions={"test-permissions": "read"})
232  
233          self.assertEqual(raisedexp.exception.status, 422)
234  
235      def testGetAccessTokenWithInvalidData(self):
236          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
237          github_integration = github.GithubIntegration(auth=auth)
238          with self.assertRaises(github.GithubException) as raisedexp:
239              github_integration.get_access_token(self.repo_installation_id, permissions="invalid_data")
240  
241          self.assertEqual(raisedexp.exception.status, 400)
242  
243      def testGetApp(self):
244          auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
245          github_integration = github.GithubIntegration(auth=auth)
246          app = github_integration.get_app()
247  
248          self.assertEqual(app.name, "PyGithubTest")
249          self.assertEqual(app.url, "/apps/pygithubtest")