Skip to content

Commit

Permalink
Cookie Requests: Use forwarded cookies, don't generate [RHELDST-18071]
Browse files Browse the repository at this point in the history
Now that exodus-gw provides the necessary cookie data for redirect
requests, origin_request can use those rather than generate them itself.

This commit makes the necessary changes for that and cleans up
now-unused code.
  • Loading branch information
negillett committed Oct 20, 2023
1 parent 9377e46 commit ef71c20
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 656 deletions.
3 changes: 0 additions & 3 deletions docs/schemas/raw/lambda_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,7 @@ required:
- table
- config_table
- config_cache_ttl
- cookie_ttl
- headers
- secret_arn
- key_id
- lambda_version
- index_filename
- logging
Expand Down
86 changes: 12 additions & 74 deletions exodus_lambda/functions/origin_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@
import time
import urllib
import urllib.parse
from base64 import b64decode
from datetime import datetime, timedelta, timezone

import boto3
import cachetools

from .base import LambdaBase
from .db import QueryHelper
from .signer import Signer

CONF_FILE = os.environ.get("EXODUS_LAMBDA_CONF_FILE") or "lambda_config.json"

Expand All @@ -22,6 +21,12 @@
ENDPOINT_URL = os.environ.get("EXODUS_AWS_ENDPOINT_URL") or None


def cf_b64decode(data):
return b64decode(
data.replace("-", "+").replace("_", "=").replace("~", "/")
)


class OriginRequest(LambdaBase):
def __init__(self, conf_file=CONF_FILE):
super().__init__("origin-request", conf_file)
Expand All @@ -36,17 +41,6 @@ def __init__(self, conf_file=CONF_FILE):
self._db = QueryHelper(self.conf, ENDPOINT_URL)
self.handler = self.__wrap_version_check(self.handler)

@property
def sm_client(self):
if not self._sm_client:
self._sm_client = boto3.client(
"secretsmanager",
region_name=self.conf.get("secret_region") or "us-east-1",
endpoint_url=ENDPOINT_URL,
)

return self._sm_client

@property
def definitions(self):
out = self._cache.get("exodus-config")
Expand Down Expand Up @@ -85,45 +79,6 @@ def definitions(self):

return out

@property
def secret(self):
out = self._cache.get("secret")
if out is None:
try:
arn = self.conf["secret_arn"]
self.logger.debug("Attempting to get secret from ARN: %s", arn)

response = self.sm_client.get_secret_value(SecretId=arn)
# get_secret_value response syntax:
# {
# "ARN": "string",
# "Name": "string",
# "VersionId": "string",
# "SecretBinary": b"bytes",
# "SecretString": "string",
# "VersionStages": [
# "string",
# ],
# "CreatedDate": datetime(2015, 1, 1)
# }
#
# We're interested in SecretString and expect it to be a JSON string
# containing cookie_key.
out = json.loads(response["SecretString"])
self._cache["secret"] = out
self.logger.debug("Loaded and cached secret from ARN: %s", arn)
except Exception as exc_info:
self.logger.error(
"Couldn't load secret %s", arn, exc_info=exc_info
)
raise exc_info

return out

@property
def cookie_key(self):
return self.secret["cookie_key"]

def uri_alias(self, uri, aliases):
# Resolve every alias between paths within the uri (e.g.
# allow RHUI paths to be aliased to non-RHUI).
Expand Down Expand Up @@ -171,28 +126,13 @@ def resolve_aliases(self, uri):
return uri

def handle_cookie_request(self, event):
now = datetime.utcnow()
ttl = timedelta(minutes=self.conf.get("cookie_ttl", 720))
domain = event["Records"][0]["cf"]["config"]["distributionDomainName"]
uri = event["Records"][0]["cf"]["request"]["uri"]
record = event["Records"][0]["cf"]
uri = record["request"]["uri"]
querystr_dict = urllib.parse.parse_qs(record["request"]["querystring"])
set_cookies = json.loads(cf_b64decode(querystr_dict["Set-Cookies"][0]))

self.logger.info("Handling cookie request: %s", uri)

signer = Signer(self.cookie_key, self.conf.get("key_id"))

cookies_content = signer.cookies_for_policy(
append="; Secure; HttpOnly; SameSite=lax; Domain=%s; Path=/content/; Max-Age=%s"
% (domain, int(ttl.total_seconds())),
resource="https://%s/content/*" % domain,
date_less_than=now + ttl,
)
cookies_origin = signer.cookies_for_policy(
append="; Secure; HttpOnly; SameSite=lax; Domain=%s; Path=/origin/; Max-Age=%s"
% (domain, int(ttl.total_seconds())),
resource="https://%s/origin/*" % domain,
date_less_than=now + ttl,
)

response = {
"status": "302",
"headers": {
Expand All @@ -202,9 +142,7 @@ def handle_cookie_request(self, event):
"cache-control": [
{"value": "no-store"},
],
"set-cookie": [
{"value": x} for x in (cookies_content + cookies_origin)
],
"set-cookie": [{"value": x} for x in set_cookies],
},
}
self.logger.debug(
Expand Down
52 changes: 0 additions & 52 deletions exodus_lambda/functions/signer.py

This file was deleted.

188 changes: 0 additions & 188 deletions support/signer

This file was deleted.

Loading

0 comments on commit ef71c20

Please sign in to comment.