--- /dev/null
+<?php
+/*
+# Copyright (c) 2012, Gjøvik University College
+# All rights reserved.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the Gjøvik University College nor the
+# names of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY Gjøvik University College ''AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL Gjøvik University College BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+require_once('config.php');
+require_once('lib/common_functions.php');
+require_once('lib/db_functions.php');
+require_once('lib/user_functions.php');
+
+function get_permission ( $username, $domain )
+{
+ global $config;
+
+ if ( ! is_kamailio_subscriber( $username, $domain ) )
+ return -1;
+
+ $query = sprintf("SELECT permittedcalls FROM %s"
+ . " WHERE username = '%s' AND domain = '%s'",
+ $config['kamailio_subscriber_table'],
+ sql_clean($username),
+ sql_clean($domain));
+
+ $result = sql_dbquery( $config['kamailio_db'], $query);
+ // If result is empty, there was either an SQL error, or simply no results.
+ if ( ! $result ) return -2;
+
+ $row = @mysql_fetch_assoc( $result );
+ return $row['permittedcalls'];
+}
+
+function set_permission ( $username, $domain, $permission )
+{
+ global $config;
+
+ if ( ! is_kamailio_subscriber( $username, $domain ) )
+ return -1;
+
+ $query = sprintf("UPDATE %s SET permittedcalls = %d"
+ . " WHERE username = '%s' AND domain = '%s'",
+ $config['kamailio_subscriber_table'],
+ sql_clean($permission),
+ sql_clean($username),
+ sql_clean($domain));
+
+ $result = sql_dbquery( $config['kamailio_db'], $query);
+ // If result is empty, there was either an SQL error, or simply no results.
+ if ( ! $result ) return 0;
+
+ return 1;
+}
+
+
--- /dev/null
+<?php
+/*
+# Copyright (c) 2012, Gjøvik University College
+# All rights reserved.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the Gjøvik University College nor the
+# names of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY Gjøvik University College ''AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL Gjøvik University College BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+require_once('config.php');
+require_once('lib/auth_base.php');
+require_once('lib/common_functions.php');
+require_once('lib/db_functions.php');
+require_once('lib/permission_functions.php');
+
+$config = get_config();
+
+$config['sql_link'] = @mysql_connect(
+ $config['sql_server'],
+ $config['sql_username'],
+ $config['sql_password']
+);
+if ( !$config['sql_link'] )
+{
+ print json_encode( array( 'response' => 'failed', 'cause' => 'error', 'detail' => 'Database connection failed.'));
+ exit;
+}
+token_auth();
+
+
+//*************************************************************************************
+ 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', $_POST) ||
+ ( array_key_exists('username', $_POST) && array_key_exists('domain', $_POST )))
+ {
+ $username = "";
+ $domain = "";
+ if ( array_key_exists('username', $_POST) )
+ {
+ $username = $_POST['username'];
+ $domain = $_POST['domain'];
+ }
+ else
+ {
+ $user = split_sipaddress($_POST['user']);
+ if ( !$user )
+ {
+ print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
+ break;
+ }
+ list ( $username, $domain ) = $user;
+ }
+
+ // Dummy-response:
+ $permission = get_permission( $username, $domain );
+ if ( $permission > -1 )
+ {
+ print json_encode( array( 'response' => 'ok', 'permission' => $permission ));
+ }
+ else
+ {
+ if ( $permission == -1 )
+ print json_encode( array ( 'response' => 'failed', 'cause' => 'nonexistant', 'detail' => 'User does not exist.'));
+ else
+ print json_encode( array ( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Database lookup failed.'));
+ }
+ }
+ else
+ print json_encode ( array( 'response' => 'invalid') );
+ break;
+
+ case "/set":
+ // 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('permission', $_POST ) &&
+ ( array_key_exists('user', $_POST) ||
+ ( array_key_exists('username', $_POST) && array_key_exists('domain', $_POST ))) )
+ {
+ $permission = 0;
+ $username = "";
+ $domain = "";
+ if ( array_key_exists('permission', $_POST) )
+ $permission = $_POST['permission'];
+
+ if ( array_key_exists('username', $_POST) )
+ {
+ $username = $_POST['username'];
+ $domain = $_POST['domain'];
+ }
+ else
+ {
+ $user = split_sipaddress($_POST['user']);
+ if ( !$user )
+ {
+ print json_encode ( array( 'response' => 'failed', 'cause' => 'invalid', 'detail' => 'Invalid SIP address') );
+ break;
+ }
+ list ( $username, $domain ) = $user;
+ }
+
+ // Dummy-response:
+ $result = set_permission( $username, $domain, $permission );
+ if ( $result == 1 )
+ {
+ print json_encode( array( 'response' => 'ok', 'permission' => $permission ));
+ }
+ else
+ {
+ print json_encode( array ( 'response' => 'failed', 'cause' => 'dbfail', 'detail' => 'Update query to database failed.'));
+ }
+ }
+ else
+ print json_encode ( array( 'response' => 'invalid') );
+ break;
+
+
+ default:
+ print json_encode ( array( 'response' => 'invalid') );
+ }
+mysql_close( $config['sql_link'] );
+?>
--- /dev/null
+#!/usr/bin/perl
+# Copyright (c) 2012, Gjøvik University College
+# All rights reserved.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the Gjøvik University College nor the
+# names of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY Gjøvik University College ''AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL Gjøvik University College BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+use strict;
+use Test::More 'no_plan';
+use tests_common;
+
+my ($data, $temp, $test_domain );
+
+isa_ok( $g_ua, 'LWP::UserAgent', '$g_ua');
+isa_ok( $g_ua->cookie_jar, 'HTTP::Cookies', '$g_ua->cookies');
+
+login_apikey();
+
+# First: fetch a supported domain from the API...
+$data = exec_apinode("domain/list", undef);
+ok($data, 'domain/list JSON decode');
+is( $data->{'response'}, 'ok', 'domain/list result');
+ok($data->{'list'}, 'domain/list array');
+
+# NOW: Set the $test_domain to something useful (i.e. the first reported domain)
+$test_domain = $data->{'list'}[0];
+
+ok($test_domain, 'test_domain set.');
+undef $data;
+
+$data = exec_apinode("user/available", { "user" => $test_username . "\@" . $test_domain });
+is( $data->{'response'}, 'ok', 'user/available is available');
+undef $data;
+
+$data = exec_apinode("permissions/get", { "user" => $test_username . "\@" . $test_domain });
+is( $data->{'response'}, 'failed', 'permissions/get returns failed');
+is( $data->{'cause'}, 'nonexistant', 'permissions/get gives nonexistant');
+undef $data;
+
+$data = exec_apinode("user/add_local", {
+ "user" => $test_username . "\@" . $test_domain,
+ "displayname" => "Automatic testing",
+ "email" => "noreply\@" . $test_domain,
+} );
+is( $data->{'response'}, 'ok', 'user/add_local created new account');
+undef $data;
+
+$data = exec_apinode("permissions/get", { "user" => $test_username . "\@" . $test_domain });
+is( $data->{'response'}, 'ok', 'permissions/get returns');
+ok( $data->{'permission'}, 'permissions/get is set');
+isnt( $data->{'permission'}, -1, 'permissions/get is not -1');
+undef $data;
+
+$data = exec_apinode("permissions/set", { "user" => $test_username . "\@" . $test_domain, "permission" => 31 });
+is( $data->{'response'}, 'ok', 'permissions/set returns');
+is( $data->{'permission'}, 31, 'permissions/set is 31');
+undef $data;
+
+$data = exec_apinode("permissions/get", { "user" => $test_username . "\@" . $test_domain });
+is( $data->{'response'}, 'ok', 'permissions/get returns');
+ok( $data->{'permission'}, 'permissions/get is set');
+is( $data->{'permission'}, 31, 'permissions/get is 31');
+undef $data;
+
+$data = exec_apinode("user/remove", { "user" => $test_username . "\@" . $test_domain });
+is( $data->{'response'}, 'ok', 'user/remove deleted user');
+undef $data;
+
+$data = exec_apinode("permissions/get", { "user" => $test_username . "\@" . $test_domain });
+is( $data->{'response'}, 'failed', 'permissions/get return failed');
+undef $data;
+
+logout();
'description' contains a text describing the actual fail.
Return 'failed' with 'cause' = 'error' on database failure.
+permission/get
+-------------------
+ Required:
+ user=foo@bar.bz *
+
+ Description:
+ Gets the permissions value for a user, with no parsing.
+ The permission system is based on bit-flags, with the following values:
+ NOCALLS 1
+ EMERGENCY 2
+ INTERNAL 4
+ VOIP 8
+ NATIONAL 16
+ SERVICES 32
+ INTERNATIONAL 64
+ OTHERS 128
+ The user must match a valid user registration.
+
+ Return:
+ Returns 'permission' set to the applied permission value on success.
+ Returns 'failed' with 'cause' = 'nonexistant' if user does not exist..
+ Returns 'failed' with 'cause' = 'dbfail' on database failure.
+
+
+permission/set
+-------------------
+ Required:
+ user=foo@bar.bz *
+ permission=63
+
+ Description:
+ Sets the permissions value for a user directly. The permission
+ system is based on bit-flags, with the following values:
+ NOCALLS 1
+ EMERGENCY 2
+ INTERNAL 4
+ VOIP 8
+ NATIONAL 16
+ SERVICES 32
+ INTERNATIONAL 64
+ OTHERS 128
+ To give a subscriber full permissions, set permission to 255.
+ To give a subscriber National calls, all internal and VOIP
+ calls, but not international, sat-phones and other, use 63.
+ To give a user emergency and internal, but no other calls,
+ the permission value becomes 7.
+ The user must match a valid user registration.
+
+ Return:
+ Returns 'permission' set to the applied permission value on success.
+ Returns 'failed' with 'cause' = 'dbfail' on database failure.
+
+
BUGS:
---------------------