Skip to content

Commit fc2d0e1

Browse files
authored
Add authentication classes, move auth logic there (#2528)
This adds argument `auth` and deprecates `login_or_token`, `password`, `jwt`, and `app_auth` arguments of `github.Github`. This adds argument `auth` and deprecates `integration_id`, `private_key` of `github.GithubIntegration`. This deprecates the `create_jwt` method of `github.GithubIntegration`, replaced by `github.Auth.AppAuth.create_jwt`.
1 parent a8e7c42 commit fc2d0e1

35 files changed

+927
-291
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,19 @@ $ pip install PyGithub
2626
```python
2727
from github import Github
2828

29-
# First create a Github instance:
29+
# Authentication is defined via github.Auth
30+
from github import Auth
3031

3132
# using an access token
32-
g = Github("access_token")
33+
auth = Auth.Token("access_token")
34+
35+
# First create a Github instance:
36+
37+
# Public Web Github
38+
g = Github(auth=auth)
3339

3440
# Github Enterprise with custom hostname
35-
g = Github(base_url="https://{hostname}/api/v3", login_or_token="access_token")
41+
g = Github(base_url="https://{hostname}/api/v3", auth=auth)
3642

3743
# Then play with your Github objects:
3844
for repo in g.get_user().get_repos():

doc/examples.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Examples
33

44

55
.. toctree::
6+
examples/Authentication
67
examples/MainClass
78
examples/Repository
89
examples/Branch

doc/examples/Authentication.rst

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
Authentication
2+
==============
3+
4+
Github supports various authentication methods. Depending on the entity that authenticates and the Github API endpoint
5+
being called, only a subset of methods is available.
6+
7+
All authentication methods require this import:
8+
9+
.. code-block:: python
10+
11+
>>> from github import Auth
12+
13+
Login authentication
14+
--------------------
15+
16+
Users can authenticate by a login and password:
17+
18+
.. code-block:: python
19+
20+
>>> auth = Auth.Login("user_login", "password")
21+
>>> g = Github(auth=auth)
22+
>>> g.get_user().login
23+
'user_login'
24+
25+
OAuth token authentication
26+
--------------------------
27+
28+
Users can authenticate by a token:
29+
30+
.. code-block:: python
31+
32+
>>> auth = Auth.Token("access_token")
33+
>>> g = Github(auth=auth)
34+
>>> g.get_user().login
35+
'login'
36+
37+
App authentication
38+
------------------
39+
40+
A Github Apps authenticate by an application id and a private key.
41+
42+
Note that there is only a limited set of endpoints that can be called when authenticated as a Github App.
43+
Instead of using ``github.Github``, entry point ``github.GithubIntegration`` should be used
44+
when authenticated as a Github App:
45+
46+
.. code-block:: python
47+
48+
>>> auth = Auth.AppAuth(123456, private_key)
49+
>>> gi = GithubIntegration(auth=auth)
50+
>>> for installation in gi.get_installations():
51+
... installation.id
52+
'1234567'
53+
54+
App installation authentication
55+
-------------------------------
56+
57+
A specific installation of a Github App can use the Github API like a normal user.
58+
It authenticates by the Github App authentication (see above) and the installation id.
59+
The ``AppInstallationAuth`` fetches an access token for the installation and handles its
60+
expiration timeout. The access token is refreshed automatically.
61+
62+
.. code-block:: python
63+
64+
>>> auth = Auth.AppAuth(123456, private_key).get_installation_auth(installation_id, token_permissions)
65+
>>> g = Github(auth=auth)
66+
>>> g.get_repo("user/repo").name
67+
'repo'

doc/introduction.rst

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,18 @@ please `open an issue <https://github.com/PyGithub/PyGithub/issues>`__.
1414
First create a Github instance::
1515

1616
from github import Github
17-
17+
18+
# Authentication is defined via github.Auth
19+
from github import Auth
20+
1821
# using an access token
19-
g = Github("access_token")
22+
auth = Auth.Token("access_token")
23+
24+
# Public Web Github
25+
g = Github(auth=auth)
2026

2127
# Github Enterprise with custom hostname
22-
g = Github(base_url="https://{hostname}/api/v3", login_or_token="access_token")
28+
g = Github(base_url="https://{hostname}/api/v3", auth=auth)
2329

2430
Then play with your Github objects::
2531

github/AppAuthentication.py

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,22 @@
2323

2424
from typing import Dict, Optional, Union
2525

26+
import deprecated
2627

27-
class AppAuthentication:
28-
app_id: Union[int, str]
29-
private_key: str
30-
installation_id: int
31-
token_permissions: Optional[Dict[str, str]]
28+
from github.Auth import AppAuth, AppInstallationAuth
3229

30+
31+
@deprecated.deprecated("Use app.Auth.AppInstallationAuth instead")
32+
class AppAuthentication(AppInstallationAuth):
3333
def __init__(
3434
self,
3535
app_id: Union[int, str],
3636
private_key: str,
3737
installation_id: int,
3838
token_permissions: Optional[Dict[str, str]] = None,
3939
):
40-
assert isinstance(app_id, (int, str)), app_id
41-
assert isinstance(private_key, str)
42-
assert isinstance(installation_id, int), installation_id
43-
assert token_permissions is None or isinstance(
44-
token_permissions, dict
45-
), token_permissions
46-
self.app_id = app_id
47-
self.private_key = private_key
48-
self.installation_id = installation_id
49-
self.token_permissions = token_permissions
40+
super().__init__(
41+
app_auth=AppAuth(app_id, private_key),
42+
installation_id=installation_id,
43+
token_permissions=token_permissions,
44+
)

github/ApplicationOAuth.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ class ApplicationOAuth(github.GithubObject.NonCompletableGithubObject):
3232
The reference can be found at https://docs.github.com/en/developers/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps
3333
"""
3434

35+
def __init__(self, requester, headers, attributes, completed):
36+
# this object requires a request without authentication
37+
requester = requester.withAuth(auth=None)
38+
super().__init__(requester, headers, attributes, completed)
39+
3540
def __repr__(self):
3641
return self.get__repr__({"client_id": self._client_id.value})
3742

@@ -91,7 +96,6 @@ def get_access_token(self, code, state=None):
9196
if state is not None:
9297
post_parameters["state"] = state
9398

94-
self._requester._Requester__authorizationHeader = None
9599
headers, data = self._requester.requestJsonAndCheck(
96100
"POST",
97101
"https://github.com/login/oauth/access_token",

github/ApplicationOAuth.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ from typing import Any, Dict, Optional
22

33
from github.AccessToken import AccessToken
44
from github.GithubObject import NonCompletableGithubObject
5+
from github.Requester import Requester
56

67
class ApplicationOAuth(NonCompletableGithubObject):
78
def __repr__(self) -> str: ...

0 commit comments

Comments
 (0)