diff --git a/htdocs/api/class/api_access.class.php b/htdocs/api/class/api_access.class.php index 68ec526ec7e0e4f0156104810ea13ee7f0ca6fd4..407f94ac915c592533a91ca879b73eb64a762f94 100644 --- a/htdocs/api/class/api_access.class.php +++ b/htdocs/api/class/api_access.class.php @@ -76,12 +76,34 @@ class DolibarrApiAccess implements iAuthenticate $userClass = Defaults::$userIdentifierClass; + /*foreach ($_SERVER as $key => $val) + { + dol_syslog($key.' - '.$val); + }*/ + + // api key can be provided in url with parameter api_key=xxx or ni header with header DOLAPIKEY:xxx + $api_key = ''; if (isset($_GET['api_key'])) + { + // TODO Add option to disable use of api key on url. Return errors if used. + $api_key = $_GET['api_key']; // For backward compatibility + } + if (isset($_GET['DOLAPIKEY'])) + { + // TODO Add option to disable use of api key on url. Return errors if used. + $api_key = $_GET['DOLAPIKEY']; // With GET method + } + if (isset($_SERVER['HTTP_DOLAPIKEY'])) + { + $api_key = $_SERVER['HTTP_DOLAPIKEY']; // With header method (recommanded) + } + + if ($api_key) { $sql = "SELECT u.login, u.datec, u.api_key, "; $sql.= " u.tms as date_modification, u.entity"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; - $sql.= " WHERE u.api_key = '".$db->escape($_GET['api_key'])."'"; + $sql.= " WHERE u.api_key = '".$db->escape($api_key)."'"; $result = $db->query($sql); if ($result) @@ -97,8 +119,8 @@ class DolibarrApiAccess implements iAuthenticate throw new RestException(503, 'Error when fetching user api_key :'.$db->error_msg); } - if ($stored_key != $_GET['api_key']) { - $userClass::setCacheIdentifier($_GET['api_key']); + if ($stored_key != $api_key) { + $userClass::setCacheIdentifier($api_key); return false; } @@ -121,7 +143,7 @@ class DolibarrApiAccess implements iAuthenticate } else { - throw new RestException(401, "Failed to login to API. No parameter 'api_key' provided"); + throw new RestException(401, "Failed to login to API. No parameter 'DOLAPIKEY' on HTTP header (neither in URL)."); } $userClass::setCacheIdentifier(static::$role); diff --git a/htdocs/api/class/api_login.class.php b/htdocs/api/class/api_login.class.php index 439308fcaeaa9bfebe66693b1890ad6ede406eef..704ec1b68746c1a34bdfc22f1940d12cdab6fad4 100644 --- a/htdocs/api/class/api_login.class.php +++ b/htdocs/api/class/api_login.class.php @@ -34,12 +34,14 @@ class Login /** * Login * - * Log user with username and password. Using method POST is recommanded for security reasons (method GET is often logged by default by web servers with parameters so with login and pass) - * - * @param string $login Username + * Request the API token for a couple username / password. + * Using method POST is recommanded for security reasons (method GET is often logged by default by web servers with parameters so with login and pass into server log file). + * Both method are provided for developer conveniance. Best is to not use at all the login API method and enter directly the "api_key" into field at the top right of page (Note: "api_key" can be found/set on the user page). + * + * @param string $login User login * @param string $password User password * @param int $entity Entity (when multicompany module is used). Empty means 1=first company. - * @param int $reset Reset token (0=get current token, 1=ask a new token, meaning that all future access using current token will failed) + * @param int $reset Reset token (0=get current token, 1=ask a new token and canceled old token. This means access using current existing API token of user will fails: new token will be required for new access) * @return array Response status and user token * * @throws RestException diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 8ad60c4b340f48e58814903eb2ff866440acaa6b..37be4d8cc26330410cd955a224d4ded133b79978 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -56,6 +56,16 @@ if (empty($conf->global->MAIN_MODULE_API)) exit; } +// Test if explorer is not disabled +if (preg_match('/api\/index\.php\/explorer/', $_SERVER["PHP_SELF"]) && ! empty($conf->global->API_EXPLORER_DISABLED)) +{ + $langs->load("admin"); + dol_syslog("Call Dolibarr API interfaces with module REST disabled"); + print $langs->trans("WarningAPIExplorerDisabled").'.<br><br>'; + exit; +} + + $api = new DolibarrApi($db); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html b/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html index 27f0d4f53daf67d7c5c3cf714c9cf60235db1aa1..a433b80056be5d9723ba2a8183c7fbcf56243fd7 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html @@ -2,8 +2,8 @@ <html> <head> <title>Api Explorer</title> - <link href='https://fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/> - <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet"> + <!-- <link href='https://fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/> + <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">--> <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/> <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/> <link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/> @@ -56,11 +56,18 @@ log("key: " + key); if(key && key.trim() != "") { log("added key " + key); - window.authorizations.add("key", new ApiKeyAuthorization("api_key", key, "query")); + + window.authorizations.add("key", new ApiKeyAuthorization("DOLAPIKEY", key, "query")); + console.log("param api_key added with value "+key); + + window.authorizations.add("key2", new ApiKeyAuthorization("DOLAPIKEY", key, "header")); + console.log("header DOLAPIKEY added with value "+key); } }) + window.swaggerUi.load(); }); + </script> </head> @@ -70,7 +77,7 @@ <a id="logo" href="#">API Explorer</a> <form id='api_selector'> <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="hidden" value="resources.json"/></div> - <div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div> + <div class='input'><input placeholder="DOLAPIKEY" id="input_apiKey" name="apiKey" type="text"/></div> <div class='input'><a id="explore" href="#">Explore</a></div> </form> </div> diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 3ed88e8e29e60c8ab22df24c0bc67745ce5b3d70..5fd1ae065ec4a6288c56f03c96f7e61fbf3c2559 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1503,10 +1503,11 @@ EndPointIs=SOAP clients must send their requests to the Dolibarr endpoint availa ##### API #### ApiSetup=API module setup ApiDesc=By enabling this module, Dolibarr become a REST server to provide miscellaneous web services. -ApiProductionMode=Enable production mode (this will activate use of a caches for services management) +ApiProductionMode=Enable production mode (this will activate use of a cache for services management) ApiExporerIs=You can explore the APIs at url OnlyActiveElementsAreExposed=Only elements from enabled modules are exposed ApiKey=Key for API +WarningAPIExplorerDisabled=The API explorer has been disabled. API explorer is not required to provide API services. It is a tool for developer to find/test REST APIs. If you need this tool, go into setup of module API REST to activate it. ##### Bank ##### BankSetupModule=Bank module setup FreeLegalTextOnChequeReceipts=Free text on cheque receipts