diff --git a/github/Organization.py b/github/Organization.py index 74e1567c61..e71d249d7d 100644 --- a/github/Organization.py +++ b/github/Organization.py @@ -1111,6 +1111,18 @@ def invite_user( input=parameters, ) + def cancel_invitation(self, invitee): + """ + :calls: `DELETE /orgs/{org}/invitations/{invitation_id} `_ + :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} `_ diff --git a/github/Organization.pyi b/github/Organization.pyi index 257c14392d..61434ba300 100644 --- a/github/Organization.pyi +++ b/github/Organization.pyi @@ -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 diff --git a/tests/Organization2072.py b/tests/Organization2072.py new file mode 100644 index 0000000000..0c42fcfae7 --- /dev/null +++ b/tests/Organization2072.py @@ -0,0 +1,40 @@ +############################ Copyrights and license ############################ +# # +# Copyright 2021 James Simpson # +# # +# 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 . # +# # +################################################################################ + +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)) diff --git a/tests/ReplayData/Organization2072.setUp.txt b/tests/ReplayData/Organization2072.setUp.txt new file mode 100644 index 0000000000..47247445e1 --- /dev/null +++ b/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}} + diff --git a/tests/ReplayData/Organization2072.testCancelInvitation.txt b/tests/ReplayData/Organization2072.testCancelInvitation.txt new file mode 100644 index 0000000000..4ae7e3d0bd --- /dev/null +++ b/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')] + +