declare local var.cookie_decoded STRING;
declare local var.expires INTEGER;
declare local var.decision STRING;
declare local var.percentage INTEGER;
declare local var.string_to_sign STRING;
declare local var.sig STRING;
declare local var.user_id STRING;
declare local var.authed_user_id STRING;
declare local var.key_id STRING;
declare local var.seed INTEGER;
declare local var.duration_key STRING;
declare local var.duration INTEGER;
declare local var.logger_prefix STRING;
if (req.restarts == 0) {
unset ;
}
set var.authed_user_id = client.ip;
set var.authed_user_id = ;
if (
fastly.ff.visits_this_service == 0 &&
req.restarts == 0 &&
table.lookup(solution_waitingroom_config, "enabled") == "true"
) {
set var.logger_prefix = "syslog " + req.service_id + " " + table.lookup(solution_waitingroom_config, "logger_name") + " :: [WAITINGROOM] ";
set var.percentage = std.atoi(table.lookup(solution_waitingroom_config, "allow_percentage", "100"));
if (var.percentage == 0 && table.lookup(solution_waitingroom_config, "allow_percentage") != "0") {
set var.percentage = 100;
}
if (var.percentage >= 100) {
set var.decision = "allow";
} else if (!:waiting_room) {
set var.decision = "anon";
} else {
set var.cookie_decoded = digest.base64_decode(:waiting_room);
set var.expires = std.atoi(subfield(var.cookie_decoded, "exp", "&"));
set var.sig = subfield(var.cookie_decoded, "sig", "&");
set var.key_id = subfield(var.cookie_decoded, "kid", "&");
set var.user_id = subfield(var.cookie_decoded, "uid", "&");
set var.decision = subfield(var.cookie_decoded,"dec","&");
if (var.user_id != var.authed_user_id) {
set var.decision = "anon";
log var.logger_prefix + "User " + var.authed_user_id + " denied while using a token generated for user " + var.user_id;
} else if (!table.lookup(solution_waitingroom_signingkeys, var.key_id)) {
set var.decision = "anon";
log var.logger_prefix + "Unable to check signature due to missing key " + var.key_id;
} else {
set var.string_to_sign = "dec=" + var.decision + "&exp=" + var.expires + "&uid=" + var.user_id + "&kid=" + var.key_id;
if (!digest.secure_is_equal(var.sig, digest.hmac_sha256(table.lookup(solution_waitingroom_signingkeys, var.key_id), var.string_to_sign))) {
set var.decision = "anon";
}
}
if (time.is_after(now, std.integer2time(var.expires))) {
if (var.decision == "allow") {
log var.logger_prefix + "Expired allow token reverted to anon";
set var.decision = "anon";
} else if (var.decision == "wait") {
set var.seed = std.strtol(substr(var.sig,0,8),16);
set var.decision = if (randombool_seeded(var.percentage, 100, var.seed), "allow", "re-wait");
}
}
}
log var.logger_prefix + "Waiting room state: " + var.decision;
if (var.decision == "anon" || var.decision == "allow" || var.decision == "re-wait") {
set var.duration_key = if (var.decision == "allow", "allow_period_timeout", "wait_period_duration");
set var.duration = std.atoi(table.lookup(solution_waitingroom_config, var.duration_key, "30"));
set var.expires = now;
if (var.decision == "allow") {
set var.expires += var.duration;
} else {
set var.expires /= var.duration;
set var.expires *= var.duration;
set var.expires += var.duration;
set var.expires += var.duration;
}
set var.key_id = table.lookup(solution_waitingroom_config, "active_key", "key1");
set var.string_to_sign = "dec=" + if (var.decision == "allow", "allow", "wait") + "&exp=" + var.expires + "&uid=" + var.authed_user_id + "&kid=" + var.key_id;
set var.sig = digest.hmac_sha256(table.lookup(solution_waitingroom_signingkeys, var.key_id), var.string_to_sign);
set = "waiting_room=" + digest.base64(var.string_to_sign + "&sig=" + var.sig) + "; path=/; max-age=" + table.lookup(solution_waitingroom_config, "cookie_lifetime", "7200");
} else if (var.decision == "deny") {
set = "waiting_room=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
}
if (var.decision == "anon") {
error 718 "waitingroom:startwaiting";
} else if (var.decision == "wait" || var.decision == "re-wait") {
error 718 "waitingroom:keepwaiting";
} else if (var.decision == "deny") {
error 718 "waitingroom:deny";
}
}