/* hubguard.js
 * 
 * JavaScript functions for implementing the ASPC hub guard
 *
 * A number of mancines with contended ADSL connections exist in the
 * ASPC office, known as "the Hub".
 * 
 * Although it is possible to visit the public APC website from these
 * machines, it is discouraged in favour of public access terminals
 * (the "PAT") which have a fast connection to a local copy of the
 * ASPC website.
 *
 * This script implements the means to label a machine as a "hub"
 * machine using a cookie (label_client_a_hub()), detect this cookie
 * (is_client_a_hub()), and redirect those which are to a notice page
 * (redirect_hubs()).
 *
 * Nick Wooley 30/5/2007
 *
 * See also: https://www.noodle<NOSPAM>factory.co.uk/projects/inter_info/trac/wiki/HubGuard
 */

// The name of the cookie used to label hubs as such
var hub_cookie_name = "aspc_hub";

// An optional domain to apply to the cookie.  By default it's applied to the 
// server host specifically, but can be made more general by specifying a 
// higher level domain here.  Specifying a domain not matching the server
// domain will invalidate the cookie and the browser may refuse to store it.
var hub_cookie_domain = "aspc.co.uk";

// if the browser is referred from an URL with a domain matching this, it is not redirected.
var exempt_domains_pattern = ".*aspc.*\.co\.uk";

// if redirect_hubs() detects a query matching this it 
// does not redirect.
var override_query = "override";

// if redirect_hubs() sees that the referrer page is called this,
// is does not redirect.
var hub_guard_page = "hub_alert.html";

// true if the referrer page name matches hub_guard_page
function referrer_is_exempt()
{
    var page = document.referrer.replace(/^.*[\/]/, '');
    return page == hub_guard_page || document.referrer.match('^https?://'+exempt_domains_pattern);
}

// true if the override_query was detected on the url
function redirect_override_requested()
{
    // we need to copy the location to avoid changing the location inadvertantly
    var query = new String(document.location); 
    query = query.replace(/^.*\?/, ''); 
    return query == override_query;
}


// true if the client is labelled with a hub cookie
function is_client_a_hub()
{
    // search the cookies for one with the right name
    var cookies = document.cookie.replace(/\s+/g, '').split(';');
    for(var ix in cookies) 
    {
        if (cookies[ix].indexOf(hub_cookie_name+"=") == 0) return true;
    }
    return false;
}


// redirects clients labelled with the hub cookie to the url given, or if none given
// to the hub_guard_page
function redirect_hubs(url)
{
    if (referrer_is_exempt() || redirect_override_requested()) return;

    // replace() redirects with no history record, i.e. no option to go 'back'
    if (is_client_a_hub())
        window.location.replace(url || hub_guard_page);
}


// sets a long-lived cookie named hub_cookie_name
function label_client_a_hub()
{
    if (is_client_a_hub()) return;

    // the order here seems to matter.
    var cookie = hub_cookie_name+"=true; "
    + "max-age=3000000000; " // a long time in the future
    + "path=/";
    if (hub_cookie_domain) cookie += "; domain="+hub_cookie_domain;
    document.cookie = cookie;
}


function unlabel_client()
{
    // this must match the original cookie.  
    // we have to clear the name too, since the cookie may not expire
    // and get removed immediately in all browsers.
    var cookie = hub_cookie_name+"=; "
    + "max-age=0; "
    + "path=/";
    if (hub_cookie_domain) cookie += "; domain="+hub_cookie_domain;
    document.cookie = cookie;
}
