]>
git.defcon.no Git - hermes/blob - api/user.php
3 # Copyright (c) 2012, Gjøvik University College
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are met:
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above copyright
11 # notice, this list of conditions and the following disclaimer in the
12 # documentation and/or other materials provided with the distribution.
13 # * Neither the name of the Gjøvik University College nor the
14 # names of its contributors may be used to endorse or promote products
15 # derived from this software without specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY Gjøvik University College ''AS IS'' AND ANY
18 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 # DISCLAIMED. IN NO EVENT SHALL Gjøvik University College BE LIABLE FOR ANY
21 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 require_once('config.php');
29 require_once('lib/auth_base.php');
30 require_once('lib/user_functions.php');
31 require_once('lib/common_functions.php');
32 require_once('lib/db_functions.php');
33 require_once('lib/phone_functions.php');
34 require_once('lib/alias_functions.php');
36 $config = get_config();
38 $config['sql_link'] = @mysql_connect
(
39 $config['sql_server'],
40 $config['sql_username'],
41 $config['sql_password']
43 if ( !$config['sql_link'] )
45 print json_encode( array( 'response' => 'failed', 'cause' => 'error', 'detail' => 'Database connection failed.'));
50 //*************************************************************************************
51 switch ( $_SERVER['PATH_INFO'] )
54 // Required GET parameters:
55 // user: authentication username, SIP-username without domain component
56 // domain: Domain/realm of the user. username + '@' + domain == SIP address.
58 if ( array_key_exists('user', $_POST) ||
59 ( array_key_exists('username', $_POST) && array_key_exists('domain', $_POST )))
63 if ( array_key_exists('username', $_POST) )
65 $username = $_POST['username'];
66 $domain = $_POST['domain'];
70 $user = split_sipaddress($_POST['user']);
73 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
76 list ( $username, $domain ) = $user;
79 // Now, do funky stuff.
81 Test if user exists in both 'kamailio.subscribers' and 'hermes.users'
82 * Return 'response' => 'ok', 'type' => 'local', 'user' => complete user object.
83 Test if user exists in 'hermes.user' only
84 * Return 'response' => 'ok', 'type' => 'remote', 'user' => complete user object.
85 If user does is neither local nor remote
86 * Return 'response' => 'failed' with 'cause' => 'nonexistant'
87 On failure, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
91 $userdata = get_userdata( $username, $domain );
94 print json_encode( array( 'response' => 'ok', 'user' => $userdata ));
98 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => 'Request for user ' . $username . '@' . $domain . ' failed.'));
102 print json_encode ( array( 'response' => 'invalid') );
106 if ( array_key_exists('user', $_POST) ||
107 ( array_key_exists('username', $_POST) && array_key_exists('domain', $_POST )))
111 if ( array_key_exists('username', $_POST) )
113 $username = $_POST['username'];
114 $domain = $_POST['domain'];
118 $user = split_sipaddress($_POST['user']);
121 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
124 list ( $username, $domain ) = $user;
126 $location = get_locations( $username, $domain );
127 if ( $location == null )
129 print json_encode( array( 'response' => 'failed', 'cause' => 'offline' ));
132 print json_encode( array( 'response' => 'ok', 'locations' => $location ));
135 print json_encode ( array( 'response' => 'invalid') );
140 Simply list all users in user@domain format
141 Perform a search operation if 'search' exists as a GET-parameter
142 * The search should try to do a "smart search" on SIP-usernames:
143 * Try to search with names in in username@domain format
144 * Do the search with wildcards before and after input text.
145 * The search must be done in the provisioning tables, to be able
146 to match non-local users.
147 * SQL SELECT CONCAT() WHERE CONCAT() must be used *shrug*
150 if ( array_key_exists ( 'search', $_POST ) )
151 $search = $_POST['search']; // TODO: Add some sanitation and input validation!
152 $list = list_users( $search );
153 print json_encode( array( 'response' => 'ok', 'list' => $list ));
158 Required parameters should be...
159 ( username & domain ) | user
163 Verify that domain is local (lookup in the 'kamailio.domain' table.
164 Verify that the username is available (nonexistant for domain in kamilio.subscribers (and hermes.users?))
165 * Autocreate password
166 * Add username, domain, email and created password to the 'kamailio.subscriber' table
167 * Get the registrar+port, proxy+port from the 'hermes.servers' table.
168 * standard dialplan from configuration.
169 * Add to the 'hermes.users' table:
171 password -> generated password
172 displayname -> displayname
174 registrar -> hermes.servers.registrar
175 r_port -> hermes.servers.r_port
176 proxy -> hermes.servers.proxy
177 p_port -> hermes.servers.p_port
179 dialplan -> standard dialplan
181 * Return 'response' => 'ok' with a full user object in JSON format.
182 If any of the tests fail, return 'response' => 'failed' with 'cause' => "description" on JSON format.
185 // Test required parameters:
187 ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) ) ||
array_key_exists('user', $_POST) )
188 && array_key_exists( 'displayname', $_POST )
189 && array_key_exists( 'email', $_POST ) )
193 if ( array_key_exists('username', $_POST) )
195 $username = $_POST['username'];
196 $domain = $_POST['domain'];
200 $user = split_sipaddress($_POST['user']);
203 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
206 list ( $username, $domain ) = $user;
209 $password = generate_password();
210 $displayname = $_POST['displayname'];
211 $email = $_POST['email'];
213 if ( !is_kamailio_domain( $domain ) )
215 print json_encode ( array( 'response' => 'failed', 'cause' => 'nxdomain', 'detail' => 'The selected domain is not local' ));
219 $servers = get_servers( $domain );
222 print json_encode( array( 'response' => 'failed', 'cause' => 'servfail', 'detail' => 'Servers lookup failed for domain '. $domain ) );
225 $registrar = $servers['registrar'];
226 $r_port = $servers['r_port'];
227 $proxy = $servers['proxy'];
228 $p_port = $servers['p_port'];
230 $linetext = $username;
231 $dialplan = $config['standard_dialplan'];
233 if ( is_provision_user ( $username, $domain ) )
235 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' ));
238 if ( is_kamailio_subscriber ( $username, $domain ) )
240 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' ));
243 if ( alias_exists ( $username, $domain ) )
245 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'Username exists as an alias' ));
249 $kam_res = add_kamailio_subscriber( $username, $domain, $password, $email );
252 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add kamailio subscriber.' ) );
255 $pro_res = add_provision_user( $username, $password, $domain, $authid, $registrar, $r_port, $proxy, $p_port, $displayname, $dialplan, $linetext );
258 // Rollback data added to Kamailio! Try to simulate atomicity, or atleast maintain integrity...
259 delete_kamailio_subscriber( $username, $domain );
260 // Give errormessage, and quit.
261 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add user for provisioning. Rolled back kamailio subscriber' ) );
264 $userdata = get_userdata( $username, $domain );
267 // Rollback data added to Kamailio! Try to simulate atomicity, or atleast maintain integrity...
268 delete_kamailio_subscriber( $username, $domain );
269 delete_provision_user( $username, $domain );
270 // Give errormessage, and quit.
271 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to read recently added data. Operations rolled back' ) );
274 print json_encode( array( 'response' => 'ok', 'user' => $userdata ));
278 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
282 Required parameters should be...
283 ( username & domain ) | user
295 Verify that the domain is not a local kamailio domain (REMOTE user..)
296 Verify that the username+domain is not already registered in 'hermes.users'.
297 * If r_port is empty, set to 5060
298 * If proxy/port is empty, set to registrar/port
299 * If authid is empty, set to username
300 * If dialplan is empty, set to standard dialplan
301 * If linetext is empty, set to username@domain
302 * Add to the 'hermes.users' table:
304 password -> supplied password
305 displayname -> displayname
307 registrar -> registrar
314 * Return 'response' => 'ok' with a full user object in JSON format.
315 If any of the tests fail, return 'response' => 'failed' with 'cause' => "description" in JSON format.
319 // Test required parameters:
321 ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) ) ||
array_key_exists('user', $_POST) )
322 && array_key_exists( 'displayname', $_POST )
323 && array_key_exists( 'password', $_POST )
324 && array_key_exists( 'registrar', $_POST ) )
328 if ( array_key_exists('username', $_POST) )
330 $username = $_POST['username'];
331 $domain = $_POST['domain'];
335 $user = split_sipaddress($_POST['user']);
338 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
341 list ( $username, $domain ) = $user;
344 $password = $_POST['password'];
345 $displayname = $_POST['displayname'];
346 $registrar = $_POST['registrar'];
347 $r_port = ( array_key_exists('r_port', $_POST) ) ?
$_POST['r_port'] : 5060;
349 $proxy = ( array_key_exists('proxy', $_POST) ) ?
$_POST['proxy'] : $registrar;
350 $p_port = ( array_key_exists('p_port', $_POST) ) ?
$_POST['p_port'] : $r_port;
351 $authid = ( array_key_exists('authid', $_POST) ) ?
$_POST['authid'] : $username;
352 $dialplan = ( array_key_exists('dialplan', $_POST) ) ?
$_POST['dialplan'] : $config['standard_dialplan'];
353 $linetext = ( array_key_exists('linetext', $_POST) ) ?
$_POST['linetext'] : $username . '@' . $domain;
355 if ( is_kamailio_domain( $domain ) )
357 print json_encode ( array( 'response' => 'failed', 'cause' => 'domain', 'detail' => 'The selected domain is local, cannot add remote user' ));
361 if ( is_provision_user ( $username, $domain ) )
363 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' ));
366 if ( is_kamailio_subscriber ( $username, $domain ) )
368 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' ));
372 // Should be impossible to hit this test, all aliases are required to be local.
373 if ( alias_exists ( $username, $domain ) )
375 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'Username exists as an alias' ));
380 $pro_res = add_provision_user( $username, $password, $domain, $authid, $registrar, $r_port, $proxy, $p_port, $displayname, $dialplan, $linetext );
383 // Give errormessage, and quit.
384 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add user for provisioning.' ) );
387 $userdata = get_userdata( $username, $domain );
390 // Rollback data added!
391 delete_provision_user( $username, $domain );
392 // Give errormessage, and quit.
393 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to read recently added data. Operations rolled back' ) );
396 print json_encode( array( 'response' => 'ok', 'user' => $userdata ));
400 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
404 Required parameters should be...
405 ( username & domain ) | user
407 * Verify that no associations/relations exist in 'hermes.phones'
408 * Verify that the user exists in 'hermes.users'
409 * Remove from 'hermes.users'
410 * Test to see of user exists in 'kamailio.subscriber'.
411 * Remove from 'kamailio.subscribers'
412 * Return response' => 'ok', 'type' => 'local'
413 * If not in 'kamailio.subscribers'
414 * Return response' => 'ok', 'type' => 'remote'
415 * If associations exist, return 'response' => 'failed', 'cause' => 'inuse'
416 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
417 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
419 if ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
420 ||
array_key_exists('user', $_POST) )
425 if ( array_key_exists('username', $_POST) )
427 $username = $_POST['username'];
428 $domain = $_POST['domain'];
432 $user = split_sipaddress($_POST['user']);
435 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
438 list ( $username, $domain ) = $user;
441 if ( get_user_phones ( $username, $domain ) )
443 print json_encode( array( 'response' => 'failed', 'cause' => 'inuse', 'detail' => 'User has associated provisioning. Remove and retry.' ) );
446 if ( is_provision_user( $username, $domain ) ||
is_kamailio_subscriber( $username, $domain ) )
448 delete_provision_user( $username, $domain );
449 delete_kamailio_subscriber( $username, $domain );
450 print json_encode( array ( 'response' => 'ok', 'detail' => 'User ' . $username . '@' . $domain . ' deleted.'));
455 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => 'Unable to remove nonexistant user.'));
462 print json_encode ( array( 'response' => 'invalid') );
466 Required parameters should be...
467 ( username & domain ) | user
470 * Verify that no associations/relations exist in 'hermes.phones'
471 * Verify that the user exists ...
472 * Test to see of user exists in 'hermes.users'
473 * Test to see of user exists in 'kamailio.subscriber'.
474 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
475 * Update user passwords in 'hermes' and 'kamailio' as appropriate
476 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
478 if ( array_key_exists('password', $_POST) &&
479 ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
480 ||
array_key_exists('user', $_POST) ))
485 if ( array_key_exists('username', $_POST) )
487 $username = $_POST['username'];
488 $domain = $_POST['domain'];
492 $user = split_sipaddress($_POST['user']);
495 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
498 list ( $username, $domain ) = $user;
500 $password = $_POST['password'];
502 // Check compatibility of password? TODO...
503 // Fetch old password for rollback? TODO...
504 // Verify that user exists for provisioning
505 if ( ! is_provision_user( $username, $domain ) )
507 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => '' . $username . '@' . $domain . ' does not exist.'));
510 if ( is_provision_user( $username, $domain ) )
512 // Update provisioning password
513 if ( update_provision_pw( $username, $domain, $password ) < 0 )
515 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update provisioning password' ) );
519 // Check for user in kamailio
520 if ( is_kamailio_subscriber( $username, $domain ) )
522 // Update kamailio password
523 if ( update_kamailio_pw( $username, $domain, $password ) < 0 )
525 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update kamailio password' ) );
529 print json_encode( array ( 'response' => 'ok', 'detail' => 'Password changed for user '.$username.'@'.$domain.'.'));
533 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
537 case "/change_email":
539 Required parameters should be...
540 ( username & domain ) | user
543 if ( array_key_exists('email', $_POST) &&
544 ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
545 ||
array_key_exists('user', $_POST) ))
550 if ( array_key_exists('username', $_POST) )
552 $username = $_POST['username'];
553 $domain = $_POST['domain'];
557 $user = split_sipaddress($_POST['user']);
560 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
563 list ( $username, $domain ) = $user;
565 $email = $_POST['email'];
567 // Check for user in kamailio
568 if ( is_kamailio_subscriber( $username, $domain ) )
570 // Update kamailio email
571 if ( update_kamailio_email( $username, $domain, $email ) < 0 )
573 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update kamailio email' ) );
577 print json_encode( array ( 'response' => 'ok', 'user' => $username.'@'.$domain, 'email' => $email));
581 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
592 Required parameters should be...
593 ( username & domain ) | user
595 * Verify that no associations/relations exist in 'hermes.phones'
596 * Verify that the user exists ...
597 * Test to see of user exists in 'hermes.users'
598 * Test to see of user exists in 'kamailio.subscriber'.
599 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
600 * Get update parameters, and change as appropriate ;)
601 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
603 if ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
604 ||
array_key_exists('user', $_POST) )
609 if ( array_key_exists('username', $_POST) )
611 $username = $_POST['username'];
612 $domain = $_POST['domain'];
616 $user = split_sipaddress($_POST['user']);
619 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
622 list ( $username, $domain ) = $user;
624 if ( ! is_provision_user ( $username, $domain ) )
626 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => '' . $username . '@' . $domain . ' does not exist.'));
633 $params = array('displayname', 'dialplan', 'linetext', 'registrar', 'r_port', 'proxy', 'p_port');
634 foreach ( $params as $p )
636 if ( array_key_exists($p, $_POST ) )
639 $t = update_provision_data($p, $username, $domain, $data);
643 array_push($failed, $p);
647 array_push( $updated, $p);
652 if ( ( $error == 1 ) ||
( $error == 0 ) )
654 $res['response'] = 'ok';
655 $res['skipped'] = $failed;
657 else if ( $error == -1 )
659 $res['response'] = 'failed';
660 $res['cause'] = 'param';
661 $res['detail'] = 'Invalid parameters';
662 $res['failed'] = $failed;
664 else if ( $error == -2 )
666 $res['response'] = 'failed';
667 $res['cause'] = 'dbfail';
668 $res['detail'] = 'Database failure';
669 $res['failed'] = $failed;
672 $res['response'] = 'error'; // Wait, what?
674 $res['updated'] = $updated;
676 print json_encode ( $res );
679 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
682 if ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
683 ||
array_key_exists('user', $_POST) )
688 if ( array_key_exists('username', $_POST) )
690 $username = $_POST['username'];
691 $domain = $_POST['domain'];
695 $user = split_sipaddress($_POST['user']);
698 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
701 list ( $username, $domain ) = $user;
703 if ( is_provision_user ( $username, $domain ) )
705 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' ));
708 if ( is_kamailio_subscriber ( $username, $domain ) )
710 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' ));
713 if ( alias_exists ( $username, $domain ) )
715 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'Username exists as an alias' ));
718 print json_encode( array ( 'response' => 'ok', 'cause' => 'nonexistant', 'detail' => '' . $username . '@' . $domain . ' does not exist.'));
722 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
725 print generate_password();
728 print json_encode ( array( 'response' => 'invalid') );
730 mysql_close( $config['sql_link'] );