]>
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 Simply list all users in user@domain format
107 Perform a search operation if 'search' exists as a GET-parameter
108 * The search should try to do a "smart search" on SIP-usernames:
109 * Try to search with names in in username@domain format
110 * Do the search with wildcards before and after input text.
111 * The search must be done in the provisioning tables, to be able
112 to match non-local users.
113 * SQL SELECT CONCAT() WHERE CONCAT() must be used *shrug*
116 if ( array_key_exists ( 'search', $_POST ) )
117 $search = $_POST['search']; // TODO: Add some sanitation and input validation!
118 $list = list_users( $search );
119 print json_encode( array( 'response' => 'ok', 'list' => $list ));
124 Required parameters should be...
125 ( username & domain ) | user
129 Verify that domain is local (lookup in the 'kamailio.domain' table.
130 Verify that the username is available (nonexistant for domain in kamilio.subscribers (and hermes.users?))
131 * Autocreate password
132 * Add username, domain, email and created password to the 'kamailio.subscriber' table
133 * Get the registrar+port, proxy+port from the 'hermes.servers' table.
134 * standard dialplan from configuration.
135 * Add to the 'hermes.users' table:
137 password -> generated password
138 displayname -> displayname
140 registrar -> hermes.servers.registrar
141 r_port -> hermes.servers.r_port
142 proxy -> hermes.servers.proxy
143 p_port -> hermes.servers.p_port
145 dialplan -> standard dialplan
147 * Return 'response' => 'ok' with a full user object in JSON format.
148 If any of the tests fail, return 'response' => 'failed' with 'cause' => "description" on JSON format.
151 // Test required parameters:
153 ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) ) ||
array_key_exists('user', $_POST) )
154 && array_key_exists( 'displayname', $_POST )
155 && array_key_exists( 'email', $_POST ) )
159 if ( array_key_exists('username', $_POST) )
161 $username = $_POST['username'];
162 $domain = $_POST['domain'];
166 $user = split_sipaddress($_POST['user']);
169 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
172 list ( $username, $domain ) = $user;
175 $password = generate_password();
176 $displayname = $_POST['displayname'];
177 $email = $_POST['email'];
179 if ( !is_kamailio_domain( $domain ) )
181 print json_encode ( array( 'response' => 'failed', 'cause' => 'nxdomain', 'detail' => 'The selected domain is not local' ));
185 $servers = get_servers( $domain );
188 print json_encode( array( 'response' => 'failed', 'cause' => 'servfail', 'detail' => 'Servers lookup failed for domain '. $domain ) );
191 $registrar = $servers['registrar'];
192 $r_port = $servers['r_port'];
193 $proxy = $servers['proxy'];
194 $p_port = $servers['p_port'];
196 $linetext = $username;
197 $dialplan = $config['standard_dialplan'];
199 if ( is_provision_user ( $username, $domain ) )
201 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' ));
204 if ( is_kamailio_subscriber ( $username, $domain ) )
206 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' ));
209 if ( alias_exists ( $username, $domain ) )
211 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'Username exists as an alias' ));
215 $kam_res = add_kamailio_subscriber( $username, $domain, $password, $email );
218 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add kamailio subscriber.' ) );
221 $pro_res = add_provision_user( $username, $password, $domain, $authid, $registrar, $r_port, $proxy, $p_port, $displayname, $dialplan, $linetext );
224 // Rollback data added to Kamailio! Try to simulate atomicity, or atleast maintain integrity...
225 delete_kamailio_subscriber( $username, $domain );
226 // Give errormessage, and quit.
227 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add user for provisioning. Rolled back kamailio subscriber' ) );
230 $userdata = get_userdata( $username, $domain );
233 // Rollback data added to Kamailio! Try to simulate atomicity, or atleast maintain integrity...
234 delete_kamailio_subscriber( $username, $domain );
235 delete_provision_user( $username, $domain );
236 // Give errormessage, and quit.
237 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to read recently added data. Operations rolled back' ) );
240 print json_encode( array( 'response' => 'ok', 'user' => $userdata ));
243 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
247 Required parameters should be...
248 ( username & domain ) | user
260 Verify that the domain is not a local kamailio domain (REMOTE user..)
261 Verify that the username+domain is not already registered in 'hermes.users'.
262 * If r_port is empty, set to 5060
263 * If proxy/port is empty, set to registrar/port
264 * If authid is empty, set to username
265 * If dialplan is empty, set to standard dialplan
266 * If linetext is empty, set to username@domain
267 * Add to the 'hermes.users' table:
269 password -> supplied password
270 displayname -> displayname
272 registrar -> registrar
279 * Return 'response' => 'ok' with a full user object in JSON format.
280 If any of the tests fail, return 'response' => 'failed' with 'cause' => "description" in JSON format.
284 // Test required parameters:
286 ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) ) ||
array_key_exists('user', $_POST) )
287 && array_key_exists( 'displayname', $_POST )
288 && array_key_exists( 'password', $_POST )
289 && array_key_exists( 'registrar', $_POST ) )
293 if ( array_key_exists('username', $_POST) )
295 $username = $_POST['username'];
296 $domain = $_POST['domain'];
300 $user = split_sipaddress($_POST['user']);
303 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
306 list ( $username, $domain ) = $user;
309 $password = $_POST['password'];
310 $displayname = $_POST['displayname'];
311 $registrar = $_POST['registrar'];
312 $r_port = ( array_key_exists('r_port', $_POST) ) ?
$_POST['r_port'] : 5060;
314 $proxy = ( array_key_exists('proxy', $_POST) ) ?
$_POST['proxy'] : $registrar;
315 $p_port = ( array_key_exists('p_port', $_POST) ) ?
$_POST['p_port'] : $r_port;
316 $authid = ( array_key_exists('authid', $_POST) ) ?
$_POST['authid'] : $username;
317 $dialplan = ( array_key_exists('dialplan', $_POST) ) ?
$_POST['dialplan'] : $config['standard_dialplan'];
318 $linetext = ( array_key_exists('linetext', $_POST) ) ?
$_POST['linetext'] : $username . '@' . $domain;
320 if ( is_kamailio_domain( $domain ) )
322 print json_encode ( array( 'response' => 'failed', 'cause' => 'domain', 'detail' => 'The selected domain is local, cannot add remote user' ));
326 if ( is_provision_user ( $username, $domain ) )
328 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' ));
331 if ( is_kamailio_subscriber ( $username, $domain ) )
333 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' ));
337 // Should be impossible to hit this test, all aliases are required to be local.
338 if ( alias_exists ( $username, $domain ) )
340 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'Username exists as an alias' ));
345 $pro_res = add_provision_user( $username, $password, $domain, $authid, $registrar, $r_port, $proxy, $p_port, $displayname, $dialplan, $linetext );
348 // Give errormessage, and quit.
349 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add user for provisioning.' ) );
352 $userdata = get_userdata( $username, $domain );
355 // Rollback data added!
356 delete_provision_user( $username, $domain );
357 // Give errormessage, and quit.
358 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to read recently added data. Operations rolled back' ) );
361 print json_encode( array( 'response' => 'ok', 'user' => $userdata ));
364 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
368 Required parameters should be...
369 ( username & domain ) | user
371 * Verify that no associations/relations exist in 'hermes.phones'
372 * Verify that the user exists in 'hermes.users'
373 * Remove from 'hermes.users'
374 * Test to see of user exists in 'kamailio.subscriber'.
375 * Remove from 'kamailio.subscribers'
376 * Return response' => 'ok', 'type' => 'local'
377 * If not in 'kamailio.subscribers'
378 * Return response' => 'ok', 'type' => 'remote'
379 * If associations exist, return 'response' => 'failed', 'cause' => 'inuse'
380 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
381 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
383 if ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
384 ||
array_key_exists('user', $_POST) )
389 if ( array_key_exists('username', $_POST) )
391 $username = $_POST['username'];
392 $domain = $_POST['domain'];
396 $user = split_sipaddress($_POST['user']);
399 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
402 list ( $username, $domain ) = $user;
405 if ( get_user_phones ( $username, $domain ) )
407 print json_encode( array( 'response' => 'failed', 'cause' => 'inuse', 'detail' => 'User has associated provisioning. Remove and retry.' ) );
410 if ( is_provision_user( $username, $domain ) ||
is_kamailio_subscriber( $username, $domain ) )
412 delete_provision_user( $username, $domain );
413 delete_kamailio_subscriber( $username, $domain );
414 print json_encode( array ( 'response' => 'ok', 'detail' => 'User ' . $username . '@' . $domain . ' deleted.'));
419 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => 'Unable to remove nonexistant user.'));
426 print json_encode ( array( 'response' => 'invalid') );
430 Required parameters should be...
431 ( username & domain ) | user
434 * Verify that no associations/relations exist in 'hermes.phones'
435 * Verify that the user exists ...
436 * Test to see of user exists in 'hermes.users'
437 * Test to see of user exists in 'kamailio.subscriber'.
438 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
439 * Update user passwords in 'hermes' and 'kamailio' as appropriate
440 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
442 if ( array_key_exists('password', $_POST) &&
443 ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
444 ||
array_key_exists('user', $_POST) ))
449 if ( array_key_exists('username', $_POST) )
451 $username = $_POST['username'];
452 $domain = $_POST['domain'];
456 $user = split_sipaddress($_POST['user']);
459 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
462 list ( $username, $domain ) = $user;
464 $password = $_POST['password'];
466 // Check compatibility of password? TODO...
467 // Fetch old password for rollback? TODO...
468 // Verify that user exists for provisioning
469 if ( ! is_provision_user( $username, $domain ) )
471 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => '' . $username . '@' . $domain . ' does not exist.'));
474 if ( is_provision_user( $username, $domain ) )
476 // Update provisioning password
477 if ( update_provision_pw( $username, $domain, $password ) < 0 )
479 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update provisioning password' ) );
483 // Check for user in kamailio
484 if ( is_kamailio_subscriber( $username, $domain ) )
486 // Update kamailio password
487 if ( update_kamailio_pw( $username, $domain, $password ) < 0 )
489 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update kamailio password' ) );
493 print json_encode( array ( 'response' => 'ok', 'detail' => 'Password changed for user '.$username.'@'.$domain.'.'));
497 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
501 case "/change_email":
503 Required parameters should be...
504 ( username & domain ) | user
507 if ( array_key_exists('email', $_POST) &&
508 ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
509 ||
array_key_exists('user', $_POST) ))
514 if ( array_key_exists('username', $_POST) )
516 $username = $_POST['username'];
517 $domain = $_POST['domain'];
521 $user = split_sipaddress($_POST['user']);
524 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
527 list ( $username, $domain ) = $user;
529 $email = $_POST['email'];
531 // Check for user in kamailio
532 if ( is_kamailio_subscriber( $username, $domain ) )
534 // Update kamailio email
535 if ( update_kamailio_email( $username, $domain, $email ) < 0 )
537 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update kamailio email' ) );
541 print json_encode( array ( 'response' => 'ok', 'user' => $username.'@'.$domain, 'email' => $email));
545 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
556 Required parameters should be...
557 ( username & domain ) | user
559 * Verify that no associations/relations exist in 'hermes.phones'
560 * Verify that the user exists ...
561 * Test to see of user exists in 'hermes.users'
562 * Test to see of user exists in 'kamailio.subscriber'.
563 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
564 * Get update parameters, and change as appropriate ;)
565 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
567 if ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
568 ||
array_key_exists('user', $_POST) )
573 if ( array_key_exists('username', $_POST) )
575 $username = $_POST['username'];
576 $domain = $_POST['domain'];
580 $user = split_sipaddress($_POST['user']);
583 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
586 list ( $username, $domain ) = $user;
588 if ( ! is_provision_user ( $username, $domain ) )
590 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => '' . $username . '@' . $domain . ' does not exist.'));
597 $params = array('displayname', 'dialplan', 'linetext', 'registrar', 'r_port', 'proxy', 'p_port');
598 foreach ( $params as $p )
600 if ( array_key_exists($p, $_POST ) )
603 $t = update_provision_data($p, $username, $domain, $data);
607 array_push($failed, $p);
611 array_push( $updated, $p);
616 if ( ( $error == 1 ) ||
( $error == 0 ) )
618 $res['response'] = 'ok';
619 $res['skipped'] = $failed;
621 else if ( $error == -1 )
623 $res['response'] = 'failed';
624 $res['cause'] = 'param';
625 $res['detail'] = 'Invalid parameters';
626 $res['failed'] = $failed;
628 else if ( $error == -2 )
630 $res['response'] = 'failed';
631 $res['cause'] = 'dbfail';
632 $res['detail'] = 'Database failure';
633 $res['failed'] = $failed;
636 $res['response'] = 'error'; // Wait, what?
638 $res['updated'] = $updated;
640 print json_encode ( $res );
643 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
646 if ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
647 ||
array_key_exists('user', $_POST) )
652 if ( array_key_exists('username', $_POST) )
654 $username = $_POST['username'];
655 $domain = $_POST['domain'];
659 $user = split_sipaddress($_POST['user']);
662 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
665 list ( $username, $domain ) = $user;
667 if ( is_provision_user ( $username, $domain ) )
669 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' ));
672 if ( is_kamailio_subscriber ( $username, $domain ) )
674 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' ));
677 if ( alias_exists ( $username, $domain ) )
679 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'Username exists as an alias' ));
682 print json_encode( array ( 'response' => 'ok', 'cause' => 'nonexistant', 'detail' => '' . $username . '@' . $domain . ' does not exist.'));
686 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
689 print generate_password();
692 print json_encode ( array( 'response' => 'invalid') );
694 mysql_close( $config['sql_link'] );