]>
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 ));
244 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
248 Required parameters should be...
249 ( username & domain ) | user
261 Verify that the domain is not a local kamailio domain (REMOTE user..)
262 Verify that the username+domain is not already registered in 'hermes.users'.
263 * If r_port is empty, set to 5060
264 * If proxy/port is empty, set to registrar/port
265 * If authid is empty, set to username
266 * If dialplan is empty, set to standard dialplan
267 * If linetext is empty, set to username@domain
268 * Add to the 'hermes.users' table:
270 password -> supplied password
271 displayname -> displayname
273 registrar -> registrar
280 * Return 'response' => 'ok' with a full user object in JSON format.
281 If any of the tests fail, return 'response' => 'failed' with 'cause' => "description" in JSON format.
285 // Test required parameters:
287 ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) ) ||
array_key_exists('user', $_POST) )
288 && array_key_exists( 'displayname', $_POST )
289 && array_key_exists( 'password', $_POST )
290 && array_key_exists( 'registrar', $_POST ) )
294 if ( array_key_exists('username', $_POST) )
296 $username = $_POST['username'];
297 $domain = $_POST['domain'];
301 $user = split_sipaddress($_POST['user']);
304 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
307 list ( $username, $domain ) = $user;
310 $password = $_POST['password'];
311 $displayname = $_POST['displayname'];
312 $registrar = $_POST['registrar'];
313 $r_port = ( array_key_exists('r_port', $_POST) ) ?
$_POST['r_port'] : 5060;
315 $proxy = ( array_key_exists('proxy', $_POST) ) ?
$_POST['proxy'] : $registrar;
316 $p_port = ( array_key_exists('p_port', $_POST) ) ?
$_POST['p_port'] : $r_port;
317 $authid = ( array_key_exists('authid', $_POST) ) ?
$_POST['authid'] : $username;
318 $dialplan = ( array_key_exists('dialplan', $_POST) ) ?
$_POST['dialplan'] : $config['standard_dialplan'];
319 $linetext = ( array_key_exists('linetext', $_POST) ) ?
$_POST['linetext'] : $username . '@' . $domain;
321 if ( is_kamailio_domain( $domain ) )
323 print json_encode ( array( 'response' => 'failed', 'cause' => 'domain', 'detail' => 'The selected domain is local, cannot add remote user' ));
327 if ( is_provision_user ( $username, $domain ) )
329 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' ));
332 if ( is_kamailio_subscriber ( $username, $domain ) )
334 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' ));
338 // Should be impossible to hit this test, all aliases are required to be local.
339 if ( alias_exists ( $username, $domain ) )
341 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'Username exists as an alias' ));
346 $pro_res = add_provision_user( $username, $password, $domain, $authid, $registrar, $r_port, $proxy, $p_port, $displayname, $dialplan, $linetext );
349 // Give errormessage, and quit.
350 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to add user for provisioning.' ) );
353 $userdata = get_userdata( $username, $domain );
356 // Rollback data added!
357 delete_provision_user( $username, $domain );
358 // Give errormessage, and quit.
359 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to read recently added data. Operations rolled back' ) );
362 print json_encode( array( 'response' => 'ok', 'user' => $userdata ));
366 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
370 Required parameters should be...
371 ( username & domain ) | user
373 * Verify that no associations/relations exist in 'hermes.phones'
374 * Verify that the user exists in 'hermes.users'
375 * Remove from 'hermes.users'
376 * Test to see of user exists in 'kamailio.subscriber'.
377 * Remove from 'kamailio.subscribers'
378 * Return response' => 'ok', 'type' => 'local'
379 * If not in 'kamailio.subscribers'
380 * Return response' => 'ok', 'type' => 'remote'
381 * If associations exist, return 'response' => 'failed', 'cause' => 'inuse'
382 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
383 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
385 if ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
386 ||
array_key_exists('user', $_POST) )
391 if ( array_key_exists('username', $_POST) )
393 $username = $_POST['username'];
394 $domain = $_POST['domain'];
398 $user = split_sipaddress($_POST['user']);
401 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
404 list ( $username, $domain ) = $user;
407 if ( get_user_phones ( $username, $domain ) )
409 print json_encode( array( 'response' => 'failed', 'cause' => 'inuse', 'detail' => 'User has associated provisioning. Remove and retry.' ) );
412 if ( is_provision_user( $username, $domain ) ||
is_kamailio_subscriber( $username, $domain ) )
414 delete_provision_user( $username, $domain );
415 delete_kamailio_subscriber( $username, $domain );
416 print json_encode( array ( 'response' => 'ok', 'detail' => 'User ' . $username . '@' . $domain . ' deleted.'));
421 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => 'Unable to remove nonexistant user.'));
428 print json_encode ( array( 'response' => 'invalid') );
432 Required parameters should be...
433 ( username & domain ) | user
436 * Verify that no associations/relations exist in 'hermes.phones'
437 * Verify that the user exists ...
438 * Test to see of user exists in 'hermes.users'
439 * Test to see of user exists in 'kamailio.subscriber'.
440 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
441 * Update user passwords in 'hermes' and 'kamailio' as appropriate
442 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
444 if ( array_key_exists('password', $_POST) &&
445 ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
446 ||
array_key_exists('user', $_POST) ))
451 if ( array_key_exists('username', $_POST) )
453 $username = $_POST['username'];
454 $domain = $_POST['domain'];
458 $user = split_sipaddress($_POST['user']);
461 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
464 list ( $username, $domain ) = $user;
466 $password = $_POST['password'];
468 // Check compatibility of password? TODO...
469 // Fetch old password for rollback? TODO...
470 // Verify that user exists for provisioning
471 if ( ! is_provision_user( $username, $domain ) )
473 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => '' . $username . '@' . $domain . ' does not exist.'));
476 if ( is_provision_user( $username, $domain ) )
478 // Update provisioning password
479 if ( update_provision_pw( $username, $domain, $password ) < 0 )
481 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update provisioning password' ) );
485 // Check for user in kamailio
486 if ( is_kamailio_subscriber( $username, $domain ) )
488 // Update kamailio password
489 if ( update_kamailio_pw( $username, $domain, $password ) < 0 )
491 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update kamailio password' ) );
495 print json_encode( array ( 'response' => 'ok', 'detail' => 'Password changed for user '.$username.'@'.$domain.'.'));
499 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
503 case "/change_email":
505 Required parameters should be...
506 ( username & domain ) | user
509 if ( array_key_exists('email', $_POST) &&
510 ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
511 ||
array_key_exists('user', $_POST) ))
516 if ( array_key_exists('username', $_POST) )
518 $username = $_POST['username'];
519 $domain = $_POST['domain'];
523 $user = split_sipaddress($_POST['user']);
526 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
529 list ( $username, $domain ) = $user;
531 $email = $_POST['email'];
533 // Check for user in kamailio
534 if ( is_kamailio_subscriber( $username, $domain ) )
536 // Update kamailio email
537 if ( update_kamailio_email( $username, $domain, $email ) < 0 )
539 print json_encode( array( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Failed to update kamailio email' ) );
543 print json_encode( array ( 'response' => 'ok', 'user' => $username.'@'.$domain, 'email' => $email));
547 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
558 Required parameters should be...
559 ( username & domain ) | user
561 * Verify that no associations/relations exist in 'hermes.phones'
562 * Verify that the user exists ...
563 * Test to see of user exists in 'hermes.users'
564 * Test to see of user exists in 'kamailio.subscriber'.
565 * If no such user exists, return 'response' => 'failed' with 'cause' => 'nonexistant'
566 * Get update parameters, and change as appropriate ;)
567 * On other failures, return 'response' => 'failed' with 'cause' => 'error' (may set 'detail' => 'message')
569 if ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
570 ||
array_key_exists('user', $_POST) )
575 if ( array_key_exists('username', $_POST) )
577 $username = $_POST['username'];
578 $domain = $_POST['domain'];
582 $user = split_sipaddress($_POST['user']);
585 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
588 list ( $username, $domain ) = $user;
590 if ( ! is_provision_user ( $username, $domain ) )
592 print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => '' . $username . '@' . $domain . ' does not exist.'));
599 $params = array('displayname', 'dialplan', 'linetext', 'registrar', 'r_port', 'proxy', 'p_port');
600 foreach ( $params as $p )
602 if ( array_key_exists($p, $_POST ) )
605 $t = update_provision_data($p, $username, $domain, $data);
609 array_push($failed, $p);
613 array_push( $updated, $p);
618 if ( ( $error == 1 ) ||
( $error == 0 ) )
620 $res['response'] = 'ok';
621 $res['skipped'] = $failed;
623 else if ( $error == -1 )
625 $res['response'] = 'failed';
626 $res['cause'] = 'param';
627 $res['detail'] = 'Invalid parameters';
628 $res['failed'] = $failed;
630 else if ( $error == -2 )
632 $res['response'] = 'failed';
633 $res['cause'] = 'dbfail';
634 $res['detail'] = 'Database failure';
635 $res['failed'] = $failed;
638 $res['response'] = 'error'; // Wait, what?
640 $res['updated'] = $updated;
642 print json_encode ( $res );
645 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
648 if ( ( array_key_exists( 'username', $_POST) && array_key_exists( 'domain', $_POST ) )
649 ||
array_key_exists('user', $_POST) )
654 if ( array_key_exists('username', $_POST) )
656 $username = $_POST['username'];
657 $domain = $_POST['domain'];
661 $user = split_sipaddress($_POST['user']);
664 print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
667 list ( $username, $domain ) = $user;
669 if ( is_provision_user ( $username, $domain ) )
671 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists in provisioning configuration' ));
674 if ( is_kamailio_subscriber ( $username, $domain ) )
676 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'User already exists as a Kamailio subscriber' ));
679 if ( alias_exists ( $username, $domain ) )
681 print json_encode ( array( 'response' => 'failed', 'cause' => 'exists', 'detail' => 'Username exists as an alias' ));
684 print json_encode( array ( 'response' => 'ok', 'cause' => 'nonexistant', 'detail' => '' . $username . '@' . $domain . ' does not exist.'));
688 print json_encode( array( 'response' => 'invalid', 'cause' => 'parameters' ) );
691 print generate_password();
694 print json_encode ( array( 'response' => 'invalid') );
696 mysql_close( $config['sql_link'] );