aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--phpBB/adm/style/acp_forums.html5
-rw-r--r--phpBB/assets/javascript/core.js103
-rw-r--r--phpBB/config/default/container/services_auth.yml22
-rw-r--r--phpBB/config/default/container/services_console.yml8
-rw-r--r--phpBB/develop/calc_email_hash.php74
-rw-r--r--phpBB/develop/regex.php40
-rw-r--r--phpBB/develop/regex_idn.php41
-rw-r--r--phpBB/develop/update_email_hash.php56
-rw-r--r--phpBB/includes/acp/acp_forums.php3
-rw-r--r--phpBB/includes/acp/acp_users.php5
-rw-r--r--phpBB/includes/functions.php174
-rw-r--r--phpBB/includes/functions_compatibility.php50
-rw-r--r--phpBB/includes/functions_convert.php10
-rw-r--r--phpBB/includes/functions_display.php7
-rw-r--r--phpBB/includes/functions_transfer.php4
-rw-r--r--phpBB/includes/functions_user.php12
-rw-r--r--phpBB/includes/ucp/ucp_profile.php1
-rw-r--r--phpBB/includes/ucp/ucp_register.php14
-rw-r--r--phpBB/includes/ucp/ucp_resend.php2
-rw-r--r--phpBB/install/convertors/convert_phpbb20.php1
-rw-r--r--phpBB/language/en/acp/forums.php2
-rw-r--r--phpBB/language/en/cli.php3
-rw-r--r--phpBB/language/en/common.php1
-rw-r--r--phpBB/phpbb/auth/provider/apache.php75
-rw-r--r--phpBB/phpbb/auth/provider/base.php2
-rw-r--r--phpBB/phpbb/auth/provider/db.php61
-rw-r--r--phpBB/phpbb/auth/provider/ldap.php53
-rw-r--r--phpBB/phpbb/auth/provider/oauth/oauth.php966
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/base.php62
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/bitly.php107
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/facebook.php99
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/google.php107
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/service_interface.php114
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/twitter.php113
-rw-r--r--phpBB/phpbb/auth/provider/oauth/token_storage.php346
-rw-r--r--phpBB/phpbb/auth/provider/provider_interface.php4
-rw-r--r--phpBB/phpbb/console/command/fixup/recalculate_email_hash.php76
-rw-r--r--phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php49
-rw-r--r--phpBB/phpbb/db/migration/data/v330/remove_email_hash.php57
-rw-r--r--phpBB/phpbb/di/service_collection.php19
-rw-r--r--phpBB/phpbb/install/module/install_database/task/add_config_settings.php1
-rw-r--r--phpBB/phpbb/session.php49
-rw-r--r--phpBB/phpbb/ucp/controller/reset_password.php2
-rw-r--r--phpBB/posting.php30
-rw-r--r--phpBB/search.php3
-rw-r--r--phpBB/styles/prosilver/template/memberlist_search.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_register.html12
-rw-r--r--phpBB/styles/prosilver/theme/colours.css5
-rw-r--r--phpBB/styles/prosilver/theme/forms.css2
-rw-r--r--tests/auth/fixtures/user.xml12
-rw-r--r--tests/auth/fixtures/user_533.xml39
-rw-r--r--tests/auth/provider_apache_test.php38
-rw-r--r--tests/auth/provider_db_test.php35
-rw-r--r--tests/auth/provider_ldap_test.php94
-rw-r--r--tests/functional/posting_test.php13
-rw-r--r--tests/functional/subforum_test.php113
-rw-r--r--tests/functions/fixtures/validate_email.xml4
-rw-r--r--tests/functions/user_delete_test.php36
-rw-r--r--tests/network/inet_ntop_pton_test.php56
-rw-r--r--tests/passwords/manager_test.php154
-rw-r--r--travis/ldap/base.ldif41
-rw-r--r--travis/ldap/slapd.conf17
-rwxr-xr-xtravis/setup-ldap.sh23
64 files changed, 1934 insertions, 1796 deletions
diff --git a/.travis.yml b/.travis.yml
index 346d067240..d6fc46c585 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -37,6 +37,7 @@ install:
before_script:
- travis/setup-database.sh $DB $TRAVIS_PHP_VERSION $NOTESTS
+ - travis/setup-ldap.sh $SLOWTESTS
- phantomjs --webdriver=8910 > /dev/null &
script:
diff --git a/phpBB/adm/style/acp_forums.html b/phpBB/adm/style/acp_forums.html
index 20bcd2e9f9..f51ce98776 100644
--- a/phpBB/adm/style/acp_forums.html
+++ b/phpBB/adm/style/acp_forums.html
@@ -211,6 +211,11 @@
<label><input type="radio" class="radio" name="display_subforum_list" value="0"<!-- IF not S_DISPLAY_SUBFORUM_LIST --> id="display_subforum_list" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
</dl>
<dl>
+ <dt><label for="display_subforum_limit">{L_LIMIT_SUBFORUMS}{L_COLON}</label><br /><span>{L_LIMIT_SUBFORUMS_EXPLAIN}</span></dt>
+ <dd><label><input type="radio" class="radio" name="display_subforum_limit" value="1"<!-- IF S_DISPLAY_SUBFORUM_LIMIT --> id="display_subforum_limit" checked="checked"<!-- ENDIF --> /> {L_YES}</label>
+ <label><input type="radio" class="radio" name="display_subforum_limit" value="0"<!-- IF not S_DISPLAY_SUBFORUM_LIMIT --> id="display_subforum_limit" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
+ </dl>
+ <dl>
<dt><label for="display_on_index">{L_LIST_INDEX}{L_COLON}</label><br /><span>{L_LIST_INDEX_EXPLAIN}</span></dt>
<dd><label><input type="radio" class="radio" name="display_on_index" value="1"<!-- IF S_DISPLAY_ON_INDEX --> id="display_on_index" checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input type="radio" class="radio" name="display_on_index" value="0"<!-- IF not S_DISPLAY_ON_INDEX --> id="display_on_index" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index bb38441622..4a61490615 100644
--- a/phpBB/assets/javascript/core.js
+++ b/phpBB/assets/javascript/core.js
@@ -11,7 +11,9 @@ phpbb.alertTime = 100;
var keymap = {
TAB: 9,
ENTER: 13,
- ESC: 27
+ ESC: 27,
+ ARROW_UP: 38,
+ ARROW_DOWN: 40
};
var $dark = $('#darkenwrapper');
@@ -561,7 +563,7 @@ phpbb.search.setValue = function($input, value, multiline) {
phpbb.search.setValueOnClick = function($input, value, $row, $container) {
$row.click(function() {
phpbb.search.setValue($input, value.result, $input.attr('data-multiline'));
- $container.hide();
+ phpbb.search.closeResults($input, $container);
});
};
@@ -575,7 +577,7 @@ phpbb.search.setValueOnClick = function($input, value, $row, $container) {
* @param {object} event Onkeyup event object.
* @param {function} sendRequest Function to execute AJAX request.
*
- * @returns {bool} Returns false.
+ * @returns {boolean} Returns false.
*/
phpbb.search.filter = function(data, event, sendRequest) {
var $this = $(this),
@@ -584,9 +586,16 @@ phpbb.search.filter = function(data, event, sendRequest) {
searchID = $this.attr('data-results'),
keyword = phpbb.search.getKeyword($this, data[dataName], $this.attr('data-multiline')),
cache = phpbb.search.cache.get(searchID),
+ key = event.keyCode || event.which,
proceed = true;
data[dataName] = keyword;
+ // No need to search if enter was pressed
+ // for selecting a value from the results.
+ if (key === keymap.ENTER) {
+ return false;
+ }
+
if (cache.timeout) {
clearTimeout(cache.timeout);
}
@@ -697,22 +706,106 @@ phpbb.search.showResults = function(results, $input, $container, callback) {
row.appendTo($resultContainer).show();
});
$container.show();
+
+ phpbb.search.navigateResults($input, $container, $resultContainer);
};
/**
* Clear search results.
*
- * @param {jQuery} $container Search results container.
+ * @param {jQuery} $container Search results container.
*/
phpbb.search.clearResults = function($container) {
$container.children(':not(.search-result-tpl)').remove();
};
+/**
+ * Close search results.
+ *
+ * @param {jQuery} $input Search input|textarea.
+ * @param {jQuery} $container Search results container.
+ */
+phpbb.search.closeResults = function($input, $container) {
+ $input.off('.phpbb.search');
+ $container.hide();
+};
+
+/**
+ * Navigate search results.
+ *
+ * @param {jQuery} $input Search input|textarea.
+ * @param {jQuery} $container Search results container.
+ * @param {jQuery} $resultContainer Search results list container.
+ */
+phpbb.search.navigateResults = function($input, $container, $resultContainer) {
+ // Add a namespace to the event (.phpbb.search),
+ // so it can be unbound specifically later on.
+ $input.on('keydown.phpbb.search', function(event) {
+ var key = event.keyCode || event.which,
+ $active = $resultContainer.children('.active');
+
+ switch (key) {
+ // Close the results
+ case keymap.ESC:
+ phpbb.search.closeResults($input, $container);
+ break;
+
+ // Set the value for the selected result
+ case keymap.ENTER:
+ if ($active.length) {
+ var value = $active.find('.search-result > span').text();
+
+ phpbb.search.setValue($input, value, $input.attr('data-multiline'));
+ }
+
+ phpbb.search.closeResults($input, $container);
+
+ // Do not submit the form
+ event.preventDefault();
+ break;
+
+ // Navigate the results
+ case keymap.ARROW_DOWN:
+ case keymap.ARROW_UP:
+ var up = key === keymap.ARROW_UP,
+ $children = $resultContainer.children();
+
+ if (!$active.length) {
+ if (up) {
+ $children.last().addClass('active');
+ } else {
+ $children.first().addClass('active');
+ }
+ } else if ($children.length > 1) {
+ if (up) {
+ if ($active.is(':first-child')) {
+ $children.last().addClass('active');
+ } else {
+ $active.prev().addClass('active');
+ }
+ } else {
+ if ($active.is(':last-child')) {
+ $children.first().addClass('active');
+ } else {
+ $active.next().addClass('active');
+ }
+ }
+
+ $active.removeClass('active');
+ }
+
+ // Do not change cursor position in the input element
+ event.preventDefault();
+ break;
+ }
+ });
+};
+
$('#phpbb').click(function() {
var $this = $(this);
if (!$this.is('.live-search') && !$this.parents().is('.live-search')) {
- $('.live-search').hide();
+ phpbb.search.closeResults($('input, textarea'), $('.live-search'));
}
});
diff --git a/phpBB/config/default/container/services_auth.yml b/phpBB/config/default/container/services_auth.yml
index ed8dc90a74..1540bea97f 100644
--- a/phpBB/config/default/container/services_auth.yml
+++ b/phpBB/config/default/container/services_auth.yml
@@ -15,12 +15,12 @@ services:
auth.provider.db:
class: phpbb\auth\provider\db
arguments:
- - '@dbal.conn'
+ - '@captcha.factory'
- '@config'
+ - '@dbal.conn'
- '@passwords.manager'
- '@request'
- '@user'
- - '@service_container'
- '%core.root_path%'
- '%core.php_ext%'
tags:
@@ -29,9 +29,9 @@ services:
auth.provider.apache:
class: phpbb\auth\provider\apache
arguments:
- - '@dbal.conn'
- '@config'
- - '@passwords.manager'
+ - '@dbal.conn'
+ - '@language'
- '@request'
- '@user'
- '%core.root_path%'
@@ -42,9 +42,9 @@ services:
auth.provider.ldap:
class: phpbb\auth\provider\ldap
arguments:
- - '@dbal.conn'
- '@config'
- - '@passwords.manager'
+ - '@dbal.conn'
+ - '@language'
- '@user'
tags:
- { name: auth.provider }
@@ -52,18 +52,18 @@ services:
auth.provider.oauth:
class: phpbb\auth\provider\oauth\oauth
arguments:
- - '@dbal.conn'
- '@config'
- - '@passwords.manager'
+ - '@dbal.conn'
+ - '@auth.provider.db'
+ - '@dispatcher'
+ - '@language'
- '@request'
+ - '@auth.provider.oauth.service_collection'
- '@user'
- '%tables.auth_provider_oauth_token_storage%'
- '%tables.auth_provider_oauth_states%'
- '%tables.auth_provider_oauth_account_assoc%'
- - '@auth.provider.oauth.service_collection'
- '%tables.users%'
- - '@service_container'
- - '@dispatcher'
- '%core.root_path%'
- '%core.php_ext%'
tags:
diff --git a/phpBB/config/default/container/services_console.yml b/phpBB/config/default/container/services_console.yml
index 05e467ff8d..b662102b35 100644
--- a/phpBB/config/default/container/services_console.yml
+++ b/phpBB/config/default/container/services_console.yml
@@ -158,14 +158,6 @@ services:
tags:
- { name: console.command }
- console.command.fixup.recalculate_email_hash:
- class: phpbb\console\command\fixup\recalculate_email_hash
- arguments:
- - '@user'
- - '@dbal.conn'
- tags:
- - { name: console.command }
-
console.command.fixup.update_hashes:
class: phpbb\console\command\fixup\update_hashes
arguments:
diff --git a/phpBB/develop/calc_email_hash.php b/phpBB/develop/calc_email_hash.php
deleted file mode 100644
index 740f9158cf..0000000000
--- a/phpBB/develop/calc_email_hash.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-//
-// Security message:
-//
-// This script is potentially dangerous.
-// Remove or comment the next line (die(".... ) to enable this script.
-// Do NOT FORGET to either remove this script or disable it after you have used it.
-//
-die("Please read the first lines of this script for instructions on how to enable it");
-@set_time_limit(300);
-
-$db = $dbhost = $dbuser = $dbpasswd = $dbport = $dbname = '';
-
-define('IN_PHPBB', 1);
-define('ANONYMOUS', 1);
-$phpEx = substr(strrchr(__FILE__, '.'), 1);
-$phpbb_root_path='./../';
-include($phpbb_root_path . 'config.'.$phpEx);
-require($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.'.$phpEx);
-require($phpbb_root_path . 'includes/db/' . $dbms . '.'.$phpEx);
-include($phpbb_root_path . 'includes/functions.'.$phpEx);
-
-$cache = new acm();
-$db = new sql_db();
-
-// Connect to DB
-$db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false);
-
-$start = 0;
-do
-{
- // Batch query for group members, call group_user_del
- $sql = "SELECT user_id, user_email
- FROM {$table_prefix}users
- LIMIT $start, 100";
- $result = $db->sql_query($sql);
-
- if ($row = $db->sql_fetchrow($result))
- {
- do
- {
- $sql = "UPDATE {$table_prefix}users
- SET user_email_hash = " . (crc32(strtolower($row['user_email'])) . strlen($row['user_email'])) . '
- WHERE user_id = ' . $row['user_id'];
- $db->sql_query($sql);
-
- $start++;
- }
- while ($row = $db->sql_fetchrow($result));
-
- echo "<br />Batch -> $start\n";
- flush();
- }
- else
- {
- $start = 0;
- }
- $db->sql_freeresult($result);
-}
-while ($start);
-
-echo "<p><b>Done</b></p>\n";
diff --git a/phpBB/develop/regex.php b/phpBB/develop/regex.php
index 46b6fff701..77c6d5c0e6 100644
--- a/phpBB/develop/regex.php
+++ b/phpBB/develop/regex.php
@@ -8,46 +8,6 @@
//
die("Please read the first lines of this script for instructions on how to enable it");
-
-// IP regular expressions
-
-$dec_octet = '(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])';
-$h16 = '[\dA-F]{1,4}';
-$ipv4 = "(?:$dec_octet\.){3}$dec_octet";
-$ls32 = "(?:$h16:$h16|$ipv4)";
-
-$ipv6_construct = array(
- array(false, '', '{6}', $ls32),
- array(false, '::', '{0,5}', "(?:$h16(?::$h16)?|$ipv4)"),
- array('', ':', '{4}', $ls32),
- array('{1,2}', ':', '{3}', $ls32),
- array('{1,3}', ':', '{2}', $ls32),
- array('{1,4}', ':', '', $ls32),
- array('{1,5}', ':', false, $ls32),
- array('{1,6}', ':', false, $h16),
- array('{1,7}', ':', false, ''),
- array(false, '::', false, '')
-);
-
-$ipv6 = '(?:';
-foreach ($ipv6_construct as $ip_type)
-{
- $ipv6 .= '(?:';
- if ($ip_type[0] !== false)
- {
- $ipv6 .= "(?:$h16:)" . $ip_type[0];
- }
- $ipv6 .= $ip_type[1];
- if ($ip_type[2] !== false)
- {
- $ipv6 .= "(?:$h16:)" . $ip_type[2];
- }
- $ipv6 .= $ip_type[3] . ')|';
-}
-$ipv6 = substr($ipv6, 0, -1) . ')';
-
-echo 'IPv4: ' . $ipv4 . "<br />\nIPv6: " . $ipv6 . "<br />\n";
-
// URL regular expressions
$pct_encoded = "%[\dA-F]{2}";
diff --git a/phpBB/develop/regex_idn.php b/phpBB/develop/regex_idn.php
index 30373f8de3..24d1eb9196 100644
--- a/phpBB/develop/regex_idn.php
+++ b/phpBB/develop/regex_idn.php
@@ -8,45 +8,6 @@
//
die("Please read the first lines of this script for instructions on how to enable it");
-// IP regular expressions
-
-$dec_octet = '(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])';
-$h16 = '[\dA-F]{1,4}';
-$ipv4 = "(?:$dec_octet\.){3}$dec_octet";
-$ls32 = "(?:$h16:$h16|$ipv4)";
-
-$ipv6_construct = array(
- array(false, '', '{6}', $ls32),
- array(false, '::', '{0,5}', "(?:$h16(?::$h16)?|$ipv4)"),
- array('', ':', '{4}', $ls32),
- array('{1,2}', ':', '{3}', $ls32),
- array('{1,3}', ':', '{2}', $ls32),
- array('{1,4}', ':', '', $ls32),
- array('{1,5}', ':', false, $ls32),
- array('{1,6}', ':', false, $h16),
- array('{1,7}', ':', false, ''),
- array(false, '::', false, '')
-);
-
-$ipv6 = '(?:';
-foreach ($ipv6_construct as $ip_type)
-{
- $ipv6 .= '(?:';
- if ($ip_type[0] !== false)
- {
- $ipv6 .= "(?:$h16:)" . $ip_type[0];
- }
- $ipv6 .= $ip_type[1];
- if ($ip_type[2] !== false)
- {
- $ipv6 .= "(?:$h16:)" . $ip_type[2];
- }
- $ipv6 .= $ip_type[3] . ')|';
-}
-$ipv6 = substr($ipv6, 0, -1) . ')';
-
-echo 'IPv4: ' . $ipv4 . "<br /><br />\n\nIPv6: " . $ipv6 . "<br /><br />\n\n";
-
// URL regular expressions
/* IDN2008 characters derivation
@@ -72,7 +33,7 @@ $no_hangul = '\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C
*/
$no_cdm = '\x{20D0}-\x{20FF}'; // \p{block=Combining_Diacritical_Marks_For_Symbols}
$no_musical = '\x{1D100}-\x{1D1FF}'; // \p{block=Musical_Symbols}
-$no_ancient_greek_musical = '\x{1D200}-\x{1D24F}'; // \p{block=Ancient_Greek_Musical_Notation}
+$no_ancient_greek_musical = '\x{1D200}-\x{1D24F}'; // \p{block=Ancient_Greek_Musical_Notation}
/* Remove certain exceptions:
** U+0640 ARABIC TATWEEL
** U+07FA NKO LAJANYALAN
diff --git a/phpBB/develop/update_email_hash.php b/phpBB/develop/update_email_hash.php
deleted file mode 100644
index c149900d64..0000000000
--- a/phpBB/develop/update_email_hash.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-/**
-* Corrects user_email_hash values if DB moved from 32-bit system to 64-bit system or vice versa.
-* The CRC32 function in PHP generates different results for both systems.
-* @PHP dev team: no, a hexdec() applied to it does not solve the issue. And please document it.
-*
-*/
-die("Please read the first lines of this script for instructions on how to enable it");
-
-set_time_limit(0);
-
-define('IN_PHPBB', true);
-$phpbb_root_path = './../';
-$phpEx = substr(strrchr(__FILE__, '.'), 1);
-include($phpbb_root_path . 'common.' . $phpEx);
-
-// Start session management
-$user->session_begin();
-$auth->acl($user->data);
-$user->setup();
-
-$start = $request->variable('start', 0);
-$num_items = 1000;
-
-echo '<br />Updating user email hashes' . "\n";
-
-$sql = 'SELECT user_id, user_email
- FROM ' . USERS_TABLE . '
- ORDER BY user_id ASC';
-$result = $db->sql_query($sql);
-
-$echos = 0;
-while ($row = $db->sql_fetchrow($result))
-{
- $echos++;
-
- $sql = 'UPDATE ' . USERS_TABLE . "
- SET user_email_hash = '" . $db->sql_escape(phpbb_email_hash($row['user_email'])) . "'
- WHERE user_id = " . (int) $row['user_id'];
- $db->sql_query($sql);
-
- if ($echos == 200)
- {
- echo '<br />';
- $echos = 0;
- }
-
- echo '.';
- flush();
-}
-$db->sql_freeresult($result);
-
-echo 'FINISHED';
-
-// Done
-$db->sql_close();
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index 572ae3692a..ba3901f67a 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -132,6 +132,7 @@ class acp_forums
'forum_image' => $request->variable('forum_image', ''),
'forum_style' => $request->variable('forum_style', 0),
'display_subforum_list' => $request->variable('display_subforum_list', true),
+ 'display_subforum_limit'=> $request->variable('display_subforum_limit', false),
'display_on_index' => $request->variable('display_on_index', true),
'forum_topics_per_page' => $request->variable('topics_per_page', 0),
'enable_indexing' => $request->variable('enable_indexing', true),
@@ -454,6 +455,7 @@ class acp_forums
'forum_image' => '',
'forum_style' => 0,
'display_subforum_list' => true,
+ 'display_subforum_limit' => false,
'display_on_index' => true,
'forum_topics_per_page' => 0,
'enable_indexing' => true,
@@ -676,6 +678,7 @@ class acp_forums
'S_ENABLE_INDEXING' => ($forum_data['enable_indexing']) ? true : false,
'S_TOPIC_ICONS' => ($forum_data['enable_icons']) ? true : false,
'S_DISPLAY_SUBFORUM_LIST' => ($forum_data['display_subforum_list']) ? true : false,
+ 'S_DISPLAY_SUBFORUM_LIMIT' => ($forum_data['display_subforum_limit']) ? true : false,
'S_DISPLAY_ON_INDEX' => ($forum_data['display_on_index']) ? true : false,
'S_PRUNE_ENABLE' => ($forum_data['enable_prune']) ? true : false,
'S_PRUNE_SHADOW_ENABLE' => ($forum_data['enable_shadow_prune']) ? true : false,
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 1b66943490..6993c86279 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -966,10 +966,7 @@ class acp_users
if ($update_email !== false)
{
- $sql_ary += array(
- 'user_email' => $update_email,
- 'user_email_hash' => phpbb_email_hash($update_email),
- );
+ $sql_ary += ['user_email' => $update_email];
$phpbb_log->add('user', $user->data['user_id'], $user->ip, 'LOG_USER_UPDATE_EMAIL', false, array(
'reportee_id' => $user_id,
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 30f9734efd..c1f77a817b 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -264,18 +264,6 @@ function still_on_time($extra_time = 15)
}
/**
-* Hashes an email address to a big integer
-*
-* @param string $email Email address
-*
-* @return string Unsigned Big Integer
-*/
-function phpbb_email_hash($email)
-{
- return sprintf('%u', crc32(strtolower($email))) . strlen($email);
-}
-
-/**
* Wrapper for version_compare() that allows using uppercase A and B
* for alpha and beta releases.
*
@@ -2851,10 +2839,13 @@ function get_preg_expression($mode)
// Whoa these look impressive!
// The code to generate the following two regular expressions which match valid IPv4/IPv6 addresses
// can be found in the develop directory
+
+ // @deprecated
case 'ipv4':
return '#^(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$#';
break;
+ // @deprecated
case 'ipv6':
return '#^(?:(?:(?:[\dA-F]{1,4}:){6}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:::(?:[\dA-F]{1,4}:){0,5}(?:[\dA-F]{1,4}(?::[\dA-F]{1,4})?|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:):(?:[\dA-F]{1,4}:){4}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,2}:(?:[\dA-F]{1,4}:){3}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,3}:(?:[\dA-F]{1,4}:){2}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,4}:(?:[\dA-F]{1,4}:)(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,5}:(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,6}:[\dA-F]{1,4})|(?:(?:[\dA-F]{1,4}:){1,7}:)|(?:::))$#i';
break;
@@ -2980,165 +2971,26 @@ function short_ipv6($ip, $length)
* @return mixed false if specified address is not valid,
* string otherwise
*/
-function phpbb_ip_normalise($address)
+function phpbb_ip_normalise(string $address)
{
- $address = trim($address);
-
- if (empty($address) || !is_string($address))
- {
- return false;
- }
-
- if (preg_match(get_preg_expression('ipv4'), $address))
- {
- return $address;
- }
-
- return phpbb_inet_ntop(phpbb_inet_pton($address));
-}
-
-/**
-* Wrapper for inet_ntop()
-*
-* Converts a packed internet address to a human readable representation
-* inet_ntop() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
-*
-* @param string $in_addr A 32bit IPv4, or 128bit IPv6 address.
-*
-* @return mixed false on failure,
-* string otherwise
-*/
-function phpbb_inet_ntop($in_addr)
-{
- $in_addr = bin2hex($in_addr);
-
- switch (strlen($in_addr))
- {
- case 8:
- return implode('.', array_map('hexdec', str_split($in_addr, 2)));
-
- case 32:
- if (substr($in_addr, 0, 24) === '00000000000000000000ffff')
- {
- return phpbb_inet_ntop(pack('H*', substr($in_addr, 24)));
- }
-
- $parts = str_split($in_addr, 4);
- $parts = preg_replace('/^0+(?!$)/', '', $parts);
- $ret = implode(':', $parts);
-
- $matches = array();
- preg_match_all('/(?<=:|^)(?::?0){2,}/', $ret, $matches, PREG_OFFSET_CAPTURE);
- $matches = $matches[0];
-
- if (empty($matches))
- {
- return $ret;
- }
-
- $longest_match = '';
- $longest_match_offset = 0;
- foreach ($matches as $match)
- {
- if (strlen($match[0]) > strlen($longest_match))
- {
- $longest_match = $match[0];
- $longest_match_offset = $match[1];
- }
- }
-
- $ret = substr_replace($ret, '', $longest_match_offset, strlen($longest_match));
+ $ip_normalised = false;
- if ($longest_match_offset == strlen($ret))
- {
- $ret .= ':';
- }
-
- if ($longest_match_offset == 0)
- {
- $ret = ':' . $ret;
- }
-
- return $ret;
-
- default:
- return false;
- }
-}
-
-/**
-* Wrapper for inet_pton()
-*
-* Converts a human readable IP address to its packed in_addr representation
-* inet_pton() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
-*
-* @param string $address A human readable IPv4 or IPv6 address.
-*
-* @return mixed false if address is invalid,
-* in_addr representation of the given address otherwise (string)
-*/
-function phpbb_inet_pton($address)
-{
- $ret = '';
- if (preg_match(get_preg_expression('ipv4'), $address))
+ if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
{
- foreach (explode('.', $address) as $part)
- {
- $ret .= ($part <= 0xF ? '0' : '') . dechex($part);
- }
-
- return pack('H*', $ret);
+ $ip_normalised = $address;
}
-
- if (preg_match(get_preg_expression('ipv6'), $address))
+ else if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
{
- $parts = explode(':', $address);
- $missing_parts = 8 - count($parts) + 1;
+ $ip_normalised = inet_ntop(inet_pton($address));
- if (substr($address, 0, 2) === '::')
+ // If is ipv4
+ if (stripos($ip_normalised, '::ffff:') === 0)
{
- ++$missing_parts;
+ $ip_normalised = substr($ip_normalised, 7);
}
-
- if (substr($address, -2) === '::')
- {
- ++$missing_parts;
- }
-
- $embedded_ipv4 = false;
- $last_part = end($parts);
-
- if (preg_match(get_preg_expression('ipv4'), $last_part))
- {
- $parts[count($parts) - 1] = '';
- $last_part = phpbb_inet_pton($last_part);
- $embedded_ipv4 = true;
- --$missing_parts;
- }
-
- foreach ($parts as $i => $part)
- {
- if (strlen($part))
- {
- $ret .= str_pad($part, 4, '0', STR_PAD_LEFT);
- }
- else if ($i && $i < count($parts) - 1)
- {
- $ret .= str_repeat('0000', $missing_parts);
- }
- }
-
- $ret = pack('H*', $ret);
-
- if ($embedded_ipv4)
- {
- $ret .= $last_part;
- }
-
- return $ret;
}
- return false;
+ return $ip_normalised;
}
// Handler, header and footer
diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php
index 1f9131c9c0..92e24c055c 100644
--- a/phpBB/includes/functions_compatibility.php
+++ b/phpBB/includes/functions_compatibility.php
@@ -623,3 +623,53 @@ function phpbb_checkdnsrr($host, $type = 'MX')
{
return checkdnsrr($host, $type);
}
+
+/*
+ * Wrapper for inet_ntop()
+ *
+ * Converts a packed internet address to a human readable representation
+ * inet_ntop() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
+ *
+ * @param string $in_addr A 32bit IPv4, or 128bit IPv6 address.
+ *
+ * @return mixed false on failure,
+ * string otherwise
+ *
+ * @deprecated 3.3.0-b2 (To be removed: 4.0.0)
+ */
+function phpbb_inet_ntop($in_addr)
+{
+ return inet_ntop($in_addr);
+}
+
+/**
+ * Wrapper for inet_pton()
+ *
+ * Converts a human readable IP address to its packed in_addr representation
+ * inet_pton() is supported by PHP since 5.1.0, since 5.3.0 also on Windows.
+ *
+ * @param string $address A human readable IPv4 or IPv6 address.
+ *
+ * @return mixed false if address is invalid,
+ * in_addr representation of the given address otherwise (string)
+ *
+ * @deprecated 3.3.0-b2 (To be removed: 4.0.0)
+ */
+function phpbb_inet_pton($address)
+{
+ return inet_pton($address);
+}
+
+/**
+ * Hashes an email address to a big integer
+ *
+ * @param string $email Email address
+ *
+ * @return string Unsigned Big Integer
+ *
+ * @deprecated 3.3.0-b2 (To be removed: 4.0.0)
+ */
+function phpbb_email_hash($email)
+{
+ return sprintf('%u', crc32(strtolower($email))) . strlen($email);
+}
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index 13e01afe51..df4c9b1875 100644
--- a/phpBB/includes/functions_convert.php
+++ b/phpBB/includes/functions_convert.php
@@ -207,16 +207,6 @@ function get_group_id($group_name)
}
/**
-* Generate the email hash stored in the users table
-*
-* Note: Deprecated, calls should directly go to phpbb_email_hash()
-*/
-function gen_email_hash($email)
-{
- return phpbb_email_hash($email);
-}
-
-/**
* Convert a boolean into the appropriate phpBB constant indicating whether the topic is locked
*/
function is_topic_locked($bool)
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index 1ac18fd3f8..44478dbe49 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -30,6 +30,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$forum_rows = $subforums = $forum_ids = $forum_ids_moderator = $forum_moderators = $active_forum_ary = array();
$parent_id = $visible_forums = 0;
+ $parent_subforum_limit = false;
// Mark forums read?
$mark_read = $request->variable('mark', '');
@@ -266,6 +267,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
// Direct child of current branch
$parent_id = $forum_id;
+ $parent_subforum_limit = $row['display_subforum_limit'];
$forum_rows[$forum_id] = $row;
if ($row['forum_type'] == FORUM_CAT && $row['parent_id'] == $root_data['forum_id'])
@@ -278,7 +280,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
}
else if ($row['forum_type'] != FORUM_CAT)
{
- $subforums[$parent_id][$forum_id]['display'] = ($row['display_on_index']) ? true : false;
+ $subforums[$parent_id][$forum_id]['display'] = ($row['display_on_index'] && (!$parent_subforum_limit || $parent_id == $row['parent_id']));
$subforums[$parent_id][$forum_id]['name'] = $row['forum_name'];
$subforums[$parent_id][$forum_id]['orig_forum_last_post_time'] = $row['forum_last_post_time'];
$subforums[$parent_id][$forum_id]['children'] = array();
@@ -539,7 +541,8 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
{
if ($row['forum_password_last_post'] === '' && $auth->acl_gets('f_read', 'f_list_topics', $row['forum_id_last_post']))
{
- $last_post_subject = censor_text($row['forum_last_post_subject']);
+ $last_post_subject = utf8_decode_ncr(censor_text($row['forum_last_post_subject']));
+
$last_post_subject_truncated = truncate_string($last_post_subject, 30, 255, false, $user->lang['ELLIPSIS']);
}
else
diff --git a/phpBB/includes/functions_transfer.php b/phpBB/includes/functions_transfer.php
index 7427b89917..f0070b4b1e 100644
--- a/phpBB/includes/functions_transfer.php
+++ b/phpBB/includes/functions_transfer.php
@@ -810,7 +810,7 @@ class ftp_fsock extends transfer
$server_ip = substr($socket_name, 0, strrpos($socket_name, ':'));
}
- if (!isset($server_ip) || preg_match(get_preg_expression('ipv4'), $server_ip))
+ if (isset($server_ip) && filter_var($server_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) // ipv4
{
// Passive mode
$this->_send_command('PASV', '', false);
@@ -831,7 +831,7 @@ class ftp_fsock extends transfer
$server_ip = $temp[0] . '.' . $temp[1] . '.' . $temp[2] . '.' . $temp[3];
$server_port = $temp[4] * 256 + $temp[5];
}
- else
+ else // ipv6
{
// Extended Passive Mode - RFC2428
$this->_send_command('EPSV', '', false);
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 7dd850111e..dc6e09268a 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -204,7 +204,6 @@ function user_add($user_row, $cp_data = false, $notifications_data = null)
'username_clean' => $username_clean,
'user_password' => (isset($user_row['user_password'])) ? $user_row['user_password'] : '',
'user_email' => strtolower($user_row['user_email']),
- 'user_email_hash' => phpbb_email_hash($user_row['user_email']),
'group_id' => $user_row['group_id'],
'user_type' => $user_row['user_type'],
);
@@ -1455,12 +1454,7 @@ function user_unban($mode, $ban)
*/
function user_ipwhois($ip)
{
- if (empty($ip))
- {
- return '';
- }
-
- if (!preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip))
+ if (!filter_var($ip, FILTER_VALIDATE_IP))
{
return '';
}
@@ -1953,9 +1947,9 @@ function validate_user_email($email, $allowed_email = false)
if (!$config['allow_emailreuse'])
{
- $sql = 'SELECT user_email_hash
+ $sql = 'SELECT user_email
FROM ' . USERS_TABLE . "
- WHERE user_email_hash = " . $db->sql_escape(phpbb_email_hash($email));
+ WHERE user_email = '" . $db->sql_escape($email) . "'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index 6d98362e08..dca7e7eeb7 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -131,7 +131,6 @@ class ucp_profile
'username' => ($auth->acl_get('u_chgname') && $config['allow_namechange']) ? $data['username'] : $user->data['username'],
'username_clean' => ($auth->acl_get('u_chgname') && $config['allow_namechange']) ? utf8_clean_string($data['username']) : $user->data['username_clean'],
'user_email' => ($auth->acl_get('u_chgemail')) ? $data['email'] : $user->data['user_email'],
- 'user_email_hash' => ($auth->acl_get('u_chgemail')) ? phpbb_email_hash($data['email']) : $user->data['user_email_hash'],
'user_password' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? $passwords_manager->hash($data['new_password']) : $user->data['user_password'],
);
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 97d2631224..694aaf1351 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -45,6 +45,11 @@ class ucp_register
$change_lang = $request->variable('change_lang', '');
$user_lang = $request->variable('lang', $user->lang_name);
+ if ($agreed && !check_form_key('ucp_register'))
+ {
+ $agreed = false;
+ }
+
/**
* Add UCP register data before they are assigned to the template or submitted
*
@@ -67,14 +72,7 @@ class ucp_register
);
extract($phpbb_dispatcher->trigger_event('core.ucp_register_requests_after', compact($vars)));
- if ($agreed)
- {
- add_form_key('ucp_register');
- }
- else
- {
- add_form_key('ucp_register_terms');
- }
+ add_form_key('ucp_register');
if ($change_lang || $user_lang != $config['default_lang'])
{
diff --git a/phpBB/includes/ucp/ucp_resend.php b/phpBB/includes/ucp/ucp_resend.php
index 44c54100cd..55923668d4 100644
--- a/phpBB/includes/ucp/ucp_resend.php
+++ b/phpBB/includes/ucp/ucp_resend.php
@@ -47,7 +47,7 @@ class ucp_resend
$sql = 'SELECT user_id, group_id, username, user_email, user_type, user_lang, user_actkey, user_inactive_reason
FROM ' . USERS_TABLE . "
- WHERE user_email_hash = '" . $db->sql_escape(phpbb_email_hash($email)) . "'
+ WHERE user_email = '" . $db->sql_escape($email) . "'
AND username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'";
$result = $db->sql_query($sql);
$user_row = $db->sql_fetchrow($result);
diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php
index c4d2be5a28..6da6e2eb22 100644
--- a/phpBB/install/convertors/convert_phpbb20.php
+++ b/phpBB/install/convertors/convert_phpbb20.php
@@ -899,7 +899,6 @@ if (!$get_info)
array('user_password', 'users.user_password', 'phpbb_convert_password_hash'),
array('user_posts', 'users.user_posts', 'intval'),
array('user_email', 'users.user_email', 'strtolower'),
- array('user_email_hash', 'users.user_email', 'gen_email_hash'),
array('user_birthday', ((defined('MOD_BIRTHDAY')) ? 'users.user_birthday' : ''), 'phpbb_get_birthday'),
array('user_lastvisit', 'users.user_lastvisit', 'intval'),
array('user_lastmark', 'users.user_lastvisit', 'intval'),
diff --git a/phpBB/language/en/acp/forums.php b/phpBB/language/en/acp/forums.php
index d92d3f8c9e..3ab152345c 100644
--- a/phpBB/language/en/acp/forums.php
+++ b/phpBB/language/en/acp/forums.php
@@ -129,6 +129,8 @@ $lang = array_merge($lang, array(
'GENERAL_FORUM_SETTINGS' => 'General forum settings',
'LINK' => 'Link',
+ 'LIMIT_SUBFORUMS' => 'Limit legend to direct child-subforums',
+ 'LIMIT_SUBFORUMS_EXPLAIN' => 'Limits the subforums to be displayed to subforums that are direct descendants (children) of the current forum. Disabling this will display all subforums with the “List subforums in legend” option enabled, regardless of depth.',
'LIST_INDEX' => 'List subforum in parent-forum’s legend',
'LIST_INDEX_EXPLAIN' => 'Displays this forum on the index and elsewhere as a link within the legend of its parent-forum if the parent-forum’s “List subforums in legend” option is enabled.',
'LIST_SUBFORUMS' => 'List subforums in legend',
diff --git a/phpBB/language/en/cli.php b/phpBB/language/en/cli.php
index 505d12e8ff..122010d2cf 100644
--- a/phpBB/language/en/cli.php
+++ b/phpBB/language/en/cli.php
@@ -78,8 +78,6 @@ $lang = array_merge($lang, array(
'CLI_DESCRIPTION_REPARSER_REPARSE_OPT_RANGE_SIZE' => 'Approximate number of records to process at a time',
'CLI_DESCRIPTION_REPARSER_REPARSE_OPT_RESUME' => 'Start reparsing where the last execution stopped',
- 'CLI_DESCRIPTION_RECALCULATE_EMAIL_HASH' => 'Recalculates the user_email_hash column of the users table.',
-
'CLI_DESCRIPTION_SET_ATOMIC_CONFIG' => 'Sets a configuration option’s value only if the old matches the current value',
'CLI_DESCRIPTION_SET_CONFIG' => 'Sets a configuration option’s value',
@@ -130,7 +128,6 @@ $lang = array_merge($lang, array(
'CLI_EXTENSIONS_ENABLED' => 'Enabled',
'CLI_FIXUP_FIX_LEFT_RIGHT_IDS_SUCCESS' => 'Successfully repaired the tree structure of the forums and modules.',
- 'CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS' => 'Successfully recalculated all email hashes.',
'CLI_FIXUP_UPDATE_HASH_BCRYPT_SUCCESS' => 'Successfully updated outdated password hashes to bcrypt.',
'CLI_MIGRATION_NAME' => 'Migration name, including the namespace (use forward slashes instead of backslashes to avoid problems).',
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index b0c6f7fd1c..609ae4fe53 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -94,6 +94,7 @@ $lang = array_merge($lang, array(
'AUTH_PROVIDER_OAUTH_ERROR_ALREADY_LINKED' => 'This external service is already associated with another board account.',
'AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY' => 'Invalid database entry.',
'AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE' => 'Invalid service type provided to OAuth service handler.',
+ 'AUTH_PROVIDER_OAUTH_ERROR_REQUEST' => 'Something went wrong when processing your OAuth request.',
'AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED' => 'OAuth service not created',
'AUTH_PROVIDER_OAUTH_SERVICE_BITLY' => 'Bitly',
'AUTH_PROVIDER_OAUTH_SERVICE_FACEBOOK' => 'Facebook',
diff --git a/phpBB/phpbb/auth/provider/apache.php b/phpBB/phpbb/auth/provider/apache.php
index aa5bf64335..a713674657 100644
--- a/phpBB/phpbb/auth/provider/apache.php
+++ b/phpBB/phpbb/auth/provider/apache.php
@@ -13,34 +13,55 @@
namespace phpbb\auth\provider;
+use phpbb\config\config;
+use phpbb\db\driver\driver_interface;
+use phpbb\language\language;
+use phpbb\request\request_interface;
+use phpbb\request\type_cast_helper;
+use phpbb\user;
+
/**
* Apache authentication provider for phpBB3
*/
-class apache extends \phpbb\auth\provider\base
+class apache extends base
{
- /**
- * phpBB passwords manager
- *
- * @var \phpbb\passwords\manager
- */
- protected $passwords_manager;
+ /** @var config phpBB config */
+ protected $config;
+
+ /** @var driver_interface Database object */
+ protected $db;
+
+ /** @var language Language object */
+ protected $language;
+
+ /** @var request_interface Request object */
+ protected $request;
+
+ /** @var user User object */
+ protected $user;
+
+ /** @var string Relative path to phpBB root */
+ protected $phpbb_root_path;
+
+ /** @var string PHP file extension */
+ protected $php_ext;
/**
* Apache Authentication Constructor
*
- * @param \phpbb\db\driver\driver_interface $db Database object
- * @param \phpbb\config\config $config Config object
- * @param \phpbb\passwords\manager $passwords_manager Passwords Manager object
- * @param \phpbb\request\request $request Request object
- * @param \phpbb\user $user User object
+ * @param config $config Config object
+ * @param driver_interface $db Database object
+ * @param language $language Language object
+ * @param request_interface $request Request object
+ * @param user $user User object
* @param string $phpbb_root_path Relative path to phpBB root
* @param string $php_ext PHP file extension
*/
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext)
+ public function __construct(config $config, driver_interface $db, language $language, request_interface $request, user $user, $phpbb_root_path, $php_ext)
{
- $this->db = $db;
$this->config = $config;
- $this->passwords_manager = $passwords_manager;
+ $this->db = $db;
+ $this->language = $language;
$this->request = $request;
$this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
@@ -52,9 +73,9 @@ class apache extends \phpbb\auth\provider\base
*/
public function init()
{
- if (!$this->request->is_set('PHP_AUTH_USER', \phpbb\request\request_interface::SERVER) || $this->user->data['username'] !== htmlspecialchars_decode($this->request->server('PHP_AUTH_USER')))
+ if (!$this->request->is_set('PHP_AUTH_USER', request_interface::SERVER) || $this->user->data['username'] !== htmlspecialchars_decode($this->request->server('PHP_AUTH_USER')))
{
- return $this->user->lang['APACHE_SETUP_BEFORE_USE'];
+ return $this->language->lang('APACHE_SETUP_BEFORE_USE');
}
return false;
}
@@ -83,7 +104,7 @@ class apache extends \phpbb\auth\provider\base
);
}
- if (!$this->request->is_set('PHP_AUTH_USER', \phpbb\request\request_interface::SERVER))
+ if (!$this->request->is_set('PHP_AUTH_USER', request_interface::SERVER))
{
return array(
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
@@ -137,7 +158,7 @@ class apache extends \phpbb\auth\provider\base
return array(
'status' => LOGIN_SUCCESS_CREATE_PROFILE,
'error_msg' => false,
- 'user_row' => $this->user_row($php_auth_user, $php_auth_pw),
+ 'user_row' => $this->user_row($php_auth_user),
);
}
@@ -154,7 +175,7 @@ class apache extends \phpbb\auth\provider\base
*/
public function autologin()
{
- if (!$this->request->is_set('PHP_AUTH_USER', \phpbb\request\request_interface::SERVER))
+ if (!$this->request->is_set('PHP_AUTH_USER', request_interface::SERVER))
{
return array();
}
@@ -164,8 +185,8 @@ class apache extends \phpbb\auth\provider\base
if (!empty($php_auth_user) && !empty($php_auth_pw))
{
- set_var($php_auth_user, $php_auth_user, 'string', true);
- set_var($php_auth_pw, $php_auth_pw, 'string', true);
+ $type_cast_helper = new type_cast_helper();
+ $type_cast_helper->set_var($php_auth_user, $php_auth_user, 'string', true);
$sql = 'SELECT *
FROM ' . USERS_TABLE . "
@@ -185,7 +206,7 @@ class apache extends \phpbb\auth\provider\base
}
// create the user if he does not exist yet
- user_add($this->user_row($php_auth_user, $php_auth_pw));
+ user_add($this->user_row($php_auth_user));
$sql = 'SELECT *
FROM ' . USERS_TABLE . "
@@ -208,11 +229,11 @@ class apache extends \phpbb\auth\provider\base
* function in order to create a user
*
* @param string $username The username of the new user.
- * @param string $password The password of the new user.
+ *
* @return array Contains data that can be passed directly to
* the user_add function.
*/
- private function user_row($username, $password)
+ private function user_row($username)
{
// first retrieve default group id
$sql = 'SELECT group_id
@@ -231,7 +252,7 @@ class apache extends \phpbb\auth\provider\base
// generate user account data
return array(
'username' => $username,
- 'user_password' => $this->passwords_manager->hash($password),
+ 'user_password' => '',
'user_email' => '',
'group_id' => (int) $row['group_id'],
'user_type' => USER_NORMAL,
@@ -246,7 +267,7 @@ class apache extends \phpbb\auth\provider\base
public function validate_session($user)
{
// Check if PHP_AUTH_USER is set and handle this case
- if ($this->request->is_set('PHP_AUTH_USER', \phpbb\request\request_interface::SERVER))
+ if ($this->request->is_set('PHP_AUTH_USER', request_interface::SERVER))
{
$php_auth_user = $this->request->server('PHP_AUTH_USER');
diff --git a/phpBB/phpbb/auth/provider/base.php b/phpBB/phpbb/auth/provider/base.php
index dea27ccc25..30e0a0fe2d 100644
--- a/phpBB/phpbb/auth/provider/base.php
+++ b/phpBB/phpbb/auth/provider/base.php
@@ -16,7 +16,7 @@ namespace phpbb\auth\provider;
/**
* Base authentication provider class that all other providers should implement
*/
-abstract class base implements \phpbb\auth\provider\provider_interface
+abstract class base implements provider_interface
{
/**
* {@inheritdoc}
diff --git a/phpBB/phpbb/auth/provider/db.php b/phpBB/phpbb/auth/provider/db.php
index 1adf85ee05..a70734fcbe 100644
--- a/phpBB/phpbb/auth/provider/db.php
+++ b/phpBB/phpbb/auth/provider/db.php
@@ -13,48 +13,69 @@
namespace phpbb\auth\provider;
+use phpbb\captcha\factory;
+use phpbb\config\config;
+use phpbb\db\driver\driver_interface;
+use phpbb\passwords\manager;
+use phpbb\request\request_interface;
+use phpbb\user;
+
/**
* Database authentication provider for phpBB3
* This is for authentication via the integrated user table
*/
-class db extends \phpbb\auth\provider\base
+class db extends base
{
+ /** @var factory CAPTCHA factory */
+ protected $captcha_factory;
+
+ /** @var config phpBB config */
+ protected $config;
+
+ /** @var driver_interface DBAL driver instance */
+ protected $db;
+
+ /** @var request_interface Request object */
+ protected $request;
+
+ /** @var user User object */
+ protected $user;
+
+ /** @var string phpBB root path */
+ protected $phpbb_root_path;
+
+ /** @var string PHP file extension */
+ protected $php_ext;
+
/**
* phpBB passwords manager
*
- * @var \phpbb\passwords\manager
+ * @var manager
*/
protected $passwords_manager;
/**
- * DI container
- *
- * @var \Symfony\Component\DependencyInjection\ContainerInterface
- */
- protected $phpbb_container;
-
- /**
* Database Authentication Constructor
*
- * @param \phpbb\db\driver\driver_interface $db
- * @param \phpbb\config\config $config
- * @param \phpbb\passwords\manager $passwords_manager
- * @param \phpbb\request\request $request
- * @param \phpbb\user $user
- * @param \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container DI container
+ * @param factory $captcha_factory
+ * @param config $config
+ * @param driver_interface $db
+ * @param manager $passwords_manager
+ * @param request_interface $request
+ * @param user $user
* @param string $phpbb_root_path
* @param string $php_ext
*/
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, $phpbb_root_path, $php_ext)
+ public function __construct(factory $captcha_factory, config $config, driver_interface $db, manager $passwords_manager, request_interface $request, user $user, $phpbb_root_path, $php_ext)
{
- $this->db = $db;
+ $this->captcha_factory = $captcha_factory;
$this->config = $config;
+ $this->db = $db;
$this->passwords_manager = $passwords_manager;
$this->request = $request;
$this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
- $this->phpbb_container = $phpbb_container;
}
/**
@@ -155,9 +176,7 @@ class db extends \phpbb\auth\provider\base
// Every auth module is able to define what to do by itself...
if ($show_captcha)
{
- /* @var $captcha_factory \phpbb\captcha\factory */
- $captcha_factory = $this->phpbb_container->get('captcha.factory');
- $captcha = $captcha_factory->get_instance($this->config['captcha_plugin']);
+ $captcha = $this->captcha_factory->get_instance($this->config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
$vc_response = $captcha->validate($row);
if ($vc_response)
diff --git a/phpBB/phpbb/auth/provider/ldap.php b/phpBB/phpbb/auth/provider/ldap.php
index 0789a6234d..6a78136e5f 100644
--- a/phpBB/phpbb/auth/provider/ldap.php
+++ b/phpBB/phpbb/auth/provider/ldap.php
@@ -1,4 +1,5 @@
<?php
+
/**
*
* This file is part of the phpBB Forum Software package.
@@ -13,32 +14,42 @@
namespace phpbb\auth\provider;
+use phpbb\config\config;
+use phpbb\db\driver\driver_interface;
+use phpbb\language\language;
+use phpbb\user;
+
/**
* Database authentication provider for phpBB3
* This is for authentication via the integrated user table
*/
-class ldap extends \phpbb\auth\provider\base
+class ldap extends base
{
- /**
- * phpBB passwords manager
- *
- * @var \phpbb\passwords\manager
- */
- protected $passwords_manager;
+ /** @var config phpBB config */
+ protected $config;
+
+ /** @var driver_interface DBAL driver interface */
+ protected $db;
+
+ /** @var language phpBB language class */
+ protected $language;
+
+ /** @var user phpBB user */
+ protected $user;
/**
* LDAP Authentication Constructor
*
- * @param \phpbb\db\driver\driver_interface $db Database object
- * @param \phpbb\config\config $config Config object
- * @param \phpbb\passwords\manager $passwords_manager Passwords manager object
- * @param \phpbb\user $user User object
+ * @param driver_interface $db DBAL driver interface
+ * @param config $config Config object
+ * @param language $language Language object
+ * @param user $user User object
*/
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\user $user)
+ public function __construct(config $config, driver_interface $db, language $language, user $user)
{
- $this->db = $db;
$this->config = $config;
- $this->passwords_manager = $passwords_manager;
+ $this->db = $db;
+ $this->language = $language;
$this->user = $user;
}
@@ -49,7 +60,7 @@ class ldap extends \phpbb\auth\provider\base
{
if (!@extension_loaded('ldap'))
{
- return $this->user->lang['LDAP_NO_LDAP_EXTENSION'];
+ return $this->language->lang('LDAP_NO_LDAP_EXTENSION');
}
$this->config['ldap_port'] = (int) $this->config['ldap_port'];
@@ -64,7 +75,7 @@ class ldap extends \phpbb\auth\provider\base
if (!$ldap)
{
- return $this->user->lang['LDAP_NO_SERVER_CONNECTION'];
+ return $this->language->lang('LDAP_NO_SERVER_CONNECTION');
}
@ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
@@ -74,7 +85,7 @@ class ldap extends \phpbb\auth\provider\base
{
if (!@ldap_bind($ldap, htmlspecialchars_decode($this->config['ldap_user']), htmlspecialchars_decode($this->config['ldap_password'])))
{
- return $this->user->lang['LDAP_INCORRECT_USER_PASSWORD'];
+ return $this->language->lang('LDAP_INCORRECT_USER_PASSWORD');
}
}
@@ -92,7 +103,7 @@ class ldap extends \phpbb\auth\provider\base
if ($search === false)
{
- return $this->user->lang['LDAP_SEARCH_FAILED'];
+ return $this->language->lang('LDAP_SEARCH_FAILED');
}
$result = @ldap_get_entries($ldap, $search);
@@ -101,12 +112,12 @@ class ldap extends \phpbb\auth\provider\base
if (!is_array($result) || count($result) < 2)
{
- return sprintf($this->user->lang['LDAP_NO_IDENTITY'], $this->user->data['username']);
+ return $this->language->lang('LDAP_NO_IDENTITY', $this->user->data['username']);
}
if (!empty($this->config['ldap_email']) && !isset($result[0][htmlspecialchars_decode($this->config['ldap_email'])]))
{
- return $this->user->lang['LDAP_NO_EMAIL'];
+ return $this->language->lang('LDAP_NO_EMAIL');
}
return false;
@@ -245,7 +256,7 @@ class ldap extends \phpbb\auth\provider\base
// generate user account data
$ldap_user_row = array(
'username' => $username,
- 'user_password' => $this->passwords_manager->hash($password),
+ 'user_password' => '',
'user_email' => (!empty($this->config['ldap_email'])) ? utf8_htmlspecialchars($ldap_result[0][htmlspecialchars_decode($this->config['ldap_email'])][0]) : '',
'group_id' => (int) $row['group_id'],
'user_type' => USER_NORMAL,
diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php
index e3f8394bba..29ffe6d591 100644
--- a/phpBB/phpbb/auth/provider/oauth/oauth.php
+++ b/phpBB/phpbb/auth/provider/oauth/oauth.php
@@ -1,169 +1,137 @@
<?php
/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
namespace phpbb\auth\provider\oauth;
+use OAuth\Common\Http\Exception\TokenResponseException;
+use OAuth\ServiceFactory;
use OAuth\Common\Consumer\Credentials;
+use OAuth\Common\Service\ServiceInterface;
+use OAuth\OAuth1\Service\AbstractService as OAuth1Service;
+use OAuth\OAuth2\Service\AbstractService as OAuth2Service;
+use phpbb\auth\provider\base;
+use phpbb\auth\provider\db;
+use phpbb\auth\provider\oauth\service\exception;
+use phpbb\config\config;
+use phpbb\db\driver\driver_interface;
+use phpbb\di\service_collection;
+use phpbb\event\dispatcher;
+use phpbb\language\language;
+use phpbb\request\request_interface;
+use phpbb\user;
/**
-* OAuth authentication provider for phpBB3
-*/
-class oauth extends \phpbb\auth\provider\base
+ * OAuth authentication provider for phpBB3
+ */
+class oauth extends base
{
- /**
- * Database driver
- *
- * @var \phpbb\db\driver\driver_interface
- */
- protected $db;
-
- /**
- * phpBB config
- *
- * @var \phpbb\config\config
- */
+ /** @var config */
protected $config;
- /**
- * phpBB passwords manager
- *
- * @var \phpbb\passwords\manager
- */
- protected $passwords_manager;
-
- /**
- * phpBB request object
- *
- * @var \phpbb\request\request_interface
- */
- protected $request;
+ /** @var driver_interface */
+ protected $db;
- /**
- * phpBB user
- *
- * @var \phpbb\user
- */
- protected $user;
+ /** @var db */
+ protected $db_auth;
- /**
- * OAuth token table
- *
- * @var string
- */
- protected $auth_provider_oauth_token_storage_table;
+ /** @var dispatcher */
+ protected $dispatcher;
- /**
- * OAuth state table
- *
- * @var string
- */
- protected $auth_provider_oauth_state_table;
+ /** @var language */
+ protected $language;
- /**
- * OAuth account association table
- *
- * @var string
- */
- protected $auth_provider_oauth_token_account_assoc;
+ /** @var request_interface */
+ protected $request;
- /**
- * All OAuth service providers
- *
- * @var \phpbb\di\service_collection Contains \phpbb\auth\provider\oauth\service_interface
- */
+ /** @var service_collection */
protected $service_providers;
- /**
- * Users table
- *
- * @var string
- */
- protected $users_table;
+ /** @var user */
+ protected $user;
- /**
- * Cached current uri object
- *
- * @var \OAuth\Common\Http\Uri\UriInterface|null
- */
- protected $current_uri;
+ /** @var string OAuth table: token storage */
+ protected $oauth_token_table;
- /**
- * DI container
- *
- * @var \Symfony\Component\DependencyInjection\ContainerInterface
- */
- protected $phpbb_container;
+ /** @var string OAuth table: state */
+ protected $oauth_state_table;
- /**
- * phpBB event dispatcher
- *
- * @var \phpbb\event\dispatcher_interface
- */
- protected $dispatcher;
+ /** @var string OAuth table: account association */
+ protected $oauth_account_table;
- /**
- * phpBB root path
- *
- * @var string
- */
- protected $phpbb_root_path;
+ /** @var string Users table */
+ protected $users_table;
- /**
- * PHP file extension
- *
- * @var string
- */
+ /** @var string phpBB root path */
+ protected $root_path;
+
+ /** @var string php File extension */
protected $php_ext;
/**
- * OAuth Authentication Constructor
- *
- * @param \phpbb\db\driver\driver_interface $db
- * @param \phpbb\config\config $config
- * @param \phpbb\passwords\manager $passwords_manager
- * @param \phpbb\request\request_interface $request
- * @param \phpbb\user $user
- * @param string $auth_provider_oauth_token_storage_table
- * @param string $auth_provider_oauth_state_table
- * @param string $auth_provider_oauth_token_account_assoc
- * @param \phpbb\di\service_collection $service_providers Contains \phpbb\auth\provider\oauth\service_interface
- * @param string $users_table
- * @param \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container DI container
- * @param \phpbb\event\dispatcher_interface $dispatcher phpBB event dispatcher
- * @param string $phpbb_root_path
- * @param string $php_ext
- */
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_state_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, \phpbb\event\dispatcher_interface $dispatcher, $phpbb_root_path, $php_ext)
+ * Constructor.
+ *
+ * @param config $config Config object
+ * @param driver_interface $db Database object
+ * @param db $db_auth DB auth provider
+ * @param dispatcher $dispatcher Event dispatcher object
+ * @param language $language Language object
+ * @param request_interface $request Request object
+ * @param service_collection $service_providers OAuth providers service collection
+ * @param user $user User object
+ * @param string $oauth_token_table OAuth table: token storage
+ * @param string $oauth_state_table OAuth table: state
+ * @param string $oauth_account_table OAuth table: account association
+ * @param string $users_table User table
+ * @param string $root_path phpBB root path
+ * @param string $php_ext php File extension
+ */
+ public function __construct(
+ config $config,
+ driver_interface $db,
+ db $db_auth,
+ dispatcher $dispatcher,
+ language $language,
+ request_interface $request,
+ service_collection $service_providers,
+ user $user,
+ $oauth_token_table,
+ $oauth_state_table,
+ $oauth_account_table,
+ $users_table,
+ $root_path,
+ $php_ext
+ )
{
- $this->db = $db;
- $this->config = $config;
- $this->passwords_manager = $passwords_manager;
- $this->request = $request;
- $this->user = $user;
- $this->auth_provider_oauth_token_storage_table = $auth_provider_oauth_token_storage_table;
- $this->auth_provider_oauth_state_table = $auth_provider_oauth_state_table;
- $this->auth_provider_oauth_token_account_assoc = $auth_provider_oauth_token_account_assoc;
- $this->service_providers = $service_providers;
- $this->users_table = $users_table;
- $this->phpbb_container = $phpbb_container;
- $this->dispatcher = $dispatcher;
- $this->phpbb_root_path = $phpbb_root_path;
- $this->php_ext = $php_ext;
+ $this->config = $config;
+ $this->db = $db;
+ $this->db_auth = $db_auth;
+ $this->dispatcher = $dispatcher;
+ $this->language = $language;
+ $this->service_providers = $service_providers;
+ $this->request = $request;
+ $this->user = $user;
+
+ $this->oauth_token_table = $oauth_token_table;
+ $this->oauth_state_table = $oauth_state_table;
+ $this->oauth_account_table = $oauth_account_table;
+ $this->users_table = $users_table;
+ $this->root_path = $root_path;
+ $this->php_ext = $php_ext;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function init()
{
// This does not test whether or not the key and secret provided are valid.
@@ -173,61 +141,85 @@ class oauth extends \phpbb\auth\provider\base
if (($credentials['key'] && !$credentials['secret']) || (!$credentials['key'] && $credentials['secret']))
{
- return $this->user->lang['AUTH_PROVIDER_OAUTH_ERROR_ELEMENT_MISSING'];
+ return $this->language->lang('AUTH_PROVIDER_OAUTH_ERROR_ELEMENT_MISSING');
}
}
+
return false;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function login($username, $password)
{
// Temporary workaround for only having one authentication provider available
if (!$this->request->is_set('oauth_service'))
{
- $provider = new \phpbb\auth\provider\db($this->db, $this->config, $this->passwords_manager, $this->request, $this->user, $this->phpbb_container, $this->phpbb_root_path, $this->php_ext);
- return $provider->login($username, $password);
+ return $this->db_auth->login($username, $password);
}
// Request the name of the OAuth service
- $service_name_original = $this->request->variable('oauth_service', '', false);
- $service_name = 'auth.provider.oauth.service.' . strtolower($service_name_original);
- if ($service_name_original === '' || !array_key_exists($service_name, $this->service_providers))
+ $provider = $this->request->variable('oauth_service', '', false);
+ $service_name = $this->get_service_name($provider);
+
+ if ($provider === '' || !array_key_exists($service_name, $this->service_providers))
{
- return array(
+ return [
'status' => LOGIN_ERROR_EXTERNAL_AUTH,
'error_msg' => 'LOGIN_ERROR_OAUTH_SERVICE_DOES_NOT_EXIST',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
+ 'user_row' => ['user_id' => ANONYMOUS],
+ ];
}
// Get the service credentials for the given service
- $service_credentials = $this->service_providers[$service_name]->get_service_credentials();
+ $storage = new token_storage($this->db, $this->user, $this->oauth_token_table, $this->oauth_state_table);
+ $query = 'mode=login&login=external&oauth_service=' . $provider;
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
- $query = 'mode=login&login=external&oauth_service=' . $service_name_original;
- $service = $this->get_service($service_name_original, $storage, $service_credentials, $query, $this->service_providers[$service_name]->get_auth_scope());
+ try
+ {
+ /** @var OAuth1Service|OAuth2Service $service */
+ $service = $this->get_service($provider, $storage, $query);
+ }
+ catch (\Exception $e)
+ {
+ return [
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => $e->getMessage(),
+ 'user_row' => ['user_id' => ANONYMOUS],
+ ];
+ }
- if (($service::OAUTH_VERSION === 2 && $this->request->is_set('code', \phpbb\request\request_interface::GET))
- || ($service::OAUTH_VERSION === 1 && $this->request->is_set('oauth_token', \phpbb\request\request_interface::GET)))
+ if ($this->is_set_code($service))
{
$this->service_providers[$service_name]->set_external_service_provider($service);
- $unique_id = $this->service_providers[$service_name]->perform_auth_login();
+
+ try
+ {
+ $unique_id = $this->service_providers[$service_name]->perform_auth_login();
+ }
+ catch (exception $e)
+ {
+ return [
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => $e->getMessage(),
+ 'user_row' => ['user_id' => ANONYMOUS],
+ ];
+ }
/**
* Check to see if this provider is already associated with an account.
*
- * Enforcing a data type to make data contains strings and not integers,
+ * Enforcing a data type to make sure it are strings and not integers,
* so values are quoted in the SQL WHERE statement.
*/
- $data = array(
- 'provider' => (string) $service_name_original,
+ $data = [
+ 'provider' => (string) utf8_strtolower($provider),
'oauth_provider_id' => (string) $unique_id
- );
+ ];
- $sql = 'SELECT user_id FROM ' . $this->auth_provider_oauth_token_account_assoc . '
+ $sql = 'SELECT user_id
+ FROM ' . $this->oauth_account_table . '
WHERE ' . $this->db->sql_build_array('SELECT', $data);
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
@@ -235,204 +227,134 @@ class oauth extends \phpbb\auth\provider\base
$redirect_data = array(
'auth_provider' => 'oauth',
- 'login_link_oauth_service' => $service_name_original,
+ 'login_link_oauth_service' => $provider,
);
/**
- * Event is triggered before check if provider is already associated with an account
- *
- * @event core.oauth_login_after_check_if_provider_id_has_match
- * @var array row User row
- * @var array data Provider data
- * @var array redirect_data Data to be appended to the redirect url
- * @var \OAuth\Common\Service\ServiceInterface service OAuth service
- * @since 3.2.3-RC1
- * @changed 3.2.6-RC1 Added redirect_data
- */
- $vars = array(
+ * Event is triggered before check if provider is already associated with an account
+ *
+ * @event core.oauth_login_after_check_if_provider_id_has_match
+ * @var array row User row
+ * @var array data Provider data
+ * @var array redirect_data Data to be appended to the redirect url
+ * @var ServiceInterface service OAuth service
+ * @since 3.2.3-RC1
+ * @changed 3.2.6-RC1 Added redirect_data
+ */
+ $vars = [
'row',
'data',
'redirect_data',
'service',
- );
+ ];
extract($this->dispatcher->trigger_event('core.oauth_login_after_check_if_provider_id_has_match', compact($vars)));
if (!$row)
{
// The user does not yet exist, ask to link or create profile
- return array(
+ return [
'status' => LOGIN_SUCCESS_LINK_PROFILE,
'error_msg' => 'LOGIN_OAUTH_ACCOUNT_NOT_LINKED',
- 'user_row' => array(),
+ 'user_row' => [],
'redirect_data' => $redirect_data,
- );
+ ];
}
// Retrieve the user's account
$sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_ip, user_type, user_login_attempts
FROM ' . $this->users_table . '
- WHERE user_id = ' . (int) $row['user_id'];
+ WHERE user_id = ' . (int) $row['user_id'];
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if (!$row)
{
- throw new \Exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY');
+ return [
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => 'AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY',
+ 'user_row' => ['user_id' => ANONYMOUS],
+ ];
}
/**
* Check if the user is banned.
- * The fourth parameter, return, has to be true,
- * otherwise the OAuth login is still called and
- * an uncaught exception is thrown as there is no
- * token stored in the database.
+ * The fourth parameter (return) has to be true, otherwise the OAuth login is still called and
+ * an uncaught exception is thrown as there is no token stored in the database.
*/
$ban = $this->user->check_ban($row['user_id'], $row['user_ip'], $row['user_email'], true);
+
if (!empty($ban))
{
$till_date = !empty($ban['ban_end']) ? $this->user->format_date($ban['ban_end']) : '';
$message = !empty($ban['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM';
- $contact_link = phpbb_get_board_contact_link($this->config, $this->phpbb_root_path, $this->php_ext);
- $message = $this->user->lang($message, $till_date, '<a href="' . $contact_link . '">', '</a>');
- $message .= !empty($ban['ban_give_reason']) ? '<br /><br />' . $this->user->lang('BOARD_BAN_REASON', $ban['ban_give_reason']) : '';
- $message .= !empty($ban['ban_triggered_by']) ? '<br /><br /><em>' . $this->user->lang('BAN_TRIGGERED_BY_' . strtoupper($ban['ban_triggered_by'])) . '</em>' : '';
+ $contact_link = phpbb_get_board_contact_link($this->config, $this->root_path, $this->php_ext);
+
+ $message = $this->language->lang($message, $till_date, '<a href="' . $contact_link . '">', '</a>');
+ $message .= !empty($ban['ban_give_reason']) ? '<br /><br />' . $this->language->lang('BOARD_BAN_REASON', $ban['ban_give_reason']) : '';
+ $message .= !empty($ban['ban_triggered_by']) ? '<br /><br /><em>' . $this->language->lang('BAN_TRIGGERED_BY_' . utf8_strtoupper($ban['ban_triggered_by'])) . '</em>' : '';
- return array(
+ return [
'status' => LOGIN_BREAK,
'error_msg' => $message,
'user_row' => $row,
- );
+ ];
}
// Update token storage to store the user_id
$storage->set_user_id($row['user_id']);
/**
- * Event is triggered after user is successfully logged in via OAuth.
- *
- * @event core.auth_oauth_login_after
- * @var array row User row
- * @since 3.1.11-RC1
- */
- $vars = array(
+ * Event is triggered after user is successfully logged in via OAuth.
+ *
+ * @event core.auth_oauth_login_after
+ * @var array row User row
+ * @since 3.1.11-RC1
+ */
+ $vars = [
'row',
- );
+ ];
extract($this->dispatcher->trigger_event('core.auth_oauth_login_after', compact($vars)));
// The user is now authenticated and can be logged in
- return array(
+ return [
'status' => LOGIN_SUCCESS,
'error_msg' => false,
'user_row' => $row,
- );
+ ];
}
else
{
- if ($service::OAUTH_VERSION === 1)
- {
- $token = $service->requestRequestToken();
- $url = $service->getAuthorizationUri(array('oauth_token' => $token->getRequestToken()));
- }
- else
- {
- $url = $service->getAuthorizationUri();
- }
- header('Location: ' . $url);
- }
- }
-
- /**
- * Returns the cached current_uri object or creates and caches it if it is
- * not already created. In each case the query string is updated based on
- * the $query parameter.
- *
- * @param string $service_name The name of the service
- * @param string $query The query string of the current_uri
- * used in redirects
- * @return \OAuth\Common\Http\Uri\UriInterface
- */
- protected function get_current_uri($service_name, $query)
- {
- if ($this->current_uri)
- {
- $this->current_uri->setQuery($query);
- return $this->current_uri;
- }
-
- $uri_factory = new \OAuth\Common\Http\Uri\UriFactory();
- $super_globals = $this->request->get_super_global(\phpbb\request\request_interface::SERVER);
- if (!empty($super_globals['HTTP_X_FORWARDED_PROTO']) && $super_globals['HTTP_X_FORWARDED_PROTO'] === 'https')
- {
- $super_globals['HTTPS'] = 'on';
- $super_globals['SERVER_PORT'] = 443;
- }
- $current_uri = $uri_factory->createFromSuperGlobalArray($super_globals);
- $current_uri->setQuery($query);
-
- $this->current_uri = $current_uri;
- return $current_uri;
- }
-
- /**
- * Returns a new service object
- *
- * @param string $service_name The name of the service
- * @param \phpbb\auth\provider\oauth\token_storage $storage
- * @param array $service_credentials {@see \phpbb\auth\provider\oauth\oauth::get_service_credentials}
- * @param string $query The query string of the
- * current_uri used in redirection
- * @param array $scopes The scope of the request against
- * the api.
- * @return \OAuth\Common\Service\ServiceInterface
- * @throws \Exception
- */
- protected function get_service($service_name, \phpbb\auth\provider\oauth\token_storage $storage, array $service_credentials, $query, array $scopes = array())
- {
- $current_uri = $this->get_current_uri($service_name, $query);
-
- // Setup the credentials for the requests
- $credentials = new Credentials(
- $service_credentials['key'],
- $service_credentials['secret'],
- $current_uri->getAbsoluteUri()
- );
-
- $service_factory = new \OAuth\ServiceFactory();
- $service = $service_factory->createService($service_name, $credentials, $storage, $scopes);
-
- if (!$service)
- {
- throw new \Exception('AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED');
+ return $this->set_redirect($service);
}
-
- return $service;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_login_data()
{
- $login_data = array(
+ $login_data = [
'TEMPLATE_FILE' => 'login_body_oauth.html',
'BLOCK_VAR_NAME' => 'oauth',
- 'BLOCK_VARS' => array(),
- );
+ 'BLOCK_VARS' => [],
+ ];
foreach ($this->service_providers as $service_name => $service_provider)
{
// Only include data if the credentials are set
$credentials = $service_provider->get_service_credentials();
+
if ($credentials['key'] && $credentials['secret'])
{
- $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
- $redirect_url = generate_board_url() . '/ucp.' . $this->php_ext . '?mode=login&login=external&oauth_service=' . $actual_name;
- $login_data['BLOCK_VARS'][$service_name] = array(
+ $provider = $this->get_provider($service_name);
+ $redirect_url = generate_board_url() . '/ucp.' . $this->php_ext . '?mode=login&login=external&oauth_service=' . $provider;
+
+ $login_data['BLOCK_VARS'][$service_name] = [
'REDIRECT_URL' => redirect($redirect_url, true),
- 'SERVICE_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
- );
+ 'SERVICE_NAME' => $this->get_provider_title($provider),
+ ];
}
}
@@ -440,51 +362,55 @@ class oauth extends \phpbb\auth\provider\base
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function acp()
{
- $ret = array();
+ $ret = [];
foreach ($this->service_providers as $service_name => $service_provider)
{
- $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
- $ret[] = 'auth_oauth_' . $actual_name . '_key';
- $ret[] = 'auth_oauth_' . $actual_name . '_secret';
+ $provider = $this->get_provider($service_name);
+
+ $provider = utf8_strtolower($provider);
+
+ $ret[] = 'auth_oauth_' . $provider . '_key';
+ $ret[] = 'auth_oauth_' . $provider . '_secret';
}
return $ret;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_acp_template($new_config)
{
- $ret = array(
+ $ret = [
'BLOCK_VAR_NAME' => 'oauth_services',
- 'BLOCK_VARS' => array(),
+ 'BLOCK_VARS' => [],
'TEMPLATE_FILE' => 'auth_provider_oauth.html',
- 'TEMPLATE_VARS' => array(),
- );
+ 'TEMPLATE_VARS' => [],
+ ];
foreach ($this->service_providers as $service_name => $service_provider)
{
- $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
- $ret['BLOCK_VARS'][$actual_name] = array(
- 'ACTUAL_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
- 'KEY' => $new_config['auth_oauth_' . $actual_name . '_key'],
- 'NAME' => $actual_name,
- 'SECRET' => $new_config['auth_oauth_' . $actual_name . '_secret'],
- );
+ $provider = $this->get_provider($service_name);
+
+ $ret['BLOCK_VARS'][$provider] = [
+ 'NAME' => $provider,
+ 'ACTUAL_NAME' => $this->get_provider_title($provider),
+ 'KEY' => $new_config['auth_oauth_' . utf8_strtolower($provider) . '_key'],
+ 'SECRET' => $new_config['auth_oauth_' . utf8_strtolower($provider) . '_secret'],
+ ];
}
return $ret;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function login_link_has_necessary_data($login_link_data)
{
if (empty($login_link_data))
@@ -502,16 +428,13 @@ class oauth extends \phpbb\auth\provider\base
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function link_account(array $link_data)
{
// Check for a valid link method (auth_link or login_link)
if (!array_key_exists('link_method', $link_data) ||
- !in_array($link_data['link_method'], array(
- 'auth_link',
- 'login_link',
- )))
+ !in_array($link_data['link_method'], ['auth_link', 'login_link']))
{
return 'LOGIN_LINK_MISSING_DATA';
}
@@ -527,7 +450,8 @@ class oauth extends \phpbb\auth\provider\base
}
}
- $service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']);
+ $service_name = $this->get_service_name($link_data['oauth_service']);
+
if (!array_key_exists($service_name, $this->service_providers))
{
return 'LOGIN_ERROR_OAUTH_SERVICE_DOES_NOT_EXIST';
@@ -539,21 +463,109 @@ class oauth extends \phpbb\auth\provider\base
return $this->link_account_auth_link($link_data, $service_name);
case 'login_link':
return $this->link_account_login_link($link_data, $service_name);
+ default:
+ return 'LOGIN_LINK_MISSING_DATA';
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function logout($data, $new_session)
+ {
+ // Clear all tokens belonging to the user
+ $storage = new token_storage($this->db, $this->user, $this->oauth_token_table, $this->oauth_state_table);
+ $storage->clearAllTokens();
+
+ return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_auth_link_data($user_id = 0)
+ {
+ $user_ids = [];
+ $block_vars = [];
+
+ $sql = 'SELECT oauth_provider_id, provider
+ FROM ' . $this->oauth_account_table . '
+ WHERE user_id = ' . ($user_id > 0 ? (int) $user_id : (int) $this->user->data['user_id']);
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $user_ids[$row['provider']] = $row['oauth_provider_id'];
+ }
+ $this->db->sql_freeresult($result);
+
+ foreach ($this->service_providers as $service_name => $service_provider)
+ {
+ // Only include data if the credentials are set
+ $credentials = $service_provider->get_service_credentials();
+
+ if ($credentials['key'] && $credentials['secret'])
+ {
+ $provider = $this->get_provider($service_name);
+
+ $block_vars[$service_name] = [
+ 'SERVICE_NAME' => $this->get_provider_title($provider),
+ 'UNIQUE_ID' => isset($user_ids[$provider]) ? $user_ids[$provider] : null,
+ 'HIDDEN_FIELDS' => [
+ 'link' => !isset($user_ids[$provider]),
+ 'oauth_service' => $provider,
+ ],
+ ];
+ }
+ }
+
+ return [
+ 'BLOCK_VAR_NAME' => 'oauth',
+ 'BLOCK_VARS' => $block_vars,
+
+ 'TEMPLATE_FILE' => 'ucp_auth_link_oauth.html',
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function unlink_account(array $link_data)
+ {
+ if (!array_key_exists('oauth_service', $link_data) || !$link_data['oauth_service'])
+ {
+ return 'LOGIN_LINK_MISSING_DATA';
}
+
+ // Remove user specified in $link_data if possible
+ $user_id = isset($link_data['user_id']) ? $link_data['user_id'] : $this->user->data['user_id'];
+
+ // Remove the link
+ $sql = 'DELETE FROM ' . $this->oauth_account_table . "
+ WHERE provider = '" . $this->db->sql_escape($link_data['oauth_service']) . "'
+ AND user_id = " . (int) $user_id;
+ $this->db->sql_query($sql);
+
+ $service_name = $this->get_service_name($link_data['oauth_service']);
+
+ // Clear all tokens belonging to the user on this service
+ $storage = new token_storage($this->db, $this->user, $this->oauth_token_table, $this->oauth_state_table);
+ $storage->clearToken($service_name);
+
+ return false;
}
/**
- * Performs the account linking for login_link
- *
- * @param array $link_data The same variable given to {@see \phpbb\auth\provider\provider_interface::link_account}
- * @param string $service_name The name of the service being used in
- * linking.
- * @return string|null Returns a language constant (string) if an error is
- * encountered, or null on success.
- */
+ * Performs the account linking for login_link.
+ *
+ * @param array $link_data The same variable given to
+ * {@see \phpbb\auth\provider\provider_interface::link_account}
+ * @param string $service_name The name of the service being used in linking.
+ * @return string|false Returns a language key (string) if an error is encountered,
+ * or false on success.
+ */
protected function link_account_login_link(array $link_data, $service_name)
{
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
+ $storage = new token_storage($this->db, $this->user, $this->oauth_token_table, $this->oauth_state_table);
// Check for an access token, they should have one
if (!$storage->has_access_token_by_session($service_name))
@@ -561,87 +573,109 @@ class oauth extends \phpbb\auth\provider\base
return 'LOGIN_LINK_ERROR_OAUTH_NO_ACCESS_TOKEN';
}
- // Prepare the query string
- $query = 'mode=login_link&login_link_oauth_service=' . strtolower($link_data['oauth_service']);
-
// Prepare for an authentication request
- $service_credentials = $this->service_providers[$service_name]->get_service_credentials();
- $scopes = $this->service_providers[$service_name]->get_auth_scope();
- $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $query, $scopes);
+ $query = 'mode=login_link&login_link_oauth_service=' . $link_data['oauth_service'];
+
+ try
+ {
+ $service = $this->get_service($link_data['oauth_service'], $storage, $query);
+ }
+ catch (\Exception $e)
+ {
+ return $e->getMessage();
+ }
+
$this->service_providers[$service_name]->set_external_service_provider($service);
- // The user has already authenticated successfully, request to authenticate again
- $unique_id = $this->service_providers[$service_name]->perform_token_auth();
+ try
+ {
+ // The user has already authenticated successfully, request to authenticate again
+ $unique_id = $this->service_providers[$service_name]->perform_token_auth();
+ }
+ catch (exception $e)
+ {
+ return $e->getMessage();
+ }
// Insert into table, they will be able to log in after this
- $data = array(
+ $data = [
'user_id' => $link_data['user_id'],
- 'provider' => strtolower($link_data['oauth_service']),
+ 'provider' => utf8_strtolower($link_data['oauth_service']),
'oauth_provider_id' => $unique_id,
- );
+ ];
$this->link_account_perform_link($data);
+
// Update token storage to store the user_id
$storage->set_user_id($link_data['user_id']);
+
+ return false;
}
/**
- * Performs the account linking for auth_link
- *
- * @param array $link_data The same variable given to {@see \phpbb\auth\provider\provider_interface::link_account}
- * @param string $service_name The name of the service being used in
- * linking.
- * @return string|null Returns a language constant (string) if an error is
- * encountered, or null on success.
- */
+ * Performs the account linking for auth_link.
+ *
+ * @param array $link_data The same variable given to
+ * {@see \phpbb\auth\provider\provider_interface::link_account}
+ * @param string $service_name The name of the service being used in linking.
+ * @return string|false Returns a language constant (string) if an error is encountered,
+ * or false on success.
+ */
protected function link_account_auth_link(array $link_data, $service_name)
{
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
- $query = 'i=ucp_auth_link&mode=auth_link&link=1&oauth_service=' . strtolower($link_data['oauth_service']);
- $service_credentials = $this->service_providers[$service_name]->get_service_credentials();
- $scopes = $this->service_providers[$service_name]->get_auth_scope();
- $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $query, $scopes);
+ $storage = new token_storage($this->db, $this->user, $this->oauth_token_table, $this->oauth_state_table);
+ $query = 'i=ucp_auth_link&mode=auth_link&link=1&oauth_service=' . $link_data['oauth_service'];
- if (($service::OAUTH_VERSION === 2 && $this->request->is_set('code', \phpbb\request\request_interface::GET))
- || ($service::OAUTH_VERSION === 1 && $this->request->is_set('oauth_token', \phpbb\request\request_interface::GET)))
+ try
+ {
+ /** @var OAuth1Service|OAuth2Service $service */
+ $service = $this->get_service($link_data['oauth_service'], $storage, $query);
+ }
+ catch (\Exception $e)
+ {
+ return $e->getMessage();
+ }
+
+ if ($this->is_set_code($service))
{
$this->service_providers[$service_name]->set_external_service_provider($service);
- $unique_id = $this->service_providers[$service_name]->perform_auth_login();
+
+ try
+ {
+ $unique_id = $this->service_providers[$service_name]->perform_auth_login();
+ }
+ catch (exception $e)
+ {
+ return $e->getMessage();
+ }
// Insert into table, they will be able to log in after this
- $data = array(
+ $data = [
'user_id' => $this->user->data['user_id'],
- 'provider' => strtolower($link_data['oauth_service']),
+ 'provider' => utf8_strtolower($link_data['oauth_service']),
'oauth_provider_id' => $unique_id,
- );
+ ];
$this->link_account_perform_link($data);
+
+ return false;
}
else
{
- if ($service::OAUTH_VERSION === 1)
- {
- $token = $service->requestRequestToken();
- $url = $service->getAuthorizationUri(array('oauth_token' => $token->getRequestToken()));
- }
- else
- {
- $url = $service->getAuthorizationUri();
- }
- header('Location: ' . $url);
+ return $this->set_redirect($service);
}
}
/**
- * Performs the query that inserts an account link
- *
- * @param array $data This array is passed to db->sql_build_array
- */
+ * Performs the query that inserts an account link
+ *
+ * @param array $data This array is passed to db->sql_build_array
+ */
protected function link_account_perform_link(array $data)
{
// Check if the external account is already associated with other user
$sql = 'SELECT user_id
- FROM ' . $this->auth_provider_oauth_token_account_assoc . "
+ FROM ' . $this->oauth_account_table . "
WHERE provider = '" . $this->db->sql_escape($data['provider']) . "'
AND oauth_provider_id = '" . $this->db->sql_escape($data['oauth_provider_id']) . "'";
$result = $this->db->sql_query($sql);
@@ -654,114 +688,172 @@ class oauth extends \phpbb\auth\provider\base
}
// Link account
- $sql = 'INSERT INTO ' . $this->auth_provider_oauth_token_account_assoc . '
- ' . $this->db->sql_build_array('INSERT', $data);
+ $sql = 'INSERT INTO ' . $this->oauth_account_table . ' ' . $this->db->sql_build_array('INSERT', $data);
$this->db->sql_query($sql);
/**
* Event is triggered after user links account.
*
* @event core.auth_oauth_link_after
- * @var array data User row
+ * @var array data User row
* @since 3.1.11-RC1
*/
- $vars = array(
+ $vars = [
'data',
- );
+ ];
extract($this->dispatcher->trigger_event('core.auth_oauth_link_after', compact($vars)));
}
/**
- * {@inheritdoc}
- */
- public function logout($data, $new_session)
+ * Returns a new service object.
+ *
+ * @param string $provider The name of the provider
+ * @param token_storage $storage Token storage object
+ * @param string $query The query string used for the redirect uri
+ * @return ServiceInterface
+ * @throws exception When OAuth service was not created
+ */
+ protected function get_service($provider, token_storage $storage, $query)
{
- // Clear all tokens belonging to the user
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
- $storage->clearAllTokens();
+ $service_name = $this->get_service_name($provider);
- return;
- }
+ /** @see \phpbb\auth\provider\oauth\service\service_interface::get_service_credentials */
+ $service_credentials = $this->service_providers[$service_name]->get_service_credentials();
- /**
- * {@inheritdoc}
- */
- public function get_auth_link_data($user_id = 0)
- {
- $block_vars = array();
+ /** @see \phpbb\auth\provider\oauth\service\service_interface::get_auth_scope */
+ $scopes = $this->service_providers[$service_name]->get_auth_scope();
- // Get all external accounts tied to the current user
- $data = array(
- 'user_id' => ($user_id <= 0) ? (int) $this->user->data['user_id'] : (int) $user_id,
+ $callback = generate_board_url() . "/ucp.{$this->php_ext}?{$query}";
+
+ // Setup the credentials for the requests
+ $credentials = new Credentials(
+ $service_credentials['key'],
+ $service_credentials['secret'],
+ $callback
);
- $sql = 'SELECT oauth_provider_id, provider FROM ' . $this->auth_provider_oauth_token_account_assoc . '
- WHERE ' . $this->db->sql_build_array('SELECT', $data);
- $result = $this->db->sql_query($sql);
- $rows = $this->db->sql_fetchrowset($result);
- $this->db->sql_freeresult($result);
- $oauth_user_ids = array();
+ $service_factory = new ServiceFactory;
- if ($rows !== false && count($rows))
+ // Allow providers to register a custom class or override the provider name
+ if ($class = $this->service_providers[$service_name]->get_external_service_class())
{
- foreach ($rows as $row)
+ if (class_exists($class))
+ {
+ try
+ {
+ $service_factory->registerService($provider, $class);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ }
+ }
+ else
{
- $oauth_user_ids[$row['provider']] = $row['oauth_provider_id'];
+ $provider = $class;
}
}
- unset($rows);
- foreach ($this->service_providers as $service_name => $service_provider)
+ $service = $service_factory->createService($provider, $credentials, $storage, $scopes);
+
+ if (!$service)
{
- // Only include data if the credentials are set
- $credentials = $service_provider->get_service_credentials();
- if ($credentials['key'] && $credentials['secret'])
- {
- $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
-
- $block_vars[$service_name] = array(
- 'HIDDEN_FIELDS' => array(
- 'link' => (!isset($oauth_user_ids[$actual_name])),
- 'oauth_service' => $actual_name,
- ),
-
- 'SERVICE_ID' => $actual_name,
- 'SERVICE_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
- 'UNIQUE_ID' => (isset($oauth_user_ids[$actual_name])) ? $oauth_user_ids[$actual_name] : null,
- );
- }
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED');
}
- return array(
- 'BLOCK_VAR_NAME' => 'oauth',
- 'BLOCK_VARS' => $block_vars,
+ return $service;
+ }
- 'TEMPLATE_FILE' => 'ucp_auth_link_oauth.html',
- );
+ /**
+ * Returns the service name for an OAuth provider name.
+ *
+ * @param string $provider The OAuth provider name
+ * @return string The service name
+ */
+ protected function get_service_name($provider)
+ {
+ if (strpos($provider, 'auth.provider.oauth.service.') !== 0)
+ {
+ $provider = 'auth.provider.oauth.service.' . utf8_strtolower($provider);
+ }
+
+ return $provider;
}
/**
- * {@inheritdoc}
- */
- public function unlink_account(array $link_data)
+ * Returns the OAuth provider name from a service name.
+ *
+ * @param string $service_name The service name
+ * @return string The OAuth provider name
+ */
+ protected function get_provider($service_name)
{
- if (!array_key_exists('oauth_service', $link_data) || !$link_data['oauth_service'])
+ return str_replace('auth.provider.oauth.service.', '', $service_name);
+ }
+
+ /**
+ * Returns the localized title for the OAuth provider.
+ *
+ * @param string $provider The OAuth provider name
+ * @return string The OAuth provider title
+ */
+ protected function get_provider_title($provider)
+ {
+ return $this->language->lang('AUTH_PROVIDER_OAUTH_SERVICE_' . utf8_strtoupper($provider));
+ }
+
+ /**
+ * Returns whether or not the authorization code is set.
+ *
+ * @param OAuth1Service|OAuth2Service $service The external OAuth service
+ * @return bool Whether or not the authorization code is set in the URL
+ * for the respective OAuth service's version
+ */
+ protected function is_set_code($service)
+ {
+ switch ($service::OAUTH_VERSION)
{
- return 'LOGIN_LINK_MISSING_DATA';
+ case 1:
+ return $this->request->is_set('oauth_token', request_interface::GET);
+
+ case 2:
+ return $this->request->is_set('code', request_interface::GET);
+
+ default:
+ return false;
}
+ }
- // Remove user specified in $link_data if possible
- $user_id = isset($link_data['user_id']) ? $link_data['user_id'] : $this->user->data['user_id'];
+ /**
+ * Sets a redirect to the authorization uri.
+ *
+ * @param OAuth1Service|OAuth2Service $service The external OAuth service
+ * @return array|false Array if an error occurred,
+ * false on success
+ */
+ protected function set_redirect($service)
+ {
+ $parameters = [];
- // Remove the link
- $sql = 'DELETE FROM ' . $this->auth_provider_oauth_token_account_assoc . "
- WHERE provider = '" . $this->db->sql_escape($link_data['oauth_service']) . "'
- AND user_id = " . (int) $user_id;
- $this->db->sql_query($sql);
+ if ($service::OAUTH_VERSION === 1)
+ {
+ try
+ {
+ $token = $service->requestRequestToken();
+ $parameters = ['oauth_token' => $token->getRequestToken()];
+ }
+ catch (TokenResponseException $e)
+ {
+ return [
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ 'error_msg' => $e->getMessage(),
+ 'user_row' => ['user_id' => ANONYMOUS],
+ ];
+ }
+ }
- // Clear all tokens belonging to the user on this service
- $service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']);
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
- $storage->clearToken($service_name);
+ redirect($service->getAuthorizationUri($parameters), false, true);
+
+ return false;
}
}
diff --git a/phpBB/phpbb/auth/provider/oauth/service/base.php b/phpBB/phpbb/auth/provider/oauth/service/base.php
index 6adf64aa30..5ab426a0aa 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/base.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/base.php
@@ -1,49 +1,57 @@
<?php
/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
namespace phpbb\auth\provider\oauth\service;
/**
-* Base OAuth abstract class that all OAuth services should implement
-*/
-abstract class base implements \phpbb\auth\provider\oauth\service\service_interface
+ * Base OAuth abstract class that all OAuth services should implement
+ */
+abstract class base implements service_interface
{
/**
- * External OAuth service provider
- *
- * @var \OAuth\Common\Service\ServiceInterface
- */
+ * External OAuth service provider
+ *
+ * @var \OAuth\Common\Service\ServiceInterface
+ */
protected $service_provider;
/**
- * {@inheritdoc}
- */
- public function get_external_service_provider()
+ * {@inheritdoc}
+ */
+ public function get_auth_scope()
{
- return $this->service_provider;
+ return [];
}
/**
- * {@inheritdoc}
- */
- public function get_auth_scope()
+ * {@inheritdoc}
+ */
+ public function get_external_service_class()
+ {
+ return '';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_external_service_provider()
{
- return array();
+ return $this->service_provider;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function set_external_service_provider(\OAuth\Common\Service\ServiceInterface $service_provider)
{
$this->service_provider = $service_provider;
diff --git a/phpBB/phpbb/auth/provider/oauth/service/bitly.php b/phpBB/phpbb/auth/provider/oauth/service/bitly.php
index 25e731a02c..ca131b2019 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/bitly.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/bitly.php
@@ -1,94 +1,107 @@
<?php
/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
namespace phpbb\auth\provider\oauth\service;
/**
-* Bitly OAuth service
-*/
-class bitly extends \phpbb\auth\provider\oauth\service\base
+ * Bitly OAuth service
+ */
+class bitly extends base
{
- /**
- * phpBB config
- *
- * @var \phpbb\config\config
- */
+ /** @var \phpbb\config\config */
protected $config;
- /**
- * phpBB request
- *
- * @var \phpbb\request\request_interface
- */
+ /** @var \phpbb\request\request_interface */
protected $request;
/**
- * Constructor
- *
- * @param \phpbb\config\config $config
- * @param \phpbb\request\request_interface $request
- */
+ * Constructor.
+ *
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\request\request_interface $request Request object
+ */
public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request)
{
- $this->config = $config;
- $this->request = $request;
+ $this->config = $config;
+ $this->request = $request;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_service_credentials()
{
- return array(
+ return [
'key' => $this->config['auth_oauth_bitly_key'],
'secret' => $this->config['auth_oauth_bitly_secret'],
- );
+ ];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_auth_login()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Bitly))
{
- throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // This was a callback request from bitly, get the token
- $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ try
+ {
+ // This was a callback request, get the token
+ $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ }
+ catch (\OAuth\Common\Http\Exception\TokenResponseException $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
- // Send a request with it
- $result = json_decode($this->service_provider->request('user/info'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('user/info'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Return the unique identifier returned from bitly
return $result['data']['login'];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_token_auth()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Bitly))
{
- throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // Send a request with it
- $result = json_decode($this->service_provider->request('user/info'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('user/info'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
- // Return the unique identifier returned from bitly
+ // Return the unique identifier
return $result['data']['login'];
}
}
diff --git a/phpBB/phpbb/auth/provider/oauth/service/facebook.php b/phpBB/phpbb/auth/provider/oauth/service/facebook.php
index bb98835e07..f7dbe307eb 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/facebook.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/facebook.php
@@ -1,63 +1,55 @@
<?php
/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
namespace phpbb\auth\provider\oauth\service;
/**
-* Facebook OAuth service
-*/
+ * Facebook OAuth service
+ */
class facebook extends base
{
- /**
- * phpBB config
- *
- * @var \phpbb\config\config
- */
+ /** @var \phpbb\config\config */
protected $config;
- /**
- * phpBB request
- *
- * @var \phpbb\request\request_interface
- */
+ /** @var \phpbb\request\request_interface */
protected $request;
/**
- * Constructor
- *
- * @param \phpbb\config\config $config
- * @param \phpbb\request\request_interface $request
- */
+ * Constructor.
+ *
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\request\request_interface $request Request object
+ */
public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request)
{
- $this->config = $config;
- $this->request = $request;
+ $this->config = $config;
+ $this->request = $request;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_service_credentials()
{
- return array(
+ return [
'key' => $this->config['auth_oauth_facebook_key'],
'secret' => $this->config['auth_oauth_facebook_secret'],
- );
+ ];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_auth_login()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Facebook))
@@ -65,19 +57,33 @@ class facebook extends base
throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // This was a callback request, get the token
- $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ try
+ {
+ // This was a callback request, get the token
+ $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ }
+ catch (\OAuth\Common\Http\Exception\TokenResponseException $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
- // Send a request with it
- $result = json_decode($this->service_provider->request('/me'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('/me'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Return the unique identifier
return $result['id'];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_token_auth()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Facebook))
@@ -85,8 +91,15 @@ class facebook extends base
throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // Send a request with it
- $result = json_decode($this->service_provider->request('/me'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('/me'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Return the unique identifier
return $result['id'];
diff --git a/phpBB/phpbb/auth/provider/oauth/service/google.php b/phpBB/phpbb/auth/provider/oauth/service/google.php
index cb9f83a94f..6e671ab13e 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/google.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/google.php
@@ -1,74 +1,66 @@
<?php
/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
namespace phpbb\auth\provider\oauth\service;
/**
-* Google OAuth service
-*/
+ * Google OAuth service
+ */
class google extends base
{
- /**
- * phpBB config
- *
- * @var \phpbb\config\config
- */
+ /** @var \phpbb\config\config */
protected $config;
- /**
- * phpBB request
- *
- * @var \phpbb\request\request_interface
- */
+ /** @var \phpbb\request\request_interface */
protected $request;
/**
- * Constructor
- *
- * @param \phpbb\config\config $config
- * @param \phpbb\request\request_interface $request
- */
+ * Constructor.
+ *
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\request\request_interface $request Request object
+ */
public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request)
{
- $this->config = $config;
- $this->request = $request;
+ $this->config = $config;
+ $this->request = $request;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_auth_scope()
{
- return array(
+ return [
'userinfo_email',
'userinfo_profile',
- );
+ ];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_service_credentials()
{
- return array(
+ return [
'key' => $this->config['auth_oauth_google_key'],
'secret' => $this->config['auth_oauth_google_secret'],
- );
+ ];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_auth_login()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Google))
@@ -76,19 +68,33 @@ class google extends base
throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // This was a callback request, get the token
- $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ try
+ {
+ // This was a callback request, get the token
+ $this->service_provider->requestAccessToken($this->request->variable('code', ''));
+ }
+ catch (\OAuth\Common\Http\Exception\TokenResponseException $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
- // Send a request with it
- $result = json_decode($this->service_provider->request('https://www.googleapis.com/oauth2/v1/userinfo'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('https://www.googleapis.com/oauth2/v1/userinfo'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Return the unique identifier
return $result['id'];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_token_auth()
{
if (!($this->service_provider instanceof \OAuth\OAuth2\Service\Google))
@@ -96,8 +102,15 @@ class google extends base
throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
- // Send a request with it
- $result = json_decode($this->service_provider->request('https://www.googleapis.com/oauth2/v1/userinfo'), true);
+ try
+ {
+ // Send a request with it
+ $result = (array) json_decode($this->service_provider->request('https://www.googleapis.com/oauth2/v1/userinfo'), true);
+ }
+ catch (\OAuth\Common\Exception\Exception $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Return the unique identifier
return $result['id'];
diff --git a/phpBB/phpbb/auth/provider/oauth/service/service_interface.php b/phpBB/phpbb/auth/provider/oauth/service/service_interface.php
index e84eb247b6..ea9ef43788 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/service_interface.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/service_interface.php
@@ -1,73 +1,87 @@
<?php
/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
namespace phpbb\auth\provider\oauth\service;
/**
-* OAuth service interface
-*/
+ * OAuth service interface
+ */
interface service_interface
{
/**
- * Returns an array of the scopes necessary for auth
- *
- * @return array An array of the required scopes
- */
+ * Returns an array of the scopes necessary for auth
+ *
+ * @return array An array of the required scopes
+ */
public function get_auth_scope();
/**
- * Returns the external library service provider once it has been set
- *
- * @param \OAuth\Common\Service\ServiceInterface|null
- */
- public function get_external_service_provider();
-
- /**
- * Returns an array containing the service credentials belonging to requested
- * service.
- *
- * @return array An array containing the 'key' and the 'secret' of the
- * service in the form:
- * array(
- * 'key' => string
- * 'secret' => string
- * )
- */
+ * Returns an array containing the service credentials belonging to requested
+ * service.
+ *
+ * @return array An array containing the 'key' and the 'secret' of the
+ * service in the form:
+ * array(
+ * 'key' => string
+ * 'secret' => string
+ * )
+ */
public function get_service_credentials();
/**
- * Returns the results of the authentication in json format
- *
- * @throws \phpbb\auth\provider\oauth\service\exception
- * @return string The unique identifier returned by the service provider
- * that is used to authenticate the user with phpBB.
- */
+ * Returns the results of the authentication in json format
+ *
+ * @throws \phpbb\auth\provider\oauth\service\exception
+ * @return string The unique identifier returned by the service provider
+ * that is used to authenticate the user with phpBB.
+ */
public function perform_auth_login();
/**
- * Returns the results of the authentication in json format
- * Use this function when the user already has an access token
- *
- * @throws \phpbb\auth\provider\oauth\service\exception
- * @return string The unique identifier returned by the service provider
- * that is used to authenticate the user with phpBB.
- */
+ * Returns the results of the authentication in json format
+ * Use this function when the user already has an access token
+ *
+ * @throws \phpbb\auth\provider\oauth\service\exception
+ * @return string The unique identifier returned by the service provider
+ * that is used to authenticate the user with phpBB.
+ */
public function perform_token_auth();
/**
- * Sets the external library service provider
- *
- * @param \OAuth\Common\Service\ServiceInterface $service_provider
- */
+ * Returns the class of external library service provider that has to be used.
+ *
+ * @return string If the string is a class, it will register the provided string as a class,
+ * which later will be generated as the OAuth external service provider.
+ * If the string is not a class, it will use this string,
+ * trying to generate a service for the version 2 and 1 respectively:
+ * \OAuth\OAuth2\Service\<string>
+ * If the string is empty, it will default to OAuth's standard service classes,
+ * trying to generate a service for the version 2 and 1 respectively:
+ * \OAuth\OAuth2\Service\Facebook
+ */
+ public function get_external_service_class();
+
+ /**
+ * Returns the external library service provider once it has been set
+ *
+ * @param \OAuth\Common\Service\ServiceInterface|null
+ */
+ public function get_external_service_provider();
+
+ /**
+ * Sets the external library service provider
+ *
+ * @param \OAuth\Common\Service\ServiceInterface $service_provider
+ */
public function set_external_service_provider(\OAuth\Common\Service\ServiceInterface $service_provider);
}
diff --git a/phpBB/phpbb/auth/provider/oauth/service/twitter.php b/phpBB/phpbb/auth/provider/oauth/service/twitter.php
index 06beac51e2..35cbc9e4f7 100644
--- a/phpBB/phpbb/auth/provider/oauth/service/twitter.php
+++ b/phpBB/phpbb/auth/provider/oauth/service/twitter.php
@@ -1,102 +1,111 @@
<?php
/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
namespace phpbb\auth\provider\oauth\service;
/**
-* Twitter OAuth service
-*/
-class twitter extends \phpbb\auth\provider\oauth\service\base
+ * Twitter OAuth service
+ */
+class twitter extends base
{
- /**
- * phpBB config
- *
- * @var \phpbb\config\config
- */
+ /** @var \phpbb\config\config */
protected $config;
- /**
- * phpBB request
- *
- * @var \phpbb\request\request_interface
- */
+ /** @var \phpbb\request\request_interface */
protected $request;
/**
- * Constructor
- *
- * @param \phpbb\config\config $config
- * @param \phpbb\request\request_interface $request
- */
+ * Constructor.
+ *
+ * @param \phpbb\config\config $config Config object
+ * @param \phpbb\request\request_interface $request Request object
+ */
public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request)
{
- $this->config = $config;
- $this->request = $request;
+ $this->config = $config;
+ $this->request = $request;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function get_service_credentials()
{
- return array(
+ return [
'key' => $this->config['auth_oauth_twitter_key'],
'secret' => $this->config['auth_oauth_twitter_secret'],
- );
+ ];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_auth_login()
{
if (!($this->service_provider instanceof \OAuth\OAuth1\Service\Twitter))
{
- throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
$storage = $this->service_provider->getStorage();
- $token = $storage->retrieveAccessToken('Twitter');
- $tokensecret = $token->getRequestTokenSecret();
- // This was a callback request from twitter, get the token
- $this->service_provider->requestAccessToken(
- $this->request->variable('oauth_token', ''),
- $this->request->variable('oauth_verifier', ''),
- $tokensecret
- );
+ try
+ {
+ /** @var \OAuth\OAuth1\Token\TokenInterface $token */
+ $token = $storage->retrieveAccessToken('Twitter');
+ }
+ catch (\OAuth\Common\Storage\Exception\TokenNotFoundException $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
+
+ $secret = $token->getRequestTokenSecret();
+
+ try
+ {
+ // This was a callback request, get the token
+ $this->service_provider->requestAccessToken(
+ $this->request->variable('oauth_token', ''),
+ $this->request->variable('oauth_verifier', ''),
+ $secret
+ );
+ }
+ catch (\OAuth\Common\Http\Exception\TokenResponseException $e)
+ {
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_REQUEST');
+ }
// Send a request with it
- $result = json_decode($this->service_provider->request('account/verify_credentials.json'), true);
+ $result = (array) json_decode($this->service_provider->request('account/verify_credentials.json'), true);
- // Return the unique identifier returned from twitter
+ // Return the unique identifier
return $result['id'];
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function perform_token_auth()
{
if (!($this->service_provider instanceof \OAuth\OAuth1\Service\Twitter))
{
- throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ throw new exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
}
// Send a request with it
- $result = json_decode($this->service_provider->request('account/verify_credentials.json'), true);
+ $result = (array) json_decode($this->service_provider->request('account/verify_credentials.json'), true);
- // Return the unique identifier returned from twitter
+ // Return the unique identifier
return $result['id'];
}
}
diff --git a/phpBB/phpbb/auth/provider/oauth/token_storage.php b/phpBB/phpbb/auth/provider/oauth/token_storage.php
index b0c2fd0d62..c0f585d7bb 100644
--- a/phpBB/phpbb/auth/provider/oauth/token_storage.php
+++ b/phpBB/phpbb/auth/provider/oauth/token_storage.php
@@ -1,15 +1,15 @@
<?php
/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
namespace phpbb\auth\provider\oauth;
@@ -20,67 +20,48 @@ use OAuth\Common\Storage\Exception\TokenNotFoundException;
use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
/**
-* OAuth storage wrapper for phpbb's cache
-*/
+ * OAuth storage wrapper for phpBB's cache
+ */
class token_storage implements TokenStorageInterface
{
- /**
- * Cache driver.
- *
- * @var \phpbb\db\driver\driver_interface
- */
+ /** @var \phpbb\db\driver\driver_interface */
protected $db;
- /**
- * phpBB user
- *
- * @var \phpbb\user
- */
+ /** @var \phpbb\user */
protected $user;
- /**
- * OAuth token table
- *
- * @var string
- */
+ /** @var string OAuth table: token storage */
protected $oauth_token_table;
- /**
- * OAuth state table
- *
- * @var string
- */
+ /** @var string OAuth table: state */
protected $oauth_state_table;
- /**
- * @var object|TokenInterface
- */
+ /** @var TokenInterface OAuth token */
protected $cachedToken;
- /**
- * @var string
- */
+ /** @var string OAuth state */
protected $cachedState;
/**
- * Creates token storage for phpBB.
- *
- * @param \phpbb\db\driver\driver_interface $db
- * @param \phpbb\user $user
- * @param string $oauth_token_table
- * @param string $oauth_state_table
- */
+ * Constructor.
+ *
+ * @param \phpbb\db\driver\driver_interface $db Database object
+ * @param \phpbb\user $user User object
+ * @param string $oauth_token_table OAuth table: token storage
+ * @param string $oauth_state_table OAuth table: state
+ */
public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $oauth_token_table, $oauth_state_table)
{
- $this->db = $db;
- $this->user = $user;
+ $this->db = $db;
+ $this->user = $user;
+
$this->oauth_token_table = $oauth_token_table;
$this->oauth_state_table = $oauth_state_table;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function retrieveAccessToken($service)
{
$service = $this->get_service_name_for_db($service);
@@ -90,10 +71,10 @@ class token_storage implements TokenStorageInterface
return $this->cachedToken;
}
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
- );
+ ];
if ((int) $this->user->data['user_id'] === ANONYMOUS)
{
@@ -104,33 +85,38 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function storeAccessToken($service, TokenInterface $token)
{
$service = $this->get_service_name_for_db($service);
$this->cachedToken = $token;
- $data = array(
+ $data = [
'oauth_token' => $this->json_encode_token($token),
- );
+ ];
$sql = 'UPDATE ' . $this->oauth_token_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $data) . '
- WHERE user_id = ' . (int) $this->user->data['user_id'] . '
- ' . ((int) $this->user->data['user_id'] === ANONYMOUS ? "AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'" : '') . "
- AND provider = '" . $this->db->sql_escape($service) . "'";
+ SET ' . $this->db->sql_build_array('UPDATE', $data) . '
+ WHERE user_id = ' . (int) $this->user->data['user_id'] . "
+ AND provider = '" . $this->db->sql_escape($service) . "'";
+
+ if ((int) $this->user->data['user_id'] === ANONYMOUS)
+ {
+ $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
+ }
+
$this->db->sql_query($sql);
if (!$this->db->sql_affectedrows())
{
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
'oauth_token' => $this->json_encode_token($token),
'session_id' => $this->user->data['session_id'],
- );
+ ];
$sql = 'INSERT INTO ' . $this->oauth_token_table . $this->db->sql_build_array('INSERT', $data);
@@ -141,8 +127,8 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function hasAccessToken($service)
{
$service = $this->get_service_name_for_db($service);
@@ -152,22 +138,22 @@ class token_storage implements TokenStorageInterface
return true;
}
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
- );
+ ];
if ((int) $this->user->data['user_id'] === ANONYMOUS)
{
$data['session_id'] = $this->user->data['session_id'];
}
- return $this->_has_acess_token($data);
+ return $this->has_access_token($data);
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function clearToken($service)
{
$service = $this->get_service_name_for_db($service);
@@ -189,13 +175,13 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function clearAllTokens()
{
$this->cachedToken = null;
- $sql = 'DELETE FROM ' . $this->oauth_token_table . '
+ $sql = 'DELETE FROM ' . $this->oauth_token_table . '
WHERE user_id = ' . (int) $this->user->data['user_id'];
if ((int) $this->user->data['user_id'] === ANONYMOUS)
@@ -209,31 +195,30 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function storeAuthorizationState($service, $state)
{
$service = $this->get_service_name_for_db($service);
$this->cachedState = $state;
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
'oauth_state' => $state,
'session_id' => $this->user->data['session_id'],
- );
+ ];
- $sql = 'INSERT INTO ' . $this->oauth_state_table . '
- ' . $this->db->sql_build_array('INSERT', $data);
+ $sql = 'INSERT INTO ' . $this->oauth_state_table . ' ' . $this->db->sql_build_array('INSERT', $data);
$this->db->sql_query($sql);
return $this;
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function hasAuthorizationState($service)
{
$service = $this->get_service_name_for_db($service);
@@ -243,10 +228,10 @@ class token_storage implements TokenStorageInterface
return true;
}
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
- );
+ ];
if ((int) $this->user->data['user_id'] === ANONYMOUS)
{
@@ -257,8 +242,8 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function retrieveAuthorizationState($service)
{
$service = $this->get_service_name_for_db($service);
@@ -268,10 +253,10 @@ class token_storage implements TokenStorageInterface
return $this->cachedState;
}
- $data = array(
+ $data = [
'user_id' => (int) $this->user->data['user_id'],
'provider' => $service,
- );
+ ];
if ((int) $this->user->data['user_id'] === ANONYMOUS)
{
@@ -282,8 +267,8 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function clearAuthorizationState($service)
{
$service = $this->get_service_name_for_db($service);
@@ -305,8 +290,8 @@ class token_storage implements TokenStorageInterface
}
/**
- * {@inheritdoc}
- */
+ * {@inheritdoc}
+ */
public function clearAllAuthorizationStates()
{
$this->cachedState = null;
@@ -325,10 +310,11 @@ class token_storage implements TokenStorageInterface
}
/**
- * Updates the user_id field in the database assosciated with the token
- *
- * @param int $user_id
- */
+ * Updates the user_id field in the database associated with the token.
+ *
+ * @param int $user_id The user identifier
+ * @return void
+ */
public function set_user_id($user_id)
{
if (!$this->cachedToken)
@@ -336,21 +322,24 @@ class token_storage implements TokenStorageInterface
return;
}
+ $data = [
+ 'user_id' => (int) $user_id,
+ ];
+
$sql = 'UPDATE ' . $this->oauth_token_table . '
- SET ' . $this->db->sql_build_array('UPDATE', array(
- 'user_id' => (int) $user_id
- )) . '
- WHERE user_id = ' . (int) $this->user->data['user_id'] . "
- AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
+ SET ' . $this->db->sql_build_array('UPDATE', $data) . '
+ WHERE user_id = ' . (int) $this->user->data['user_id'] . "
+ AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
$this->db->sql_query($sql);
}
/**
- * Checks to see if an access token exists solely by the session_id of the user
- *
- * @param string $service The name of the OAuth service
- * @return bool true if they have token, false if they don't
- */
+ * Checks to see if an access token exists solely by the session_id of the user.
+ *
+ * @param string $service The OAuth service name
+ * @return bool true if the user's access token exists,
+ * false if the user's access token does not exist
+ */
public function has_access_token_by_session($service)
{
$service = $this->get_service_name_for_db($service);
@@ -360,20 +349,21 @@ class token_storage implements TokenStorageInterface
return true;
}
- $data = array(
+ $data = [
'session_id' => $this->user->data['session_id'],
'provider' => $service,
- );
+ ];
- return $this->_has_acess_token($data);
+ return $this->has_access_token($data);
}
/**
- * Checks to see if a state exists solely by the session_id of the user
- *
- * @param string $service The name of the OAuth service
- * @return bool true if they have state, false if they don't
- */
+ * Checks to see if a state exists solely by the session_id of the user.
+ *
+ * @param string $service The OAuth service name
+ * @return bool true if the user's state exists,
+ * false if the user's state does not exist
+ */
public function has_state_by_session($service)
{
$service = $this->get_service_name_for_db($service);
@@ -383,25 +373,34 @@ class token_storage implements TokenStorageInterface
return true;
}
- $data = array(
+ $data = [
'session_id' => $this->user->data['session_id'],
'provider' => $service,
- );
+ ];
return (bool) $this->get_state_row($data);
}
/**
- * A helper function that performs the query for has access token functions
- *
- * @param array $data
- * @return bool
- */
- protected function _has_acess_token($data)
+ * A helper function that performs the query for has access token functions.
+ *
+ * @param array $data The SQL WHERE data
+ * @return bool true if the user's access token exists,
+ * false if the user's access token does not exist
+ */
+ protected function has_access_token($data)
{
return (bool) $this->get_access_token_row($data);
}
+ /**
+ * A helper function that performs the query for retrieving access token functions by session.
+ * Also checks if the token is a valid token.
+ *
+ * @param string $service The OAuth service provider name
+ * @return TokenInterface
+ * @throws TokenNotFoundException
+ */
public function retrieve_access_token_by_session($service)
{
$service = $this->get_service_name_for_db($service);
@@ -411,14 +410,21 @@ class token_storage implements TokenStorageInterface
return $this->cachedToken;
}
- $data = array(
+ $data = [
'session_id' => $this->user->data['session_id'],
- 'provider' => $service,
- );
+ 'provider' => $service,
+ ];
return $this->_retrieve_access_token($data);
}
+ /**
+ * A helper function that performs the query for retrieving state functions by session.
+ *
+ * @param string $service The OAuth service provider name
+ * @return string The OAuth state
+ * @throws AuthorizationStateNotFoundException
+ */
public function retrieve_state_by_session($service)
{
$service = $this->get_service_name_for_db($service);
@@ -428,22 +434,22 @@ class token_storage implements TokenStorageInterface
return $this->cachedState;
}
- $data = array(
+ $data = [
'session_id' => $this->user->data['session_id'],
- 'provider' => $service,
- );
+ 'provider' => $service,
+ ];
return $this->_retrieve_state($data);
}
/**
- * A helper function that performs the query for retrieve access token functions
- * Also checks if the token is a valid token
- *
- * @param array $data
- * @return mixed
- * @throws \OAuth\Common\Storage\Exception\TokenNotFoundException
- */
+ * A helper function that performs the query for retrieve access token functions.
+ * Also checks if the token is a valid token.
+ *
+ * @param array $data The SQL WHERE data
+ * @return TokenInterface
+ * @throws TokenNotFoundException
+ */
protected function _retrieve_access_token($data)
{
$row = $this->get_access_token_row($data);
@@ -459,19 +465,21 @@ class token_storage implements TokenStorageInterface
if (!($token instanceof TokenInterface))
{
$this->clearToken($data['provider']);
+
throw new TokenNotFoundException('AUTH_PROVIDER_OAUTH_TOKEN_ERROR_INCORRECTLY_STORED');
}
$this->cachedToken = $token;
+
return $token;
}
/**
- * A helper function that performs the query for retrieve state functions
+ * A helper function that performs the query for retrieve state functions.
*
- * @param array $data
- * @return mixed
- * @throws \OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException
+ * @param array $data The SQL WHERE data
+ * @return string The OAuth state
+ * @throws AuthorizationStateNotFoundException
*/
protected function _retrieve_state($data)
{
@@ -483,18 +491,21 @@ class token_storage implements TokenStorageInterface
}
$this->cachedState = $row['oauth_state'];
+
return $this->cachedState;
}
/**
- * A helper function that performs the query for retrieving an access token
- *
- * @param array $data
- * @return mixed
- */
+ * A helper function that performs the query for retrieving an access token.
+ *
+ * @param array $data The SQL WHERE data
+ * @return array|false array with the OAuth token row,
+ * false if the token does not exist
+ */
protected function get_access_token_row($data)
{
- $sql = 'SELECT oauth_token FROM ' . $this->oauth_token_table . '
+ $sql = 'SELECT oauth_token
+ FROM ' . $this->oauth_token_table . '
WHERE ' . $this->db->sql_build_array('SELECT', $data);
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
@@ -504,14 +515,16 @@ class token_storage implements TokenStorageInterface
}
/**
- * A helper function that performs the query for retrieving a state
+ * A helper function that performs the query for retrieving a state.
*
- * @param array $data
- * @return mixed
+ * @param array $data The SQL WHERE data
+ * @return array|false array with the OAuth state row,
+ * false if the state does not exist
*/
protected function get_state_row($data)
{
- $sql = 'SELECT oauth_state FROM ' . $this->oauth_state_table . '
+ $sql = 'SELECT oauth_state
+ FROM ' . $this->oauth_state_table . '
WHERE ' . $this->db->sql_build_array('SELECT', $data);
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
@@ -520,16 +533,22 @@ class token_storage implements TokenStorageInterface
return $row;
}
+ /**
+ * A helper function that JSON encodes a TokenInterface's data.
+ *
+ * @param TokenInterface $token
+ * @return string The json encoded TokenInterface's data
+ */
public function json_encode_token(TokenInterface $token)
{
- $members = array(
+ $members = [
'accessToken' => $token->getAccessToken(),
'endOfLife' => $token->getEndOfLife(),
'extraParams' => $token->getExtraParams(),
'refreshToken' => $token->getRefreshToken(),
'token_class' => get_class($token),
- );
+ ];
// Handle additional data needed for OAuth1 tokens
if ($token instanceof StdOAuth1Token)
@@ -542,6 +561,13 @@ class token_storage implements TokenStorageInterface
return json_encode($members);
}
+ /**
+ * A helper function that JSON decodes a data string and creates a TokenInterface.
+ *
+ * @param string $json The json encoded TokenInterface's data
+ * @return TokenInterface
+ * @throws TokenNotFoundException
+ */
public function json_decode_token($json)
{
$token_data = json_decode($json, true);
@@ -557,7 +583,10 @@ class token_storage implements TokenStorageInterface
$endOfLife = $token_data['endOfLife'];
$extra_params = $token_data['extraParams'];
- // Create the token
+ /**
+ * Create the token
+ * @var TokenInterface $token
+ */
$token = new $token_class($access_token, $refresh_token, TokenInterface::EOL_NEVER_EXPIRES, $extra_params);
$token->setEndOfLife($endOfLife);
@@ -573,20 +602,19 @@ class token_storage implements TokenStorageInterface
}
/**
- * Returns the name of the service as it must be stored in the database.
- *
- * @param string $service The name of the OAuth service
- * @return string The name of the OAuth service as it needs to be stored
- * in the database.
- */
- protected function get_service_name_for_db($service)
+ * Returns the service name as it must be stored in the database.
+ *
+ * @param string $provider The OAuth provider name
+ * @return string The OAuth service name
+ */
+ protected function get_service_name_for_db($provider)
{
// Enforce the naming convention for oauth services
- if (strpos($service, 'auth.provider.oauth.service.') !== 0)
+ if (strpos($provider, 'auth.provider.oauth.service.') !== 0)
{
- $service = 'auth.provider.oauth.service.' . strtolower($service);
+ $provider = 'auth.provider.oauth.service.' . strtolower($provider);
}
- return $service;
+ return $provider;
}
}
diff --git a/phpBB/phpbb/auth/provider/provider_interface.php b/phpBB/phpbb/auth/provider/provider_interface.php
index 463324ff46..21c73a33c5 100644
--- a/phpBB/phpbb/auth/provider/provider_interface.php
+++ b/phpBB/phpbb/auth/provider/provider_interface.php
@@ -53,7 +53,7 @@ interface provider_interface
* Autologin function
*
* @return array|null containing the user row, empty if no auto login
- * should take place, or null if not impletmented.
+ * should take place, or null if not implemented.
*/
public function autologin();
@@ -68,7 +68,7 @@ interface provider_interface
/**
* This function updates the template with variables related to the acp
- * options with whatever configuraton values are passed to it as an array.
+ * options with whatever configuration values are passed to it as an array.
* It then returns the name of the acp file related to this authentication
* provider.
*
diff --git a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
deleted file mode 100644
index 6f7096296d..0000000000
--- a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-namespace phpbb\console\command\fixup;
-
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Style\SymfonyStyle;
-
-class recalculate_email_hash extends \phpbb\console\command\command
-{
- /** @var \phpbb\db\driver\driver_interface */
- protected $db;
-
- public function __construct(\phpbb\user $user, \phpbb\db\driver\driver_interface $db)
- {
- $this->db = $db;
-
- parent::__construct($user);
- }
-
- protected function configure()
- {
- $this
- ->setName('fixup:recalculate-email-hash')
- ->setDescription($this->user->lang('CLI_DESCRIPTION_RECALCULATE_EMAIL_HASH'))
- ;
- }
-
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- $io = new SymfonyStyle($input, $output);
-
- $sql = 'SELECT user_id, user_email, user_email_hash
- FROM ' . USERS_TABLE . '
- WHERE user_type <> ' . USER_IGNORE . "
- AND user_email <> ''";
- $result = $this->db->sql_query($sql);
-
- while ($row = $this->db->sql_fetchrow($result))
- {
- $user_email_hash = phpbb_email_hash($row['user_email']);
- if ($user_email_hash !== $row['user_email_hash'])
- {
- $sql_ary = array(
- 'user_email_hash' => $user_email_hash,
- );
-
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . '
- WHERE user_id = ' . (int) $row['user_id'];
- $this->db->sql_query($sql);
-
- if ($output->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG)
- {
- $io->table(
- array('user_id', 'user_email', 'user_email_hash'),
- array(array($row['user_id'], $row['user_email'], $user_email_hash))
- );
- }
- }
- }
- $this->db->sql_freeresult($result);
-
- $io->success($this->user->lang('CLI_FIXUP_RECALCULATE_EMAIL_HASH_SUCCESS'));
- }
-}
diff --git a/phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php b/phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php
new file mode 100644
index 0000000000..c5a4beef38
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php
@@ -0,0 +1,49 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v330;
+
+class forums_legend_limit extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return $this->db_tools->sql_column_exists($this->table_prefix . 'forums', 'display_subforum_limit');
+ }
+
+ static public function depends_on()
+ {
+ return ['\phpbb\db\migration\data\v330\v330b1'];
+ }
+
+ public function update_schema()
+ {
+ return [
+ 'add_columns' => [
+ $this->table_prefix . 'forums' => [
+ 'display_subforum_limit' => ['BOOL', 0, 'after' => 'display_subforum_list'],
+ ],
+ ],
+ ];
+ }
+
+ public function revert_schema()
+ {
+ return [
+ 'drop_columns' => [
+ $this->table_prefix . 'forums' => [
+ 'display_subforum_limit',
+ ],
+ ],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v330/remove_email_hash.php b/phpBB/phpbb/db/migration/data/v330/remove_email_hash.php
new file mode 100644
index 0000000000..dc43678625
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/remove_email_hash.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\db\migration\data\v330;
+
+class remove_email_hash extends \phpbb\db\migration\migration
+{
+ public function update_schema()
+ {
+ return [
+ 'add_index' => [
+ $this->table_prefix . 'users' => [
+ 'user_email' => ['user_email'],
+ ],
+ ],
+ 'drop_keys' => [
+ $this->table_prefix . 'users' => [
+ 'user_email_hash',
+ ],
+ ],
+ 'drop_columns' => [
+ $this->table_prefix . 'users' => ['user_email_hash'],
+ ],
+ ];
+ }
+
+ public function revert_schema()
+ {
+ return [
+ 'add_columns' => [
+ $this->table_prefix . 'users' => [
+ 'user_email_hash' => ['BINT', 0],
+ ],
+ ],
+ 'add_index' => [
+ $this->table_prefix . 'users' => [
+ 'user_email_hash',
+ ],
+ ],
+ 'drop_keys' => [
+ $this->table_prefix . 'users' => [
+ 'user_email' => ['user_email'],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/di/service_collection.php b/phpBB/phpbb/di/service_collection.php
index 8c1c172e36..6298670c42 100644
--- a/phpBB/phpbb/di/service_collection.php
+++ b/phpBB/phpbb/di/service_collection.php
@@ -49,21 +49,6 @@ class service_collection extends \ArrayObject
return new service_collection_iterator($this);
}
- // Because of a PHP issue we have to redefine offsetExists
- // (even with a call to the parent):
- // https://bugs.php.net/bug.php?id=66834
- // https://bugs.php.net/bug.php?id=67067
- // But it triggers a sniffer issue that we have to skip
- // @codingStandardsIgnoreStart
- /**
- * {@inheritdoc}
- */
- public function offsetExists($index)
- {
- return parent::offsetExists($index);
- }
- // @codingStandardsIgnoreEnd
-
/**
* {@inheritdoc}
*/
@@ -76,11 +61,11 @@ class service_collection extends \ArrayObject
* Add a service to the collection
*
* @param string $name The service name
- * @return null
+ * @return void
*/
public function add($name)
{
- $this->offsetSet($name, null);
+ $this->offsetSet($name, false);
}
/**
diff --git a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php
index ba439609ff..91d7884aa4 100644
--- a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php
+++ b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php
@@ -245,7 +245,6 @@ class add_config_settings extends \phpbb\install\task_base
user_lang = '" . $this->db->sql_escape($this->install_config->get('user_language', 'en')) . "',
user_email='" . $this->db->sql_escape($this->install_config->get('board_email')) . "',
user_dateformat='" . $this->db->sql_escape($this->language->lang('default_dateformat')) . "',
- user_email_hash = " . $this->db->sql_escape(phpbb_email_hash($this->install_config->get('board_email'))) . ",
username_clean = '" . $this->db->sql_escape(utf8_clean_string($this->install_config->get('admin_name'))) . "'
WHERE username = 'Admin'",
diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php
index ba200f38df..7c76c08b73 100644
--- a/phpBB/phpbb/session.php
+++ b/phpBB/phpbb/session.php
@@ -250,8 +250,7 @@ class session
$ips = explode(' ', $this->forwarded_for);
foreach ($ips as $ip)
{
- // check IPv4 first, the IPv6 is hopefully only going to be used very seldom
- if (!empty($ip) && !preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip))
+ if (!filter_var($ip, FILTER_VALIDATE_IP))
{
// contains invalid data, don't use the forwarded for header
$this->forwarded_for = '';
@@ -311,49 +310,17 @@ class session
foreach ($ips as $ip)
{
- if (function_exists('phpbb_ip_normalise'))
- {
- // Normalise IP address
- $ip = phpbb_ip_normalise($ip);
-
- if (empty($ip))
- {
- // IP address is invalid.
- break;
- }
-
- // IP address is valid.
- $this->ip = $ip;
+ // Normalise IP address
+ $ip = phpbb_ip_normalise($ip);
- // Skip legacy code.
- continue;
- }
-
- if (preg_match(get_preg_expression('ipv4'), $ip))
- {
- $this->ip = $ip;
- }
- else if (preg_match(get_preg_expression('ipv6'), $ip))
+ if ($ip === false)
{
- // Quick check for IPv4-mapped address in IPv6
- if (stripos($ip, '::ffff:') === 0)
- {
- $ipv4 = substr($ip, 7);
-
- if (preg_match(get_preg_expression('ipv4'), $ipv4))
- {
- $ip = $ipv4;
- }
- }
-
- $this->ip = $ip;
- }
- else
- {
- // We want to use the last valid address in the chain
- // Leave foreach loop when address is invalid
+ // IP address is invalid.
break;
}
+
+ // IP address is valid.
+ $this->ip = $ip;
}
$this->load = false;
diff --git a/phpBB/phpbb/ucp/controller/reset_password.php b/phpBB/phpbb/ucp/controller/reset_password.php
index 7bd1b20cb3..5c27c4f414 100644
--- a/phpBB/phpbb/ucp/controller/reset_password.php
+++ b/phpBB/phpbb/ucp/controller/reset_password.php
@@ -173,7 +173,7 @@ class reset_password
'SELECT' => 'user_id, username, user_permissions, user_email, user_jabber, user_notify_type, user_type,'
. ' user_lang, user_inactive_reason, reset_token, reset_token_expiration',
'FROM' => [$this->users_table => 'u'],
- 'WHERE' => "user_email_hash = '" . $this->db->sql_escape(phpbb_email_hash($email)) . "'" .
+ 'WHERE' => "user_email = '" . $this->db->sql_escape($email) . "'" .
(!empty($username) ? " AND username_clean = '" . $this->db->sql_escape(utf8_clean_string($username)) . "'" : ''),
];
diff --git a/phpBB/posting.php b/phpBB/posting.php
index 20f6ddf8e5..c5d0693f35 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -256,12 +256,6 @@ if ($mode == 'popup')
$user->setup(array('posting', 'mcp', 'viewtopic'), $post_data['forum_style']);
-if ($config['enable_post_confirm'] && !$user->data['is_registered'])
-{
- $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
- $captcha->init(CONFIRM_POST);
-}
-
// Use post_row values in favor of submitted ones...
$forum_id = (!empty($post_data['forum_id'])) ? (int) $post_data['forum_id'] : (int) $forum_id;
$topic_id = (!empty($post_data['topic_id'])) ? (int) $post_data['topic_id'] : (int) $topic_id;
@@ -427,6 +421,12 @@ if (!$is_authed || !empty($error))
login_box('', $message);
}
+if ($config['enable_post_confirm'] && !$user->data['is_registered'])
+{
+ $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
+ $captcha->init(CONFIRM_POST);
+}
+
// Is the user able to post within this forum?
if ($post_data['forum_type'] != FORUM_POST && in_array($mode, array('post', 'bump', 'quote', 'reply')))
{
@@ -1181,11 +1181,23 @@ if ($submit || $preview || $refresh)
$error[] = $user->lang['EMPTY_SUBJECT'];
}
- // Check for out-of-bounds characters that are currently
- // not supported by utf8_bin in MySQL
+ /**
+ * Replace Emojis and other 4bit UTF-8 chars not allowed by MySQL to UCR/NCR.
+ * Using their Numeric Character Reference's Hexadecimal notation.
+ */
+ $post_data['post_subject'] = utf8_encode_ucr($post_data['post_subject']);
+
+ /**
+ * This should never happen again.
+ * Leaving the fallback here just in case there will be the need of it.
+ *
+ * Check for out-of-bounds characters that are currently
+ * not supported by utf8_bin in MySQL
+ */
if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $post_data['post_subject'], $matches))
{
- $character_list = implode('<br />', $matches[0]);
+ $character_list = implode('<br>', $matches[0]);
+
$error[] = $user->lang('UNSUPPORTED_CHARACTERS_SUBJECT', $character_list);
}
diff --git a/phpBB/search.php b/phpBB/search.php
index 8dde46f999..bd8025dae5 100644
--- a/phpBB/search.php
+++ b/phpBB/search.php
@@ -720,6 +720,8 @@ if ($keywords || $author || $author_id || $search_id || $submit)
if ($sql_where)
{
+ $zebra = [];
+
if ($show_results == 'posts')
{
// @todo Joining this query to the one below?
@@ -728,7 +730,6 @@ if ($keywords || $author || $author_id || $search_id || $submit)
WHERE user_id = ' . $user->data['user_id'];
$result = $db->sql_query($sql);
- $zebra = array();
while ($row = $db->sql_fetchrow($result))
{
$zebra[($row['friend']) ? 'friend' : 'foe'][] = $row['zebra_id'];
diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html
index b1c7a81709..34915ebc41 100644
--- a/phpBB/styles/prosilver/template/memberlist_search.html
+++ b/phpBB/styles/prosilver/template/memberlist_search.html
@@ -12,7 +12,7 @@
<dt><label for="username">{L_USERNAME}{L_COLON}</label></dt>
<dd>
<!-- IF U_LIVE_SEARCH --><div class="dropdown-container dropdown-{S_CONTENT_FLOW_END}"><!-- ENDIF -->
- <input type="text" name="username" id="username" value="{USERNAME}" class="inputbox"<!-- IF U_LIVE_SEARCH --> autocomplete="off" data-filter="phpbb.search.filter" data-ajax="member_search" data-min-length="3" data-url="{U_LIVE_SEARCH}" data-results="#user-search" data-overlay="false"<!-- ENDIF --> />
+ <input type="text" name="username" id="username" value="{USERNAME}" class="inputbox"<!-- IF U_LIVE_SEARCH --> autocomplete="off" data-filter="phpbb.search.filter" data-ajax="member_search" data-min-length="3" data-url="{U_LIVE_SEARCH}" data-results="#user-search"<!-- ENDIF --> />
<!-- IF U_LIVE_SEARCH -->
<div class="dropdown live-search hidden" id="user-search">
<div class="pointer"><div class="pointer-inner"></div></div>
diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html
index ee8aa319bc..f44382f500 100644
--- a/phpBB/styles/prosilver/template/ucp_register.html
+++ b/phpBB/styles/prosilver/template/ucp_register.html
@@ -12,16 +12,16 @@
}
</script>
-<div class="panel">
- <div class="inner">
+{% if PROVIDER_TEMPLATE_FILE %}
+ <div class="panel">
+ <div class="inner">
- <h2>{{ SITENAME }} - {{ lang('OAUTH_REGISTRATION') }}</h2>
+ <h2>{{ SITENAME }} - {{ lang('OAUTH_REGISTRATION') }}</h2>
- {% if PROVIDER_TEMPLATE_FILE %}
{% include PROVIDER_TEMPLATE_FILE %}
- {% endif %}
+ </div>
</div>
-</div>
+{% endif %}
<form id="register" method="post" action="{S_UCP_ACTION}"{S_FORM_ENCTYPE}>
diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css
index ffaa71034f..1ead493926 100644
--- a/phpBB/styles/prosilver/theme/colours.css
+++ b/phpBB/styles/prosilver/theme/colours.css
@@ -672,6 +672,11 @@ Colours and backgrounds for buttons.css
box-shadow: 0 0 10px #0075B0;
}
+.search-results li:hover,
+.search-results li.active {
+ background-color: #CFE1F6;
+}
+
/* Icon images
---------------------------------------- */
diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css
index 5646a7d6c7..99c898f41e 100644
--- a/phpBB/styles/prosilver/theme/forms.css
+++ b/phpBB/styles/prosilver/theme/forms.css
@@ -355,7 +355,7 @@ input.button3 {
font-variant: small-caps;
}
-input[type="button"], input[type="submit"], input[type="reset"], input[type="checkbox"], input[type="radio"] {
+input[type="button"], input[type="submit"], input[type="reset"], input[type="checkbox"], input[type="radio"], .search-results li {
cursor: pointer;
}
diff --git a/tests/auth/fixtures/user.xml b/tests/auth/fixtures/user.xml
index 1e0eb6ee49..33f69a9067 100644
--- a/tests/auth/fixtures/user.xml
+++ b/tests/auth/fixtures/user.xml
@@ -1,5 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
+ <table name="phpbb_groups">
+ <column>group_id</column>
+ <column>group_name</column>
+ <column>group_type</column>
+ <column>group_desc</column>
+ <row>
+ <value>1</value>
+ <value>REGISTERED</value>
+ <value>3</value>
+ <value>foobar</value>
+ </row>
+ </table>
<table name="phpbb_users">
<column>user_id</column>
<column>username</column>
diff --git a/tests/auth/fixtures/user_533.xml b/tests/auth/fixtures/user_533.xml
deleted file mode 100644
index 9731e4db4a..0000000000
--- a/tests/auth/fixtures/user_533.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<dataset>
- <table name="phpbb_users">
- <column>user_id</column>
- <column>username</column>
- <column>username_clean</column>
- <column>user_password</column>
- <column>user_passchg</column>
- <column>user_email</column>
- <column>user_type</column>
- <column>user_login_attempts</column>
- <column>user_permissions</column>
- <column>user_sig</column>
- <row>
- <value>1</value>
- <value>foobar</value>
- <value>foobar</value>
- <value>$2a$10$e01Syh9PbJjUkio66eFuUu4FhCE2nRgG7QPc1JACalsPXcIuG2bbi</value>
- <value>0</value>
- <value>example@example.com</value>
- <value>0</value>
- <value>0</value>
- <value></value>
- <value></value>
- </row>
- <row>
- <value>2</value>
- <value>foobar2</value>
- <value>foobar2</value>
- <value>$H$9E45lK6J8nLTSm9oJE5aNCSTFK9wqa/</value>
- <value>0</value>
- <value>example@example.com</value>
- <value>0</value>
- <value>0</value>
- <value></value>
- <value></value>
- </row>
- </table>
-</dataset>
diff --git a/tests/auth/provider_apache_test.php b/tests/auth/provider_apache_test.php
index 58d6354228..ebc97c204a 100644
--- a/tests/auth/provider_apache_test.php
+++ b/tests/auth/provider_apache_test.php
@@ -28,41 +28,14 @@ class phpbb_auth_provider_apache_test extends phpbb_database_test_case
$lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx);
$lang = new \phpbb\language\language($lang_loader);
$this->request = $this->createMock('\phpbb\request\request');
- $this->user = new \phpbb\user($lang, '\phpbb\datetime');
- $driver_helper = new \phpbb\passwords\driver\helper($config);
- $passwords_drivers = array(
- 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $driver_helper),
- 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $driver_helper),
- 'passwords.driver.salted_md5' => new \phpbb\passwords\driver\salted_md5($config, $driver_helper),
- 'passwords.driver.phpass' => new \phpbb\passwords\driver\phpass($config, $driver_helper),
- );
-
- $passwords_helper = new \phpbb\passwords\helper;
- // Set up passwords manager
- $passwords_manager = new \phpbb\passwords\manager($config, $passwords_drivers, $passwords_helper, array_keys($passwords_drivers));
-
- if (version_compare(PHP_VERSION, '5.3.7', '<'))
- {
- $this->password_hash = '$2a$10$e01Syh9PbJjUkio66eFuUu4FhCE2nRgG7QPc1JACalsPXcIuG2bbi';
- }
- else
- {
- $this->password_hash = '$2y$10$4RmpyVu2y8Yf/lP3.yQBquKvE54TCUuEDEBJYY6FDDFN3LcbCGz9i';
- }
+ $this->user = new \phpbb\user($lang, '\phpbb\datetime');;
- $this->provider = new \phpbb\auth\provider\apache($db, $config, $passwords_manager, $this->request, $this->user, $phpbb_root_path, $phpEx);
+ $this->provider = new \phpbb\auth\provider\apache($config, $db, $lang, $this->request, $this->user, $phpbb_root_path, $phpEx);
}
public function getDataSet()
{
- if ((version_compare(PHP_VERSION, '5.3.7', '<')))
- {
- return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user_533.xml');
- }
- else
- {
- return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user.xml');
- }
+ return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user.xml');
}
/**
@@ -109,7 +82,7 @@ class phpbb_auth_provider_apache_test extends phpbb_database_test_case
'user_row' => array(
'user_id' => '1',
'username' => 'foobar',
- 'user_password' => $this->password_hash,
+ 'user_password' => '$2y$10$4RmpyVu2y8Yf/lP3.yQBquKvE54TCUuEDEBJYY6FDDFN3LcbCGz9i',
'user_passchg' => '0',
'user_email' => 'example@example.com',
'user_type' => '0',
@@ -145,10 +118,9 @@ class phpbb_auth_provider_apache_test extends phpbb_database_test_case
'user_regdate' => '0',
'username' => 'foobar',
'username_clean' => 'foobar',
- 'user_password' => $this->password_hash,
+ 'user_password' => '$2y$10$4RmpyVu2y8Yf/lP3.yQBquKvE54TCUuEDEBJYY6FDDFN3LcbCGz9i',
'user_passchg' => '0',
'user_email' => 'example@example.com',
- 'user_email_hash' => '0',
'user_birthday' => '',
'user_lastvisit' => '0',
'user_lastmark' => '0',
diff --git a/tests/auth/provider_db_test.php b/tests/auth/provider_db_test.php
index b7d94ed046..8305e7caa4 100644
--- a/tests/auth/provider_db_test.php
+++ b/tests/auth/provider_db_test.php
@@ -15,14 +15,7 @@ class phpbb_auth_provider_db_test extends phpbb_database_test_case
{
public function getDataSet()
{
- if ((version_compare(PHP_VERSION, '5.3.7', '<')))
- {
- return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user_533.xml');
- }
- else
- {
- return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user.xml');
- }
+ return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user.xml');
}
public function test_login()
@@ -52,16 +45,21 @@ class phpbb_auth_provider_db_test extends phpbb_database_test_case
$passwords_manager = new \phpbb\passwords\manager($config, $passwords_drivers, $passwords_helper, array_keys($passwords_drivers));
$phpbb_container = new phpbb_mock_container_builder();
+ $plugins = new \phpbb\di\service_collection($phpbb_container);
+ $plugins->add('core.captcha.plugins.nogd');
+ $phpbb_container->set(
+ 'captcha.factory',
+ new \phpbb\captcha\factory($phpbb_container, $plugins)
+ );
+ $phpbb_container->set(
+ 'core.captcha.plugins.nogd',
+ new \phpbb\captcha\plugins\nogd()
+ );
+ /** @var \phpbb\captcha\factory $captcha_factory */
+ $captcha_factory = $phpbb_container->get('captcha.factory');
- $provider = new \phpbb\auth\provider\db($db, $config, $passwords_manager, $request, $user, $phpbb_container, $phpbb_root_path, $phpEx);
- if (version_compare(PHP_VERSION, '5.3.7', '<'))
- {
- $password_hash = '$2a$10$e01Syh9PbJjUkio66eFuUu4FhCE2nRgG7QPc1JACalsPXcIuG2bbi';
- }
- else
- {
- $password_hash = '$2y$10$4RmpyVu2y8Yf/lP3.yQBquKvE54TCUuEDEBJYY6FDDFN3LcbCGz9i';
- }
+ $provider = new \phpbb\auth\provider\db($captcha_factory, $config, $db, $passwords_manager, $request, $user, $phpbb_root_path, $phpEx);
+ $password_hash = '$2y$10$4RmpyVu2y8Yf/lP3.yQBquKvE54TCUuEDEBJYY6FDDFN3LcbCGz9i';
$expected = array(
'status' => LOGIN_SUCCESS,
@@ -88,7 +86,6 @@ class phpbb_auth_provider_db_test extends phpbb_database_test_case
// Check if convert works
$login_return = $provider->login('foobar2', 'example');
- $password_start = (version_compare(PHP_VERSION, '5.3.7', '<')) ? '$2a$10$' : '$2y$10$';
- $this->assertStringStartsWith($password_start, $login_return['user_row']['user_password']);
+ $this->assertStringStartsWith('$2y$10$', $login_return['user_row']['user_password']);
}
}
diff --git a/tests/auth/provider_ldap_test.php b/tests/auth/provider_ldap_test.php
new file mode 100644
index 0000000000..0bc9961f52
--- /dev/null
+++ b/tests/auth/provider_ldap_test.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+/**
+ * @group slow
+ */
+class phpbb_auth_provider_ldap_test extends phpbb_database_test_case
+{
+ /** @var \phpbb\auth\provider\ldap */
+ protected $provider;
+
+ protected $user;
+
+ protected function setup() : void
+ {
+ parent::setUp();
+
+ global $phpbb_root_path, $phpEx;
+
+ $db = $this->new_dbal();
+ $config = new \phpbb\config\config([
+ 'ldap_server' => 'localhost',
+ 'ldap_port' => 3389,
+ 'ldap_base_dn' => 'dc=example,dc=com',
+ 'ldap_uid' => 'uid',
+ 'ldap_email' => 'mail',
+ ]);
+ $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx);
+ $lang = new \phpbb\language\language($lang_loader);
+ $this->user = new \phpbb\user($lang, '\phpbb\datetime');
+ $this->user->data['username'] = 'admin';
+
+ $this->provider = new \phpbb\auth\provider\ldap($config, $db, $lang, $this->user);
+ }
+
+ public function getDataSet()
+ {
+ return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/user.xml');
+ }
+
+ /**
+ * Test to see if a user is identified to Apache. Expects false if they are.
+ */
+ public function test_init()
+ {
+ $this->assertFalse($this->provider->init());
+ }
+
+ public function test_login()
+ {
+ $username = 'admin';
+ $password = 'adminadmin';
+
+ $expected = array(
+ 'status' => LOGIN_SUCCESS_CREATE_PROFILE, // successful login and user created
+ 'error_msg' => false,
+ 'user_row' => array(
+ 'username' => 'admin',
+ 'user_password' => '',
+ 'user_email' => 'admin@example.com',
+ 'user_type' => 0,
+ 'group_id' => 1,
+ 'user_new' => 0,
+ 'user_ip' => '',
+ ),
+ );
+
+ $this->assertEquals($expected, $this->provider->login($username, $password));
+ }
+
+ public function test_autologin()
+ {
+ $this->assertNull($this->provider->autologin());
+ }
+
+ public function test_validate_session()
+ {
+ $user = array(
+ 'username' => 'admin',
+ );
+
+ $this->assertNull($this->provider->validate_session($user));
+ }
+}
diff --git a/tests/functional/posting_test.php b/tests/functional/posting_test.php
index 7150f20a9d..49447e1133 100644
--- a/tests/functional/posting_test.php
+++ b/tests/functional/posting_test.php
@@ -41,15 +41,10 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
{
$this->login();
- $this->add_lang('posting');
-
- self::create_post(2,
- 1,
- "Unsupported: \xF0\x9F\x88\xB3 \xF0\x9F\x9A\xB6",
- 'This is a test with emoji characters in the topic title.',
- array(),
- 'Your subject contains the following unsupported characters'
- );
+ $post = $this->create_topic(2, "Test Topic \xF0\x9F\xA4\x94 3\xF0\x9D\x94\xBB\xF0\x9D\x95\x9A", 'This is a test with emoji character in the topic title.');
+ $this->create_post(2, $post['topic_id'], "Re: Test Topic 1 \xF0\x9F\xA4\x94 3\xF0\x9D\x94\xBB\xF0\x9D\x95\x9A", 'This is a test with emoji characters in the topic title.');
+ $crawler = self::request('GET', "viewtopic.php?t={$post['topic_id']}&sid={$this->sid}");
+ $this->assertContains("\xF0\x9F\xA4\x94 3\xF0\x9D\x94\xBB\xF0\x9D\x95\x9A", $crawler->text());
}
public function test_supported_unicode_characters()
diff --git a/tests/functional/subforum_test.php b/tests/functional/subforum_test.php
new file mode 100644
index 0000000000..6ce4f53c20
--- /dev/null
+++ b/tests/functional/subforum_test.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+/**
+ * @group functional
+ */
+class phpbb_functional_subforum_test extends phpbb_functional_test_case
+{
+ public function test_setup_forums()
+ {
+ $this->login();
+ $this->admin_login();
+
+ $forum_name = 'Subforum Test #1';
+ $crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}");
+ $form = $crawler->selectButton('addforum')->form([
+ 'forum_name' => $forum_name,
+ ]);
+ $crawler = self::submit($form);
+ $form = $crawler->selectButton('update')->form([
+ 'forum_perm_from' => 2,
+ ]);
+ self::submit($form);
+ $forum_id = self::get_forum_id($forum_name);
+
+ // 'Feeds #1.1' is a sub-forum of 'Feeds #1'
+ $forum_name = 'Subforum Test #1.1';
+ $crawler = self::request('GET', "adm/index.php?i=acp_forums&sid={$this->sid}&icat=6&mode=manage&parent_id={$forum_id}");
+ $form = $crawler->selectButton('addforum')->form([
+ 'forum_name' => $forum_name,
+ ]);
+ $crawler = self::submit($form);
+ $form = $crawler->selectButton('update')->form([
+ 'forum_perm_from' => 2,
+ ]);
+ self::submit($form);
+ $forum_id = self::get_forum_id('Subforum Test #1.1');
+
+ // 'Feeds #news' will be used for feed.php?mode=news
+ $crawler = self::request('GET', "adm/index.php?i=acp_forums&sid={$this->sid}&icat=6&mode=manage&parent_id={$forum_id}");
+ $form = $crawler->selectButton('addforum')->form([
+ 'forum_name' => 'Subforum Test #1.1.1',
+ ]);
+ $crawler = self::submit($form);
+ $form = $crawler->selectButton('update')->form([
+ 'forum_perm_from' => 2,
+ ]);
+ self::submit($form);
+ }
+
+ /**
+ * @depends test_setup_forums
+ */
+ public function test_display_subforums()
+ {
+ $crawler = self::request('GET', "index.php?sid={$this->sid}");
+ $this->assertContains('Subforum Test #1.1', $crawler->html());
+ $this->assertContains('Subforum Test #1.1.1', $crawler->html());
+ }
+
+ /**
+ * @depends test_display_subforums
+ */
+ public function test_display_subforums_limit()
+ {
+ $this->login();
+ $this->admin_login();
+
+ // Disable listing subforums
+ $forum_id = $this->get_forum_id('Subforum Test #1');
+ $crawler = self::request('GET', "adm/index.php?i=acp_forums&sid={$this->sid}&icat=7&mode=manage&parent_id=0&f={$forum_id}&action=edit");
+ $form = $crawler->selectButton('submit')->form([
+ 'display_subforum_limit' => 1,
+ ]);
+ self::submit($form);
+
+ $crawler = self::request('GET', "index.php?sid={$this->sid}");
+ $this->assertContains('Subforum Test #1.1', $crawler->html());
+ $this->assertNotContains('Subforum Test #1.1.1', $crawler->html());
+ }
+
+ protected function get_forum_id($forum_name)
+ {
+ $this->db = $this->get_db();
+ $forum_id = 0;
+
+ $sql = 'SELECT *
+ FROM ' . FORUMS_TABLE . '
+ WHERE ' . $this->db->sql_in_set('forum_name', $forum_name);
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ if ($row['forum_name'] == $forum_name)
+ {
+ $forum_id = (int) $row['forum_id'];
+ break;
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ return $forum_id;
+ }
+}
diff --git a/tests/functions/fixtures/validate_email.xml b/tests/functions/fixtures/validate_email.xml
index fa139f6f18..985050cedc 100644
--- a/tests/functions/fixtures/validate_email.xml
+++ b/tests/functions/fixtures/validate_email.xml
@@ -30,14 +30,14 @@
<column>username_clean</column>
<column>user_permissions</column>
<column>user_sig</column>
- <column>user_email_hash</column>
+ <column>user_email</column>
<row>
<value>1</value>
<value>admin</value>
<value>admin</value>
<value></value>
<value></value>
- <value>143317126117</value>
+ <value>admin@example.com</value>
</row>
</table>
</dataset>
diff --git a/tests/functions/user_delete_test.php b/tests/functions/user_delete_test.php
index 89aecdefb9..f4ea5696b9 100644
--- a/tests/functions/user_delete_test.php
+++ b/tests/functions/user_delete_test.php
@@ -60,21 +60,43 @@ class phpbb_functions_user_delete_test extends phpbb_database_test_case
// Set up passwords manager
$passwords_manager = new \phpbb\passwords\manager($config, $passwords_drivers, $passwords_helper, array_keys($passwords_drivers));
- $oauth_provider = new \phpbb\auth\provider\oauth\oauth(
- $db,
+ $plugins = new \phpbb\di\service_collection($phpbb_container);
+ $plugins->add('core.captcha.plugins.nogd');
+ $phpbb_container->set(
+ 'captcha.factory',
+ new \phpbb\captcha\factory($phpbb_container, $plugins)
+ );
+ $phpbb_container->set(
+ 'core.captcha.plugins.nogd',
+ new \phpbb\captcha\plugins\nogd()
+ );
+ // Set up passwords manager
+ $db_auth_provider = new \phpbb\auth\provider\db(
+ new \phpbb\captcha\factory($phpbb_container, $plugins),
$config,
+ $db,
$passwords_manager,
$request,
$user,
+ $phpbb_root_path,
+ $phpEx
+ );
+
+ $oauth_provider = new \phpbb\auth\provider\oauth\oauth(
+ $config,
+ $db,
+ $db_auth_provider,
+ $phpbb_dispatcher,
+ $lang,
+ $request,
+ $oauth_provider_collection,
+ $user,
'phpbb_oauth_tokens',
'phpbb_oauth_states',
'phpbb_oauth_accounts',
- $oauth_provider_collection,
'phpbb_users',
- $phpbb_container,
- $phpbb_dispatcher,
- $this->phpbb_root_path,
- $this->php_ext
+ $phpbb_root_path,
+ $phpEx
);
$provider_collection->offsetSet('auth.provider.oauth', $oauth_provider);
diff --git a/tests/network/inet_ntop_pton_test.php b/tests/network/inet_ntop_pton_test.php
deleted file mode 100644
index dbd58ce783..0000000000
--- a/tests/network/inet_ntop_pton_test.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-class phpbb_network_inet_ntop_pton_test extends phpbb_test_case
-{
- public function data_provider()
- {
- return array(
- array('127.0.0.1', '7f000001'),
- array('192.232.131.223', 'c0e883df'),
- array('13.1.68.3', '0d014403'),
- array('129.144.52.38', '81903426'),
-
- array('2001:280:0:10::5', '20010280000000100000000000000005'),
- array('fe80::200:4cff:fefe:172f', 'fe8000000000000002004cfffefe172f'),
-
- array('::', '00000000000000000000000000000000'),
- array('::1', '00000000000000000000000000000001'),
- array('1::', '00010000000000000000000000000000'),
-
- array('1:1:0:0:1::', '00010001000000000001000000000000'),
-
- array('0:2:3:4:5:6:7:8', '00000002000300040005000600070008'),
- array('1:2:0:4:5:6:7:8', '00010002000000040005000600070008'),
- array('1:2:3:4:5:6:7:0', '00010002000300040005000600070000'),
-
- array('2001:0:0:1::1', '20010000000000010000000000000001'),
- );
- }
-
- /**
- * @dataProvider data_provider
- */
- public function test_inet_ntop($address, $hex)
- {
- $this->assertEquals($address, phpbb_inet_ntop(pack('H*', $hex)));
- }
-
- /**
- * @dataProvider data_provider
- */
- public function test_inet_pton($address, $hex)
- {
- $this->assertEquals($hex, bin2hex(phpbb_inet_pton($address)));
- }
-}
diff --git a/tests/passwords/manager_test.php b/tests/passwords/manager_test.php
index dc5c539316..90dbb47f46 100644
--- a/tests/passwords/manager_test.php
+++ b/tests/passwords/manager_test.php
@@ -51,26 +51,13 @@ class phpbb_passwords_manager_test extends \phpbb_test_case
public function hash_password_data()
{
- if (version_compare(PHP_VERSION, '5.3.7', '<'))
- {
- return array(
- array('', '2a', 60),
- array('passwords.driver.bcrypt_2y', '2a', 60),
- array('passwords.driver.bcrypt', '2a', 60),
- array('passwords.driver.salted_md5', 'H', 34),
- array('passwords.driver.foobar', '', false),
- );
- }
- else
- {
- return array(
- array('', '2y', 60),
- array('passwords.driver.bcrypt_2y', '2y', 60),
- array('passwords.driver.bcrypt', '2a', 60),
- array('passwords.driver.salted_md5', 'H', 34),
- array('passwords.driver.foobar', '', false),
- );
- }
+ return array(
+ array('', '2y', 60),
+ array('passwords.driver.bcrypt_2y', '2y', 60),
+ array('passwords.driver.bcrypt', '2a', 60),
+ array('passwords.driver.salted_md5', 'H', 34),
+ array('passwords.driver.foobar', '', false),
+ );
}
/**
@@ -100,23 +87,12 @@ class phpbb_passwords_manager_test extends \phpbb_test_case
public function check_password_data()
{
- if (version_compare(PHP_VERSION, '5.3.7', '<'))
- {
- return array(
- array('passwords.driver.bcrypt'),
- array('passwords.driver.salted_md5'),
- array('passwords.driver.phpass'),
- );
- }
- else
- {
- return array(
- array('passwords.driver.bcrypt_2y'),
- array('passwords.driver.bcrypt'),
- array('passwords.driver.salted_md5'),
- array('passwords.driver.phpass'),
- );
- }
+ return array(
+ array('passwords.driver.bcrypt_2y'),
+ array('passwords.driver.bcrypt'),
+ array('passwords.driver.salted_md5'),
+ array('passwords.driver.phpass'),
+ );
}
/**
@@ -136,7 +112,7 @@ class phpbb_passwords_manager_test extends \phpbb_test_case
}
// Check if convert_flag is correctly set
- $default_type = (version_compare(PHP_VERSION, '5.3.7', '<')) ? 'passwords.driver.bcrypt' : 'passwords.driver.bcrypt_2y';
+ $default_type = 'passwords.driver.bcrypt_2y';
$this->assertEquals(($hash_type !== $default_type), $this->manager->convert_flag);
}
@@ -200,79 +176,43 @@ class phpbb_passwords_manager_test extends \phpbb_test_case
public function test_hash_password_8bit_bcrypt()
{
$this->assertEquals(false, $this->manager->hash('foobar𝄞', 'passwords.driver.bcrypt'));
- if (version_compare(PHP_VERSION, '5.3.7', '<'))
- {
- $this->assertEquals(false, $this->manager->hash('foobar𝄞', 'passwords.driver.bcrypt_2y'));
- }
- else
- {
- $this->assertNotEquals(false, $this->manager->hash('foobar𝄞', 'passwords.driver.bcrypt_2y'));
- }
+ $this->assertNotEquals(false, $this->manager->hash('foobar𝄞', 'passwords.driver.bcrypt_2y'));
}
public function combined_hash_data()
{
- if (version_compare(PHP_VERSION, '5.3.7', '<'))
- {
- return array(
- array(
- 'passwords.driver.salted_md5',
- array('passwords.driver.bcrypt'),
- ),
- array(
- 'passwords.driver.phpass',
- array('passwords.driver.salted_md5'),
- ),
- array(
- 'passwords.driver.salted_md5',
- array('passwords.driver.phpass', 'passwords.driver.bcrypt'),
- ),
- array(
- 'passwords.driver.salted_md5',
- array('passwords.driver.salted_md5'),
- false,
- ),
- array(
- '$H$',
- array('$2a$'),
- ),
- );
- }
- else
- {
- return array(
- array(
- 'passwords.driver.salted_md5',
- array('passwords.driver.bcrypt_2y'),
- ),
- array(
- 'passwords.driver.salted_md5',
- array('passwords.driver.bcrypt'),
- ),
- array(
- 'passwords.driver.phpass',
- array('passwords.driver.salted_md5'),
- ),
- array(
- 'passwords.driver.salted_md5',
- array('passwords.driver.bcrypt_2y', 'passwords.driver.bcrypt'),
- ),
- array(
- 'passwords.driver.salted_md5',
- array('passwords.driver.salted_md5'),
- false,
- ),
- array(
- 'passwords.driver.bcrypt_2y',
- array('passwords.driver.salted_md4'),
- false,
- ),
- array(
- '$H$',
- array('$2y$'),
- ),
- );
- }
+ return array(
+ array(
+ 'passwords.driver.salted_md5',
+ array('passwords.driver.bcrypt_2y'),
+ ),
+ array(
+ 'passwords.driver.salted_md5',
+ array('passwords.driver.bcrypt'),
+ ),
+ array(
+ 'passwords.driver.phpass',
+ array('passwords.driver.salted_md5'),
+ ),
+ array(
+ 'passwords.driver.salted_md5',
+ array('passwords.driver.bcrypt_2y', 'passwords.driver.bcrypt'),
+ ),
+ array(
+ 'passwords.driver.salted_md5',
+ array('passwords.driver.salted_md5'),
+ false,
+ ),
+ array(
+ 'passwords.driver.bcrypt_2y',
+ array('passwords.driver.salted_md4'),
+ false,
+ ),
+ array(
+ '$H$',
+ array('$2y$'),
+ ),
+ );
}
/**
diff --git a/travis/ldap/base.ldif b/travis/ldap/base.ldif
new file mode 100644
index 0000000000..09fe7cecc6
--- /dev/null
+++ b/travis/ldap/base.ldif
@@ -0,0 +1,41 @@
+dn: dc=example,dc=com
+objectClass: top
+objectClass: dcObject
+objectClass: organization
+o: example
+dc: example
+
+dn: ou=foo,dc=example,dc=com
+objectClass: organizationalUnit
+ou: foo
+
+dn: cn=admin,dc=example,dc=com
+objectClass: simpleSecurityObject
+objectClass: organizationalRole
+cn: admin
+description: LDAP administrator
+userPassword:: e1NTSEF9NytMR2gveUxTMzdsc3RRd1V1dENZSVA0TWdYdm9SdDY=
+
+dn: ou=group,dc=example,dc=com
+objectClass: organizationalUnit
+ou: group
+
+dn: cn=admin,ou=foo,dc=example,dc=com
+objectClass: posixAccount
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+loginShell: /bin/bash
+homeDirectory: /home/admin
+uid: admin
+cn: admin
+uidNumber: 10000
+gidNumber: 10000
+sn: admin
+mail: admin@example.com
+userPassword:: e1NTSEF9WHpueGZURHZZc21JSkl6czdMVXBjdCtWYTA1dlMzVlQ=
+
+dn: cn=admin,ou=group,dc=example,dc=com
+objectClass: posixGroup
+gidNumber: 10000
+cn: admin
diff --git a/travis/ldap/slapd.conf b/travis/ldap/slapd.conf
new file mode 100644
index 0000000000..5fce95cee2
--- /dev/null
+++ b/travis/ldap/slapd.conf
@@ -0,0 +1,17 @@
+# See slapd.conf(5) for details on configuration options.
+include /etc/ldap/schema/core.schema
+include /etc/ldap/schema/cosine.schema
+include /etc/ldap/schema/inetorgperson.schema
+include /etc/ldap/schema/nis.schema
+
+pidfile /tmp/slapd/slapd.pid
+argsfile /tmp/slapd/slapd.args
+
+modulepath /usr/lib/openldap
+
+database ldif
+directory /tmp/slapd
+
+suffix "dc=example,dc=com"
+rootdn "cn=admin,dc=example,dc=com"
+rootpw adminadmin
diff --git a/travis/setup-ldap.sh b/travis/setup-ldap.sh
new file mode 100755
index 0000000000..9be816d77d
--- /dev/null
+++ b/travis/setup-ldap.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+#
+# This file is part of the phpBB Forum Software package.
+#
+# @copyright (c) phpBB Limited <https://www.phpbb.com>
+# @license GNU General Public License, version 2 (GPL-2.0)
+#
+# For full copyright and license information, please see
+# the docs/CREDITS.txt file.
+#
+set -e
+set -x
+
+SLOWTESTS=$1
+
+if [ "$SLOWTESTS" == '1' ]
+then
+ sudo apt-get -y install ldap-utils slapd php-ldap
+ mkdir /tmp/slapd
+ slapd -f travis/ldap/slapd.conf -h ldap://localhost:3389 &
+ sleep 3
+ ldapadd -h localhost:3389 -D "cn=admin,dc=example,dc=com" -w adminadmin -f travis/ldap/base.ldif
+fi