Skip to content

Commit

Permalink
Merge pull request #63 from 4dn-dcic/redis-session-token-ctor-fix-202…
Browse files Browse the repository at this point in the history
…40618

Fix call to RedisSessionToken creation to pass email.
  • Loading branch information
dmichaels-harvard authored Jun 20, 2024
2 parents 4750e9f + 1a8d384 commit 8544094
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 9 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ foursight-core
Change Log
----------

5.5.0
=====
* Fix RedisSessionToken creation in react_api_base.ReactApiBase.react_authentication_callback to pass email
which was missing (for some reaseon - previous oversight - was working only because ENCODED_REDIS_SERVER
was not being defined in AWS Secrets Manager, e.g. for FoursightDevelopmentApplicationConfiguration)


5.4.3
=====
* 2024-04-25/dmichaels
Expand Down
6 changes: 5 additions & 1 deletion foursight_core/app_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from .fs_connection import FSConnection
from .s3_connection import S3Connection
from .react.api.auth import Auth
from .react.api.jwt_utils import jwt_decode
from .react.api.react_api import ReactApi
from .react.api.datetime_utils import (
convert_time_t_to_utc_datetime_string,
Expand Down Expand Up @@ -478,8 +479,11 @@ def auth0_callback(self, request, env):
conn = self.init_connection(env)
redis_handler = conn.get_redis_base()
if redis_handler:
# Get email from JWT.
jwt_decoded = jwt_decode(id_token, self._auth0_config.get_client(), self._auth0_config.get_secret())
email = jwt_decoded.get("email")
redis_session_token = RedisSessionToken(
namespace=Auth.get_redis_namespace(env), jwt=id_token
namespace=Auth.get_redis_namespace(env), jwt=id_token, email=email
)
redis_session_token.store_session_token(redis_handler=redis_handler)
# overwrite id_token in this case to be the session token
Expand Down
8 changes: 4 additions & 4 deletions foursight_core/react/api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging
import time
import redis
from typing import Optional
from typing import Optional, Tuple
from dcicutils.env_utils import full_env_name
from dcicutils.function_cache_decorator import function_cache
from dcicutils.misc_utils import ignored, PRINT
Expand Down Expand Up @@ -125,7 +125,7 @@ def authorize(self, request: dict, env: Optional[str] = None) -> dict:
logger.error(f"Authorization exception: {e}")
return self._create_unauthenticated_response(request, "exception: " + str(e))

def create_authtoken(self, jwt: str, jwt_expires_at: int, domain: str, request: Optional[dict] = None) -> str:
def create_authtoken(self, jwt: str, jwt_expires_at: int, domain: str, request: Optional[dict] = None) -> Tuple[str, str]:
"""
Creates and returns a new signed JWT, to be used as the login authtoken (cookie), from
the given AUTHENTICATED and signed and encoded JWT, which will contain the following:
Expand All @@ -141,7 +141,7 @@ def create_authtoken(self, jwt: str, jwt_expires_at: int, domain: str, request:
- The audience (aka "aud" aka Auth0 client ID).
The allowed environments and first/last name are obtained via the users ElasticSearch store;
the first/last names are just for informational/display purposes in the client.
Returns the JWT-signed-encoded authtoken value as a string.
Returns the JWT-signed-encoded authtoken value as a string and the email in a tuple.
"""
jwt_decoded = jwt_decode(jwt, self._auth0_client, self._auth0_secret)
email = jwt_decoded.get("email")
Expand Down Expand Up @@ -222,7 +222,7 @@ def create_authtoken(self, jwt: str, jwt_expires_at: int, domain: str, request:
# it was also in the given JWT (i.e. jwt_decoded["aud"]), and these should match (no
# need to check); it came from the original Auth0 invocation on the client-side (in the
# Auth0Lock box); we communicate it to the client-side via the non-protected /header endpoint.
return jwt_encode(authtoken_decoded, audience=self._auth0_client, secret=self._auth0_secret)
return jwt_encode(authtoken_decoded, audience=self._auth0_client, secret=self._auth0_secret), email

def decode_authtoken(self, authtoken: str) -> dict:
"""
Expand Down
4 changes: 2 additions & 2 deletions foursight_core/react/api/react_api_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def react_authentication_callback(self, request: dict, env: str) -> Response:
jwt_expires_at = convert_datetime_to_time_t(datetime.datetime.utcnow() +
datetime.timedelta(seconds=jwt_expires_in))
domain, context = app.core.get_domain_and_context(request)
authtoken = self._auth.create_authtoken(jwt, jwt_expires_at, domain, request=request)
authtoken, email = self._auth.create_authtoken(jwt, jwt_expires_at, domain, request=request)
authtoken_cookie = create_set_cookie_string(request, name=AUTH_TOKEN_COOKIE,
value=authtoken,
domain=domain,
Expand All @@ -177,7 +177,7 @@ def react_authentication_callback(self, request: dict, env: str) -> Response:
redis_handler = self._auth.get_redis_handler()
if redis_handler:
redis_session_token = RedisSessionToken(
namespace=Auth.get_redis_namespace(env), jwt=jwt
namespace=Auth.get_redis_namespace(env), jwt=jwt, email=email
)
redis_session_token.store_session_token(redis_handler=redis_handler)
c4_st_cookie = create_set_cookie_string(request, name=SESSION_TOKEN_COOKIE,
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "foursight-core"
version = "5.4.2.1b1"
version = "5.5.0"
description = "Serverless Chalice Application for Monitoring"
authors = ["4DN-DCIC Team <[email protected]>"]
license = "MIT"
Expand Down
3 changes: 2 additions & 1 deletion tests/test_react_auth_defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ def create_test_authtoken(expires_or_expired_at: int = EXPIRES_AT, use_invalid_a
jwt = create_test_jwt(use_invalid_auth0_secret)
os.environ["ENV_NAME"] = DEFAULT_ENV
auth = Auth(AUTH0_CLIENT_ID, AUTH0_SECRET_INVALID if use_invalid_auth0_secret else AUTH0_SECRET, ENVS)
authtoken = auth.create_authtoken(jwt, expires_or_expired_at, DOMAIN)
authtoken, email = auth.create_authtoken(jwt, expires_or_expired_at, DOMAIN)
assert email == EMAIL
return authtoken


Expand Down

0 comments on commit 8544094

Please sign in to comment.