Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for cancellation of organization invitations #2072

Merged
merged 1 commit into from Oct 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions github/Organization.py
Expand Up @@ -1111,6 +1111,18 @@ def invite_user(
input=parameters,
)

def cancel_invitation(self, invitee):
"""
:calls: `DELETE /orgs/{org}/invitations/{invitation_id} <https://docs.github.com/en/rest/reference/orgs#cancel-an-organization-invitation>`_
:param invitee: :class:`github.NamedUser.NamedUser`
:rtype: None
"""
assert isinstance(invitee, github.NamedUser.NamedUser), invitee
status, headers, data = self._requester.requestJson(
"DELETE", f"{self.url}/invitations/{invitee.id}"
)
return status == 204

def has_in_members(self, member):
"""
:calls: `GET /orgs/{org}/members/{user} <https://docs.github.com/en/rest/reference/orgs#members>`_
Expand Down
1 change: 1 addition & 0 deletions github/Organization.pyi
Expand Up @@ -178,6 +178,7 @@ class Organization(CompletableGithubObject):
role: Union[str, _NotSetType] = ...,
teams: Union[List[Team], _NotSetType] = ...,
) -> None: ...
def cancel_invitation(self, invitee: NamedUser) -> bool: ...
@property
def location(self) -> str: ...
@property
Expand Down
40 changes: 40 additions & 0 deletions tests/Organization2072.py
@@ -0,0 +1,40 @@
############################ Copyrights and license ############################
# #
# Copyright 2021 James Simpson <james@snowterminal.com> #
# #
# This file is part of PyGithub. #
# http://pygithub.readthedocs.io/ #
# #
# PyGithub is free software: you can redistribute it and/or modify it under #
# the terms of the GNU Lesser General Public License as published by the Free #
# Software Foundation, either version 3 of the License, or (at your option) #
# any later version. #
# #
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
# details. #
# #
# You should have received a copy of the GNU Lesser General Public License #
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################

from . import Framework


class Organization2072(Framework.TestCase):
def setUp(self):
super().setUp()
self.org = self.g.get_organization("TestOrganization2072")

def testCancelInvitation(self):
self.assertFalse(
any([i for i in self.org.invitations() if i.email == "foo@bar.org"])
)
self.org.invite_user(email="foo@bar.org")
self.assertTrue(
any([i for i in self.org.invitations() if i.email == "foo@bar.org"])
)
invitation = [i for i in self.org.invitations() if i.email == "foo@bar.org"][0]
self.assertTrue(self.org.cancel_invitation(invitation))
11 changes: 11 additions & 0 deletions tests/ReplayData/Organization2072.setUp.txt
@@ -0,0 +1,11 @@
https
GET
api.github.com
None
/orgs/TestOrganization2072
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
None
200
[('Server', 'GitHub.com'), ('Date', 'Tue, 12 Oct 2021 05:32:32 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"0e8e9cdb8a79214111e22bae109cc8cd2ad163242dd751ce30d501009b7776d6"'), ('Last-Modified', 'Mon, 11 Oct 2021 05:17:24 GMT'), ('X-OAuth-Scopes', 'admin:org, admin:org_hook'), ('X-Accepted-OAuth-Scopes', 'admin:org, read:org, repo, user, write:org'), ('github-authentication-token-expiration', '2021-10-18 05:11:21 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4977'), ('X-RateLimit-Reset', '1634019426'), ('X-RateLimit-Used', '23'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'ADB2:4907:F9EF7D:10E5C1E:61651DEF')]
{"login":"TestOrganization2072","id":92288976,"node_id":"O_kgDOBYA30A","url":"https://api.github.com/orgs/TestOrganization2072","repos_url":"https://api.github.com/orgs/TestOrganization2072/repos","events_url":"https://api.github.com/orgs/TestOrganization2072/events","hooks_url":"https://api.github.com/orgs/TestOrganization2072/hooks","issues_url":"https://api.github.com/orgs/TestOrganization2072/issues","members_url":"https://api.github.com/orgs/TestOrganization2072/members{/member}","public_members_url":"https://api.github.com/orgs/TestOrganization2072/public_members{/member}","avatar_url":"https://avatars.githubusercontent.com/u/92288976?v=4","description":null,"is_verified":false,"has_organization_projects":true,"has_repository_projects":true,"public_repos":0,"public_gists":0,"followers":0,"following":0,"html_url":"https://github.com/TestOrganization2072","created_at":"2021-10-11T05:17:24Z","updated_at":"2021-10-11T05:17:24Z","type":"Organization","total_private_repos":0,"owned_private_repos":0,"private_gists":0,"disk_usage":0,"collaborators":0,"billing_email":"james@snowterminal.com","default_repository_permission":"read","members_can_create_repositories":true,"two_factor_requirement_enabled":false,"members_allowed_repository_creation_type":"all","members_can_create_public_repositories":true,"members_can_create_private_repositories":true,"members_can_create_internal_repositories":false,"members_can_create_pages":true,"members_can_create_public_pages":true,"members_can_create_private_pages":true,"plan":{"name":"free","space":976562499,"private_repos":10000,"filled_seats":1,"seats":0}}

55 changes: 55 additions & 0 deletions tests/ReplayData/Organization2072.testCancelInvitation.txt
@@ -0,0 +1,55 @@
https
GET
api.github.com
None
/orgs/TestOrganization2072/invitations
{'Accept': 'application/vnd.github.dazzler-preview+json', 'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
None
200
[('Server', 'GitHub.com'), ('Date', 'Tue, 12 Oct 2021 05:32:32 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '2'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding, Accept, X-Requested-With'), ('ETag', '"5c630c6c596d65b5a9953f65c07259ecf58c131e8ee0a60fee72772cfee9ca50"'), ('X-OAuth-Scopes', 'admin:org, admin:org_hook'), ('X-Accepted-OAuth-Scopes', 'admin:org, repo'), ('github-authentication-token-expiration', '2021-10-18 05:11:21 UTC'), ('X-GitHub-Media-Type', 'github.v3; param=dazzler-preview; format=json'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4976'), ('X-RateLimit-Reset', '1634019426'), ('X-RateLimit-Used', '24'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'ADB4:057F:44AD24:4B0F03:61651DF0')]
[]

https
POST
api.github.com
None
/orgs/TestOrganization2072/invitations
{'Accept': 'application/vnd.github.dazzler-preview+json', 'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'}
{"email": "foo@bar.org"}
201
[('Server', 'GitHub.com'), ('Date', 'Tue, 12 Oct 2021 05:32:33 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1203'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding, Accept, X-Requested-With'), ('ETag', '"fd548c290791934f62fbc9f7bb04ed6a0af779377f3aa5122e0460ef20d75725"'), ('X-OAuth-Scopes', 'admin:org, admin:org_hook'), ('X-Accepted-OAuth-Scopes', 'admin:org'), ('github-authentication-token-expiration', '2021-10-18 05:11:21 UTC'), ('X-GitHub-Media-Type', 'github.v3; param=dazzler-preview; format=json'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4975'), ('X-RateLimit-Reset', '1634019426'), ('X-RateLimit-Used', '25'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'ADB6:057A:39FF:65433:61651DF0')]
{"id":28984230,"node_id":"OI_kwDOBYA30M4BukOm","login":null,"email":"foo@bar.org","role":"direct_member","created_at":"2021-10-12T05:32:33Z","inviter":{"login":"jsimpso","id":10970100,"node_id":"MDQ6VXNlcjEwOTcwMTAw","avatar_url":"https://avatars.githubusercontent.com/u/10970100?u=303b0ceb6458644496499b0031b67badce03d5e4&v=4","gravatar_id":"","url":"https://api.github.com/users/jsimpso","html_url":"https://github.com/jsimpso","followers_url":"https://api.github.com/users/jsimpso/followers","following_url":"https://api.github.com/users/jsimpso/following{/other_user}","gists_url":"https://api.github.com/users/jsimpso/gists{/gist_id}","starred_url":"https://api.github.com/users/jsimpso/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsimpso/subscriptions","organizations_url":"https://api.github.com/users/jsimpso/orgs","repos_url":"https://api.github.com/users/jsimpso/repos","events_url":"https://api.github.com/users/jsimpso/events{/privacy}","received_events_url":"https://api.github.com/users/jsimpso/received_events","type":"User","site_admin":false},"team_count":0,"invitation_teams_url":"https://api.github.com/organizations/92288976/invitations/28984230/teams"}

https
GET
api.github.com
None
/orgs/TestOrganization2072/invitations
{'Accept': 'application/vnd.github.dazzler-preview+json', 'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
None
200
[('Server', 'GitHub.com'), ('Date', 'Tue, 12 Oct 2021 05:32:33 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"da2a9a62ed895da63af620e18d93b07f09c1511c7f08df957a1bbe33ba67ed7c"'), ('X-OAuth-Scopes', 'admin:org, admin:org_hook'), ('X-Accepted-OAuth-Scopes', 'admin:org, repo'), ('github-authentication-token-expiration', '2021-10-18 05:11:21 UTC'), ('X-GitHub-Media-Type', 'github.v3; param=dazzler-preview; format=json'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4974'), ('X-RateLimit-Reset', '1634019426'), ('X-RateLimit-Used', '26'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'ADB8:4907:F9EFD9:10E5C87:61651DF1')]
[{"id":28984230,"node_id":"OI_kwDOBYA30M4BukOm","login":null,"email":"foo@bar.org","role":"direct_member","created_at":"2021-10-12T13:32:33.000+08:00","failed_at":null,"failed_reason":null,"inviter":{"login":"jsimpso","id":10970100,"node_id":"MDQ6VXNlcjEwOTcwMTAw","avatar_url":"https://avatars.githubusercontent.com/u/10970100?v=4","gravatar_id":"","url":"https://api.github.com/users/jsimpso","html_url":"https://github.com/jsimpso","followers_url":"https://api.github.com/users/jsimpso/followers","following_url":"https://api.github.com/users/jsimpso/following{/other_user}","gists_url":"https://api.github.com/users/jsimpso/gists{/gist_id}","starred_url":"https://api.github.com/users/jsimpso/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsimpso/subscriptions","organizations_url":"https://api.github.com/users/jsimpso/orgs","repos_url":"https://api.github.com/users/jsimpso/repos","events_url":"https://api.github.com/users/jsimpso/events{/privacy}","received_events_url":"https://api.github.com/users/jsimpso/received_events","type":"User","site_admin":false},"team_count":0,"invitation_teams_url":"https://api.github.com/organizations/92288976/invitations/28984230/teams"}]

https
GET
api.github.com
None
/orgs/TestOrganization2072/invitations
{'Accept': 'application/vnd.github.dazzler-preview+json', 'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
None
200
[('Server', 'GitHub.com'), ('Date', 'Tue, 12 Oct 2021 05:32:34 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"da2a9a62ed895da63af620e18d93b07f09c1511c7f08df957a1bbe33ba67ed7c"'), ('X-OAuth-Scopes', 'admin:org, admin:org_hook'), ('X-Accepted-OAuth-Scopes', 'admin:org, repo'), ('github-authentication-token-expiration', '2021-10-18 05:11:21 UTC'), ('X-GitHub-Media-Type', 'github.v3; param=dazzler-preview; format=json'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4973'), ('X-RateLimit-Reset', '1634019426'), ('X-RateLimit-Used', '27'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'ADBA:4906:3B6198:4F41C8:61651DF2')]
[{"id":28984230,"node_id":"OI_kwDOBYA30M4BukOm","login":null,"email":"foo@bar.org","role":"direct_member","created_at":"2021-10-12T13:32:33.000+08:00","failed_at":null,"failed_reason":null,"inviter":{"login":"jsimpso","id":10970100,"node_id":"MDQ6VXNlcjEwOTcwMTAw","avatar_url":"https://avatars.githubusercontent.com/u/10970100?v=4","gravatar_id":"","url":"https://api.github.com/users/jsimpso","html_url":"https://github.com/jsimpso","followers_url":"https://api.github.com/users/jsimpso/followers","following_url":"https://api.github.com/users/jsimpso/following{/other_user}","gists_url":"https://api.github.com/users/jsimpso/gists{/gist_id}","starred_url":"https://api.github.com/users/jsimpso/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsimpso/subscriptions","organizations_url":"https://api.github.com/users/jsimpso/orgs","repos_url":"https://api.github.com/users/jsimpso/repos","events_url":"https://api.github.com/users/jsimpso/events{/privacy}","received_events_url":"https://api.github.com/users/jsimpso/received_events","type":"User","site_admin":false},"team_count":0,"invitation_teams_url":"https://api.github.com/organizations/92288976/invitations/28984230/teams"}]

https
DELETE
api.github.com
None
/orgs/TestOrganization2072/invitations/28984230
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
None
204
[('Server', 'GitHub.com'), ('Date', 'Tue, 12 Oct 2021 05:32:34 GMT'), ('X-OAuth-Scopes', 'admin:org, admin:org_hook'), ('X-Accepted-OAuth-Scopes', 'admin:org'), ('github-authentication-token-expiration', '2021-10-18 05:11:21 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4972'), ('X-RateLimit-Reset', '1634019426'), ('X-RateLimit-Used', '28'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Vary', 'Accept-Encoding, Accept, X-Requested-With'), ('X-GitHub-Request-Id', 'ADBC:057F:44AD76:4B0F5B:61651DF2')]