Page tree
Skip to end of metadata
Go to start of metadata

BMO Handles Ajax calls when called with the Javascript variable that is automatically inserted into the page.

  • For FreePBX that variable is: FreePBX.ajaxurl
  • For UCP that variable is: UCP.ajaxUrl

There is a definition method called: 'ajaxRequest', and a callback method called: 'ajaxHandler'.

ajaxRequest

Ajax Request defines permissions per 'command'. In this function you can also define settings

class Ponies implements \BMO {
    public function ajaxRequest($req, &$setting) {
        // Default settings array passed to ajaxRequest
        // $setting = array('authenticate' => true, 'allowremote' => false, 'changesession' => false);
        // (DONT USE THE ABOVE SETTING YOUR CODE, YOU WILL OVERWRITE THE ARRAY, USE THE CODE BELOW, WHERE YOU DEFINE EACH ITEM)
		switch($req) {
			case "foo"
				//DO NOT USE THIS IN PRODUCTION CODE UNLESS YOU KNOW WHAT YOU ARE DOING
            	$setting['authenticate'] = false;
            	$setting['allowremote'] = true;
				$setting['changesession'] = false;
           		return true;
			break;
			case "foo2"
				return true; 
			break;
			case "foo3"
				return true; 
			break;
		}
        return false; // Returning false, or anything APART from (bool) true will abort the request
    }
}

Setting Options

allowremote

This allows an AJAX request to come from a remote host. Specifically, it enables the 'Access-Control-Allow-Origin: *' header to be sent. You can return 'true' to have the system check for a valid remote IP.

authenticate

Setting this to false means that the session does NOT need to be valid, and can be requested by anyone.

Any request you set to 'authenticate' = false and 'allowremote' = true should only be EXTREMELY public information - such as as a public key request - or an explicit logon request. 

changesession

If you set this to true, changes to the $_SESSION variable will be saved.  If you do not set this, the $_SESSION variable will be visible, but you will not be able to change this . You should avoid setting this, or if you do need to change session variables, call session_write_close() as soon as possible, as this causes FreePBX to run in, effectively, a single thread.

ajaxHandler

Anything returned from the Ajax Handler will be encoded into either JSON or XML depending on what the remote source requested.

Any unknown requests should return just false

class Ponies implements \BMO {
    public function ajaxHandler() {
		switch($_REQUEST['command']) {


		}
        if ($_REQUEST['command'] == "foo") {
            return array("This was unauthed, and remote");
        } elseif ($_REQUEST['command'] == "foo2") {
			return array("This was authed", "and not remote");
		} else {
			return false
		}
    }
}

ajaxCustomHandler

If the command is defined in ajaxRequest but ajaxHandler has returned false for that command then the next step will be ajaxCustomHandler.

The customHandler will not do any post process handling. Therefore any encoding you wish to do must be done at this point.

Make sure to return either (and ONLY) boolean of true or false last. True if it works, false if there was an error (or throw an exception)

class Ponies implements \BMO {
	public function ajaxCustomHandler() {
		switch($_REQUEST['command']) {
			case "foo3":
				echo "Hello World";
			return true;
			default:
				return false;
			break;
		}
		return false;
	}
}

Manually building the AJAX URL

The new ajax handler is ajax.php which knows of two parameters - 'module' and 'command'. To run the ajax command 'foo' in the ponies module, you would call:

ajax.php?module=ponies&command=foo

Alternatively you could also use the ajax url variables:

UCP

UCP.ajaxUrl+"?module=ponies&command=foo"

FreePBX

FreePBX.ajaxurl+"?module=ponies&command=foo"

Limitations

  • It is important you understand the security implications of 'allowremote'. Do not turn it on idly.
  • You can only use the modules explicit BMO Class file, sub-modules are not processed.

Suggestions of when, and when not, to use allowremote = true

  • Do: You should when you don't mind if anyone on the internet can do it or read it (eg: 'getpublickey', 'getmachinetime')
  • Don't: When it'll change anything.
  • Do: When you are doing secondary nonce-based authentication to avoid replay attacks... but it would be better to use REST for that.
  • Don't: When you're not happy pasting the information you're sending or receiving to the outside of your house and onto your car so everyone can read it.

This has been added for a specific set of low-use circumstances, but, there may be others that we haven't thought of. So, really - don't use allowremote unless you have an extremely good reason why.And even then, there's probably a better way.

 

 

  • No labels