diff --git a/github/Branch.py b/github/Branch.py index 0cf690b8..72d9e8c0 100644 --- a/github/Branch.py +++ b/github/Branch.py @@ -371,3 +371,34 @@ class Branch(github.GithubObject.NonCompletableGithubObject): "DELETE", self.protection_url + "/restrictions" ) + + def get_required_signatures(self): + """ + :calls: `GET /repos/:owner/:repo/branches/:branch/protection/required_signatures ` + """ + headers, data = self._requester.requestJsonAndCheck( + "GET", + self.protection_url + "/required_signatures", + headers={'Accept': Consts.signaturesProtectedBranchesPreview} + ) + return data["enabled"] + + def add_required_signatures(self): + """ + :calls: `POST /repos/:owner/:repo/branches/:branch/protection/required_signatures ` + """ + headers, data = self._requester.requestJsonAndCheck( + "POST", + self.protection_url + "/required_signatures", + headers={'Accept': Consts.signaturesProtectedBranchesPreview} + ) + + def remove_required_signatures(self): + """ + :calls: `DELETE /repos/:owner/:repo/branches/:branch/protection/required_signatures ` + """ + headers, data = self._requester.requestJsonAndCheck( + "DELETE", + self.protection_url + "/required_signatures", + headers={'Accept': Consts.signaturesProtectedBranchesPreview} + ) diff --git a/github/Consts.py b/github/Consts.py index 9aead92e..c59f4197 100644 --- a/github/Consts.py +++ b/github/Consts.py @@ -92,3 +92,6 @@ mediaTypeRequireMultipleApprovingReviews = "application/vnd.github.luke-cage-pre # https://developer.github.com/v3/search/#highlighting-code-search-results-1 highLightSearchPreview = "application/vnd.github.v3.text-match+json" + +# https://developer.github.com/changes/2018-02-22-protected-branches-required-signatures/ +signaturesProtectedBranchesPreview = "application/vnd.github.zzzax-preview+json" diff --git a/github/tests/Branch.py b/github/tests/Branch.py index 110b0969..0764a043 100644 --- a/github/tests/Branch.py +++ b/github/tests/Branch.py @@ -188,3 +188,13 @@ class Branch(Framework.TestCase): u'message': u'Push restrictions not enabled' } ) + + def testGetRequiredSignatures(self): + required_signature = self.protected_branch.get_required_signatures() + assert required_signature + + def testRemoveRequiredSignatures(self): + self.protected_branch.remove_required_signatures() + + def testAddRequiredSignatures(self): + self.protected_branch.add_required_signatures() diff --git a/github/tests/ReplayData/Branch.testAddRequiredSignatures.txt b/github/tests/ReplayData/Branch.testAddRequiredSignatures.txt new file mode 100644 index 00000000..b7df3778 --- /dev/null +++ b/github/tests/ReplayData/Branch.testAddRequiredSignatures.txt @@ -0,0 +1,11 @@ +https +POST +api.github.com +None +/repos/jacquev6/PyGithub/branches/integrations/protection/required_signatures +{'Accept': 'application/vnd.github.zzzax-preview+json', 'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Server', 'GitHub.com'), ('Date', 'Sun, 21 Oct 2018 18:46:31 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4973'), ('X-RateLimit-Reset', '1540150652'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP'), ('ETag', 'W/"dd58dd0663dbf118bceffe9dc228747e"'), ('X-OAuth-Scopes', 'admin:gpg_key, admin:public_key, admin:repo_hook, gist, notifications, repo, user, write:discussion'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.zzzax-preview; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'AA54:4C24:3031AD3:6A57E17:5BCCC987')] +{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/required_signatures","enabled":true} + diff --git a/github/tests/ReplayData/Branch.testGetRequiredSignatures.txt b/github/tests/ReplayData/Branch.testGetRequiredSignatures.txt new file mode 100644 index 00000000..a6149a16 --- /dev/null +++ b/github/tests/ReplayData/Branch.testGetRequiredSignatures.txt @@ -0,0 +1,11 @@ +https +GET +api.github.com +None +/repos/jacquev6/PyGithub/branches/integrations/protection/required_signatures +{'Accept': 'application/vnd.github.zzzax-preview+json', 'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Server', 'GitHub.com'), ('Date', 'Sun, 21 Oct 2018 18:41:55 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4985'), ('X-RateLimit-Reset', '1540150652'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP'), ('ETag', 'W/"dd58dd0663dbf118bceffe9dc228747e"'), ('X-OAuth-Scopes', 'admin:gpg_key, admin:public_key, admin:repo_hook, gist, notifications, repo, user, write:discussion'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.zzzax-preview; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'AA32:4C24:302E1BE:6A4FE10:5BCCC873')] +{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/integrations/protection/required_signatures","enabled":true} + diff --git a/github/tests/ReplayData/Branch.testRemoveRequiredSignatures.txt b/github/tests/ReplayData/Branch.testRemoveRequiredSignatures.txt new file mode 100644 index 00000000..e64b0fda --- /dev/null +++ b/github/tests/ReplayData/Branch.testRemoveRequiredSignatures.txt @@ -0,0 +1,11 @@ +https +DELETE +api.github.com +None +/repos/jacquev6/PyGithub/branches/integrations/protection/required_signatures +{'Accept': 'application/vnd.github.zzzax-preview+json', 'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Server', 'GitHub.com'), ('Date', 'Sun, 21 Oct 2018 18:46:19 GMT'), ('Content-Type', 'application/octet-stream'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4979'), ('X-RateLimit-Reset', '1540150652'), ('X-OAuth-Scopes', 'admin:gpg_key, admin:public_key, admin:repo_hook, gist, notifications, repo, user, write:discussion'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.zzzax-preview; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'AA48:4C25:3BECB3F:7CD7C22:5BCCC97A')] + +