Skip to content

Commit

Permalink
pkce implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
feyruzb committed Oct 24, 2024
1 parent 65adbbd commit 1617633
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 83 deletions.
97 changes: 35 additions & 62 deletions web/server/codechecker_server/api/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,20 +185,19 @@ def insertDataOauth(self, state, code_verifier, provider):
LOG.debug("State inserted into the database")

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
.filter(
OAuthSession.state == new_state.state
and
OAuthSession.expires_at == new_state.expires_at
and
OAuthSession.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("verifier %s inserted sucessfully ", code_verifier)
return oauth_data_id
except sqlite3.Error as e:
LOG.error(f"An error occurred: {e}") # added here re1move
Expand Down Expand Up @@ -228,11 +227,8 @@ def createLink(self, provider):
authorization_uri = oauth_config["oauth_authorization_uri"]
redirect_uri = oauth_config["oauth_redirect_uri"]
# code verifier for PKCE
stored_code_verifier = generate_token(48)
token_url = oauth_config["oauth_token_uri"]
pkce_verifier = generate_token(48)

# generated state and verifyer
LOG.info(f"State: {stored_state} and code verifier: {stored_code_verifier}")
# Create an OAuth2Session instance
session = OAuth2Session(
client_id,
Expand All @@ -248,24 +244,19 @@ def createLink(self, provider):
authorization_uri,
nonce=nonce,
state=stored_state,
code_verifier=stored_code_verifier
code_verifier=pkce_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=pkce_verifier,
provider=provider)
if not oauth_data_id:
raise codechecker_api_shared.ttypes.RequestFailed(
codechecker_api_shared.ttypes.ErrorCode.AUTH_DENIED,
"OAuth data insertion failed.")

LOG.debug(f"State {state} inserted successfully with ID {oauth_data_id}")
LOG.debug("State inserted successfully with ID %s", oauth_data_id)
return url + "&oauth_data_id=" + str(oauth_data_id)

@timeit
Expand Down Expand Up @@ -294,34 +285,28 @@ 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)
code = parsed_query.get("code")[0]
state = parsed_query.get("state")[0]
code_challenge = parsed_query.get("code_challenge")[0]
code_challenge_method = parsed_query.get("code_challenge_method")[0]
cc = parsed_query.get("code_challenge")[0]
cc_method = parsed_query.get("code_challenge_method")[0]
# code_verifier = parsed_query.get("code_verifier")[0]
oauth_data_id = parsed_query.get("oauth_data_id")[0]
# for code verifier from created link and original
code_verifier_db = None
state_db = None
provider_db = None
with DBSession(self.__config_db) as session:
state_db, code_verifier_db, provider_db = session.query(OAuthSession.state,
OAuthSession.code_verifier,
OAuthSession.provider
) \
.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:
state_db, code_verifier_db, provider_db = \
session.query(OAuthSession.state,
OAuthSession.code_verifier,
OAuthSession.provider) \
.filter(OAuthSession.id == oauth_data_id) \
.first()

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,
Expand Down Expand Up @@ -359,42 +344,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=" + cc + \
"&code_challenge_method=" + cc_method

LOG.info("URL has been constructed successfully")
print(url)
token = None
try:
# code_verifier_db is not supported for github provider
# 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
from alembic import op
import sqlalchemy as sa



# Revision identifiers, used by Alembic.
revision = 'b523b36d79ba'
down_revision = '00099e8bc212'
Expand All @@ -23,15 +21,19 @@
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 ###


Expand Down
8 changes: 1 addition & 7 deletions web/server/vue-cli/src/views/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@ export default {
valid: false,
providers: [],
dialog: false,
on: false,
url: null
on: false
};
},
Expand Down Expand Up @@ -216,10 +215,6 @@ export default {
const baseMethod = `${baseUrlOAuthId}&code_challenge_method=${method}`;
const fullUrl = `${baseMethod}&code_challenge=${code_challenge}`;
// const url = `https://example.com` +
// `/oauth2/token?grant_type=authorization_code&code=${url.code}` +
// `&redirect_uri=${baseUrlOAuthId}`;
this.$store
.dispatch(LOGIN, {
type: "oauth",
Expand Down Expand Up @@ -264,7 +259,6 @@ export default {
}));
}).then(url => {
if (url) {
this.url = url;
this.success = false;
this.error = false;
const params = new URLSearchParams(url);
Expand Down
7 changes: 6 additions & 1 deletion web/tests/functional/authentication/oauth_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,14 @@ def login_tester(self):
state = params['state']
code = query_result['code']
oauth_data_id = params['oauth_data_id']
code_challenge = params['code_challenge']
ccm = params['code_challenge_method']
return self.show_json({"code": code,
"state": state,
"oauth_data_id": oauth_data_id})
"oauth_data_id": oauth_data_id,
"code_challenge": code_challenge,
"code_challenge_method": ccm})

return self.show_rejection("Invalid credentials")
except IndexError:
return self.show_rejection("Invalid query parameters")
Expand Down
10 changes: 7 additions & 3 deletions web/tests/functional/authentication/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,14 @@ def try_login(self, provider, username, password):
raise RequestFailed(data['error'])

link = link.split('?')[0]
code, state, oauth_data_id = data['code'], data['state'], \
data['oauth_data_id']
code, state, oauth_data_id, code_challenge, code_challenge_method = \
data['code'], data['state'], data['oauth_data_id'], \
data['code_challenge'], \
data['code_challenge_method']
auth_string = f"{link}?code={code}&state={state}" \
f"&oauth_data_id={oauth_data_id}"
f"&oauth_data_id={oauth_data_id}" \
f"&code_challenge_method={code_challenge_method}" \
f"&code_challenge={code_challenge}"

self.session_token = auth_client.performLogin(
"oauth", provider + "@" + auth_string)
Expand Down

0 comments on commit 1617633

Please sign in to comment.