-
Notifications
You must be signed in to change notification settings - Fork 383
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
Implementation of Oauth of Github, Google and Microsoft #4298
base: master
Are you sure you want to change the base?
Conversation
5ce7f18
to
68eaf7b
Compare
de2e213
to
d3f6b29
Compare
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.
Please see my remarks.
I have some additional comments apart from the direct in code messages:
- My major concern with the implementation is that the oauth related API and its implementation is not generalized enough. The configuration is good enough for the time being.
- I am not sure if we are allowed to use the Git Hub logo in our repo.
- Please invite @cservakt to review the JS and VueJS parts.
I did not do a thorough review of the oauth flow in authentication.py
after you addressed the above issues I will do another round concentrating on that.
Thanks for the hard work!
12c68e7
to
f064c2b
Compare
b4d5a0a
to
d3847d6
Compare
…s, commented lines
9256875
to
75072a3
Compare
75072a3
to
d6561b8
Compare
with DBSession(self.__config_db) as session: | ||
state_db = session.query(StateCodes) \ | ||
.filter(StateCodes.id == state_id) \ | ||
.first().state |
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.
Expired states might not have been purged at this point - add an explicit check here for expires_at.
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.
fixed
.filter(StateCodes.state == new_state.state | ||
and | ||
StateCodes.expires_at == new_state.expires_at) \ | ||
.first().id |
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.
It might be worthwhile to explicitly store other parameters of the "state" here as well - oauth provider, PKCE if added, etc.
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.
fixed
Pkce problem
5eb341c
to
c474b4f
Compare
c474b4f
to
3f774da
Compare
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's the workflow for OAuth authentication via the command-line client? If the user logs in via CodeChecker cmd, and only OAuth providers are enabled, how will they get their CodeChecker session token?
#### OAUTH Configuration options <a name="oauth-configuration-options"></a> | ||
* `enabled` | ||
|
||
Indicated if OAUTH authentication is enabled (required for any methods below) |
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.
Official capitalization is OAuth.
* `oauth_callback_url` | ||
|
||
User will be redirected back to the provided link after login with returned data. | ||
It should be constructed in that format `http://codechecker_path/login/OAuthLogin/provider` wher `provider` is the the name of the provider of OAuth and should match existing `provider_name`. The `oauth_callback_url` should also match the callback url specified in the config of your provider on their webpage. |
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.
If the path of the URL is always the same, wouldn't it make sense to ask for just the domain name? Or at least give a server warning when the path doesn't match the format it should be in.
"oauth_client_id": "client id", | ||
"oauth_client_secret": "client secret", | ||
"oauth_authorization_uri": "https://accounts.google.com/o/oauth2/auth", | ||
"oauth_callback_url": "http://localhost:8080/login/provider", |
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.
(As an example of where a server warning would be useful, this callback is in the wrong format :D )
codechecker_api_shared.ttypes.ErrorCode.AUTH_DENIED, | ||
"User info fetch failed.") | ||
|
||
if provider == "github" and \ |
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.
Are providers case-sensitive?
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.
yes
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.
fixed, now whatever the performLogin() gets as provider is being transformed into lowercase
token = None | ||
try: | ||
# code_verifier_db is not supported for github provider | ||
# if it will be fixed the code should adjust automatically |
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.
This should probably be in the documentation as well, along with how the code fetches Github email addresses instead of just usernames.
"oauth_client_id" : "ExampleClientID", | ||
"oauth_client_secret": "ExampleClientSecret", | ||
"oauth_authorization_uri": "https://github.com/login/oauth/authorize", | ||
"oauth_callback_url": "http://path_To_CodeChecker_Login_Page/provider", |
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.
This should also follow the correct format.
const baseUrl = window.location.href.replace("#", ""); | ||
const baseUrlOAuthId = `${baseUrl}&oauth_data_id=${oauth_data_id}`; | ||
const baseMethod = `${baseUrlOAuthId}&code_challenge_method=${method}`; | ||
const fullUrl = `${baseMethod}&code_challenge=${code_challenge}`; |
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.
This snippet looks suspect. Why are you reconstructing a URL yourself based on what's in the localStorage, when you are trying to pass the callback URL along as-is? In fact, why are these details stored at all, other than what is strictly necessary?
The stored details in localStorage, and all other variables are checked on the server side, and that is the only check that matters in the chain.
These details in the localStorage also become prone to the same thing that caused the mix-up attack - when someone dispatches a second OAuth login session, and they still didn't finish the first one, these stored details are overwritten.
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.
fixed, The localStorage is not used anymore, the necessary arguments are stored on server side in database, the oauth_id is removed, the database querying is happening based on state ,
7149ef4
to
1287f13
Compare
1287f13
to
ad5beec
Compare
545caa6
to
e3d6d7a
Compare
fixes #4160
The right way it should look after logging in
new added button to log in with github
Changes: