aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB')
-rw-r--r--phpBB/.htaccess7
-rw-r--r--phpBB/assets/javascript/core.js6
-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/update_email_hash.php56
-rw-r--r--phpBB/docs/CHANGELOG.html25
-rw-r--r--phpBB/docs/INSTALL.html2
-rw-r--r--phpBB/docs/coding-guidelines.html6
-rw-r--r--phpBB/docs/nginx.sample.conf4
-rw-r--r--phpBB/includes/acp/acp_board.php1
-rw-r--r--phpBB/includes/acp/acp_users.php5
-rw-r--r--phpBB/includes/constants.php2
-rw-r--r--phpBB/includes/functions.php13
-rw-r--r--phpBB/includes/functions_compatibility.php14
-rw-r--r--phpBB/includes/functions_convert.php10
-rw-r--r--phpBB/includes/functions_messenger.php25
-rw-r--r--phpBB/includes/functions_user.php5
-rw-r--r--phpBB/includes/ucp/ucp_pm_compose.php5
-rw-r--r--phpBB/includes/ucp/ucp_profile.php1
-rw-r--r--phpBB/includes/ucp/ucp_register.php29
-rw-r--r--phpBB/includes/ucp/ucp_resend.php2
-rw-r--r--phpBB/install/convertors/convert_phpbb20.php3
-rwxr-xr-xphpBB/install/phpbbcli.php2
-rw-r--r--phpBB/install/schemas/schema_data.sql2
-rw-r--r--phpBB/language/en/acp/board.php2
-rw-r--r--phpBB/language/en/cli.php3
-rw-r--r--phpBB/language/en/common.php2
-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/cache/driver/memcache.php122
-rw-r--r--phpBB/phpbb/cache/driver/memcached.php22
-rw-r--r--phpBB/phpbb/console/command/fixup/recalculate_email_hash.php76
-rw-r--r--phpBB/phpbb/content_visibility.php20
-rw-r--r--phpBB/phpbb/db/migration/data/v330/add_display_unapproved_posts_config.php (renamed from phpBB/phpbb/db/tools.php)13
-rw-r--r--phpBB/phpbb/db/migration/data/v330/remove_email_hash.php57
-rw-r--r--phpBB/phpbb/db/migration/data/v330/v330b2.php38
-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/textformatter/s9e/bbcode_merger.php26
-rw-r--r--phpBB/phpbb/textformatter/s9e/factory.php2
-rw-r--r--phpBB/phpbb/textformatter/s9e/link_helper.php2
-rw-r--r--phpBB/phpbb/textformatter/s9e/parser.php20
-rw-r--r--phpBB/phpbb/textformatter/s9e/quote_helper.php22
-rw-r--r--phpBB/phpbb/ucp/controller/reset_password.php2
-rw-r--r--phpBB/search.php3
-rw-r--r--phpBB/styles/prosilver/style.cfg4
-rw-r--r--phpBB/styles/prosilver/template/bbcode.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_agreement.html3
-rw-r--r--phpBB/styles/prosilver/template/viewtopic_body.html7
-rw-r--r--phpBB/viewforum.php5
-rw-r--r--phpBB/viewtopic.php1
63 files changed, 1514 insertions, 1400 deletions
diff --git a/phpBB/.htaccess b/phpBB/.htaccess
index 53bce762ea..0be28ab670 100644
--- a/phpBB/.htaccess
+++ b/phpBB/.htaccess
@@ -36,6 +36,13 @@ RewriteRule ^(.*)$ app.php [QSA,L]
#Options +FollowSymLinks
</IfModule>
+# Apache content negotation tries to interpret non-existent paths as files if
+# MultiViews is enabled. This will however cause issues with paths containg
+# dots, e.g. for the cron tasks
+<IfModule mod_negotiation.c>
+ Options -MultiViews
+</IfModule>
+
# With Apache 2.4 the "Order, Deny" syntax has been deprecated and moved from
# module mod_authz_host to a new module called mod_access_compat (which may be
# disabled) and a new "Require" syntax has been introduced to mod_authz_host.
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index 4a61490615..bedbd23532 100644
--- a/phpBB/assets/javascript/core.js
+++ b/phpBB/assets/javascript/core.js
@@ -740,6 +740,8 @@ phpbb.search.closeResults = function($input, $container) {
phpbb.search.navigateResults = function($input, $container, $resultContainer) {
// Add a namespace to the event (.phpbb.search),
// so it can be unbound specifically later on.
+ // Rebind it, to ensure the event is 'dynamic'.
+ $input.off('.phpbb.search');
$input.on('keydown.phpbb.search', function(event) {
var key = event.keyCode || event.which,
$active = $resultContainer.children('.active');
@@ -1585,7 +1587,7 @@ phpbb.colorPalette = function(dir, width, height) {
* @param {jQuery} el jQuery object for the palette container.
*/
phpbb.registerPalette = function(el) {
- var orientation = el.attr('data-color-palette'),
+ var orientation = el.attr('data-color-palette') || el.attr('data-orientation'), // data-orientation kept for backwards compat.
height = el.attr('data-height'),
width = el.attr('data-width'),
target = el.attr('data-target'),
@@ -1799,7 +1801,7 @@ $(function() {
phpbb.registerPageDropdowns();
- $('[data-color-palette]').each(function() {
+ $('[data-color-palette], [data-orientation]').each(function() {
phpbb.registerPalette($(this));
});
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/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/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html
index 08804e5ce5..d229b91bd6 100644
--- a/phpBB/docs/CHANGELOG.html
+++ b/phpBB/docs/CHANGELOG.html
@@ -50,6 +50,7 @@
<ol>
<li><a href="#changelog">Changelog</a>
<ul>
+ <li><a href="#v330b1">Changes since 3.3.0-b1</a></li>
<li><a href="#v32x">Changes since 3.2.x</a></li>
<li><a href="#v328rc1">Changes since 3.2.8-RC1</a></li>
<li><a href="#v327">Changes since 3.2.7</a></li>
@@ -141,6 +142,30 @@
<div class="inner">
<div class="content">
+ <a name="v330b1"></a><h3>Changes since 3.3.0-b1</h3>
+ <h4>Bug</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16008">PHPBB3-16008</a>] - oAuth does not respect custom server settings</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16167">PHPBB3-16167</a>] - phpbb_email_hash creates false duplicates</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16188">PHPBB3-16188</a>] - Statistics Panel in ACP</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16192">PHPBB3-16192</a>] - Installing Extensions Via CLI Broken</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16205">PHPBB3-16205</a>] - Undefined variable 'zebra' in search.php</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16210">PHPBB3-16210</a>] - Terms of use should not be skippable</li>
+ </ul>
+ <h4>Improvement</h4>
+ <ul>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12539">PHPBB3-12539</a>] - Live Member Search Improvements</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12559">PHPBB3-12559</a>] - Add forum setting to limit subforums legend to direct children only</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12574">PHPBB3-12574</a>] - Don't require the passwords_manager in the constructor of the auth plugins</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15958">PHPBB3-15958</a>] - Created forums and default forum created during install have diferent options</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16187">PHPBB3-16187</a>] - Correctly display registration using external services</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16189">PHPBB3-16189</a>] - Deprecate inet_ntop and inet_pton wrappers</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16190">PHPBB3-16190</a>] - Deprecate phpbb's checkdnsrr wrapper</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16195">PHPBB3-16195</a>] - Copy forum permissions missing paragraph</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16196">PHPBB3-16196</a>] - Remove random_compat</li>
+ <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16206">PHPBB3-16206</a>] - Remove offsetExists reimplementation in service_collection</li>
+ </ul>
+
<a name="v32x"></a><h3>Changes since 3.2.x</h3>
<h4>Bug</h4>
<ul>
diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html
index 33609837eb..fbc701a2ca 100644
--- a/phpBB/docs/INSTALL.html
+++ b/phpBB/docs/INSTALL.html
@@ -147,7 +147,7 @@
<li>Oracle</li>
</ul>
</li>
- <li><strong>PHP 7.1.0+</strong> but less than <strong>PHP 7.4</strong> with support for the database you intend to use.</li>
+ <li><strong>PHP 7.1.0+</strong> up to and including <strong>PHP 7.4</strong> with support for the database you intend to use.</li>
<li>The following PHP modules are required:
<ul>
<li>json</li>
diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html
index 6cf647c55f..ffa2112771 100644
--- a/phpBB/docs/coding-guidelines.html
+++ b/phpBB/docs/coding-guidelines.html
@@ -234,9 +234,9 @@ PHPBB_USE_BOARD_URL_PATH (use generate_board_url() for image paths instead of
PHPBB_DISABLE_ACP_EDITOR (disable ACP style editor for templates)
PHPBB_DISABLE_CONFIG_CHECK (disable ACP config.php writeable check)
-PHPBB_ACM_MEMCACHE_PORT (overwrite memcached port, default is 11211)
-PHPBB_ACM_MEMCACHE_COMPRESS (overwrite memcached compress setting, default is disabled)
-PHPBB_ACM_MEMCACHE_HOST (overwrite memcached host name, default is localhost)
+PHPBB_ACM_MEMCACHED_PORT (overwrite memcached port, default is 11211)
+PHPBB_ACM_MEMCACHED_COMPRESS (overwrite memcached compress setting, default is disabled)
+PHPBB_ACM_MEMCACHED_HOST (overwrite memcached host name, default is localhost)
PHPBB_ACM_REDIS_HOST (overwrite redis host name, default is localhost)
PHPBB_ACM_REDIS_PORT (overwrite redis port, default is 6379)
diff --git a/phpBB/docs/nginx.sample.conf b/phpBB/docs/nginx.sample.conf
index 55c01a1fc9..848998cfeb 100644
--- a/phpBB/docs/nginx.sample.conf
+++ b/phpBB/docs/nginx.sample.conf
@@ -93,7 +93,7 @@ http {
# Correctly pass scripts for installer
location /install/ {
# phpBB uses index.htm
- try_files $uri $uri/ @rewrite_installapp;
+ try_files $uri $uri/ @rewrite_installapp =404;
# Pass the php scripts to fastcgi server specified in upstream declaration.
location ~ \.php(/|$) {
@@ -104,7 +104,7 @@ http {
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
- try_files $uri $uri/ /install/app.php$is_args$args;
+ try_files $uri $uri/ /install/app.php$is_args$args =404;
fastcgi_pass php;
}
}
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index 05871e4157..2441a37edc 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -101,6 +101,7 @@ class acp_board
'allow_bookmarks' => array('lang' => 'ALLOW_BOOKMARKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'allow_birthdays' => array('lang' => 'ALLOW_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'display_last_subject' => array('lang' => 'DISPLAY_LAST_SUBJECT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'display_unapproved_posts' => array('lang' => 'DISPLAY_UNAPPROVED_POSTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'allow_quick_reply' => array('lang' => 'ALLOW_QUICK_REPLY', 'validate' => 'bool', 'type' => 'custom', 'method' => 'quick_reply', 'explain' => true),
'legend2' => 'ACP_SUBMIT_CHANGES',
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/constants.php b/phpBB/includes/constants.php
index 759bc94520..493399bd71 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))
*/
// phpBB Version
-@define('PHPBB_VERSION', '3.3.0-b2-dev');
+@define('PHPBB_VERSION', '3.3.0-RC1-dev');
// QA-related
// define('PHPBB_QA', 1);
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index d2d5b503a2..994323531a 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.
*
@@ -2276,6 +2264,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
$err = '';
$form_name = 'login';
+ $username = $autologin = false;
// Make sure user->setup() has been called
if (!$user->is_setup())
diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php
index 2578290875..92e24c055c 100644
--- a/phpBB/includes/functions_compatibility.php
+++ b/phpBB/includes/functions_compatibility.php
@@ -659,3 +659,17 @@ 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_messenger.php b/phpBB/includes/functions_messenger.php
index 7f8238e1bf..ec297b536a 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -1893,14 +1893,21 @@ function mail_encode($str, $eol = "\r\n")
}
/**
-* Wrapper for sending out emails with the PHP's mail function
-*/
+ * Wrapper for sending out emails with the PHP's mail function
+ */
function phpbb_mail($to, $subject, $msg, $headers, $eol, &$err_msg)
{
global $config, $phpbb_root_path, $phpEx;
- // We use the EOL character for the OS here because the PHP mail function does not correctly transform line endings. On Windows SMTP is used (SMTP is \r\n), on UNIX a command is used...
- // Reference: http://bugs.php.net/bug.php?id=15841
+ // Convert Numeric Character References to UTF-8 chars (ie. Emojis)
+ $subject = utf8_decode_ncr($subject);
+ $msg = utf8_decode_ncr($msg);
+
+ /**
+ * We use the EOL character for the OS here because the PHP mail function does not correctly transform line endings.
+ * On Windows SMTP is used (SMTP is \r\n), on UNIX a command is used...
+ * Reference: http://bugs.php.net/bug.php?id=15841
+ */
$headers = implode($eol, $headers);
if (!class_exists('\phpbb\error_collector'))
@@ -1911,10 +1918,14 @@ function phpbb_mail($to, $subject, $msg, $headers, $eol, &$err_msg)
$collector = new \phpbb\error_collector;
$collector->install();
- // On some PHP Versions mail() *may* fail if there are newlines within the subject.
- // Newlines are used as a delimiter for lines in mail_encode() according to RFC 2045 section 6.8.
- // Because PHP can't decide what is wanted we revert back to the non-RFC-compliant way of separating by one space (Use '' as parameter to mail_encode() results in SPACE used)
+ /**
+ * On some PHP Versions mail() *may* fail if there are newlines within the subject.
+ * Newlines are used as a delimiter for lines in mail_encode() according to RFC 2045 section 6.8.
+ * Because PHP can't decide what is wanted we revert back to the non-RFC-compliant way of separating by one space
+ * (Use '' as parameter to mail_encode() results in SPACE used)
+ */
$additional_parameters = $config['email_force_sender'] ? '-f' . $config['board_email'] : '';
+
$result = mail($to, mail_encode($subject, ''), wordwrap(utf8_wordwrap($msg), 997, "\n", true), $headers, $additional_parameters);
$collector->uninstall();
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 5c94a90d9d..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'],
);
@@ -1948,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_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php
index 06baa279a5..87a8c91fd2 100644
--- a/phpBB/includes/ucp/ucp_pm_compose.php
+++ b/phpBB/includes/ucp/ucp_pm_compose.php
@@ -999,7 +999,10 @@ function compose_pm($id, $mode, $action, $user_folders = array())
{
$quote_attributes['post_id'] = $post['msg_id'];
}
-
+ if ($action === 'quote')
+ {
+ $quote_attributes['msg_id'] = $post['msg_id'];
+ }
/** @var \phpbb\language\language $language */
$language = $phpbb_container->get('language');
/** @var \phpbb\textformatter\utils_interface $text_formatter_utils */
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..00fa8034f9 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -39,12 +39,23 @@ class ucp_register
trigger_error('UCP_REGISTER_DISABLE');
}
- $coppa = $request->is_set('coppa') ? (int) $request->variable('coppa', false) : false;
+ $coppa = $request->is_set('coppa_yes') ? 1 : ($request->is_set('coppa_no') ? 0 : false);
+ $coppa = $request->is_set('coppa') ? $request->variable('coppa', 0) : $coppa;
$agreed = $request->variable('agreed', false);
$submit = $request->is_set_post('submit');
$change_lang = $request->variable('change_lang', '');
$user_lang = $request->variable('lang', $user->lang_name);
+ if ($agreed && !check_form_key('ucp_register'))
+ {
+ $agreed = false;
+ }
+
+ if ($coppa !== false && !check_form_key('ucp_register'))
+ {
+ $coppa = false;
+ }
+
/**
* Add UCP register data before they are assigned to the template or submitted
*
@@ -67,14 +78,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'])
{
@@ -168,11 +172,8 @@ class ucp_register
$template_vars = array(
'S_LANG_OPTIONS' => (count($lang_row) > 1) ? language_select($user_lang) : '',
- 'L_COPPA_NO' => sprintf($user->lang['UCP_COPPA_BEFORE'], $coppa_birthday),
- 'L_COPPA_YES' => sprintf($user->lang['UCP_COPPA_ON_AFTER'], $coppa_birthday),
-
- 'U_COPPA_NO' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register&amp;coppa=0'),
- 'U_COPPA_YES' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register&amp;coppa=1'),
+ 'L_COPPA_NO' => $user->lang('UCP_COPPA_BEFORE', $coppa_birthday),
+ 'L_COPPA_YES' => $user->lang('UCP_COPPA_ON_AFTER', $coppa_birthday),
'S_SHOW_COPPA' => true,
'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields),
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..cefb33fe3c 100644
--- a/phpBB/install/convertors/convert_phpbb20.php
+++ b/phpBB/install/convertors/convert_phpbb20.php
@@ -38,7 +38,7 @@ $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);
$convertor_data = array(
'forum_name' => 'phpBB 2.0.x',
'version' => '1.0.3',
- 'phpbb_version' => '3.3.0',
+ 'phpbb_version' => '3.3.0-b2',
'author' => '<a href="https://www.phpbb.com/">phpBB Limited</a>',
'dbms' => $dbms,
'dbhost' => $dbhost,
@@ -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/install/phpbbcli.php b/phpBB/install/phpbbcli.php
index b7a07488ac..6ac261aa13 100755
--- a/phpBB/install/phpbbcli.php
+++ b/phpBB/install/phpbbcli.php
@@ -23,7 +23,7 @@ if (php_sapi_name() !== 'cli')
define('IN_PHPBB', true);
define('IN_INSTALL', true);
define('PHPBB_ENVIRONMENT', 'production');
-define('PHPBB_VERSION', '3.3.0-b2-dev');
+define('PHPBB_VERSION', '3.3.0-b2');
$phpbb_root_path = __DIR__ . '/../';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index 97fc23f0bf..8e7b26d60c 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -278,7 +278,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.3.0-b2-dev');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.3.0-RC1-dev');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400');
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index fdc02d9ae8..cb9013805d 100644
--- a/phpBB/language/en/acp/board.php
+++ b/phpBB/language/en/acp/board.php
@@ -52,6 +52,8 @@ $lang = array_merge($lang, array(
'DISABLE_BOARD_EXPLAIN' => 'This will make the board unavailable to users who are neither administrators nor moderators. You can also enter a short (255 character) message to display if you wish.',
'DISPLAY_LAST_SUBJECT' => 'Display subject of last added post on forum list',
'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'The subject of the last added post will be displayed in the forum list with a hyperlink to the post. Subjects from password protected forums and forums in which user doesn’t have read access are not shown.',
+ 'DISPLAY_UNAPPROVED_POSTS' => 'Display unapproved posts to the author',
+ 'DISPLAY_UNAPPROVED_POSTS_EXPLAIN' => 'Unapproved posts can be viewed by the author. Does not apply to Guest posts.',
'GUEST_STYLE' => 'Guest style',
'GUEST_STYLE_EXPLAIN' => 'The board style for guests.',
'OVERRIDE_STYLE' => 'Override user style',
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 d050c1b109..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',
@@ -615,6 +616,7 @@ $lang = array_merge($lang, array(
'POST_TOPIC' => 'Post a new topic',
'POST_UNAPPROVED_ACTION' => 'Post awaiting approval:',
'POST_UNAPPROVED' => 'This post has not been approved.',
+ 'POST_UNAPPROVED_EXPLAIN' => 'This post is not visible to other users until it has been approved by a moderator.',
'POWERED_BY' => 'Powered by %s',
'PREVIEW' => 'Preview',
'PREVIOUS' => 'Previous', // Used in pagination
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/cache/driver/memcache.php b/phpBB/phpbb/cache/driver/memcache.php
deleted file mode 100644
index 57f138f574..0000000000
--- a/phpBB/phpbb/cache/driver/memcache.php
+++ /dev/null
@@ -1,122 +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\cache\driver;
-
-if (!defined('PHPBB_ACM_MEMCACHE_PORT'))
-{
- define('PHPBB_ACM_MEMCACHE_PORT', 11211);
-}
-
-if (!defined('PHPBB_ACM_MEMCACHE_COMPRESS'))
-{
- define('PHPBB_ACM_MEMCACHE_COMPRESS', false);
-}
-
-if (!defined('PHPBB_ACM_MEMCACHE_HOST'))
-{
- define('PHPBB_ACM_MEMCACHE_HOST', 'localhost');
-}
-
-if (!defined('PHPBB_ACM_MEMCACHE'))
-{
- //can define multiple servers with host1/port1,host2/port2 format
- define('PHPBB_ACM_MEMCACHE', PHPBB_ACM_MEMCACHE_HOST . '/' . PHPBB_ACM_MEMCACHE_PORT);
-}
-
-/**
-* ACM for Memcached
-*/
-class memcache extends \phpbb\cache\driver\memory
-{
- var $extension = 'memcache';
-
- var $memcache;
- var $flags = 0;
-
- function __construct()
- {
- // Call the parent constructor
- parent::__construct();
-
- $this->memcache = new \Memcache;
- foreach (explode(',', PHPBB_ACM_MEMCACHE) as $u)
- {
- preg_match('#(.*)/(\d+)#', $u, $parts);
- $this->memcache->addServer(trim($parts[1]), (int) trim($parts[2]));
- }
- $this->flags = (PHPBB_ACM_MEMCACHE_COMPRESS) ? MEMCACHE_COMPRESSED : 0;
- }
-
- /**
- * {@inheritDoc}
- */
- function unload()
- {
- parent::unload();
-
- $this->memcache->close();
- }
-
- /**
- * {@inheritDoc}
- */
- function purge()
- {
- $this->memcache->flush();
-
- parent::purge();
- }
-
- /**
- * Fetch an item from the cache
- *
- * @access protected
- * @param string $var Cache key
- * @return mixed Cached data
- */
- function _read($var)
- {
- return $this->memcache->get($this->key_prefix . $var);
- }
-
- /**
- * Store data in the cache
- *
- * @access protected
- * @param string $var Cache key
- * @param mixed $data Data to store
- * @param int $ttl Time-to-live of cached data
- * @return bool True if the operation succeeded
- */
- function _write($var, $data, $ttl = 2592000)
- {
- if (!$this->memcache->replace($this->key_prefix . $var, $data, $this->flags, $ttl))
- {
- return $this->memcache->set($this->key_prefix . $var, $data, $this->flags, $ttl);
- }
- return true;
- }
-
- /**
- * Remove an item from the cache
- *
- * @access protected
- * @param string $var Cache key
- * @return bool True if the operation succeeded
- */
- function _delete($var)
- {
- return $this->memcache->delete($this->key_prefix . $var);
- }
-}
diff --git a/phpBB/phpbb/cache/driver/memcached.php b/phpBB/phpbb/cache/driver/memcached.php
index 7d66759ec2..fbb587a369 100644
--- a/phpBB/phpbb/cache/driver/memcached.php
+++ b/phpBB/phpbb/cache/driver/memcached.php
@@ -50,12 +50,16 @@ class memcached extends \phpbb\cache\driver\memory
/**
* Memcached constructor
+ *
+ * @param string $memcached_servers Memcached servers string (optional)
*/
- public function __construct()
+ public function __construct($memcached_servers = '')
{
// Call the parent constructor
parent::__construct();
+ $memcached_servers = $memcached_servers ?: PHPBB_ACM_MEMCACHED;
+
$this->memcached = new \Memcached();
$this->memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
// Memcached defaults to using compression, disable if we don't want
@@ -65,10 +69,20 @@ class memcached extends \phpbb\cache\driver\memory
$this->memcached->setOption(\Memcached::OPT_COMPRESSION, false);
}
- foreach (explode(',', PHPBB_ACM_MEMCACHED) as $u)
+ $server_list = [];
+ foreach (explode(',', $memcached_servers) as $u)
+ {
+ if (preg_match('#(.*)/(\d+)#', $u, $parts))
+ {
+ $server_list[] = [trim($parts[1]), (int) trim($parts[2])];
+ }
+ }
+
+ $this->memcached->addServers($server_list);
+
+ if (empty($server_list) || empty($this->memcached->getStats()))
{
- preg_match('#(.*)/(\d+)#', $u, $parts);
- $this->memcached->addServer(trim($parts[1]), (int) trim($parts[2]));
+ trigger_error('Could not connect to memcached server(s).');
}
}
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/content_visibility.php b/phpBB/phpbb/content_visibility.php
index 704ec6badb..fbc56f3db2 100644
--- a/phpBB/phpbb/content_visibility.php
+++ b/phpBB/phpbb/content_visibility.php
@@ -144,7 +144,14 @@ class content_visibility
*/
public function is_visible($mode, $forum_id, $data)
{
- $is_visible = $this->auth->acl_get('m_approve', $forum_id) || $data[$mode . '_visibility'] == ITEM_APPROVED;
+ $visibility = $data[$mode . '_visibility'];
+ $poster_key = ($mode === 'topic') ? 'topic_poster' : 'poster_id';
+ $is_visible = ($visibility == ITEM_APPROVED) ||
+ ($this->config['display_unapproved_posts'] &&
+ ($this->user->data['user_id'] != ANONYMOUS) &&
+ ($visibility == ITEM_UNAPPROVED || $visibility == ITEM_REAPPROVE) &&
+ ($this->user->data['user_id'] == $data[$poster_key])) ||
+ $this->auth->acl_get('m_approve', $forum_id);
/**
* Allow changing the result of calling is_visible
@@ -216,9 +223,16 @@ class content_visibility
}
else
{
- $where_sql .= $table_alias . $mode . '_visibility = ' . ITEM_APPROVED;
- }
+ $visibility_query = $table_alias . $mode . '_visibility = ';
+ $where_sql .= '(' . $visibility_query . ITEM_APPROVED . ')';
+ if ($this->config['display_unapproved_posts'] && ($this->user->data['user_id'] != ANONYMOUS))
+ {
+ $poster_key = ($mode === 'topic') ? 'topic_poster' : 'poster_id';
+ $where_sql .= ' OR ((' . $visibility_query . ITEM_UNAPPROVED . ' OR ' . $visibility_query . ITEM_REAPPROVE .')';
+ $where_sql .= ' AND ' . $table_alias . $poster_key . ' = ' . ((int) $this->user->data['user_id']) . ')';
+ }
+ }
return '(' . $where_sql . ')';
}
diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/migration/data/v330/add_display_unapproved_posts_config.php
index 4d1b91f7b4..b429270827 100644
--- a/phpBB/phpbb/db/tools.php
+++ b/phpBB/phpbb/db/migration/data/v330/add_display_unapproved_posts_config.php
@@ -11,11 +11,14 @@
*
*/
-namespace phpbb\db;
+namespace phpbb\db\migration\data\v330;
-/**
- * @deprecated 3.2.0-dev (To be removed 3.3.0) use \phpbb\db\tools\tools instead
- */
-class tools extends \phpbb\db\tools\tools
+class add_display_unapproved_posts_config extends \phpbb\db\migration\migration
{
+ public function update_data()
+ {
+ return [
+ ['config.add', ['display_unapproved_posts', 1]],
+ ];
+ }
}
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/db/migration/data/v330/v330b2.php b/phpBB/phpbb/db/migration/data/v330/v330b2.php
new file mode 100644
index 0000000000..1badc1387a
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/v330b2.php
@@ -0,0 +1,38 @@
+<?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 v330b2 extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return version_compare($this->config['version'], '3.3.0-b2', '>=');
+ }
+
+ static public function depends_on()
+ {
+ return array(
+ '\phpbb\db\migration\data\v330\add_display_unapproved_posts_config',
+ '\phpbb\db\migration\data\v330\forums_legend_limit',
+ '\phpbb\db\migration\data\v330\remove_email_hash',
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.update', array('version', '3.3.0-b2')),
+ );
+ }
+}
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/textformatter/s9e/bbcode_merger.php b/phpBB/phpbb/textformatter/s9e/bbcode_merger.php
index af644192d8..d1bedb0b72 100644
--- a/phpBB/phpbb/textformatter/s9e/bbcode_merger.php
+++ b/phpBB/phpbb/textformatter/s9e/bbcode_merger.php
@@ -50,7 +50,7 @@ class bbcode_merger
$with = $this->create_bbcode($with);
// Select the appropriate strategy for merging this BBCode
- if ($this->is_content_bbcode($without, $with))
+ if (!$this->is_optional_bbcode($without, $with) && $this->is_content_bbcode($without, $with))
{
$merged = $this->merge_content_bbcode($without, $with);
}
@@ -107,12 +107,12 @@ class bbcode_merger
/**
* Test whether the two definitions form a "content"-style BBCode
*
- * Such BBCodes include the [URL] BBCode, which uses its text content as
+ * Such BBCodes include the [url] BBCode, which uses its text content as
* attribute if none is provided
*
* @param array $without BBCode definition without an attribute
* @param array $with BBCode definition with an attribute
- * @return array Merged definition
+ * @return bool
*/
protected function is_content_bbcode(array $without, array $with)
{
@@ -123,6 +123,22 @@ class bbcode_merger
}
/**
+ * Test whether the two definitions form BBCode with an optional attribute
+ *
+ * @param array $without BBCode definition without an attribute
+ * @param array $with BBCode definition with an attribute
+ * @return bool
+ */
+ protected function is_optional_bbcode(array $without, array $with)
+ {
+ // Remove the default attribute from the definition
+ $with['usage'] = preg_replace('(=[^\\]]++)', '', $with['usage']);
+
+ // Test whether both definitions are the same, regardless of case
+ return strcasecmp($without['usage'], $with['usage']) === 0;
+ }
+
+ /**
* Merge the two BBCode definitions of a "content"-style BBCode
*
* @param array $without BBCode definition without an attribute
@@ -131,7 +147,7 @@ class bbcode_merger
*/
protected function merge_content_bbcode(array $without, array $with)
{
- // Convert [X={X}] into [X={X;useContent}]
+ // Convert [x={X}] into [x={X;useContent}]
$usage = preg_replace('(\\})', ';useContent}', $with['usage'], 1);
// Use the template from the definition that uses an attribute
@@ -143,7 +159,7 @@ class bbcode_merger
/**
* Merge the two BBCode definitions of a BBCode with an optional argument
*
- * Such BBCodes include the [QUOTE] BBCode, which takes an optional argument
+ * Such BBCodes include the [quote] BBCode, which takes an optional argument
* but otherwise does not behave differently
*
* @param array $without BBCode definition without an attribute
diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php
index dca1c78d40..f82c7b0771 100644
--- a/phpBB/phpbb/textformatter/s9e/factory.php
+++ b/phpBB/phpbb/textformatter/s9e/factory.php
@@ -89,6 +89,8 @@ class factory implements \phpbb\textformatter\cache_interface
author={TEXT1;optional}
post_id={UINT;optional}
post_url={URL;optional;postFilter=#false}
+ msg_id={UINT;optional}
+ msg_url={URL;optional;postFilter=#false}
profile_url={URL;optional;postFilter=#false}
time={UINT;optional}
url={URL;optional}
diff --git a/phpBB/phpbb/textformatter/s9e/link_helper.php b/phpBB/phpbb/textformatter/s9e/link_helper.php
index 483794a83e..1cd5dd2fa7 100644
--- a/phpBB/phpbb/textformatter/s9e/link_helper.php
+++ b/phpBB/phpbb/textformatter/s9e/link_helper.php
@@ -61,7 +61,7 @@ class link_helper
$text = substr($parser->getText(), $start, $length);
// Create a tag that consumes the link's text and make it depends on this tag
- $link_text_tag = $parser->addSelfClosingTag('LINK_TEXT', $start, $length);
+ $link_text_tag = $parser->addSelfClosingTag('LINK_TEXT', $start, $length, 10);
$link_text_tag->setAttribute('text', $text);
$tag->cascadeInvalidationTo($link_text_tag);
}
diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php
index a36fc63141..f7e4668980 100644
--- a/phpBB/phpbb/textformatter/s9e/parser.php
+++ b/phpBB/phpbb/textformatter/s9e/parser.php
@@ -15,6 +15,7 @@ namespace phpbb\textformatter\s9e;
use s9e\TextFormatter\Parser\AttributeFilters\UrlFilter;
use s9e\TextFormatter\Parser\Logger;
+use s9e\TextFormatter\Parser\Tag;
/**
* s9e\TextFormatter\Parser adapter
@@ -219,7 +220,7 @@ class parser implements \phpbb\textformatter\parser_interface
{
$errors[] = array($msg, $context['max_' . strtolower($m[1])]);
}
- else if ($msg === 'Tag is disabled')
+ else if ($msg === 'Tag is disabled' && $this->is_a_bbcode($context['tag']))
{
$name = strtolower($context['tag']->getName());
$errors[] = array('UNAUTHORISED_BBCODE', '[' . $name . ']');
@@ -396,4 +397,21 @@ class parser implements \phpbb\textformatter\parser_interface
return $url;
}
+
+ /**
+ * Test whether given tag consumes text that looks like BBCode-styled markup
+ *
+ * @param Tag $tag Original tag
+ * @return bool
+ */
+ protected function is_a_bbcode(Tag $tag)
+ {
+ if ($tag->getLen() < 3)
+ {
+ return false;
+ }
+ $markup = substr($this->parser->getText(), $tag->getPos(), $tag->getLen());
+
+ return (bool) preg_match('(^\\[\\w++.*?\\]$)s', $markup);
+ }
}
diff --git a/phpBB/phpbb/textformatter/s9e/quote_helper.php b/phpBB/phpbb/textformatter/s9e/quote_helper.php
index 86c33c7591..3011ec88dc 100644
--- a/phpBB/phpbb/textformatter/s9e/quote_helper.php
+++ b/phpBB/phpbb/textformatter/s9e/quote_helper.php
@@ -21,6 +21,11 @@ class quote_helper
protected $post_url;
/**
+ * @var string Base URL for a private message link, uses {MSG_ID} as placeholder
+ */
+ protected $msg_url;
+
+ /**
* @var string Base URL for a profile link, uses {USER_ID} as placeholder
*/
protected $profile_url;
@@ -40,6 +45,7 @@ class quote_helper
public function __construct(\phpbb\user $user, $root_path, $php_ext)
{
$this->post_url = append_sid($root_path . 'viewtopic.' . $php_ext, 'p={POST_ID}#p{POST_ID}', false);
+ $this->msg_url = append_sid($root_path . 'ucp.' . $php_ext, 'i=pm&mode=view&p={MSG_ID}', false);
$this->profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=viewprofile&u={USER_ID}', false);
$this->user = $user;
}
@@ -52,26 +58,26 @@ class quote_helper
*/
public function inject_metadata($xml)
{
- $post_url = $this->post_url;
- $profile_url = $this->profile_url;
- $user = $this->user;
-
return \s9e\TextFormatter\Utils::replaceAttributes(
$xml,
'QUOTE',
- function ($attributes) use ($post_url, $profile_url, $user)
+ function ($attributes)
{
if (isset($attributes['post_id']))
{
- $attributes['post_url'] = str_replace('{POST_ID}', $attributes['post_id'], $post_url);
+ $attributes['post_url'] = str_replace('{POST_ID}', $attributes['post_id'], $this->post_url);
+ }
+ if (isset($attributes['msg_id']))
+ {
+ $attributes['msg_url'] = str_replace('{MSG_ID}', $attributes['msg_id'], $this->msg_url);
}
if (isset($attributes['time']))
{
- $attributes['date'] = $user->format_date($attributes['time']);
+ $attributes['date'] = $this->user->format_date($attributes['time']);
}
if (isset($attributes['user_id']))
{
- $attributes['profile_url'] = str_replace('{USER_ID}', $attributes['user_id'], $profile_url);
+ $attributes['profile_url'] = str_replace('{USER_ID}', $attributes['user_id'], $this->profile_url);
}
return $attributes;
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/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/style.cfg b/phpBB/styles/prosilver/style.cfg
index cdf67d5a0c..9b9a02c1fb 100644
--- a/phpBB/styles/prosilver/style.cfg
+++ b/phpBB/styles/prosilver/style.cfg
@@ -21,8 +21,8 @@
# General Information about this style
name = prosilver
copyright = © phpBB Limited, 2007
-style_version = 3.3.0-b1
-phpbb_version = 3.3.0-b1
+style_version = 3.3.0-b2
+phpbb_version = 3.3.0-b2
# Defining a different template bitfield
# template_bitfield = //g=
diff --git a/phpBB/styles/prosilver/template/bbcode.html b/phpBB/styles/prosilver/template/bbcode.html
index 940c0ace29..b37ba238d2 100644
--- a/phpBB/styles/prosilver/template/bbcode.html
+++ b/phpBB/styles/prosilver/template/bbcode.html
@@ -37,6 +37,10 @@
<xsl:text> </xsl:text>
<a href="{@post_url}" data-post-id="{@post_id}" onclick="if(document.getElementById(hash.substr(1)))href=hash">&#8593;</a>
</xsl:if>
+ <xsl:if test="@msg_url">
+ <xsl:text> </xsl:text>
+ <a href="{@msg_url}" data-msg-id="{@msg_id}">&#8593;</a>
+ </xsl:if>
<xsl:if test="@date">
<div class="responsive-hide"><xsl:value-of select="@date"/></div>
</xsl:if>
diff --git a/phpBB/styles/prosilver/template/ucp_agreement.html b/phpBB/styles/prosilver/template/ucp_agreement.html
index d4fef9f0a5..7959925d30 100644
--- a/phpBB/styles/prosilver/template/ucp_agreement.html
+++ b/phpBB/styles/prosilver/template/ucp_agreement.html
@@ -43,7 +43,8 @@
<div class="inner">
<fieldset class="submit-buttons">
<!-- IF S_SHOW_COPPA -->
- <strong><a href="{U_COPPA_NO}" class="button1">{L_COPPA_NO}</a></strong>&nbsp; <a href="{U_COPPA_YES}" class="button2">{L_COPPA_YES}</a>
+ <input type="submit" name="coppa_no" id="coppa_no" value="{{ L_COPPA_NO }}" class="button1" />
+ <input type="submit" name="coppa_yes" id="coppa_yes" value="{{ L_COPPA_YES }}" class="button2" />
<!-- ELSE -->
<input type="submit" name="agreed" id="agreed" value="{L_AGREE}" class="button1" />&nbsp;
<input type="submit" name="not_agreed" value="{L_NOT_AGREE}" class="button2" />
diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html
index 9bfa07e52b..6af33f2f87 100644
--- a/phpBB/styles/prosilver/template/viewtopic_body.html
+++ b/phpBB/styles/prosilver/template/viewtopic_body.html
@@ -294,6 +294,7 @@
<!-- EVENT viewtopic_body_postrow_post_details_after -->
<!-- IF postrow.S_POST_UNAPPROVED -->
+ <!-- IF postrow.S_CAN_APPROVE -->
<form method="post" class="mcp_approve" action="{postrow.U_APPROVE_ACTION}">
<p class="post-notice unapproved">
<span><i class="icon fa-question icon-red fa-fw" aria-hidden="true"></i></span>
@@ -304,6 +305,12 @@
{S_FORM_TOKEN}
</p>
</form>
+ <!-- ELSE -->
+ <p class="post-notice unapproved">
+ <span><i class="icon fa-exclamation icon-red fa-fw" aria-hidden="true"></i></span>
+ <strong>{L_POST_UNAPPROVED_EXPLAIN}</strong>
+ </p>
+ <!-- ENDIF -->
<!-- ELSEIF postrow.S_POST_DELETED -->
<form method="post" class="mcp_approve" action="{postrow.U_APPROVE_ACTION}">
<p class="post-notice deleted">
diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php
index 4691512cbd..eb6b37ada8 100644
--- a/phpBB/viewforum.php
+++ b/phpBB/viewforum.php
@@ -899,6 +899,11 @@ if (count($topic_list))
// Replies
$replies = $phpbb_content_visibility->get_count('topic_posts', $row, $topic_forum_id) - 1;
+ // Correction for case of unapproved topic visible to poster
+ if ($replies < 0)
+ {
+ $replies = 0;
+ }
if ($row['topic_status'] == ITEM_MOVED)
{
diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php
index 4e502538c8..df241a5e8b 100644
--- a/phpBB/viewtopic.php
+++ b/phpBB/viewtopic.php
@@ -2092,6 +2092,7 @@ for ($i = 0, $end = count($post_list); $i < $end; ++$i)
'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false,
'S_MULTIPLE_ATTACHMENTS' => !empty($attachments[$row['post_id']]) && count($attachments[$row['post_id']]) > 1,
'S_POST_UNAPPROVED' => ($row['post_visibility'] == ITEM_UNAPPROVED || $row['post_visibility'] == ITEM_REAPPROVE) ? true : false,
+ 'S_CAN_APPROVE' => $auth->acl_get('m_approve', $forum_id),
'S_POST_DELETED' => ($row['post_visibility'] == ITEM_DELETED) ? true : false,
'L_POST_DELETED_MESSAGE' => $l_deleted_message,
'S_POST_REPORTED' => ($row['post_reported'] && $auth->acl_get('m_report', $forum_id)) ? true : false,