Compare commits

..

10 Commits

Author SHA1 Message Date
Guillermo Pages
68bfb7fdbb fix: Argument #2 () cannot be null 2021-09-13 16:11:56 +02:00
Guillermo Pages
145a3e83d4 refactor: remove trailing slashes 2021-08-30 12:56:06 +02:00
Guillermo Pages
81af47f183 fix: php8 unknown named parameter 2021-08-30 12:50:26 +02:00
gbili
e6ea6a5add fix: remove sensitive data 2020-09-17 14:19:05 +02:00
gbili
a745b60654 feat: start session only once 2020-09-17 14:17:14 +02:00
gbili
cac44cad01 feat: allow starting session from extenders 2020-09-17 14:14:00 +02:00
gbili
a8813bc325 feat: allow starting session from extenders 2020-09-17 13:51:48 +02:00
Guillermo Dev
1720f8c8da initialize array 2019-02-09 06:51:38 +01:00
Guillermo Dev
e65b4d1bd3 allow filtering and altering output before it is sent 2019-02-09 06:38:37 +01:00
Guillermo Dev
941b47eb06 allow api methods whitelisting 2018-12-05 00:25:41 +01:00
7 changed files with 751 additions and 395 deletions

View File

@@ -27,7 +27,6 @@
}, },
"require-dev": { "require-dev": {
"bsr/utils" : "dev-master", "bsr/utils" : "dev-master",
"pds/skeleton": "^1.0", "phpunit/phpunit": "^8"
"phpunit/phpunit": "^6"
} }
} }

1005
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,18 +3,18 @@
* 'odbc:Driver=FreeTDS; * 'odbc:Driver=FreeTDS;
* Server=192.168.0.8; * Server=192.168.0.8;
* Port=1218; * Port=1218;
* Database=netbiblio; * Database=dbname;
* TDS_Version=7.4; * TDS_Version=7.4;
* ClientCharset=UTF-8'* 'alcoda', 'alcodaonly' * ClientCharset=UTF-8'* 'user', 'password'
*/ */
return array( return array(
'db' => array( 'db' => array(
'driver' => 'FreeTDS', 'driver' => 'FreeTDS',
'server' => '192.168.0.8', 'server' => '192.168.0.8',
'port' => '1218', 'port' => '1218',
'username' => 'alcoda', 'username' => 'user',
'password' => 'alcodaonly', 'password' => 'password',
'name' => 'netbiblio', 'name' => 'dbname',
), ),
'solr' => array( 'solr' => array(
'server' => '212.147.56.162', 'server' => '212.147.56.162',
@@ -42,4 +42,4 @@ return array(
'netbiblio_worker_id' => 45, 'netbiblio_worker_id' => 45,
'www_employee_id' => 45, 'www_employee_id' => 45,
'www_library_id' => 2, 'www_library_id' => 2,
);; );

View File

@@ -1,16 +1,16 @@
(n-a) - [14.10.2018 12:35:19] - 400 NoArguments - 2.01ms - (none) (n-a) - [04.12.2018 23:25:12] - 400 NoArguments - 1.29ms - (none)
(n-a) - [14.10.2018 12:35:19] - 400 NoArguments - 0.73ms - (none) (n-a) - [04.12.2018 23:25:12] - 400 NoArguments - 1.13ms - (none)
(n-a) - [14.10.2018 12:35:19] - 400 MissingMethod - 1.23ms - (none) (n-a) - [04.12.2018 23:25:12] - 400 MissingMethod - 0.91ms - (none)
(n-a) - [14.10.2018 12:35:19] - 400 MissingMethod - 0.04ms - (none) (n-a) - [04.12.2018 23:25:12] - 400 MissingMethod - 0.07ms - (none)
(n-a) - [14.10.2018 12:35:19] - 400 MissingMethod - 0.06ms - (none) (n-a) - [04.12.2018 23:25:12] - 400 MissingMethod - 0.05ms - (none)
(n-a) - [14.10.2018 12:35:19] - 400 BadMethod - 0.06ms - someNonExistentMockFunction() (n-a) - [04.12.2018 23:25:12] - 400 BadMethod - 0.06ms - (none)
(n-a) - [14.10.2018 12:35:19] - 400 BadMethod - 0.05ms - someNonExistentMockFunction() (n-a) - [04.12.2018 23:25:12] - 400 BadMethod - 0.06ms - (none)
(n-a) - [14.10.2018 12:35:19] - 400 TooFewArgs - 0.85ms - someMockFunction() (n-a) - [04.12.2018 23:25:12] - 400 TooFewArgs - 0.91ms - (none)
(n-a) - [14.10.2018 12:35:19] - 400 TooFewArgs - 0.18ms - someMockFunction(val) (n-a) - [04.12.2018 23:25:12] - 400 TooFewArgs - 0.23ms - (none)
(n-a) - [14.10.2018 12:35:19] - 400 TooManyArgs - 0.15ms - someMockFunction(val, val, val, val) (n-a) - [04.12.2018 23:25:12] - 400 TooManyArgs - 0.28ms - (none)
(n-a) - [14.10.2018 12:35:19] - 200 - 0.03ms - someMockFunction(val, val) (n-a) - [04.12.2018 23:25:12] - 200 - 0.05ms - someMockFunction(val, val)
(n-a) - [14.10.2018 12:35:19] - 200 - 0.03ms - someMockFunction(val, val, val) (n-a) - [04.12.2018 23:25:12] - 200 - 0.05ms - someMockFunction(val, val, val)
(n-a) - [14.10.2018 12:35:19] - 200 - 0.03ms - someMockFunction(val, val, val) (n-a) - [04.12.2018 23:25:12] - 200 - 0.04ms - someMockFunction(val, val, val)
(n-a) - [14.10.2018 12:35:19] - 200 - 0.03ms - someOtherMockFunction(one, two, threeOpt) (n-a) - [04.12.2018 23:25:12] - 200 - 0.04ms - someOtherMockFunction(one, two, threeOpt)
(n-a) - [14.10.2018 12:35:19] - 200 - 0.03ms - someOtherMockFunction(two, threeOpt, one) (n-a) - [04.12.2018 23:25:12] - 200 - 0.05ms - someOtherMockFunction(two, threeOpt, one)
(n-a) - [14.10.2018 12:35:19] - 200 - 0.03ms - someOtherMockFunction(two, threeOpt, one) (n-a) - [04.12.2018 23:25:12] - 200 - 0.06ms - someOtherMockFunction(two, threeOpt, one)

View File

@@ -0,0 +1,12 @@
<?php
namespace Bsr\Webservice\Exception;
/**
* This exception should be raised by the WebService engine when
* there is an error in the provided configuration information.
*
* @package Bsr\Webservice\Exception
*/
class ConfigException extends \Exception {
}

View File

@@ -1,6 +1,7 @@
<?php <?php
namespace Bsr\Webservice; namespace Bsr\Webservice;
use Bsr\Webservice\Exception\BugException;
use Bsr\Webservice\Exception\WebException; use Bsr\Webservice\Exception\WebException;
use Bsr\Webservice\Formatter\Html; use Bsr\Webservice\Formatter\Html;
@@ -16,7 +17,7 @@ class Help
* @param mixed $ws * @param mixed $ws
* @param sting $func the function to be presented * @param sting $func the function to be presented
*/ */
private static function func($ws, $func) private static function func($ws, string $func)
{ {
try { try {
$rm = new \ReflectionMethod($ws, $func); $rm = new \ReflectionMethod($ws, $func);

View File

@@ -3,6 +3,7 @@
namespace Bsr\Webservice; namespace Bsr\Webservice;
use Bsr\Webservice\Exception\UsageException; use Bsr\Webservice\Exception\UsageException;
use Bsr\Webservice\Exception\ConfigException;
use Bsr\Webservice\Exception\WebException; use Bsr\Webservice\Exception\WebException;
use Bsr\Utils\Configuration\Configuration; use Bsr\Utils\Configuration\Configuration;
use Bsr\Utils\Logger\Logger; use Bsr\Utils\Logger\Logger;
@@ -15,6 +16,8 @@ abstract class WebService
private $version = null; private $version = null;
private $sessionStarted = false;
public function __construct($version) { public function __construct($version) {
$this->version = $version; $this->version = $version;
} }
@@ -36,15 +39,21 @@ abstract class WebService
try { try {
$result = $this->call($sendSession); $result = $this->call($sendSession);
$data['result'] = array();
$data["result"][$this->func] = $result; $data["result"][$this->func] = $result;
$data = $this->filterOutput($data);
} catch (WebException $e) { } catch (WebException $e) {
$data["error"]["code"] = $e->getCode(); $data["error"]["code"] = $e->getCode();
$data["error"]["reason"] = $e->getMessage(); $data["error"]["reason"] = $e->getMessage();
$data["error"]["name"] = $e->getName(); $data["error"]["name"] = $e->getName();
if ($this->func !== null) {
$data['extra'] = Help::exception($e, $this, $this->func); $data['extra'] = Help::exception($e, $this, $this->func);
}
$this->status = 400; $this->status = 400;
@@ -64,6 +73,15 @@ abstract class WebService
$renderer->render($this->status, $data); $renderer->render($this->status, $data);
} }
protected function startSession()
{
if (!$this->sessionStarted) {
session_save_path(Configuration::get('session.save_path'));
session_start();
$this->sessionStarted = true;
}
}
/** /**
* Determines which method to call based on GET or POST parameters and * Determines which method to call based on GET or POST parameters and
* call it before returning the result. * call it before returning the result.
@@ -75,8 +93,7 @@ abstract class WebService
private function call($sendSession = true) private function call($sendSession = true)
{ {
if ($sendSession) { if ($sendSession) {
session_save_path(Configuration::get('session.save_path')); $this->startSession();
session_start();
} }
$params = empty($_GET) ? $_POST : $_GET; $params = empty($_GET) ? $_POST : $_GET;
@@ -91,19 +108,33 @@ abstract class WebService
$params = $this->filterParams($params); $params = $this->filterParams($params);
$this->isAllowedMethodNameOrThrow($params["func"]);
$this->func = $params["func"]; $this->func = $params["func"];
unset($params['func']); unset($params['func']);
$this->paramsMatchMethodDeclarationOrThrow($params);
Logger::info(array( Logger::info(array(
'func' => $this->func.'('.implode(', ', $params).')', 'func' => $this->func.'('.implode(', ', $params).')',
)); ));
if (!is_callable(array($this, $this->func))) { return call_user_func_array(array($this, $this->func), array_values($params));
throw new UsageException("BadMethod", "Method {$this->func} does not exists.", UsageException::BAD_METHOD); }
/**
* Verify that the provided params match the declaration of the requested method
* @param array $params
* @throws UsageException
*/
protected function paramsMatchMethodDeclarationOrThrow($params)
{
if (!is_callable(array($this, $this->func))) {
throw new UsageException("BadMethod", "Method {$this->func} does not exist.", UsageException::BAD_METHOD);
} }
$rm = new \ReflectionMethod($this, $this->func);
$nbParams = count($params); $nbParams = count($params);
$rm = new \ReflectionMethod($this, $this->func);
$nbArgsFix = $rm->getNumberOfRequiredParameters(); $nbArgsFix = $rm->getNumberOfRequiredParameters();
$nbArgs = $rm->getNumberOfParameters(); $nbArgs = $rm->getNumberOfParameters();
@@ -114,16 +145,44 @@ abstract class WebService
if ($nbParams > $nbArgs) { if ($nbParams > $nbArgs) {
throw new UsageException("TooManyArgs", "You must provide at most $nbArgs arguments.", UsageException::TOO_MANY_ARGS); throw new UsageException("TooManyArgs", "You must provide at most $nbArgs arguments.", UsageException::TOO_MANY_ARGS);
} }
}
return call_user_func_array(array($this, $this->func), $params); /**
* If no configuration is available assumes that all public methods are allowed
* @param string the requested method name from api param func
*/
protected function isAllowedMethodNameOrThrow($requestedMethodName)
{
$allowedMethodNames = Configuration::get('webservice.api_method_names', null);
if (null === $allowedMethodNames) {
return;
}
if (!is_array($allowedMethodNames)) {
throw new ConfigException('Bad config. You should pass an array of method names as strings, in "webservice" key and "api_method_names" subkey');
}
if (!in_array($requestedMethodName, $allowedMethodNames)) {
throw new UsageException("BadMethod", "Method {$requestedMethodName} is not whitelisted. Pick one of :" . implode(', ', $allowedMethodNames), UsageException::BAD_METHOD);
}
} }
/** /**
* Allow subclasses to filter params by overriding this * Allow subclasses to filter params by overriding this
* @param $params * @param $params
* @param array
*/ */
protected function filterParams($params) protected function filterParams($params)
{ {
return $params; return $params;
} }
/**
* Allow subclasses to filter the output before it is sent
* by overriding this method
* @param $params
* @return array
*/
protected function filterOutput(array $data)
{
return $data;
}
} }