-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Add authentication classes, move auth logic there #2528
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
Conversation
Codecov ReportPatch coverage:
❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more. Additional details and impacted files@@ Coverage Diff @@
## master #2528 +/- ##
==========================================
- Coverage 98.68% 98.57% -0.12%
==========================================
Files 117 118 +1
Lines 11831 11980 +149
==========================================
+ Hits 11676 11809 +133
- Misses 155 171 +16
☔ View full report in Codecov by Sentry. |
d6b0c07 to
aefd5e6
Compare
aefd5e6 to
13ce695
Compare
b70a186 to
1add482
Compare
91e65cf to
1b92df1
Compare
| self._app_id = app_id | ||
| self._private_key = private_key |
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.
Probably good to fail-fast here and verify that these aren't empty or None at this point
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 agree, but asserting for not None is not common in this project, and I am too lazy to start this.
Given the arguments are not optional, None values would be surprising from a user point of view. Also, typing suggests None is not allowed.
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.
Sure, but id suggest checking for empty.
The rationale being that, for most of the API, the use of the passed arguments is immediate, here they are passed and used later.
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.
done
| """ | ||
|
|
||
| def __init__(self, token: str): | ||
| self._token = token |
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 would add a type check, and an emptiness check here as a sanity check
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.
done
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.
General suggestion for this class. Consider using the python @dataclass annotation on these classes with the frozen=True flag.
These classes should be immutable, right?
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 would love to use immutable classes here, but I prefer to keep the code base consistent. Maybe a future rework.
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.
Btw., some auth classes like the AppInstallationAuth has to refresh its token, so they are not all immutable.
github/Auth.py
Outdated
| from github.GithubIntegration import GithubIntegration | ||
|
|
||
| self.__integration: Optional[GithubIntegration] = None | ||
| self.__installation_authorization: Optional[InstallationAuthorization] = None |
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.
Can't these be declared at the top of the class?
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.
The import is here for typing. It is imported here because this would cause a circular import otherwise.
The declaration cannot happen in the class body as this would also cause the circular import. Suggestions welcome.
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 stand corrected, the import can happen in the class body, will fix.
| if password is not None: | ||
| warnings.warn( | ||
| "Arguments login_or_token and password are deprecated, please use " | ||
| "auth=github.Auth.Login(...) instead", | ||
| category=DeprecationWarning, | ||
| ) | ||
| auth = Auth.Login(login_or_token, password) | ||
| elif login_or_token is not None: | ||
| warnings.warn( | ||
| "Argument login_or_token is deprecated, please use " | ||
| "auth=github.Auth.Token(...) instead", | ||
| category=DeprecationWarning, | ||
| ) | ||
| auth = Auth.Token(login_or_token) | ||
| elif jwt is not None: | ||
| warnings.warn( | ||
| "Argument jwt is deprecated, please use " | ||
| "auth=github.Auth.AppAuth(...) or " | ||
| "auth=github.Auth.AppAuthToken(...) instead", | ||
| category=DeprecationWarning, | ||
| ) | ||
| auth = Auth.AppAuthToken(jwt) | ||
| elif app_auth is not None: | ||
| warnings.warn( | ||
| "Argument app_auth is deprecated, please use " | ||
| "auth=github.Auth.AppInstallationAuth(...) instead", | ||
| category=DeprecationWarning, | ||
| ) | ||
| auth = app_auth |
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.
What if no auth is provided, is that anonymous auth at that point? Should an Auth.Auth type for anonymous access be added too, just so that there isn't a 'None' case?
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.
Also, is there any standard in the library for being explicit about what version release of the library will formally remove the support for these deprecated APIs?
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.
Well, I think that should be removed in the next major release (v2) as this is quite fundamental / widespread use.
We have seen lots of small breaking changes in minor releases, recently, and given there is a lot of refactoring still need, I would refrain from following semantic versioning.
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.
What if no auth is provided, is that anonymous auth at that point? Should an
Auth.Authtype for anonymous access be added too, just so that there isn't a 'None' case?
Good point. I think auth=None is expressive enough. I don't see benefit for an NoAuth or Anonymous auth class.
| def testBasicAuthentication(self): | ||
| g = github.Github(self.login, self.password) | ||
| g = github.Github(self.login.login, self.login.password) | ||
| self.assertEqual(g.get_user("jacquev6").name, "Vincent Jacques") | ||
|
|
||
| def testOAuthAuthentication(self): | ||
| g = github.Github(self.oauth_token) | ||
| g = github.Github(self.oauth_token.token) | ||
| self.assertEqual(g.get_user("jacquev6").name, "Vincent Jacques") | ||
|
|
||
| def testJWTAuthentication(self): | ||
| g = github.Github(jwt=self.jwt) | ||
| self.assertEqual(g.get_user("jacquev6").name, "Vincent Jacques") | ||
|
|
||
| def testUserAgent(self): | ||
| g = github.Github(user_agent="PyGithubTester") | ||
| g = github.Github(jwt=self.jwt.token) | ||
| self.assertEqual(g.get_user("jacquev6").name, "Vincent Jacques") |
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.
Any assertions you want to put in here around verifying that the warning is logged?
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.
done
4a9c4aa to
1c2532c
Compare
github/Auth.py
Outdated
| ) | ||
|
|
||
|
|
||
| class Auth: |
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 think to be correct, this needs to also implement ABC
| class Auth: | |
| class Auth(abc.ABC): |
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.
done
JLLeitschuh
left a comment
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.
One final thing about ABC, and I think this is good to go
JLLeitschuh
left a comment
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.
LGTM!
|
Thanks! |
Reduces complexity from Requester and moves lots of auth-specific logic into
Authimplementations.Fixes #2431.
Allows for easy fix of #2471 and #2504: EnricoMi#4.
Fixes bad code like
PyGithub/github/ApplicationOAuth.py
Line 94 in b94a83c
https://github.com/PyGithub/PyGithub/pull/2528/files#diff-e1bc4144bb47d4a87072d8149e91f8c66463d81346d958b6f5d3d7dcd9f33375
This is backward compatible to existing auth arguments.