view mod_aws_profile/mod_aws_profile.lua @ 5519:83ebfc367169

mod_http_oauth2: Return Authentication Time per OpenID Core Section 2 Mandatory To Implement, either MUST include or OPTIONAL depending on things we don't look at, so might as well include it all the time. Since we do not persist authentication state with cookies or such, the authentication time will always be some point between the user being sent to the authorization endpoint and the time they are sent back to the client application.
author Kim Alvefur <zash@zash.se>
date Mon, 05 Jun 2023 22:32:44 +0200
parents 1d719d4ef18f
children 616c0459aca7
line wrap: on
line source

local http = require "net.http";
local json = require "util.json";
local parse_timestamp = require "util.datetime".parse;

module:set_global();

local current_credentials = module:shared("/*/aws_profile/credentials");

local function get_role_credentials(role_name, cb)
	http.request("http://169.254.169.254/latest/meta-data/iam/security-credentials/"..role_name, nil, function (credentials_json)
		local credentials = credentials_json and json.decode(credentials_json);
		if not credentials or not (credentials.AccessKeyId and credentials.SecretAccessKey) then
			module:log("warn", "Failed to fetch credentials for %q", role_name);
			cb(nil);
			return;
		end
		local expiry = parse_timestamp(credentials.Expiration);
		local ttl = os.difftime(expiry, os.time());
		cb({
			access_key = credentials.AccessKeyId;
			secret_key = credentials.SecretAccessKey;
			ttl = ttl;
			expiry = expiry;
		});
	end);
end

local function get_credentials(cb)
	http.request("http://169.254.169.254/latest/meta-data/iam/security-credentials", nil, function (role_name)
		role_name = role_name and role_name:match("%S+");
		if not role_name then
			module:log("warn", "Unable to discover role name");
			cb(nil);
			return;
		end
		get_role_credentials(role_name, cb);
	end);
end

function refresh_credentials(force)
	if not force and current_credentials.expiry and current_credentials.expiry - os.time() > 300 then
		return;
	end
	get_credentials(function (credentials)
		if not credentials then
			module:log("warn", "Failed to refresh credentials!");
			return;
		end
		current_credentials.access_key = credentials.access_key;
		current_credentials.secret_key = credentials.secret_key;
		current_credentials.expiry = credentials.expiry;
		module:timer(credentials.ttl or 240, refresh_credentials);
		module:fire_event("aws_profile/credentials-refreshed", current_credentials);
	end);
end

function module.load()
	refresh_credentials(true);
end