From 0b98d8c8f628320b5d387bd7dd5543e88230a4ae Mon Sep 17 00:00:00 2001 From: Jon Langseth Date: Fri, 16 Aug 2013 14:13:27 +0200 Subject: [PATCH] Permissions, a naive approach --- api/lib/permission_functions.php | 75 ++++++++++++++++ api/permissions.php | 147 +++++++++++++++++++++++++++++++ api/t/permissions.t | 92 +++++++++++++++++++ doc/api-nodes.txt | 53 +++++++++++ 4 files changed, 367 insertions(+) create mode 100644 api/lib/permission_functions.php create mode 100644 api/permissions.php create mode 100644 api/t/permissions.t diff --git a/api/lib/permission_functions.php b/api/lib/permission_functions.php new file mode 100644 index 0000000..19a2874 --- /dev/null +++ b/api/lib/permission_functions.php @@ -0,0 +1,75 @@ + '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'] ); +?> diff --git a/api/t/permissions.t b/api/t/permissions.t new file mode 100644 index 0000000..c06db8f --- /dev/null +++ b/api/t/permissions.t @@ -0,0 +1,92 @@ +#!/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(); diff --git a/doc/api-nodes.txt b/doc/api-nodes.txt index a3cafc9..56e2a05 100644 --- a/doc/api-nodes.txt +++ b/doc/api-nodes.txt @@ -717,6 +717,59 @@ domain/set_servers '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: --------------------- -- 2.39.2