Project

General

Profile

« Previous | Next » 

Revision dedfdca1

Added by Benoît PECCATTE about 7 years ago

Fixes #10138: pass ttl through url parameters in sharedfiles api

View differences:

rudder-server-relay/SOURCES/relay-api/relay_api/shared_files.py
# Extract a public key object from headers
def get_pubkey(header_info):
# validate header content first
if 'digest' not in header_info or 'pubkey' not in header_info:
if 'digest' not in header_info or 'short_pubkey' not in header_info:
raise ValueError("ERROR incomplete header, missing digest or public key")
pem = "-----BEGIN RSA PRIVATE KEY-----\n" + header_info['pubkey'] + "\n-----END RSA PRIVATE KEY-----\n"
pem = "-----BEGIN RSA PRIVATE KEY-----\n" + header_info['short_pubkey'] + "\n-----END RSA PRIVATE KEY-----\n"
return RSA.importKey(pem)
# Create expiry header line
def expiry_line(header_info):
if 'ttl' not in header_info:
raise ValueError("ERROR: No TTL provided")
else:
def expiry_line(header_info, ttl_value):
if ttl_value is None or ttl_value == '':
if 'ttl' not in header_info:
raise ValueError("ERROR: No TTL provided")
ttl = parse_ttl(header_info['ttl'])
expires = datetime.datetime.utcnow() + ttl # we take utcnow because we write a unix timestamp
timestamp = int((expires - datetime.datetime(1970, 1, 1)).total_seconds()) # convert to unix timestamp
return "expires=" + str(timestamp) + "\n"
else:
ttl = parse_ttl(ttl_value)
expires = datetime.datetime.utcnow() + ttl # we take utcnow because we write a unix timestamp
delta = expires - datetime.datetime(1970, 1, 1)
timestamp = delta.days*24*3600 + delta.seconds # convert to unix timestamp
return "expires=" + str(timestamp) + "\n"
# Hash a message with a given algorithm
......
# - nodes the content of the nodes_list file
# - my_uuid uuid of the current relay (self)
# - shared_path the shared-files directory path
# - ttl duration to keep the file
# Returns the full path of the created file
def shared_files_put(target_uuid, source_uuid, file_id, data_stream, nodes, my_uuid, shared_path):
def shared_files_put(target_uuid, source_uuid, file_id, data_stream, nodes, my_uuid, shared_path, ttl):
header = get_header(data_stream)
info = parse_header(header)
......
pubkey = get_pubkey(info)
if source_uuid not in nodes:
raise ValueError("ERROR unknown source node: " + str(source_uuid))
if "keyhash" not in nodes[source_uuid]:
if "key-hash" not in nodes[source_uuid]:
raise ValueError("ERROR invalid nodes file on the server for " + source_uuid)
keyhash = nodes[source_uuid]["keyhash"]
keyhash = nodes[source_uuid]["key-hash"]
# validate key
if not validate_key(pubkey, keyhash):
......
raise ValueError("ERROR invalid signature")
# add headers
header += expiry_line(info)
header += expiry_line(info, ttl)
# replace hash by a guaranteed one
header = re.sub(r'hash_value=.*?\n', "hash_value=" + message_hash + "\n", header)
rudder-server-relay/SOURCES/relay-api/relay_api/views.py
def put_file(target_uuid, source_uuid, file_id):
try:
nodes = get_nodes_list(NODESLIST_FILE)
ttl = request.args.get('ttl', '')
my_uuid = get_file_content(UUID_FILE)
if target_uuid not in nodes:
# forward the file if the node is unknown
policy_server = get_file_content(POLICY_SERVER_FILE)
if policy_server == "root":
if my_uuid == "root":
return format_response("Unknown UUID: "+target_uuid, 404)
else:
url = "https://"+policy_server+"/rudder/relay-api/shared-files/" + target_uuid + "/" + source_uuid + "/" + file_id + "?hash=" + file_hash
policy_server = get_file_content(POLICY_SERVER_FILE)
url = "https://"+policy_server+"/rudder/relay-api/shared-files/" + target_uuid + "/" + source_uuid + "/" + file_id + "?ttl=" + ttl
res = shared_files_put_forward(request.stream, url)
else:
# process the file if it is known
my_uuid = get_file_content(UUID_FILE)
filename = shared_files_put(target_uuid, source_uuid, file_id, request.stream, nodes, my_uuid, SHARED_FILES_PATH)
filename = shared_files_put(target_uuid, source_uuid, file_id, request.stream, nodes, my_uuid, SHARED_FILES_PATH, ttl)
if API_DEBUGINFO:
res = "OK\nWritten to: " + filename + "\n"
else:
......
try:
nodes = get_nodes_list(NODESLIST_FILE)
file_hash = request.args.get('hash', '')
my_uuid = get_file_content(UUID_FILE)
if target_uuid not in nodes:
# forward the request if the node is unknown
policy_server = get_file_content(POLICY_SERVER_FILE)
if policy_server == "root":
if my_uuid == "root":
return format_response("Unknown UUID: "+target_uuid, 404)
else:
policy_server = get_file_content(POLICY_SERVER_FILE)
url = "https://"+policy_server+"/rudder/relay-api/shared-files/" + target_uuid + "/" + source_uuid + "/" + file_id + "?hash=" + file_hash
res = shared_files_head_forward(url)
else:
# process the request if it is known
my_uuid = get_file_content(UUID_FILE)
res = shared_files_head(target_uuid, source_uuid, file_id, file_hash, nodes, my_uuid, SHARED_FILES_PATH)
if res:
return format_response("", 200)
rudder-webapp/SOURCES/rudder-apache-webapp-common.conf
# Prevent Chrome loop detection to block the page after too many
# page reloads.
<LocationMatch "/rudder">
<LocationMatch "/rudder(?!/relay-api|/api)">
Header add X-Chrome-Exponential-Throttling "disable"
</LocationMatch>

Also available in: Unified diff