Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit830b562

Browse files
authored
Merge pull requestsigmavirus24#889 from sigmavirus24/apps-support
Add support for GitHub Apps
2 parents5eff8c6 +416ecc2 commit830b562

File tree

14 files changed

+780
-10
lines changed

14 files changed

+780
-10
lines changed

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ tests/id_rsa
2323
.mypy_cache/
2424
.pytest_cache/
2525
t.py
26+
*.pem

‎docs/source/api-reference/apps.rst‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
==================================
2+
App and Installation API Objects
3+
==================================
4+
5+
This section of the documentation covers the representations of various
6+
objects related to the `Apps API`_.
7+
8+
..autoclass::github3.apps.App
9+
:inherited-members:
10+
11+
..autoclass::github3.apps.Installation
12+
:inherited-members:
13+
14+
15+
.. ---
16+
.. links
17+
.. _Apps API:
18+
https://developer.github.com/v3/apps

‎docs/source/api-reference/index.rst‎

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

88
api
9+
apps
910
auths
1011
events
1112
gists

‎docs/source/release-notes/1.2.0.rst‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,38 @@ This is a small release with some enhancements.
66
Features Added
77
``````````````
88

9+
- Partial GitHub Apps support. We added the following:
10+
11+
- ``GitHub.login_as_app`` to login using JWT as an Application
12+
13+
- ``GitHub.login_as_app_installation`` to login using a token obtained from
14+
an App's JWT
15+
16+
- ``GitHub.app`` to retrieve an application by its "slug"
17+
18+
- ``GitHub.app_installation`` to retrieve a specific installation by its ID
19+
20+
- ``GitHub.app_installations`` to retrieve all of an App's installations
21+
22+
- ``GitHub.app_installation_for_organization`` to retrieve an organization's
23+
installation of an App
24+
25+
- ``GitHub.app_installation_for_repository`` to retrieve an installation for
26+
a specific repository
27+
28+
- ``GitHub.app_installation_for_user`` to retrieve an installation for a
29+
specific user
30+
31+
- ``GitHub.authenticated_app`` to retrieve the metadata for a specific App
32+
33+
- Not supported as of this release:
34+
35+
- `Installations API`_
36+
37+
- `List installations for user`_
38+
39+
- `User-to-server OAuth access token`_
40+
941
- Organization Invitations Preview API is now supported. This includes an
1042
additional ``Invitation`` object. This is the result of hard work by Hal
1143
Wine.
@@ -14,3 +46,14 @@ Features Added
1446
representation of labels returned by the API.
1547

1648
- The branch protections API is now completely represented in github3.py.
49+
50+
51+
.. links
52+
.. _Installations API:
53+
https://developer.github.com/v3/apps/installations/
54+
55+
.. _List installations for user:
56+
https://developer.github.com/v3/apps/#list-installations-for-user
57+
58+
.. _User-to-server OAuth access token:
59+
https://developer.github.com/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps/#identifying-users-on-your-site

‎setup.cfg‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ requires-dist=
66
requests>=2.0
77
uritemplate>=3.0.0
88
python-dateutil>=2.6.0
9+
jwcrypto>=0.5.0
910
pyOpenSSL>=0.13; python_version<="2.7"
1011
ndg-httpsclient; python_version<="2.7"
1112
pyasn1; python_version<="2.7"

‎setup.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
SNI_requirements= [
2222
'pyOpenSSL',
2323
'ndg-httpsclient',
24-
'pyasn1'
24+
'pyasn1',
2525
]
2626

2727
kwargs['tests_require']= ['betamax>=0.8.0','pytest>2.3.5',
@@ -39,6 +39,7 @@
3939
"requests >= 2.18",
4040
"uritemplate >= 3.0.0",
4141
"python-dateutil >= 2.6.0",
42+
"jwcrypto >= 0.5.0",
4243
])
4344

4445
__version__=''

‎src/github3/apps.py‎

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
"""Module containing helpers for dealing with GitHub Apps.
2+
3+
https://developer.github.com/apps/building-github-apps/
4+
"""
5+
importtime
6+
7+
fromjwcryptoimportjwk
8+
fromjwcryptoimportjwt
9+
10+
from .importmodels
11+
from .importusers
12+
13+
TEN_MINUTES_AS_SECONDS=10*60
14+
DEFAULT_JWT_TOKEN_EXPIRATION=TEN_MINUTES_AS_SECONDS
15+
APP_PREVIEW_HEADERS= {
16+
'Accept':'application/vnd.github.machine-man-preview+json',
17+
}
18+
19+
20+
classApp(models.GitHubCore):
21+
"""An object representing a GitHub App.
22+
23+
.. versionadded:: 1.2.0
24+
25+
.. seealso::
26+
27+
`GitHub Apps`_
28+
Documentation for Apps on GitHub
29+
30+
`GitHub Apps API Documentation`_
31+
API documentation of what's available about an App.
32+
33+
This object has the following attributes:
34+
35+
.. attribute:: created_at
36+
37+
A :class:`~datetime.datetime` object representing the day and time
38+
the App was created.
39+
40+
.. attribute:: description
41+
42+
The description of the App provided by the owner.
43+
44+
.. attribute:: external_url
45+
46+
The URL provided for the App by the owner.
47+
48+
.. attribute:: html_url
49+
50+
The HTML URL provided for the App by the owner.
51+
52+
.. attribute:: id
53+
54+
The unique identifier for the App. This is useful in cases where you
55+
may want to authenticate either as an App or as a specific
56+
installation of an App.
57+
58+
.. attribute:: name
59+
60+
The display name of the App that the user sees.
61+
62+
.. attribute:: node_id
63+
64+
A base64-encoded blob returned by the GitHub API for who knows what
65+
reason.
66+
67+
.. attribute:: owner
68+
69+
A :class:`~github3.users.ShortUser` object representing the GitHub
70+
user who owns the App.
71+
72+
.. attribute:: updated_at
73+
74+
A :class:`~datetime.datetime` object representing the day and time
75+
the App was last updated.
76+
77+
.. _GitHub Apps:
78+
https://developer.github.com/apps/
79+
.. _GitHub Apps API Documentation:
80+
https://developer.github.com/v3/apps/
81+
"""
82+
83+
def_update_attributes(self,json):
84+
self.created_at=self._strptime(json['created_at'])
85+
self.description=json['description']
86+
self.external_url=json['external_url']
87+
self.html_url=json['html_url']
88+
self.id=json['id']
89+
self.name=json['name']
90+
self.node_id=json['node_id']
91+
self.owner=users.ShortUser(json['owner'],self)
92+
self.updated_at=self._strptime(json['updated_at'])
93+
94+
def_repr(self):
95+
return'<App ["{}" by {}]>'.format(self.name,str(self.owner))
96+
97+
98+
classInstallation(models.GitHubCore):
99+
"""An installation of a GitHub App either on a User or Org.
100+
101+
.. versionadded:: 1.2.0
102+
103+
This has the following attributes:
104+
105+
.. attribute:: access_tokens_url
106+
.. attribute:: account
107+
.. attribute:: app_id
108+
.. attribute:: created_at
109+
.. attribute:: events
110+
.. attribute:: html_url
111+
.. attribute:: id
112+
.. attribute:: permissions
113+
.. attribute:: repositories_url
114+
.. attribute:: repository_selection
115+
.. attribute:: single_file_name
116+
.. attribute:: target_id
117+
.. attribute:: target_type
118+
.. attribute:: updated_at
119+
"""
120+
121+
def_update_attributes(self,json):
122+
self.access_tokens_url=json['access_tokens_url']
123+
self.account=json['account']
124+
self.app_id=json['app_id']
125+
self.created_at=self._strptime(json['created_at'])
126+
self.events=json['events']
127+
self.html_url=json['html_url']
128+
self.id=json['id']
129+
self.permissions=json['permissions']
130+
self.repositories_url=json['repositories_url']
131+
self.repository_selection=json['repository_selection']
132+
self.single_file_name=json['single_file_name']
133+
self.target_id=json['target_id']
134+
self.target_type=json['target_type']
135+
self.updated_at=self._strptime(json['updated_at'])
136+
137+
138+
def_load_private_key(pem_key_bytes):
139+
returnjwk.JWK.from_pem(pem_key_bytes)
140+
141+
142+
defcreate_token(private_key_pem,app_id,expire_in=TEN_MINUTES_AS_SECONDS):
143+
"""Create an encrypted token for the specified App.
144+
145+
:param bytes private_key_pem:
146+
The bytes of the private key for this GitHub Application.
147+
:param int app_id:
148+
The integer identifier for this GitHub Application.
149+
:param int expire_in:
150+
The length in seconds for this token to be valid for.
151+
Default: 600 seconds (10 minutes)
152+
:returns:
153+
Serialized encrypted token.
154+
:rtype:
155+
text
156+
"""
157+
ifnotisinstance(private_key_pem,bytes):
158+
raiseValueError('"private_key_pem" parameter must be byte-string')
159+
key=_load_private_key(private_key_pem)
160+
now=int(time.time())
161+
token=jwt.JWT(
162+
header={
163+
'alg':'RS256'
164+
},
165+
claims={
166+
'iat':now,
167+
'exp':now+expire_in,
168+
'iss':app_id,
169+
},
170+
algs=['RS256'],
171+
)
172+
token.make_signed_token(key)
173+
returntoken.serialize()
174+
175+
176+
defcreate_jwt_headers(private_key_pem,app_id,
177+
expire_in=DEFAULT_JWT_TOKEN_EXPIRATION):
178+
"""Create an encrypted token for the specified App.
179+
180+
:param bytes private_key_pem:
181+
The bytes of the private key for this GitHub Application.
182+
:param int app_id:
183+
The integer identifier for this GitHub Application.
184+
:param int expire_in:
185+
The length in seconds for this token to be valid for.
186+
Default: 600 seconds (10 minutes)
187+
:returns:
188+
Dictionary of headers for retrieving a token from a JWT.
189+
:rtype:
190+
dict
191+
"""
192+
jwt_token=create_token(private_key_pem,app_id,expire_in)
193+
headers= {'Authorization':'Bearer {}'.format(jwt_token)}
194+
headers.update(APP_PREVIEW_HEADERS)
195+
returnheaders

‎src/github3/decorators.py‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,42 @@ def auth_wrapper(self, *args, **kwargs):
8282
returnauth_wrapper
8383

8484

85+
defrequires_app_bearer_auth(func):
86+
"""Require the use of application authentication.
87+
88+
.. versionadded:: 1.2.0
89+
"""
90+
@wraps(func)
91+
defauth_wrapper(self,*args,**kwargs):
92+
from .importsession
93+
ifisinstance(self.session.auth,session.AppBearerTokenAuth):
94+
returnfunc(self,*args,**kwargs)
95+
else:
96+
from .importexceptions
97+
raiseexceptions.MissingAppBearerAuthentication(
98+
"This method requires GitHub App authentication."
99+
)
100+
returnauth_wrapper
101+
102+
103+
defrequires_app_installation_auth(func):
104+
"""Require the use of App's installation authentication.
105+
106+
.. versionadded:: 1.2.0
107+
"""
108+
@wraps(func)
109+
defauth_wrapper(self,*args,**kwargs):
110+
from .importsession
111+
ifisinstance(self.session.auth,session.AppInstallationTokenAuth):
112+
returnfunc(self,*args,**kwargs)
113+
else:
114+
from .importexceptions
115+
raiseexceptions.MissingAppInstallationAuthentication(
116+
"This method requires GitHub App authentication."
117+
)
118+
returnauth_wrapper
119+
120+
85121
defgenerate_fake_error_response(msg,status_code=401,encoding='utf-8'):
86122
"""Generate a fake Response from requests."""
87123
r=Response()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp