'failed', 'cause' => 'error', 'detail' => 'Database connection failed.')); exit; } //************************************************************************************* switch ( $_SERVER['PATH_INFO'] ) { case "/get": // Required GET parameters: // user: authentication username, SIP-username without domain component // domain: Domain/realm of the user. username + '@' + domain == SIP address. if ( array_key_exists('user', $_GET) || ( array_key_exists('username', $_GET) && array_key_exists('domain', $_GET ))) { $username = ""; $domain = ""; if ( array_key_exists('username', $_GET) ) { $username = $_GET['username']; $domain = $_GET['domain']; } else { $user = split_sipaddress($_GET['user']); if ( !$user ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); break; } list ( $username, $domain ) = $user; } // Now, do funky stuff. /* Test if user exists in both 'kamailio.subscribers' and 'provision.users' * Return 'response' => 'ok', 'type' => 'local', 'user' => complete user object. Test if user exists in 'provision.user' only * Return 'response' => 'ok', 'type' => 'remote', 'user' => complete user object. If user does is neither local nor remote * Return 'response' => 'failed' with 'cause' => 'nonexistant' On failure, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message') */ // Dummy-response: $userdata = get_userdata( $username, $domain ); if ( $userdata ) { print json_encode( array( 'response' => 'ok', 'user' => $userdata )); } else { print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => 'Request for user ' . $username . '@' . $domain . ' failed.')); } } else print json_encode ( array( 'response' => 'invalid') ); break; case "/list": /* Simply list all users in user@domain format Perform a search operation if 'search' exists as a GET-parameter * The search should try to do a "smart search" on SIP-usernames: * Try to search with names in in username@domain format * Do the search with wildcards before and after input text. * The search must be done in the provisioning tables, to be able to match non-local users. * SQL SELECT CONCAT() WHERE CONCAT() must be used *shrug* */ $search = null; if ( array_key_exists ( 'search', $_GET ) ) $search = $_GET['search']; // TODO: Add some sanitation and input validation! $list = list_users( $search ); print json_encode( array( 'response' => 'ok', 'list' => $list )); break; case "/add_local": /* What to do?? Required parameters should be... ( username & domain ) | user displayname email Verify that domain is local (lookup in the 'kamailio.domain' table. Verify that the username is available (nonexistant for domain in kamilio.subscribers (and provision.users?)) * Autocreate password * Add username, domain, email and created password to the 'kamailio.subscriber' table * Get the registrar+port, proxy+port from the 'provision.servers' table. * standard dialplan from configuration. * Add to the 'provision.users' table: username -> username password -> generated password displayname -> displayname domain -> domain registrar -> provision.servers.registrar r_port -> provision.servers.r_port proxy -> provision.servers.proxy p_port -> provision.servers.p_port authid -> username dialplan -> standard dialplan linetext -> username * Return 'response' => 'ok' with a full user object in JSON format. If any of the tests fail, return 'response' => 'failed' with 'cause' => "description" on JSON format. */ // Test required parameters: if ( ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) || array_key_exists('user', $_GET) ) && array_key_exists( 'displayname', $_GET ) && array_key_exists( 'email', $_GET ) ) { $username = ""; $domain = ""; if ( array_key_exists('username', $_GET) ) { $username = $_GET['username']; $domain = $_GET['domain']; } else { $user = split_sipaddress($_GET['user']); if ( !$user ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); break; } list ( $username, $domain ) = $user; } $password = generate_password(); $displayname = $_GET['displayname']; $email = $_GET['email']; if ( !is_kamailio_domain( $domain ) ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'nxdomain', 'detail' => 'The selected domain is not local' )); break; } $servers = get_servers( $domain ); if ( !$servers ) { print json_encode( array( 'response' => 'failed', 'cause' => 'servfail', 'detail' => 'Servers lookup failed for domain '. $domain ) ); break; } $registrar = $servers['registrar']; $r_port = $servers['r_port']; $proxy = $servers['proxy']; $p_port = $servers['p_port']; $authid = $username; $linetext = $username; $dialplan = $config['standard_dialplan']; if ( is_provision_user ( $username, $domain ) ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' )); break; } if ( is_kamailio_subscriber ( $username, $domain ) ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' )); break; } $kam_res = add_kamailio_subscriber( $username, $domain, $password, $email ); if ( !$kam_res ) { print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add kamailio subscriber.' ) ); break; } $pro_res = add_provision_user( $username, $password, $domain, $authid, $registrar, $r_port, $proxy, $p_port, $displayname, $dialplan, $linetext ); if ( !$pro_res ) { // Rollback data added to Kamailio! Try to simulate atomicity, or atleast maintain integrity... delete_kamailio_subscriber( $username, $domain ); // Give errormessage, and quit. print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add user for provisioning. Rolled back kamailio subscriber' ) ); break; } $userdata = get_userdata( $username, $domain ); if ( !$userdata ) { // Rollback data added to Kamailio! Try to simulate atomicity, or atleast maintain integrity... delete_kamailio_subscriber( $username, $domain ); delete_provision_user( $username, $domain ); // Give errormessage, and quit. print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to read recently added data. Operations rolled back' ) ); } print json_encode( array( 'response' => 'ok', 'user' => $userdata )); } else print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) ); break; case "/add_remote": /* Required parameters should be... ( username & domain ) | user displayname password registrar Optional parameters r_port proxy p_port authid dialplan linetext Verify that the domain is not a local kamailio domain (REMOTE user..) Verify that the username+domain is not already registered in 'provision.users'. * If r_port is empty, set to 5060 * If proxy/port is empty, set to registrar/port * If authid is empty, set to username * If dialplan is empty, set to standard dialplan * If linetext is empty, set to username@domain * Add to the 'provision.users' table: username -> username password -> supplied password displayname -> displayname domain -> domain registrar -> registrar r_port -> r_port proxy -> proxy p_port -> p_port authid -> authid dialplan -> dialplan linetext -> linetext * Return 'response' => 'ok' with a full user object in JSON format. If any of the tests fail, return 'response' => 'failed' with 'cause' => "description" in JSON format. */ // Test required parameters: if ( ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) || array_key_exists('user', $_GET) ) && array_key_exists( 'displayname', $_GET ) && array_key_exists( 'password', $_GET ) && array_key_exists( 'registrar', $_GET ) ) { $username = ""; $domain = ""; if ( array_key_exists('username', $_GET) ) { $username = $_GET['username']; $domain = $_GET['domain']; } else { $user = split_sipaddress($_GET['user']); if ( !$user ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); break; } list ( $username, $domain ) = $user; } $password = $_GET['password']; $displayname = $_GET['displayname']; $registrar = $_GET['registrar']; $r_port = ( array_key_exists('r_port', $_GET) ) ? $_GET['r_port'] : 5060; $proxy = ( array_key_exists('proxy', $_GET) ) ? $_GET['proxy'] : $registrar; $p_port = ( array_key_exists('p_port', $_GET) ) ? $_GET['p_port'] : $r_port; $authid = ( array_key_exists('authid', $_GET) ) ? $_GET['authid'] : $username; $dialplan = ( array_key_exists('dialplan', $_GET) ) ? $_GET['dialplan'] : $config['standard_dialplan']; $linetext = ( array_key_exists('linetext', $_GET) ) ? $_GET['linetext'] : $username . '@' . $domain; if ( is_kamailio_domain( $domain ) ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'domain', 'detail' => 'The selected domain is local, cannot add remote user' )); break; } if ( is_provision_user ( $username, $domain ) ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' )); break; } if ( is_kamailio_subscriber ( $username, $domain ) ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' )); break; } $pro_res = add_provision_user( $username, $password, $domain, $authid, $registrar, $r_port, $proxy, $p_port, $displayname, $dialplan, $linetext ); if ( !$pro_res ) { // Give errormessage, and quit. print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add user for provisioning.' ) ); break; } $userdata = get_userdata( $username, $domain ); if ( !$userdata ) { // Rollback data added! delete_provision_user( $username, $domain ); // Give errormessage, and quit. print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to read recently added data. Operations rolled back' ) ); } print json_encode( array( 'response' => 'ok', 'user' => $userdata )); } else print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) ); break; case "/remove": /* Required parameters should be... ( username & domain ) | user * Verify that no associations/relations exist in 'provision.phones' * Verify that the user exists in 'provision.users' * Remove from 'provision.users' * Test to see of user exists in 'kamailio.subscriber'. * Remove from 'kamailio.subscribers' * Return response' => 'ok', 'type' => 'local' * If not in 'kamailio.subscribers' * Return response' => 'ok', 'type' => 'remote' * If associations exist, return 'response' => 'failed', 'cause' => 'inuse' * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant' * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message') */ if ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) || array_key_exists('user', $_GET) ) { $username = ""; $domain = ""; if ( array_key_exists('username', $_GET) ) { $username = $_GET['username']; $domain = $_GET['domain']; } else { $user = split_sipaddress($_GET['user']); if ( !$user ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); break; } list ( $username, $domain ) = $user; } if ( get_user_phones ( $username, $domain ) ) { print json_encode( array( 'response' => 'failed', 'cause' => 'inuse', 'detail' => 'User has associated provisioning. Remove and retry.' ) ); break; } if ( is_provision_user( $username, $domain ) || is_kamailio_subscriber( $username, $domain ) ) { delete_provision_user( $username, $domain ); delete_kamailio_subscriber( $username, $domain ); print json_encode( array ( 'response' => 'ok', 'detail' => 'User ' . $username . '@' . $domain . ' deleted.')); break; } else { print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => 'Unable to remove nonexistant user.')); break; } break; } print json_encode ( array( 'response' => 'invalid') ); break; case "/change_pw": /* Required parameters should be... ( username & domain ) | user password * Verify that no associations/relations exist in 'provision.phones' * Verify that the user exists ... * Test to see of user exists in 'provision.users' * Test to see of user exists in 'kamailio.subscriber'. * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant' * Update user passwords in 'provision' and 'kamailio' as appropriate * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message') */ if ( array_key_exists('password', $_GET) && ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) || array_key_exists('user', $_GET) )) { $username = ""; $domain = ""; if ( array_key_exists('username', $_GET) ) { $username = $_GET['username']; $domain = $_GET['domain']; } else { $user = split_sipaddress($_GET['user']); if ( !$user ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); break; } list ( $username, $domain ) = $user; } $password = $_GET['password']; // Check compatibility of password? TODO... // Fetch old password for rollback? TODO... // Verify that user exists for provisioning if ( ! is_provision_user( $username, $domain ) ) { print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => '' . $username . '@' . $domain . ' does not exist.')); break; } if ( is_provision_user( $username, $domain ) ) { // Update provisioning password if (! update_provision_pw( $username, $domain, $password ) ) { print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update provisioning password' ) ); break; } } // Check for user in kamailio if ( is_kamailio_subscriber( $username, $domain ) ) { // Update kamailio password if (! update_kamailio_pw( $username, $domain, $password ) ) { print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update kamailio password' ) ); break; } } print json_encode( array ( 'response' => 'ok', 'detail' => 'Password changed for user '.$username.'@'.$domain.'.')); break; } else print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) ); break; case "/update": /* Required parameters should be... ( username & domain ) | user * Verify that no associations/relations exist in 'provision.phones' * Verify that the user exists ... * Test to see of user exists in 'provision.users' * Test to see of user exists in 'kamailio.subscriber'. * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant' * Get update parameters, and change as appropriate ;) * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message') */ if ( ( array_key_exists( 'username', $_GET) && array_key_exists( 'domain', $_GET ) ) || array_key_exists('user', $_GET) ) { $username = ""; $domain = ""; if ( array_key_exists('username', $_GET) ) { $username = $_GET['username']; $domain = $_GET['domain']; } else { $user = split_sipaddress($_GET['user']); if ( !$user ) { print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') ); break; } list ( $username, $domain ) = $user; } print json_encode ( array( 'response' => 'failed', 'cause' => 'notimplemented', 'detail' => 'Requested feature valid, but not implemented' ) ); } else print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) ); break; case "/gen_pw": print generate_password(); break; default: print json_encode ( array( 'response' => 'invalid') ); } mysql_close( $config['sql_link'] ); ?>