Skip to content

Commit

Permalink
apply changes from code review
Browse files Browse the repository at this point in the history
  • Loading branch information
sevignyj committed Nov 14, 2023
1 parent 0158d6d commit 3708285
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 74 deletions.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
beautifulsoup4>=4.6.0
botocore>=1.12.36
certifi>=2022.12.07 # This can be removed when requests updates its requirements from 2017.4.17 to >=2022.12.07
platformdirs>=2.5.4
requests>=2.19.0
2 changes: 1 addition & 1 deletion tokendito/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""Tokendito module initialization."""

__version__ = "2.2.0.rc4"
__version__ = "2.3.0"
__title__ = "tokendito"
__description__ = "Get AWS STS tokens from Okta SSO"
__long_description_content_type__ = "text/markdown"
Expand Down
4 changes: 2 additions & 2 deletions tokendito/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def get(self, url, params=None, headers=None, allow_redirects=True):
"""Perform a GET request."""
response = None
try:
logger.debug(f"get to {url}")
logger.debug(f"GET to {url}")
logger.debug(f"Sending cookies: {self.session.cookies}")
logger.debug(f"Sending headers: {self.session.headers}")
response = self.session.get(
Expand All @@ -53,7 +53,7 @@ def get(self, url, params=None, headers=None, allow_redirects=True):

def post(self, url, data=None, json=None, headers=None, return_json=False):
"""Perform a POST request."""
logger.debug(f"post to {url}")
logger.debug(f"POST to {url}")
try:
response = self.session.post(url, data=data, json=json, headers=headers)
response.raise_for_status()
Expand Down
92 changes: 21 additions & 71 deletions tokendito/okta.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ def api_error_code_parser(status=None):
param status: Response status
return message: status message
"""
logger.debug(f"api_error_code_parser({status})")
if status and status in _status_dict.keys():
message = f"Okta auth failed: {_status_dict[status]}"
else:
Expand All @@ -57,7 +56,6 @@ def get_auth_pipeline(url=None):
"""Get auth pipeline version."""
logger.debug(f"get_auth_pipeline({url})")
headers = {"accept": "application/json"}
# https://developer.okta.com/docs/api/openapi/okta-management/management/tag/OrgSetting/
url = f"{url}/.well-known/okta-organization"

response = HTTP_client.get(url, headers=headers)
Expand Down Expand Up @@ -89,9 +87,7 @@ def get_auth_properties(userid=None, url=None):
:param url: Okta organization URL where we are looking up the user.
:returns: Dictionary containing authentication properties.
"""
logger.debug(f"get_auth_properies({userid}, {url})")
payload = {"resource": f"okta:acct:{userid}", "rel": "okta:idp"}
# payload = {"resource": f"okta:acct:{userid}"}
headers = {"accept": "application/jrd+json"}
url = f"{url}/.well-known/webfinger"
logger.debug(f"Looking up auth endpoint for {userid} in {url}")
Expand Down Expand Up @@ -152,7 +148,7 @@ def get_saml_request(auth_properties):
return saml_request


def send_saml_request(saml_request, cookies):
def send_saml_request(saml_request):
"""
Submit SAML request to IdP, and get the response back.
Expand All @@ -162,11 +158,10 @@ def send_saml_request(saml_request, cookies):
"""
logger.debug(
f"""
send_saml_request
HTTP_client cookies is {HTTP_client.session.cookies}")
we'll set them to {cookies}
"""
HTTP_client cookies is {HTTP_client.session.cookies}")
"""
)
# Define the payload and headers for the request
payload = {
Expand Down Expand Up @@ -198,13 +193,10 @@ def send_saml_request(saml_request, cookies):
# Mask sensitive values for logging purposes
user.add_sensitive_value_to_be_masked(saml_response["response"])

# Log the formed SAML response
# logger.debug(f"SAML response is {saml_response}")
logger.debug(
f"""
After SAML Request call,
we have HTTP_client.session cookies at {HTTP_client.session.cookies}
"""
we have HTTP_client.session cookies: {HTTP_client.session.cookies}
"""
)

# Return the formed SAML response
Expand Down Expand Up @@ -254,30 +246,28 @@ def send_saml_response(config, saml_response):

# Log the SAML response details.
logger.debug(
f""" send_saml_response
f"""
Sending SAML response back to {url}
Sending SAML response back to {url}
and HTTP_client session cookies is {HTTP_client.session.cookies}
"""
HTTP_client session cookies is {HTTP_client.session.cookies}
"""
)

# Use the HTTP client to make a POST request.
response = HTTP_client.post(url, data=payload, headers=headers)

# Extract cookies from the response.
session_cookies = response.cookies
# session_cookies.set("session_token", session_token, path="/")

# Get the 'sid' value from the cookies.

sid = session_cookies.get("sid")
logger.debug(f" new sid is {sid}")

# If 'sid' is present, mask its value for logging purposes.
if sid is not None:
user.add_sensitive_value_to_be_masked(sid)
else:
logger.debug("we dont have a sid cookies.")
logger.debug("We did not find a 'sid' entry in the cookies.")
# Log the session cookies.
logger.debug(
f"""
Expand All @@ -299,7 +289,7 @@ def send_saml_response(config, saml_response):
)
session_cookies = myresponse.cookies

logger.debug(f"in send SAML response, we return {session_cookies}")
logger.debug(f"We return session_cookies: {session_cookies}")

# Return the session cookies.
return session_cookies
Expand Down Expand Up @@ -398,11 +388,6 @@ def get_authorize_scope():
So we're only returning "openid", which is ok for what we do.
"""
# return"""
# openid profile email okta.users.read.self okta.users.manage.self
# okta.internal.enduser.read okta.internal.enduser.manage okta.enduser.dashboard.read
# okta.enduser.dashboard.manage
# """
return "openid"


Expand Down Expand Up @@ -482,7 +467,6 @@ def get_authorize_code(response, payload):
)
sys.exit(1)
authorize_code = re.search(r"(?<=code=)[^&]+", callback_url)
# authorize_state = re.search(r"(?<=state=)[^&]+", callback_url).group()
if authorize_code:
return authorize_code.group()

Expand All @@ -498,13 +482,11 @@ def authorization_code_request(config, authz_code_flow_data):
"""
logger.debug(f"oauth_code_request({config}, {authz_code_flow_data})")
headers = {"accept": "application/json", "content-type": "application/json"}
session_token = HTTP_client.session.cookies.get("session_token")

payload = {
"client_id": authz_code_flow_data["client_id"],
"redirect_uri": authz_code_flow_data["redirect_uri"],
"response_type": authz_code_flow_data["response_type"],
"sessionToken": session_token,
"scope": authz_code_flow_data["scope"],
"state": authz_code_flow_data["state"],
"code_challenge": authz_code_flow_data["code_challenge"],
Expand Down Expand Up @@ -674,36 +656,6 @@ def create_sid_cookies(authn_org_url, session_token):
return cookies


def create_idx_cookies(authn_org_url, session_cookies):
"""
Create session cookie.
:param authn_org_url: org url
:param session_token: session token, str
:returns: cookies jar with session_id value we got using the token
"""
# Construct the URL from the base URL provided.
url = f"{authn_org_url}/api/v1/sessions"

# Define the payload and headers for the request.
data = {"sessionToken": session_cookies}
headers = {"Content-Type": "application/json", "accept": "application/json"}

# Log the request details.
logger.debug(f"Requesting session cookies from {url}")

# Use the HTTP client to make a POST request.
response_json = HTTP_client.post(url, json=data, headers=headers, return_json=True)
if "id" not in response_json:
logger.error(f"'id' not found in response. Full response: {response_json}")
sys.exit(1)

session_id = response_json["id"]
cookies = requests.cookies.RequestsCookieJar()
cookies.set("sid", session_id, domain=urlparse(url).netloc, path="/")
return cookies


def idp_auth(config):
"""Authenticate and authorize with the IDP.
Expand All @@ -729,7 +681,6 @@ def idp_auth(config):
=======
"""
)

if is_saml2_authentication(auth_properties):
# We may loop thru the saml2 servers until
# we find the authentication server.
Expand All @@ -740,15 +691,15 @@ def idp_auth(config):
cookies are {HTTP_client.session.cookies}
"""
)
elif user_authentication_enabled(auth_properties):
session_token = user_authenticate(config)
elif local_authentication_enabled(auth_properties):
session_token = local_authenticate(config)
# authentication sends us a token
# which we then put in our session cookies

HTTP_client.session.cookies = create_sid_cookies(config.okta["org"], session_token)
logger.debug(
f"""
authenticated via user_authenticate
authenticated via local_authenticate
http session cookies are {HTTP_client.session.cookies}
"""
Expand All @@ -760,9 +711,9 @@ def idp_auth(config):
# Once we get there, the user is authenticated.

if config.okta["client_id"] is not None:
# If the user passed a client-id value
# we will run the oauth2 authorize flow on OIE enabled okta.
# we will then get and idx cookies
# If the user passed a client-id value,
# we will run the oauth2 authorize flow on OIE enabled okta
# and we will then get an idx cookies
logger.debug("client_id = {client_id}")
if oie_enabled(config.okta["org"]):
logger.debug(
Expand Down Expand Up @@ -800,7 +751,7 @@ def saml2_authenticate(config, auth_properties):

# Once we are authenticated, send the SAML request to the IdP.
# This call requires session cookies.
saml_response = send_saml_request(saml_request, session_cookies)
saml_response = send_saml_request(saml_request)

# Send SAML response from the IdP back to the SP, which will generate new
# session cookies.
Expand All @@ -821,13 +772,12 @@ def oie_enabled(url):
return False


def user_authenticate(config):
def local_authenticate(config):
"""Authenticate user on local okta instance.
:param config: Config object
:return: auth session ID cookie.
"""
logger.debug(f"user_authenticate({config}")
session_token = None
headers = {"content-type": "application/json", "accept": "application/json"}
payload = {"username": config.okta["username"], "password": config.okta["password"]}
Expand All @@ -852,7 +802,7 @@ def user_authenticate(config):
return session_token


def user_authentication_enabled(auth_properties):
def local_authentication_enabled(auth_properties):
"""Check whether authentication happens on the current instance.
:param auth_properties: auth_properties dict
Expand Down

0 comments on commit 3708285

Please sign in to comment.