Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.0] Token authentication for the API application #27021

Merged
merged 30 commits into from Mar 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
05d6e76
Token Authentication for the API application
Nov 7, 2019
3b05898
Token Authentication for the API application
Nov 7, 2019
86a9af4
Token Authentication for the API application
Nov 7, 2019
25877ea
Token Authentication for the API application
Nov 7, 2019
5f55cdd
Token Authentication for the API application
Nov 8, 2019
96f45f8
Token Authentication for the API application
Nov 8, 2019
b966064
Token Authentication for the API application
Nov 8, 2019
9208ce4
Token Authentication for the API application
Nov 8, 2019
2152e97
Token Authentication for the API application
Nov 9, 2019
0ddfd3c
Token Authentication for the API application
Nov 10, 2019
504174c
Token Authentication for the API application
Nov 10, 2019
cc42da3
Token Authentication for the API application
Nov 10, 2019
5acc38f
Token Authentication for the API application
Nov 10, 2019
52052ba
Token Authentication for the API application
Nov 10, 2019
154bcc8
Token Authentication for the API application
Nov 10, 2019
47006a4
Token Authentication for the API application
Nov 11, 2019
c27183e
Merge branch '4.0-dev' into feature/26925-token-auth
Nov 11, 2019
a7263e3
Token Authentication for the API application
Nov 12, 2019
89dcfd1
Token Authentication for the API application
Nov 12, 2019
cbd062d
Changing a line to trigger the build
Feb 4, 2020
bce9f1d
Merge branch '4.0-dev' into feature/26925-token-auth
Feb 8, 2020
b7d90e0
Add constant site secret for API tests
wilsonge Mar 22, 2020
1ce6be1
Move api suite to dist file
wilsonge Mar 22, 2020
403c8eb
Static db hash
wilsonge Mar 22, 2020
6e8edf9
Bodge support for apache FPM
wilsonge Mar 22, 2020
fa65131
Fixed user id
wilsonge Mar 22, 2020
56c8f46
Merge pull request #5 from wilsonge/tests/token-api-auth
Mar 23, 2020
fae9dfa
Merge branch '4.0-dev' into feature/26925-token-auth
Mar 23, 2020
1ffc1c1
Add method missing from previous PR
wilsonge Mar 23, 2020
8366f6d
Merge pull request #6 from wilsonge/token_auth
Mar 23, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -37,6 +37,8 @@ composer.phar
/.phpunit.result.cache
/tests/Codeception/acceptance.suite.yml
/tests/Codeception/_output/
/tests/Codeception/api.suite.yml


# Vendor directory handeling
/libraries/vendor
Expand Down
@@ -0,0 +1,11 @@
--
-- Joomla API authentication with token
--
INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES
(0, 'plg_user_token', 'plugin', 'token', 'user', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_api-authentication_token', 'plugin', 'token', 'api-authentication', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0);

--
-- Disable the less secure basic authentication
--
UPDATE `#__extensions` SET `enabled` = 0 WHERE `name` = 'plg_api-authentication_basic' AND `type` = 'plugin';
@@ -0,0 +1,11 @@
--
-- Joomla API authentication with token
--
INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "checked_out", "checked_out_time", "ordering", "state") VALUES
(0, 'plg_user_token', 'plugin', 'token', 'user', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_api-authentication_token', 'plugin', 'token', 'api-authentication', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0);

--
-- Disable the less secure basic authentication
--
UPDATE "#__extensions" SET "enabled" = 0 WHERE "name" = 'plg_api-authentication_basic' AND "type" = 'plugin';
@@ -0,0 +1,7 @@
; Joomla! Project
; Copyright (C) 2005 - 2019 Open Source Matters. All rights reserved.
; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
; Note : All ini files need to be saved as UTF-8

PLG_API-AUTHENTICATION_TOKEN="API Authentication - Joomla Token"
PLG_API-AUTHENTICATION_TOKEN_XML_DESCRIPTION="Used to allow token-based authentication to Web Services in Joomla."
@@ -0,0 +1,7 @@
; Joomla! Project
; Copyright (C) 2005 - 2019 Open Source Matters. All rights reserved.
; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
; Note : All ini files need to be saved as UTF-8

PLG_API-AUTHENTICATION_TOKEN="API Authentication - Joomla Token"
PLG_API-AUTHENTICATION_TOKEN_XML_DESCRIPTION="Used to allow token-based authentication to Web Services in Joomla."
23 changes: 23 additions & 0 deletions administrator/language/en-GB/en-GB.plg_user_token.ini
@@ -0,0 +1,23 @@
; Joomla! Project
; Copyright (C) 2005 - 2019 Open Source Matters. All rights reserved.
; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
; Note : All ini files need to be saved as UTF-8

PLG_USER_TOKEN="User - Joomla Token"
PLG_USER_TOKEN_XML_DESCRIPTION="Allows the management of security tokens used for authenticating to the Joomla API application (remote access to your site). These tokens are strictly personal. You can view your own token but you can only disable or reset other users' tokens."

PLG_USER_TOKEN_GROUP_LABEL="Joomla Token"
PLG_USER_TOKEN_GROUP_DESC="Manage the security tokens used for authenticating to the Joomla API application (remote access to your site). If you are not sure what this does chances are you don't need and can safely ignore these settings."

PLG_USER_TOKEN_TOKEN_LABEL="Token"
PLG_USER_TOKEN_TOKEN_DESC="This is your token. Use it in third party applications requiring remote access to your access through the Joomla API application."

PLG_USER_TOKEN_ENABLED_LABEL="Active"
PLG_USER_TOKEN_ENABLED_DESC="Set to No to temporarily prevent access to your site with this token."

PLG_USER_TOKEN_RESET_LABEL="Reset"
PLG_USER_TOKEN_RESET_DESC="Set to Yes and save your user profile to create a new token, replacing the old one."

PLG_USER_TOKEN_SAVEME_DESC="You do not have a token yet. Please save your user profile to generate a token. Come back to this page to view and manage your token."
PLG_USER_TOKEN_NOTOKENFOROTHERPEOPLE_DESC="You cannot see the token for users other than yourself. You can still enable, disable or reset their token e.g. when there is a suspicion their token has leaked to unauthorised persons."
PLG_USER_TOKEN_SAVEMEFOROTHERPEOPLE_DESC="This user does not have a token yet. If you save their profile a new token will be generated but you will not be able to see it for security reasons. You will still be able to enable, disable or reset their token."
10 changes: 10 additions & 0 deletions administrator/language/en-GB/en-GB.plg_user_token.sys.ini
@@ -0,0 +1,10 @@
; Joomla! Project
; Copyright (C) 2005 - 2019 Open Source Matters. All rights reserved.
; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
; Note : All ini files need to be saved as UTF-8

PLG_USER_TOKEN="User - Joomla Token"
PLG_USER_TOKEN_XML_DESCRIPTION="Allows the management of security tokens used for authenticating to the Joomla API application (remote access to your site). These tokens are strictly personal. You can view your own token but you can only disable or reset other users' tokens."

PLG_USER_TOKEN_ALLOWEDUSERGROUPS_LABEL="Allowed User Groups"
PLG_USER_TOKEN_ALLOWEDUSERGROUPS_DESC="Which Joomla User Groups are allowed to use Joomla Tokens to authenticate to the Joomla API application. Also controls which user groups see the Joomla Token management interface in their user profile. Default: Joomla's built-in Super Users group (User Group ID 8)."
4 changes: 3 additions & 1 deletion installation/sql/mysql/joomla.sql
Expand Up @@ -681,6 +681,7 @@ INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`,
(0, 'plg_privacy_user', 'plugin', 'user', 'privacy', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_quickicon_privacycheck', 'plugin', 'privacycheck', 'quickicon', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_user_terms', 'plugin', 'terms', 'user', 0, 0, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_user_token', 'plugin', 'token', 'user', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_privacy_contact', 'plugin', 'contact', 'privacy', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_privacy_content', 'plugin', 'content', 'privacy', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
Expand All @@ -697,7 +698,8 @@ INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`,
(0, 'plg_quickicon_overridecheck', 'plugin', 'overridecheck', 'quickicon', 0, 1, 1, 1, '', '', 0, NULL, 0, 0),
(0, 'plg_extension_finder', 'plugin', 'finder', 'extension', 0, 1, 1, 0, '', '', 0, NULL, 0, 0),
(0, 'plg_system_skipto', 'plugin', 'skipto', 'system', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_api-authentication_basic', 'plugin', 'basic', 'api-authentication', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_api-authentication_basic', 'plugin', 'basic', 'api-authentication', 0, 0, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_api-authentication_token', 'plugin', 'token', 'api-authentication', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_webservices_banners', 'plugin', 'banners', 'webservices', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_webservices_contact', 'plugin', 'contact', 'webservices', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_webservices_config', 'plugin', 'config', 'webservices', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
Expand Down
4 changes: 3 additions & 1 deletion installation/sql/postgresql/joomla.sql
Expand Up @@ -692,6 +692,7 @@ INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder",
(0, 'plg_privacy_user', 'plugin', 'user', 'privacy', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_quickicon_privacycheck', 'plugin', 'privacycheck', 'quickicon', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_user_terms', 'plugin', 'terms', 'user', 0, 0, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_user_token', 'plugin', 'token', 'user', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_privacy_contact', 'plugin', 'contact', 'privacy', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_privacy_content', 'plugin', 'content', 'privacy', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
Expand All @@ -708,7 +709,8 @@ INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder",
(0, 'plg_quickicon_overridecheck', 'plugin', 'overridecheck', 'quickicon', 0, 1, 1, 1, '', '', 0, NULL, 0, 0),
(0, 'plg_extension_finder', 'plugin', 'finder', 'extension', 0, 1, 1, 0, '', '', 0, NULL, 0, 0),
(0, 'plg_system_skipto', 'plugin', 'skipto', 'system', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_api-authentication_basic', 'plugin', 'basic', 'api-authentication', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_api-authentication_basic', 'plugin', 'basic', 'api-authentication', 0, 0, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_api-authentication_token', 'plugin', 'token', 'api-authentication', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_webservices_banners', 'plugin', 'banners', 'webservices', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_webservices_config', 'plugin', 'config', 'webservices', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
(0, 'plg_webservices_contact', 'plugin', 'contact', 'webservices', 0, 1, 1, 0, '', '{}', 0, NULL, 0, 0),
Expand Down
35 changes: 34 additions & 1 deletion libraries/src/Crypt/Crypt.php
Expand Up @@ -35,7 +35,40 @@ class Crypt extends JCrypt
*/
public static function timingSafeCompare($known, $unknown)
{
return hash_equals((string) $known, (string) $unknown);
/**
* Explanation about the function_exists
*
* Yes, hash_equals has existed since PHP 5.6.0 and Joomla's minimum requirements are higher
* than that. However, this does not prevent a misguided server administrator from disabling
* hash_equals in php.ini. Hence the need for checking whether the function exists or not.
*/
if (function_exists('hash_equals'))
{
return hash_equals($known, $unknown);
}

/**
* If hash_equals is not available we use a pure PHP implementation by Anthony Ferrara.
*
* @see https://blog.ircmaxell.com/2014/11/its-all-about-time.html
*/
$safeLen = strlen($known);
$userLen = strlen($unknown);

if ($userLen != $safeLen)
{
return false;
}

$result = 0;

for ($i = 0; $i < $userLen; $i++)
{
$result |= (ord($known[$i]) ^ ord($unknown[$i]));
}

// They are only identical strings if $result is exactly 0...
return $result === 0;
}

/**
Expand Down