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
Issue 1655: Add authorize credentials list and removal on organization under SAML #1676
base: main
Are you sure you want to change the base?
Changes from 5 commits
87c6a62
4003b14
0453b04
94ccd2d
d7e541f
c7ffb4b
843cb8f
9eadbd0
a4c6954
3560a0e
3659f4b
de00b40
a699832
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
############################ Copyrights and license ############################ | ||
# # | ||
# Copyright 2020 Alexandre Delisle <alexodelisle@gmail.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/>. # | ||
# # | ||
################################################################################ | ||
|
||
import github.GithubObject | ||
|
||
|
||
class AuthorizationOrganization(github.GithubObject.NonCompletableGithubObject): | ||
""" | ||
This class represents a credential id. | ||
""" | ||
|
||
def __repr__(self): | ||
return self.get__repr__( | ||
{ | ||
"login": self.login, | ||
"credential_id": self.credential_id, | ||
"credential_type": self.credential_type, | ||
"credential_authorized_at": self.credential_authorized_at, | ||
"credential_accessed_at": self.credential_accessed_at, | ||
"token_last_eight": self.token_last_eight, | ||
"scopes": self.scopes | ||
} | ||
) | ||
|
||
@property | ||
def login(self): | ||
""" | ||
:type: string | ||
""" | ||
return self._login.value | ||
|
||
@property | ||
def credential_id(self): | ||
""" | ||
:type: string | ||
""" | ||
return self._credential_id.value | ||
|
||
@property | ||
def credential_type(self): | ||
""" | ||
:type: string | ||
""" | ||
return self._credential_type.value | ||
|
||
@property | ||
def credential_authorized_at(self): | ||
""" | ||
:type: string | ||
""" | ||
return self._credential_authorized_at.value | ||
|
||
@property | ||
def credential_accessed_at(self): | ||
""" | ||
:type: string | ||
""" | ||
return self._credential_accessed_at.value | ||
|
||
@property | ||
def token_last_eight(self): | ||
""" | ||
:type: string | ||
""" | ||
return self._token_last_eight.value | ||
|
||
@property | ||
def scopes(self): | ||
""" | ||
:type: list | ||
""" | ||
return self._scopes.value | ||
|
||
def _initAttributes(self): | ||
self._login = github.GithubObject.NotSet | ||
self._credential_id = github.GithubObject.NotSet | ||
self._credential_type = github.GithubObject.NotSet | ||
self._credential_authorized_at = github.GithubObject.NotSet | ||
self._credential_accessed_at = github.GithubObject.NotSet | ||
self._token_last_eight = github.GithubObject.NotSet | ||
self._scopes = github.GithubObject.NotSet | ||
|
||
def _useAttributes(self, attributes): | ||
if "login" in attributes: # pragma no branch | ||
self._login = self._makeStringAttribute(attributes["login"]) | ||
if "credential_id" in attributes: # pragma no branch | ||
self._credential_id = self._makeIntAttribute(attributes["credential_id"]) | ||
if "credential_type" in attributes: # pragma no branch | ||
self._credential_type = self._makeStringAttribute(attributes["credential_type"]) | ||
if "credential_authorized_at" in attributes: # pragma no branch | ||
self._credential_authorized_at = self._makeDatetimeAttribute(attributes["credential_authorized_at"]) | ||
if "credential_accessed_at" in attributes: # pragma no branch | ||
self._credential_accessed_at = self._makeDatetimeAttribute(attributes["credential_accessed_at"]) | ||
if "token_last_eight" in attributes: # pragma no branch | ||
self._token_last_eight = self._makeStringAttribute(attributes["token_last_eight"]) | ||
if "scopes" in attributes: # pragma no branch | ||
self._scopes = self._makeListOfStringsAttribute(attributes["scopes"]) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from typing import Dict | ||
|
||
from github.GithubObject import CompletableGithubObject | ||
|
||
class AuthorizationOrganization(CompletableGithubObject): | ||
def _initAttributes(self) -> None: ... | ||
def _useAttributes(self, attributes: Dict[str, str]) -> None: ... | ||
@property | ||
def login(self) -> str: ... | ||
@property | ||
def credential_id(self) -> str: ... | ||
@property | ||
def credential_type(self) -> str: ... | ||
@property | ||
def credential_authorized_at(self) -> str: ... | ||
@property | ||
def credential_accessed_at(self) -> str: ... | ||
@property | ||
def token_last_eight(self) -> str: ... | ||
@property | ||
def scopes(self) -> list: ... | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. List[] including the types, such as List[str], please. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,7 @@ | |
|
||
import datetime | ||
|
||
import github.AuthorizationOrganization | ||
import github.Event | ||
import github.GithubObject | ||
import github.NamedUser | ||
|
@@ -1156,6 +1157,33 @@ def get_migrations(self): | |
headers={"Accept": Consts.mediaTypeMigrationPreview}, | ||
) | ||
|
||
def get_credential_authorizations(self): | ||
""" | ||
:calls: `GET /orgs/:org/credential-authorizations <https://developer.github.com/v3/orgs>`_ | ||
:rtype: list | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. list of :class: (I'm not certain of the formatting, but roughly that, please) |
||
""" | ||
headers, data = self._requester.requestJsonAndCheck( | ||
"GET", self.url + "/credential-authorizations" | ||
) | ||
return [ | ||
github.AuthorizationOrganization.AuthorizationOrganization( | ||
self._requester, headers, x, completed=True | ||
) | ||
for x in data | ||
] | ||
|
||
def remove_credential_authorization(self, credential_id): | ||
""" | ||
:calls: `DELETE /orgs/:org/credential-authorizations/:credential_id <https://developer.github.com/v3/orgs/>`_ | ||
:param credential_id: string | ||
:rtype: bool | ||
""" | ||
assert isinstance(credential_id, str), credential_id | ||
status, headers, data = self._requester.requestJson( | ||
"DELETE", self.url + "/credential-authorizations/" + credential_id | ||
) | ||
return status == 204 | ||
|
||
def _initAttributes(self): | ||
self._default_repository_permission = github.GithubObject.NotSet | ||
self._has_organization_projects = github.GithubObject.NotSet | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
############################ Copyrights and license ############################ | ||
# # | ||
# Copyright 2020 Alexandre Delisle <alexodelisle @gmail.com> # | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. space in the email address. |
||
# # | ||
# 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 Organization1655(Framework.TestCase): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we have a better name, such as OrganizationAuthorization? |
||
def setUp(self): | ||
super().setUp() | ||
self.org = self.g.get_organization("ThoughtCamera") | ||
|
||
def testGetCredentialsAuth(self): | ||
credentials_list = self.org.get_credential_authorizations() | ||
self.assertListEqual(credentials_list, []) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You also need to test delete, but I'd also prefer we return something so we can verify the returned attributes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will need to wait in that case, since the only Organization I have available at the moment,with SAML SSO, is private. I can not display the credentials list in the --record. I will ask GitHub sales for a trial for Entreprise Org hosted on GitHub. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
https | ||
GET | ||
api.github.com | ||
None | ||
/orgs/ThoughtCamera | ||
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} | ||
None | ||
200 | ||
[('Server', 'GitHub.com'), ('Date', 'Thu, 27 Aug 2020 23:39:23 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Status', '200 OK'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"90bb3c9ef9cc6ef2b55c66902f5b7ac7"'), ('Last-Modified', 'Sun, 16 Aug 2020 00:03:17 GMT'), ('X-OAuth-Scopes', 'admin:enterprise, admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete:packages, delete_repo, gist, notifications, read:packages, repo, user, workflow, write:discussion, write:packages'), ('X-Accepted-OAuth-Scopes', 'admin:org, read:org, repo, user, write:org'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4999'), ('X-RateLimit-Reset', '1598575163'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 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', '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', 'A040:0AAE:38AE6F:99F702:5F48442B')] | ||
{"login":"ThoughtCamera","id":69738166,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY5NzM4MTY2","url":"https://api.github.com/orgs/ThoughtCamera","repos_url":"https://api.github.com/orgs/ThoughtCamera/repos","events_url":"https://api.github.com/orgs/ThoughtCamera/events","hooks_url":"https://api.github.com/orgs/ThoughtCamera/hooks","issues_url":"https://api.github.com/orgs/ThoughtCamera/issues","members_url":"https://api.github.com/orgs/ThoughtCamera/members{/member}","public_members_url":"https://api.github.com/orgs/ThoughtCamera/public_members{/member}","avatar_url":"https://avatars1.githubusercontent.com/u/69738166?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/ThoughtCamera","created_at":"2020-08-16T00:03:17Z","updated_at":"2020-08-16T00:03:17Z","type":"Organization","total_private_repos":1,"owned_private_repos":1,"private_gists":0,"disk_usage":0,"collaborators":0,"billing_email":"alexodelisle@gmail.com","default_repository_permission":"read","members_can_create_repositories":true,"two_factor_requirement_enabled":false,"plan":{"name":"free","space":976562499,"private_repos":10000,"filled_seats":1,"seats":0}} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
https | ||
GET | ||
api.github.com | ||
None | ||
/orgs/ThoughtCamera/credential-authorizations | ||
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} | ||
None | ||
200 | ||
[('Server', 'GitHub.com'), ('Date', 'Thu, 27 Aug 2020 23:39:23 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '2'), ('Status', '200 OK'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding, Accept, X-Requested-With'), ('ETag', '"3c038471d2d388d890804c1a35971cde"'), ('X-OAuth-Scopes', 'admin:enterprise, admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete:packages, delete_repo, gist, notifications, read:packages, repo, user, workflow, write:discussion, write:packages'), ('X-Accepted-OAuth-Scopes', 'read:org'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4998'), ('X-RateLimit-Reset', '1598575163'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, 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', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'A042:61B4:FF4FDA:1A91260:5F48442B')] | ||
[] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like more detail here, along with a link to the documentation of the object.