From c1f2c7a00e99736a5ca379c7de776b0675082844 Mon Sep 17 00:00:00 2001 From: Baghirov Feyruz Date: Thu, 24 Oct 2024 13:41:22 +0200 Subject: [PATCH] pkce implemented --- .../codechecker_server/api/authentication.py | 76 ++++++------------- ...36d79ba_create_table_for_oauth_sessions.py | 23 +++--- 2 files changed, 37 insertions(+), 62 deletions(-) diff --git a/web/server/codechecker_server/api/authentication.py b/web/server/codechecker_server/api/authentication.py index 46bdf6965a..976cea0a5b 100644 --- a/web/server/codechecker_server/api/authentication.py +++ b/web/server/codechecker_server/api/authentication.py @@ -184,21 +184,22 @@ def insertDataOauth(self, state, code_verifier, provider): session.commit() LOG.debug("State inserted into the database") - oauth_data_id = session.query(OAuthSession) \ + oauth_data_id = \ + + session.query(OAuthSession) \ .filter(OAuthSession.state == new_state.state - and - OAuthSession.expires_at == new_state.expires_at - and - OAuth2Session.code_verifier == new_state.code_verifier - and - OAuthSession.provider == new_state.provider - ) \ - .first().id + and + OAuthSession.expires_at == new_state.expires_at + and + OAuth2Session.code_verifier == new_state.code_verifier + and + OAuthSession.provider == new_state.provider + ).first().id + LOG.debug("FETCHED STATE ID") - LOG.debug(f"State {state} inserted successfully") - LOG.debug(f"State {state[0]} inserted successfully.") - LOG.info(f"code verifier has been inserted sucessfully {code_verifier}") + LOG.debug("State %s inserted successfully", state) + LOG.debug("code verifier %s has been inserted sucessfully ", code_verifier) return oauth_data_id except sqlite3.Error as e: LOG.error(f"An error occurred: {e}") # added here re1move @@ -209,7 +210,6 @@ def insertDataOauth(self, state, code_verifier, provider): @timeit def getOauthProviders(self): return self.__manager.get_oauth_providers() - @timeit def createLink(self, provider): """ @@ -229,10 +229,7 @@ def createLink(self, provider): redirect_uri = oauth_config["oauth_redirect_uri"] # code verifier for PKCE stored_code_verifier = generate_token(48) - token_url = oauth_config["oauth_token_uri"] - # generated state and verifyer - LOG.info(f"State: {stored_state} and code verifier: {stored_code_verifier}") # Create an OAuth2Session instance session = OAuth2Session( client_id, @@ -250,16 +247,11 @@ def createLink(self, provider): state=stored_state, code_verifier=stored_code_verifier ) - # print("stored code_verifyer", stored_code_verifier) - # print(url) - # toekn = session.fetch_token( - # url=token_url, - # authorization_response=url, - # code_verifier=stored_code_verifier - # ) - # print("REASFISIGFJRG", toekn) + # Save the state and nonce to the database - oauth_data_id = self.insertDataOauth(state, stored_code_verifier, provider) + oauth_data_id = self.insertDataOauth(state=state, + code_verifier=stored_code_verifier, + provider=provider) if not oauth_data_id: raise codechecker_api_shared.ttypes.RequestFailed( codechecker_api_shared.ttypes.ErrorCode.AUTH_DENIED, @@ -294,7 +286,6 @@ def performLogin(self, auth_method, auth_string): msg) elif auth_method == "oauth": - print(auth_string) provider, url = auth_string.split("@") url_new = urlparse(url) parsed_query = parse_qs(url_new.query) @@ -315,13 +306,8 @@ def performLogin(self, auth_method, auth_string): ) \ .filter(OAuthSession.id == oauth_data_id) \ .first() - print("**************************") - print(state_db) - print(code_verifier_db) - print(provider_db) - print("**************************") - # if state_db != state or code_verifier_db != code_verifier or provider_db != provider: - if state_db != state or provider_db != provider or not code_verifier_db: + + if str(state_db) != state or str(provider_db) != provider: LOG.error("State code mismatch.") raise codechecker_api_shared.ttypes.RequestFailed( codechecker_api_shared.ttypes.ErrorCode.AUTH_DENIED, @@ -359,42 +345,30 @@ def performLogin(self, auth_method, auth_string): raise codechecker_api_shared.ttypes.RequestFailed( codechecker_api_shared.ttypes.ErrorCode.AUTH_DENIED, "OAuth2Session creation failed.") - # fetch url that is not used anywhere for the purpose - # of adding code_verifier to the instance of OAuth2Session - # url_notused, state_notused = session.create_authorization_url( - # url=token_url, - # state=state_db, - # code_verifier=code_verifier_db - # ) - # print("&&&&&&&&&&&&&&&&&&&&&&&&&&&&") - # print(url_notused) - # print("&&&&&&&&&&&&&&&&&&&&&&&&&&&&") # FIXME: This is a workaround for the Microsoft OAuth2 provider # which doesn't correctly fetch the code from url. - # print("#############################") - # print(url_new) - # print("#############################") + # the workaround is to construct the url manually + url = url_new.scheme + "://" + url_new.netloc + url_new.path + \ "?code=" + code + "&state=" + state + \ "&code_challenge=" + code_challenge + \ - "&code_challenge_method=" +code_challenge_method + "&code_challenge_method=" + code_challenge_method LOG.info("URL has been constructed successfully") - print(url) token = None try: + # code_verifier_db is not supported for github provider(their issue) + # if it will be fixed the code should adjust automatically token = session.fetch_token( url=token_url, - #replaced url with url_notused , subject to change!!!!!!🚧🚧🚧 authorization_response=url, - code_verifier="GGGGGHGFHT") + code_verifier=code_verifier_db) except Exception as ex: LOG.error("Token fetch failed: %s", str(ex)) raise codechecker_api_shared.ttypes.RequestFailed( codechecker_api_shared.ttypes.ErrorCode.AUTH_DENIED, "Token fetch failed.") - print(token) LOG.info("Token fetched successfully for provider: %s", provider) user_info = None diff --git a/web/server/codechecker_server/migrations/config/versions/b523b36d79ba_create_table_for_oauth_sessions.py b/web/server/codechecker_server/migrations/config/versions/b523b36d79ba_create_table_for_oauth_sessions.py index d664f74c87..3540ff037d 100644 --- a/web/server/codechecker_server/migrations/config/versions/b523b36d79ba_create_table_for_oauth_sessions.py +++ b/web/server/codechecker_server/migrations/config/versions/b523b36d79ba_create_table_for_oauth_sessions.py @@ -11,8 +11,6 @@ from alembic import op import sqlalchemy as sa - - # Revision identifiers, used by Alembic. revision = 'b523b36d79ba' down_revision = '00099e8bc212' @@ -23,18 +21,21 @@ def upgrade(): LOG = getLogger("migration/config") # ### commands auto generated by Alembic - please adjust! ### - op.create_table('oauth_sessions', - sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), - sa.Column('provider', sa.String(), nullable=False), - sa.Column('state', sa.String(), nullable=False), - sa.Column('code_verifier', sa.String(), nullable=False), - sa.Column('expires_at', sa.DateTime(), nullable=True), - sa.PrimaryKeyConstraint('id', name=op.f('pk_oauth_sessions')) + op.create_table( + 'oauth_sessions', + sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), + sa.Column('provider', sa.String(), nullable=False), + sa.Column('state', sa.String(), nullable=False), + sa.Column('code_verifier', sa.String(), nullable=False), + sa.Column('expires_at', sa.DateTime(), nullable=True), + sa.PrimaryKeyConstraint('id', name=op.f('pk_oauth_sessions')) + ) + op.add_column( + 'auth_sessions', + sa.Column('access_token', sa.String(), nullable=True) ) - op.add_column('auth_sessions', sa.Column('access_token', sa.String(), nullable=True)) # ### end Alembic commands ### - def downgrade(): LOG = getLogger("migration/config") # ### commands auto generated by Alembic - please adjust! ###