From dd339aa6c50267337e786e9e20811b535edd985b Mon Sep 17 00:00:00 2001 From: rvelices Date: Tue, 6 Feb 2007 01:02:06 +0000 Subject: web services: - respect conf['allow_web_services'] - added conf['ws_max_images_per_page'] to limit the number of images returned per web call - fixes for Vincent's partners - added comments git-svn-id: http://piwigo.org/svn/trunk@1781 68402e56-0260-453c-a942-63ccdbb3a9ee --- admin/ws_checker.php | 80 +++++++++++++- include/config_default.inc.php | 12 +- include/ws_core.inc.php | 15 ++- include/ws_functions.inc.php | 245 ++++++++++++++++------------------------- ws.php | 10 +- 5 files changed, 195 insertions(+), 167 deletions(-) diff --git a/admin/ws_checker.php b/admin/ws_checker.php index e887da3a2..305160afd 100644 --- a/admin/ws_checker.php +++ b/admin/ws_checker.php @@ -38,13 +38,83 @@ if((!defined("PHPWG_ROOT_PATH")) or (!$conf['allow_web_services'])) die('Hacking attempt!'); } include_once(PHPWG_ROOT_PATH.'admin/include/functions.php'); +include_once(PHPWG_ROOT_PATH.'include/ws_functions.inc.php'); /** - * include ws_functions in only managed from ws_checker but - * if ws_methods would be generalized in the code this one would be promoted - * somewhere else... Maybe very soon because it can be in plugins. - * */ -include_once( PHPWG_ROOT_PATH .'include/ws_functions.inc.php' ); + * official_req returns the managed requests list in array format + * FIXME A New list need to be build for ws_checker.php + * returns array of authrorized request/methods + * */ +function official_req() +{ + $official = array( /* Requests are limited to */ + 'categories.' /* all categories. methods */ + , 'categories.getImages' /* <= see */ + , 'categories.getList' /* <= see */ + , 'images.' /* all images. methods */ + , 'images.getInfo' /* <= see */ + , 'tags.' /* all tags. methods */ + , 'tags.getImages' /* <= see */ + , 'tags.getList' /* <= see */ + ); + if (function_exists('local_req')) { + $local = local_req(); + return array_merge( $official, $local ); + } + return $official; +} + +/** + * check_target($string) verifies and corrects syntax of target parameter + * example : check_target(cat/23,24,24,24,25,27) returns cat/23-25,27 + * */ +function check_target($list) +{ + if ( $list !== '' ) + { + $type = explode('/',$list); // Find type list + if ( !in_array($type[0],array('list','cat','tag') ) ) + { + $type[0] = 'list'; // Assume an id list + } + $ids = explode( ',',$type[1] ); + $list = $type[0] . '/'; + + // 1,2,21,3,22,4,5,9-12,6,11,12,13,2,4,6, + + $result = expand_id_list( $ids ); + + // 1,2,3,4,5,6,9,10,11,12,13,21,22, + // I would like + // 1-6,9-13,21-22 + $serial[] = $result[0]; // To be shifted + foreach ($result as $k => $id) + { + $next_less_1 = (isset($result[$k + 1]))? $result[$k + 1] - 1:-1; + if ( $id == $next_less_1 and end($serial)=='-' ) + { // nothing to do + } + elseif ( $id == $next_less_1 ) + { + $serial[]=$id; + $serial[]='-'; + } + else + { + $serial[]=$id; // end serie or non serie + } + } + $null = array_shift($serial); // remove first value + $list .= array_shift($serial); // add the real first one + $separ = ','; + foreach ($serial as $id) + { + $list .= ($id=='-') ? '' : $separ . $id; + $separ = ($id=='-') ? '-':','; // add comma except if hyphen + } + } + return $list; +} // +-----------------------------------------------------------------------+ // | Check Access and exit when user status is not ok | diff --git a/include/config_default.inc.php b/include/config_default.inc.php index e0d24e791..8e6a190c9 100644 --- a/include/config_default.inc.php +++ b/include/config_default.inc.php @@ -588,18 +588,20 @@ $conf['enable_plugins']=true; // | Set default for Web Service | // +-----------------------------------------------------------------------+ +// Web services are allowed (true) or completely forbidden (false) +$conf['allow_web_services'] = true; + +// Maximum number of images to be returned foreach call to the web service +$conf['ws_max_images_per_page'] = 500; + // On Access control false // Controls are done on public basis or // if connected on member authorization basis - - $conf['ws_access_control'] = false; +$conf['ws_access_control'] = false; // On Access control true // Additionnal controls are made based on Web Service Access Table -// Web services are accepted - $conf['allow_web_services'] = true; - // Max returned rows number ( > 0 ) $conf['ws_allowed_limit'] = array(1,2,3,5,10,25); diff --git a/include/ws_core.inc.php b/include/ws_core.inc.php index 77f79388c..a3e8c7770 100644 --- a/include/ws_core.inc.php +++ b/include/ws_core.inc.php @@ -3,11 +3,10 @@ // | PhpWebGallery - a PHP based picture gallery | // | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net | // +-----------------------------------------------------------------------+ -// | branch : BSF (Best So Far) -// | file : $URL: svn+ssh://rvelices@svn.gna.org/svn/phpwebgallery/trunk/action.php $ -// | last update : $Date: 2006-12-21 18:49:12 -0500 (Thu, 21 Dec 2006) $ -// | last modifier : $Author: rvelices $ -// | revision : $Rev: 1678 $ +// | file : $Id$ +// | last update : $Date$ +// | last modifier : $Author$ +// | revision : $Revision$ // +-----------------------------------------------------------------------+ // | This program is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | @@ -142,7 +141,7 @@ class PwgNamedStruct * @link http://php.net/function.array_walk_recursive * @author Tom Buskens * @author Aidan Lister - * @version $Revision: 1.7 $ + * @version $Revision$ * @since PHP 5 * @require PHP 4.0.6 (is_callable) */ @@ -556,6 +555,10 @@ Response format: ".@$this->_responseFormat." encoder:".$this->_responseEncoder." { $this->makeArrayParam( $the_param ); } + if ( isset($options['maxValue']) and $the_param>$options['maxValue']) + { + $the_param = $options['maxValue']; + } $params[$name] = $the_param; } } diff --git a/include/ws_functions.inc.php b/include/ws_functions.inc.php index 6feb743a0..61b17dc78 100644 --- a/include/ws_functions.inc.php +++ b/include/ws_functions.inc.php @@ -7,7 +7,7 @@ // | file : $Id$ // | last update : $Date$ // | last modifier : $Author$ -// | revision : $Rev$ +// | revision : $Revision$ // +-----------------------------------------------------------------------+ // | This program is free software; you can redistribute it and/or modify | // | it under the terms of the GNU General Public License as published by | @@ -33,7 +33,8 @@ function ws_isInvokeAllowed($res, $methodName, $params) { global $conf, $calling_partner_id; - if ( !$conf['ws_access_control']) + if ( !$conf['ws_access_control'] + or strpos($methodName,'reflection.')===0 ) { return $res; // No controls are requested } @@ -45,92 +46,88 @@ SELECT * FROM '.WEB_SERVICES_ACCESS_TABLE." $row = mysql_fetch_assoc($result); if ( empty($row) ) { - return new PwgError(403, 'Partner id does not exist'); + return new PwgError(403, 'Partner id does not exist or is expired'); } + if ( !empty($row['request']) + and strpos($methodName, $row['request'])==false ) + { + return new PwgError(403, 'Method not allowed'); + } + return $res; } /** * ws_addControls * returns additionnal controls if requested - * usable for 99% of Web Service methods - * - * - Args + * usable for 99% of Web Service methods + * + * - Args * $methodName: is the requested method * $partner: is the key * $tbl_name: is the alias_name in the query (sometimes called correlation name) - * null if !getting picture informations + * null if !getting picture informations * - Logic - * Access_control is not active: Return - * Key is incorrect: Return 0 = 1 (False condition for MySQL) - * One of Params doesn't match with type of request: return 0 = 1 again + * Access_control is not active: Return + * Key is incorrect: Return 0 = 1 (False condition for MySQL) + * One of Params doesn't match with type of request: return 0 = 1 again * Access list(id/cat/tag) is converted in expended image-id list * image-id list: converted to an in-where-clause - * + * * The additionnal in-where-clause is return - */ -function ws_addControls( $methodName, $tbl_name ) + */ +function ws_addControls( $methodName, &$params, $tbl_name ) { - global $conf, $calling_partner_id, $params; - if ( !$conf['ws_access_control'] ) + global $conf, $calling_partner_id; + if ( !$conf['ws_access_control'] or !isset($calling_partner_id) ) { - return ' 1 = 1 '; // No controls are requested + return '1=1'; // No controls are requested } - -// Is it an active Partner? + +// Is it an active Partner? $query = ' SELECT * FROM '.WEB_SERVICES_ACCESS_TABLE." WHERE `name` = '$calling_partner_id' AND NOW() <= end; "; $result = pwg_query($query); if ( mysql_num_rows( $result ) == 0 ) - { - return ' 0 = 1 '; // Unknown partner or Obsolate agreement + { + return '0=1'; // Unknown partner or Obsolate agreement } - + $row = mysql_fetch_array($result); -// Method / Request matching -// Generic is not ready -// For generic you can say... tags. or categories. or images. maybe? - $filter = $row['request']; - $request_method = substr($methodName, 0, strlen($filter)) ; - if ( $filter !== $filter_method ) - { - return ' 0 = 1'; // Unauthorized method request - } -// Overide general object limit +// Overide general object limit $params['per_page'] = $row['limit']; - + // Target restrict // 3 cases: list, cat or tag // Behind / we could found img-ids, cat-ids or tag-ids $target = $row['access']; list($type, $str_ids) = explode('/',$target); // Find type list - $ids = explode( ',',$str_ids ); // (array) 1,2,21,3,22,4,5,9-12,6,11,12,13,2,4,6, - $arr_ids = expand_id_list( $ids ); - $addings = implode(',', $arr_ids); -// (string) 1,2,3,4,5,6,9,10,11,12,13,21,22, - if ( $type = 'list') + $arr_ids = expand_id_list( explode( ',',$str_ids ) ); + $addings = implode(',', $arr_ids); +// (string) 1,2,3,4,5,6,9,10,11,12,13,21,22, + if ( $type == 'list') { return $tbl_name . 'id IN ( ' . $addings . ' ) '; } - - if ( $type = 'cat' ) + + if ( $type == 'cat' ) { $addings = implode(',', get_image_ids_for_cats($arr_ids)); return $tbl_name . 'id IN ( ' . $addings . ' ) '; } - - if ( $type = 'tag' ) - { + + if ( $type == 'tag' ) + { $addings = implode(',', get_image_ids_for_tags($arr_ids, 'OR')); return $tbl_name . 'id IN ( ' . $addings . ' ) '; } // Unmanaged new type? - return ' 0 = 1 '; // ??? + return ' 0 = 1 '; // ??? } /** @@ -247,14 +244,18 @@ function ws_std_get_urls($image_row) } +/** + * returns PWG version (web service method) + */ function ws_getVersion($params, &$service) { // TODO = Version availability is under control of $conf['show_version'] return PHPWG_VERSION; } + /** - * returns images per category (wb service method) + * returns images per category (web service method) */ function ws_categories_getImages($params, &$service) { @@ -308,10 +309,12 @@ SELECT id, name, image_order $where_clauses[] = 'category_id IN (' .implode(',', array_keys($cats) ) .')'; + $where_clauses[] = get_sql_condition_FandF( array( + 'visible_images' => 'i.id' + ), null, true + ); + $where_clauses[] = ws_addControls( 'categories.getImages', $params, 'i.' ); - $where_clause[] = - ws_addControls( 'categories.getImages', 'i.' ); - $order_by = ws_std_image_sql_order($params, 'i.'); if (empty($order_by)) {// TODO check for category order by (image_order) @@ -396,8 +399,9 @@ LIMIT '.$params['per_page']*$params['page'].','.$params['per_page']; ); } + /** - * returns a list of categories + * returns a list of categories (web service method) */ function ws_categories_getList($params, &$service) { @@ -466,6 +470,10 @@ ORDER BY global_rank'; ); } + +/** + * returns detailed information for an element (web service method) + */ function ws_images_getInfo($params, &$service) { @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php'); @@ -475,7 +483,7 @@ function ws_images_getInfo($params, &$service) { return new PwgError(WS_ERR_INVALID_PARAM, "Invalid image_id"); } - + $query=' SELECT * FROM '.IMAGES_TABLE.' WHERE id='.$params['image_id']. @@ -483,7 +491,7 @@ SELECT * FROM '.IMAGES_TABLE.' array('visible_images' => 'id'), ' AND' ).' AND '. - ws_addControls( 'images.getInfo', '' ).' + ws_addControls( 'images.getInfo', $params, '' ).' LIMIT 1;'; $image_row = mysql_fetch_assoc(pwg_query($query)); @@ -600,6 +608,9 @@ SELECT COUNT(rate) AS count } +/** + * perform a login (web service method) + */ function ws_session_login($params, &$service) { global $conf; @@ -615,6 +626,10 @@ function ws_session_login($params, &$service) return new PwgError(999, 'Invalid username/password'); } + +/** + * performs a logout (web service method) + */ function ws_session_logout($params, &$service) { global $user, $conf; @@ -642,6 +657,9 @@ function ws_session_getStatus($params, &$service) } +/** + * returns a list of tags (web service method) + */ function ws_tags_getList($params, &$service) { global $user; @@ -669,6 +687,10 @@ function ws_tags_getList($params, &$service) return array('tags' => new PwgNamedArray($tags, 'tag', array('id','url_name','url', 'counter' )) ); } + +/** + * returns a list of images for tags (web service method) + */ function ws_tags_getImages($params, &$service) { @include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php'); @@ -709,7 +731,7 @@ function ws_tags_getImages($params, &$service) $image_ids = array(); $image_tag_map = array(); - + if ( !empty($tag_ids) ) { // build list of image ids with associated tags per image if ($params['tag_mode_and']) @@ -747,8 +769,7 @@ SELECT image_id, GROUP_CONCAT(tag_id) tag_ids '', true ); $where_clauses[] = 'id IN ('.implode(',',$image_ids).')'; - $where_clause[] = - ws_addControls( 'tags.getImages', 'i.' ); + $where_clauses[] = ws_addControls( 'tags.getImages', $params, 'i.' ); $order_by = ws_std_image_sql_order($params); if (empty($order_by)) @@ -830,128 +851,54 @@ LIMIT '.$params['per_page']*$params['page'].','.$params['per_page']; ); } -/** - * official_req returns the managed requests list in array format - * FIXME A New list need to be build for ws_checker.php - * returns array of authrorized request/methods - * */ -function official_req() -{ - $official = array( /* Requests are limited to */ - 'categories.' /* all categories. methods */ - , 'categories.getImages' /* <= see */ - , 'categories.getList' /* <= see */ - , 'images.' /* all images. methods */ - , 'images.getInfo' /* <= see */ - , 'tags.' /* all tags. methods */ - , 'tags.getImages' /* <= see */ - , 'tags.getList' /* <= see */ - ); - if (function_exists('local_req')) { - $local = local_req(); - return array_merge( $official, $local ); - } - return $official; -} /** * expand_id_list($ids) convert a human list expression to a full ordered list * example : expand_id_list( array(5,2-3,2) ) returns array( 2, 3, 5) - * */ + * */ function expand_id_list($ids) { - $tid = array(); - foreach ( $ids as $id ) - { - if ( is_numeric($id) ) - { - $tid[] = (int) $id; - } - else - { - $range = explode( '-', $id ); - if ( is_numeric($range[0]) and is_numeric($range[1]) ) - { - $from = min($range[0],$range[1]); - $to = max($range[0],$range[1]); - for ($i = $from; $i <= $to; $i++) - { - $tid[] = (int) $i; - } - } - } - } - $result = array_unique ($tid); // remove duplicates... - sort ($result); - return $result; -} - -/** - * check_target($string) verifies and corrects syntax of target parameter - * example : check_target(cat/23,24,24,24,25,27) returns cat/23-25,27 - * */ -function check_target($list) -{ - if ( $list !== '' ) + $tid = array(); + foreach ( $ids as $id ) { - $type = explode('/',$list); // Find type list - if ( !in_array($type[0],array('list','cat','tag') ) ) + if ( is_numeric($id) ) { - $type[0] = 'list'; // Assume an id list - } - $ids = explode( ',',$type[1] ); - $list = $type[0] . '/'; - - // 1,2,21,3,22,4,5,9-12,6,11,12,13,2,4,6, - - $result = expand_id_list( $ids ); - - // 1,2,3,4,5,6,9,10,11,12,13,21,22, - // I would like - // 1-6,9-13,21-22 - $serial[] = $result[0]; // To be shifted - foreach ($result as $k => $id) + $tid[] = (int) $id; + } + else { - $next_less_1 = (isset($result[$k + 1]))? $result[$k + 1] - 1:-1; - if ( $id == $next_less_1 and end($serial)=='-' ) - { // nothing to do - } - elseif ( $id == $next_less_1 ) - { - $serial[]=$id; - $serial[]='-'; - } - else + $range = explode( '-', $id ); + if ( is_numeric($range[0]) and is_numeric($range[1]) ) { - $serial[]=$id; // end serie or non serie + $from = min($range[0],$range[1]); + $to = max($range[0],$range[1]); + for ($i = $from; $i <= $to; $i++) + { + $tid[] = (int) $i; + } } } - $null = array_shift($serial); // remove first value - $list .= array_shift($serial); // add the real first one - $separ = ','; - foreach ($serial as $id) - { - $list .= ($id=='-') ? '' : $separ . $id; - $separ = ($id=='-') ? '-':','; // add comma except if hyphen - } } - return $list; + $result = array_unique ($tid); // remove duplicates... + sort ($result); + return $result; } + /** * converts a cat-ids array in image-ids array * FIXME Function which should already exist somewhere else - * */ + * */ function get_image_ids_for_cats($cat_ids) { $cat_list = implode(',', $cat_ids); $ret_ids = array(); $query = ' - SELECT DISTINCT image_id + SELECT DISTINCT image_id FROM '.IMAGE_CATEGORY_TABLE.' WHERE category_id in ('.$cat_list.') ;'; - return $array_from_query($query, 'image_id'); + return array_from_query($query, 'image_id'); } ?> diff --git a/ws.php b/ws.php index 2b5d636f4..a196d49e0 100644 --- a/ws.php +++ b/ws.php @@ -29,12 +29,18 @@ define ('PHPWG_ROOT_PATH', './'); include_once(PHPWG_ROOT_PATH.'include/common.inc.php'); include_once(PHPWG_ROOT_PATH.'include/ws_core.inc.php'); +if ( !$conf['allow_web_services'] ) +{ + page_forbidden('Web services are disabled'); +} + /** * event handler that registers standard methods with the web service */ function ws_addDefaultMethods( $arr ) { include_once(PHPWG_ROOT_PATH.'include/ws_functions.inc.php'); + global $conf; $service = &$arr[0]; $service->addMethod('pwg.getVersion', 'ws_getVersion', null, 'retrieves the PWG version'); @@ -43,7 +49,7 @@ function ws_addDefaultMethods( $arr ) array( 'cat_id'=>array('default'=>0, 'flags'=>WS_PARAM_FORCE_ARRAY), 'recursive'=>array('default'=>false), - 'per_page' => array('default'=>100), + 'per_page' => array('default'=>100, 'maxValue'=>$conf['ws_max_images_per_page']), 'page' => array('default'=>0), 'order' => array('default'=>null), 'f_min_rate' => array( 'default'=> null ), @@ -90,7 +96,7 @@ function ws_addDefaultMethods( $arr ) 'tag_url_name'=>array('default'=>null, 'flags'=>WS_PARAM_FORCE_ARRAY ), 'tag_name'=>array('default'=>null, 'flags'=>WS_PARAM_FORCE_ARRAY ), 'tag_mode_and'=>array('default'=>false), - 'per_page' => array('default'=>100), + 'per_page' => array('default'=>100, 'maxValue'=>$conf['ws_max_images_per_page']), 'page' => array('default'=>0), 'order' => array('default'=>null), 'f_min_rate' => array( 'default'=> null ), -- cgit v1.2.3