- add additional auth check to the permission roles modules

- added new function to return globally used expressions (get_preg_expression($mode)). This should be very helpful in getting wide spread similar checks (regular expressions) to one place reducing the risk of forgetting to change every location if you fix one. ;) We will add additional ones later, at the moment only the email check is retrieved...
- added "active module" var to the module class returning the current active module
- changed call to image magick
- add administrator to global moderators group by default
- extend auth_option column a little bit
- other bugfixes


git-svn-id: file:///svn/phpbb/trunk@6135 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
Meik Sievertsen 2006-07-01 19:11:52 +00:00
parent 7ad5db1856
commit 6df6eb0e60
29 changed files with 256 additions and 131 deletions

View file

@ -143,10 +143,8 @@
</dl>
<dl>
<dt><label for="enable_prune">{L_FORUM_AUTO_PRUNE}:</label><br /><span>{L_FORUM_AUTO_PRUNE_EXPLAIN}</span></dt>
<dd><input type="radio" class="radio" name="enable_prune" onchange="dE('forum_prune_options', 1)" value="1"<!-- IF S_PRUNE_ENABLE --> id="enable_prune" checked="checked"<!-- ENDIF --> /> {L_YES} &nbsp; <input type="radio" class="radio" name="enable_prune" onchange="dE('forum_prune_options', -1)" value="0"<!-- IF not S_PRUNE_ENABLE --> id="enable_prune" checked="checked"<!-- ENDIF --> /> {L_NO}</dd>
<dd><input type="radio" class="radio" name="enable_prune" value="1"<!-- IF S_PRUNE_ENABLE --> id="enable_prune" checked="checked"<!-- ENDIF --> /> {L_YES} &nbsp; <input type="radio" class="radio" name="enable_prune" value="0"<!-- IF not S_PRUNE_ENABLE --> id="enable_prune" checked="checked"<!-- ENDIF --> /> {L_NO}</dd>
</dl>
<div id="forum_prune_options"<!-- IF not S_PRUNE_ENABLE --> style="display: none;"<!-- ENDIF -->>
<dl>
<dt><label for="prune_freq">{L_AUTO_PRUNE_FREQ}:</label><br /><span>{L_AUTO_PRUNE_FREQ_EXPLAIN}</span></dt>
<dd><input type="text" id="prune_freq" name="prune_freq" value="{PRUNE_FREQ}" /> {L_DAYS}</dd>
@ -171,8 +169,6 @@
<dt><label for="prune_sticky">{L_PRUNE_STICKY}:</label></dt>
<dd><input type="radio" class="radio" name="prune_sticky" value="1"<!-- IF S_PRUNE_STICKY --> id="prune_sticky" checked="checked"<!-- ENDIF --> /> {L_YES} &nbsp; <input type="radio" class="radio" name="prune_sticky" value="0"<!-- IF not S_PRUNE_STICKY --> id="prune_sticky" checked="checked"<!-- ENDIF --> /> {L_NO}</dd>
</dl>
</div>
<dl>
<dt><label for="topics_per_page">{L_FORUM_TOPICS_PAGE}:</label><br /><span>{L_FORUM_TOPICS_PAGE_EXPLAIN}</span></dt>
<dd><input type="text" id="topics_per_page" name="topics_per_page" value="{TOPICS_PER_PAGE}" /></dd>

View file

@ -118,6 +118,7 @@
<tr>
<th>{L_USERNAME}</th>
<th>{L_JOINED}</th>
<th>{L_LAST_VISIT}</th>
<th>{L_MARK}</th>
</tr>
</thead>
@ -127,6 +128,7 @@
<td><a href="{inactive.U_USER_ADMIN}">{inactive.USERNAME}</a></td>
<td>{inactive.DATE}</td>
<td>{inactive.LAST_VISIT}</td>
<td>&nbsp;<input type="checkbox" class="radio" name="mark[]" value="{inactive.USER_ID}" />&nbsp;</td>
</tr>
<!-- BEGINELSE -->

View file

@ -40,7 +40,7 @@
<fieldset>
<legend>{L_VISIBILITY_OPTION}</legend>
<dl>
<dt><label for="field_option_none">{L_DISPLAY_AT_PROFILE}:</label></dt>
<dt><label for="field_option_none">{L_DISPLAY_AT_PROFILE}:</label><br /><span>{L_DISPLAY_AT_PROFILE_EXPLAIN}</span></dt>
<dd><input type="radio" class="radio" id="field_option_none" name="field_option" value="none"<!-- IF not S_SHOW_ON_REG and not S_FIELD_REQUIRED and not S_FIELD_HIDE --> checked="checked"<!-- ENDIF --> /></dd>
</dl>
<dl>

View file

@ -701,7 +701,7 @@ class acp_attachments
$sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id
FROM ' . FORUMS_TABLE . '
ORDER BY left_id ASC';
$result = $db->sql_query($sql);
$result = $db->sql_query($sql, 600);
$right = $cat_right = $padding_inc = 0;
$padding = $forum_list = $holding = '';

View file

@ -439,7 +439,7 @@ class acp_main
if ($auth->acl_get('a_user'))
{
$sql = 'SELECT user_id, username, user_regdate
$sql = 'SELECT user_id, username, user_regdate, user_lastvisit
FROM ' . USERS_TABLE . '
WHERE user_type = ' . USER_INACTIVE . '
ORDER BY user_regdate ASC';
@ -449,6 +449,7 @@ class acp_main
{
$template->assign_block_vars('inactive', array(
'DATE' => $user->format_date($row['user_regdate']),
'LAST_VISIT' => (!$row['user_lastvisit']) ? ' - ' : $user->format_date($row['user_lastvisit']),
'USER_ID' => $row['user_id'],
'USERNAME' => $row['username'],
'U_USER_ADMIN' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=users&amp;mode=overview&amp;u={$row['user_id']}"))

View file

@ -130,7 +130,7 @@ class acp_ranks
{
foreach ($img_ary as $img)
{
$img = substr($path, 1) . (($path != '') ? '/' : '') . $img;
$img = $path . $img;
if (!in_array($img, $existing_imgs) || $action == 'edit')
{

View file

@ -485,9 +485,6 @@ class acp_search
{
global $db;
/**
* @todo what is faster, doing a MAX() or an ORDER BY post_id and LIMIT 1?
*/
$sql = 'SELECT MAX(post_id) as max_post_id
FROM '. POSTS_TABLE;
$result = $db->sql_query($sql);

View file

@ -736,6 +736,9 @@ class acp_users
user_update_name($user_row['username'], $update_username);
}
// Let the users permissions being updated
$auth->acl_clear_prefetch($user_id);
add_log('admin', 'LOG_USER_USER_UPDATE', $data['username']);
trigger_error($user->lang['USER_OVERVIEW_UPDATED'] . adm_back_link($this->u_action . '&amp;u=' . $user_id));

View file

@ -20,10 +20,10 @@ class acp_permission_roles_info
'title' => 'ACP_PERMISSION_ROLES',
'version' => '1.0.0',
'modes' => array(
'admin_roles' => array('title' => 'ACP_ADMIN_ROLES', 'auth' => 'acl_a_roles', 'cat' => array('ACP_PERMISSION_ROLES')),
'user_roles' => array('title' => 'ACP_USER_ROLES', 'auth' => 'acl_a_roles', 'cat' => array('ACP_PERMISSION_ROLES')),
'mod_roles' => array('title' => 'ACP_MOD_ROLES', 'auth' => 'acl_a_roles', 'cat' => array('ACP_PERMISSION_ROLES')),
'forum_roles' => array('title' => 'ACP_FORUM_ROLES', 'auth' => 'acl_a_roles', 'cat' => array('ACP_PERMISSION_ROLES')),
'admin_roles' => array('title' => 'ACP_ADMIN_ROLES', 'auth' => 'acl_a_roles && acl_a_aauth', 'cat' => array('ACP_PERMISSION_ROLES')),
'user_roles' => array('title' => 'ACP_USER_ROLES', 'auth' => 'acl_a_roles && acl_a_uauth', 'cat' => array('ACP_PERMISSION_ROLES')),
'mod_roles' => array('title' => 'ACP_MOD_ROLES', 'auth' => 'acl_a_roles && acl_a_mauth', 'cat' => array('ACP_PERMISSION_ROLES')),
'forum_roles' => array('title' => 'ACP_FORUM_ROLES', 'auth' => 'acl_a_roles && acl_a_fauth', 'cat' => array('ACP_PERMISSION_ROLES')),
),
);
}

View file

@ -1515,7 +1515,11 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
if ($admin && !$auth->acl_get('a_'))
{
// Not authd
add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
// anonymous/inactive users are never able to go to the ACP even if they have the relevant permissions
if ($user->data['is_registered'])
{
add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
}
trigger_error('NO_AUTH_ADMIN');
}
@ -1548,7 +1552,12 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
}
else
{
add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
// Only log the failed attempt if a real user tried to.
// anonymous/inactive users are never able to go to the ACP even if they have the relevant permissions
if ($user->data['is_registered'])
{
add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
}
}
}
@ -1566,12 +1575,6 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
trigger_error($message . '<br /><br />' . sprintf($l_redirect, '<a href="' . $redirect . '">', '</a>'));
}
// The user wanted to re-authenticate, but something failed - log this
if ($admin)
{
add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
}
// Something failed, determine what...
if ($result['status'] == LOGIN_BREAK)
{
@ -1950,7 +1953,7 @@ function make_clickable($text, $server_url = false)
$magic_url_replace[] = "'\$1<!-- w --><a href=\"http://\$2\" target=\"_blank\">' . ((strlen('\$2') > 55) ? substr(str_replace('&amp;', '&', '\$2'), 0, 39) . ' ... ' . substr(str_replace('&amp;', '&', '\$2'), -10) : '\$2') . '</a><!-- w -->'";
// matches an email@domain type address at the start of a line, or after a space or after what might be a BBCode.
$magic_url_match[] = '#(^|[\n ]|\()([a-z0-9&\-_.]+?@[\w\-]+\.(?:[\w\-\.]+\.)?[\w]+)#ie';
$magic_url_match[] = '/(^|[\n ]|\()(' . get_preg_expression('email') . ')/ie';
$magic_url_replace[] = "'\$1<!-- e --><a href=\"mailto:\$2\">' . ((strlen('\$2') > 55) ? substr('\$2', 0, 39) . ' ... ' . substr('\$2', -10) : '\$2') . '</a><!-- e -->'";
}
@ -2254,6 +2257,23 @@ function get_backtrace()
return $output;
}
/**
* This function returns a regular expression pattern for commonly used expressions
* Use with / as delimiter
* mode can be: email|
*/
function get_preg_expression($mode)
{
switch ($mode)
{
case 'email':
return '[a-z0-9&\'\.\-_\+]+@[a-z0-9\-]+\.([a-z0-9\-]+\.)*?[a-z]+';
break;
}
return '';
}
// Handler, header and footer
/**

View file

@ -245,7 +245,7 @@ function get_forum_list($acl_list = 'f_list', $id_only = true, $postable_only =
// This query is identical to the jumpbox one
$expire_time = ($no_cache) ? 0 : 120;
$sql = 'SELECT forum_id, parent_id, forum_name, forum_type, left_id, right_id
$sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id
FROM ' . FORUMS_TABLE . '
ORDER BY left_id ASC';
$result = $db->sql_query($sql, $expire_time);

View file

@ -20,8 +20,8 @@ class p_master
var $p_mode;
var $p_parent;
var $active_module = false;
var $acl_forum_id = false;
var $module_ary = array();
/**
@ -239,6 +239,7 @@ class p_master
function set_active($id = false, $mode = false)
{
$icat = false;
$this->active_module = false;
if (request_var('icat', ''))
{
@ -247,20 +248,20 @@ class p_master
}
$category = false;
foreach ($this->module_ary as $row_id => $itep_ary)
foreach ($this->module_ary as $row_id => $item_ary)
{
// If this is a module and it's selected, active
// If this is a category and the module is the first within it, active
// If this is a module and no mode selected, select first mode
// If no category or module selected, go active for first module in first category
if (
(($itep_ary['name'] === $id || $itep_ary['id'] === (int) $id) && (($itep_ary['mode'] == $mode && !$itep_ary['cat']) || ($icat && $itep_ary['cat']))) ||
($itep_ary['parent'] === $category && !$itep_ary['cat'] && !$icat) ||
(($itep_ary['name'] === $id || $itep_ary['id'] === (int) $id) && !$mode && !$itep_ary['cat']) ||
(!$id && !$mode && !$itep_ary['cat'])
(($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && (($item_ary['mode'] == $mode && !$item_ary['cat']) || ($icat && $item_ary['cat']))) ||
($item_ary['parent'] === $category && !$item_ary['cat'] && !$icat) ||
(($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && !$mode && !$item_ary['cat']) ||
(!$id && !$mode && !$item_ary['cat'])
)
{
if ($itep_ary['cat'])
if ($item_ary['cat'])
{
$id = $icat;
$icat = false;
@ -268,20 +269,21 @@ class p_master
continue;
}
$this->p_id = $itep_ary['id'];
$this->p_parent = $itep_ary['parent'];
$this->p_name = $itep_ary['name'];
$this->p_mode = $itep_ary['mode'];
$this->p_left = $itep_ary['left'];
$this->p_right = $itep_ary['right'];
$this->p_id = $item_ary['id'];
$this->p_parent = $item_ary['parent'];
$this->p_name = $item_ary['name'];
$this->p_mode = $item_ary['mode'];
$this->p_left = $item_ary['left'];
$this->p_right = $item_ary['right'];
$this->module_cache['parents'] = $this->module_cache['parents'][$this->p_id];
$this->active_module = $item_ary['id'];
break;
}
else if (($itep_ary['cat'] && $itep_ary['id'] === (int) $id) || ($itep_ary['parent'] === $category && $itep_ary['cat']))
else if (($item_ary['cat'] && $item_ary['id'] === (int) $id) || ($item_ary['parent'] === $category && $item_ary['cat']))
{
$category = $itep_ary['id'];
$category = $item_ary['id'];
}
}
}
@ -298,6 +300,11 @@ class p_master
$module_path = $phpbb_root_path . 'includes/' . $this->p_class;
$icat = request_var('icat', '');
if ($this->active_module === false)
{
trigger_error('Module not accessible', E_USER_ERROR);
}
if (!class_exists("{$this->p_class}_$this->p_name"))
{
if (!file_exists("$module_path/{$this->p_class}_$this->p_name.$phpEx"))
@ -464,10 +471,10 @@ class p_master
// 1) In a linear fashion
// 2) In a combined tabbed + linear fashion ... tabs for the categories
// and a linear list for subcategories/items
foreach ($this->module_ary as $row_id => $itep_ary)
foreach ($this->module_ary as $row_id => $item_ary)
{
// Skip hidden modules
if (!$itep_ary['display'])
if (!$item_ary['display'])
{
continue;
}
@ -475,7 +482,7 @@ class p_master
// Skip branch
if ($right_id !== false)
{
if ($itep_ary['left'] < $right_id)
if ($item_ary['left'] < $right_id)
{
continue;
}
@ -484,14 +491,14 @@ class p_master
}
// Category with no members on their way down (we have to check every level)
if (!$itep_ary['name'])
if (!$item_ary['name'])
{
$empty_category = true;
// We go through the branch and look for an activated module
foreach (array_slice($this->module_ary, $row_id + 1) as $temp_row)
{
if ($temp_row['left'] > $itep_ary['left'] && $temp_row['left'] < $itep_ary['right'])
if ($temp_row['left'] > $item_ary['left'] && $temp_row['left'] < $item_ary['right'])
{
// Module there and displayed?
if ($temp_row['name'] && $temp_row['display'])
@ -507,18 +514,18 @@ class p_master
// Skip the branch
if ($empty_category)
{
$right_id = $itep_ary['right'];
$right_id = $item_ary['right'];
continue;
}
}
// Select first id we can get
if (!$current_id && (in_array($itep_ary['id'], array_keys($this->module_cache['parents'])) || $itep_ary['id'] == $this->p_id))
if (!$current_id && (in_array($item_ary['id'], array_keys($this->module_cache['parents'])) || $item_ary['id'] == $this->p_id))
{
$current_id = $itep_ary['id'];
$current_id = $item_ary['id'];
}
$depth = $itep_ary['depth'];
$depth = $item_ary['depth'];
if ($depth > $current_depth)
{
@ -534,30 +541,30 @@ class p_master
}
}
$u_title = $module_url . $delim . 'i=' . (($itep_ary['cat']) ? $itep_ary['id'] : $itep_ary['name'] . (($itep_ary['is_duplicate']) ? '&amp;icat=' . $current_id : '') . '&amp;mode=' . $itep_ary['mode']);
$u_title .= (!$itep_ary['cat'] && isset($itep_ary['url_extra'])) ? $itep_ary['url_extra'] : '';
$u_title = $module_url . $delim . 'i=' . (($item_ary['cat']) ? $item_ary['id'] : $item_ary['name'] . (($item_ary['is_duplicate']) ? '&amp;icat=' . $current_id : '') . '&amp;mode=' . $item_ary['mode']);
$u_title .= (!$item_ary['cat'] && isset($item_ary['url_extra'])) ? $item_ary['url_extra'] : '';
// Only output a categories items if it's currently selected
if (!$depth || ($depth && (in_array($itep_ary['parent'], array_values($this->module_cache['parents'])) || $itep_ary['parent'] == $this->p_parent)))
if (!$depth || ($depth && (in_array($item_ary['parent'], array_values($this->module_cache['parents'])) || $item_ary['parent'] == $this->p_parent)))
{
$use_tabular_offset = (!$depth) ? 't_block1' : $tabular_offset;
$tpl_ary = array(
'L_TITLE' => $itep_ary['lang'],
'S_SELECTED' => (in_array($itep_ary['id'], array_keys($this->module_cache['parents'])) || $itep_ary['id'] == $this->p_id) ? true : false,
'L_TITLE' => $item_ary['lang'],
'S_SELECTED' => (in_array($item_ary['id'], array_keys($this->module_cache['parents'])) || $item_ary['id'] == $this->p_id) ? true : false,
'U_TITLE' => $u_title
);
$template->assign_block_vars($use_tabular_offset, array_merge($tpl_ary, array_change_key_case($itep_ary, CASE_UPPER)));
$template->assign_block_vars($use_tabular_offset, array_merge($tpl_ary, array_change_key_case($item_ary, CASE_UPPER)));
}
$tpl_ary = array(
'L_TITLE' => $itep_ary['lang'],
'S_SELECTED' => (in_array($itep_ary['id'], array_keys($this->module_cache['parents'])) || $itep_ary['id'] == $this->p_id) ? true : false,
'L_TITLE' => $item_ary['lang'],
'S_SELECTED' => (in_array($item_ary['id'], array_keys($this->module_cache['parents'])) || $item_ary['id'] == $this->p_id) ? true : false,
'U_TITLE' => $u_title
);
$template->assign_block_vars($linear_offset, array_merge($tpl_ary, array_change_key_case($itep_ary, CASE_UPPER)));
$template->assign_block_vars($linear_offset, array_merge($tpl_ary, array_change_key_case($item_ary, CASE_UPPER)));
$current_depth = $depth;
}
@ -593,7 +600,10 @@ class p_master
{
$this->p_class = $class;
$this->p_name = $name;
// Set active module to true instead of using the id
$this->active_module = true;
$this->load_active($mode);
}
@ -633,9 +643,9 @@ class p_master
*/
function set_display($id, $mode = false, $display = true)
{
foreach ($this->module_ary as $row_id => $itep_ary)
foreach ($this->module_ary as $row_id => $item_ary)
{
if (($itep_ary['name'] === $id || $itep_ary['id'] === (int) $id) && (!$mode || $itep_ary['mode'] === $mode))
if (($item_ary['name'] === $id || $item_ary['id'] === (int) $id) && (!$mode || $item_ary['mode'] === $mode))
{
$this->module_ary[$row_id]['display'] = (int) $display;
}

View file

@ -521,9 +521,10 @@ function create_thumbnail($source, $destination, $mimetype)
$used_imagick = false;
if ($config['img_imagick'])
// Only use imagemagick if defined and the passthru function not disabled
if ($config['img_imagick'] && function_exists('passthru'))
{
passthru($config['img_imagick'] . 'convert' . ((defined('PHP_OS') && preg_match('#win#i', PHP_OS)) ? '.exe' : '') . ' -quality 85 -antialias -sample ' . $new_width . 'x' . $new_height . ' "' . str_replace('\\', '/', $source) . '" +profile "*" "' . str_replace('\\', '/', $destination) . '"');
passthru(escapeshellcmd($config['img_imagick']) . 'convert' . ((defined('PHP_OS') && preg_match('#win#i', PHP_OS)) ? '.exe' : '') . ' -quality 85 -antialias -sample ' . $new_width . 'x' . $new_height . ' "' . str_replace('\\', '/', $source) . '" +profile "*" "' . str_replace('\\', '/', $destination) . '"');
if (file_exists($destination))
{
$used_imagick = true;

View file

@ -464,7 +464,7 @@ class template_compile
{
preg_match('#^((?:[a-z0-9\-_]+\.)+)?\$(?=[A-Z])([A-Z0-9_\-]*)(?: = (\'?)([^\']*)(\'?))?$#', $tag_args, $match);
if (empty($match[2]) || (empty($match[4]) && $op))
if (empty($match[2]) || (!isset($match[4]) && $op))
{
return;
}

View file

@ -1095,7 +1095,7 @@ function validate_email($email)
return false;
}
if (!preg_match('#^[a-z0-9\.\-_\+]+?@(.*?\.)*?[a-z0-9\-_]+?\.[a-z]{2,4}$#i', $email))
if (!preg_match('/^' . get_preg_expression('email') . '$/i', $email))
{
return 'EMAIL_INVALID';
}

View file

@ -720,7 +720,7 @@ class bbcode_firstpass extends bbcode
$validated = true;
if (!preg_match('!([a-z0-9]+[a-z0-9\-\._]*@(?:(?:[0-9]{1,3}\.){3,5}[0-9]{1,3}|[a-z0-9]+[a-z0-9\-\._]*\.[a-z]+))!i', $email))
if (!preg_match('/^' . get_preg_expression('email') . '$/i', $email))
{
$validated = false;
}

View file

@ -56,7 +56,7 @@ CREATE INDEX phpbb_acl_groups_group_id ON phpbb_acl_groups(group_id);;
# phpbb_acl_options
CREATE TABLE phpbb_acl_options (
auth_option_id INTEGER NOT NULL,
auth_option VARCHAR(20) NOT NULL,
auth_option VARCHAR(50) NOT NULL,
is_global INTEGER DEFAULT 0 NOT NULL,
is_local INTEGER DEFAULT 0 NOT NULL,
founder_only INTEGER DEFAULT 0 NOT NULL

View file

@ -99,7 +99,7 @@ GO
*/
CREATE TABLE [phpbb_acl_options] (
[auth_option_id] [int] IDENTITY (1, 1) NOT NULL ,
[auth_option] [varchar] (20) NOT NULL ,
[auth_option] [varchar] (50) NOT NULL ,
[is_global] [int] NOT NULL ,
[is_local] [int] NOT NULL ,
[founder_only] [int] NOT NULL

View file

@ -43,7 +43,7 @@ CREATE TABLE phpbb_acl_groups (
# Table: 'phpbb_acl_options'
CREATE TABLE phpbb_acl_options (
auth_option_id mediumint(8) UNSIGNED NOT NULL auto_increment,
auth_option varchar(20) NOT NULL,
auth_option varchar(50) NOT NULL,
is_global tinyint(1) DEFAULT '0' NOT NULL,
is_local tinyint(1) DEFAULT '0' NOT NULL,
founder_only tinyint(1) DEFAULT '0' NOT NULL,

View file

@ -113,7 +113,7 @@ CREATE INDEX phpbb_acl_groups_auth_opt_id on phpbb_acl_groups (auth_option_id)
*/
CREATE TABLE phpbb_acl_options (
auth_option_id number(8) NOT NULL,
auth_option varchar2(20) NOT NULL,
auth_option varchar2(50) NOT NULL,
is_global number(1) DEFAULT '0' NOT NULL,
is_local number(1) DEFAULT '0' NOT NULL,
founder_only number(1) DEFAULT '0' NOT NULL,

View file

@ -136,7 +136,7 @@ CREATE SEQUENCE phpbb_acl_options_seq;
CREATE TABLE phpbb_acl_options (
auth_option_id INT4 DEFAULT nextval('phpbb_acl_options_seq'),
auth_option varchar(20) NOT NULL,
auth_option varchar(50) NOT NULL,
is_global INT2 DEFAULT '0' NOT NULL,
is_local INT2 DEFAULT '0' NOT NULL,
founder_only INT2 DEFAULT '0' NOT NULL,

View file

@ -413,6 +413,7 @@ INSERT INTO phpbb_groups (group_name, group_type, group_colour, group_legend, gr
# -- User -> Group
INSERT INTO phpbb_user_group (group_id, user_id, user_pending, group_leader) VALUES (1, 1, 0, 0);
INSERT INTO phpbb_user_group (group_id, user_id, user_pending, group_leader) VALUES (4, 2, 0, 0);
INSERT INTO phpbb_user_group (group_id, user_id, user_pending, group_leader) VALUES (6, 2, 0, 0);
INSERT INTO phpbb_user_group (group_id, user_id, user_pending, group_leader) VALUES (7, 2, 0, 1);
# -- Ranks

View file

@ -48,7 +48,7 @@ CREATE INDEX phpbb_acl_groups_auth_option_id on phpbb_acl_groups (auth_option_id
# Table: phpbb_acl_options
CREATE TABLE phpbb_acl_options (
auth_option_id INTEGER PRIMARY KEY NOT NULL,
auth_option varchar(20) NOT NULL,
auth_option varchar(50) NOT NULL,
is_global tinyint(1) NOT NULL DEFAULT '0',
is_local tinyint(1) NOT NULL DEFAULT '0',
founder_only tinyint(1) NOT NULL DEFAULT '0'

View file

@ -44,7 +44,7 @@ $lang = array_merge($lang, array(
'CP_LANG_DEFAULT_VALUE' => 'Default Value',
'CP_LANG_EXPLAIN' => 'Field Description',
'CP_LANG_EXPLAIN_EXPLAIN' => 'The Explanation for this field presented to the user',
'CP_LANG_NAME' => 'Field Name presented to the user',
'CP_LANG_NAME' => 'Field Name/Title presented to the user',
'CP_LANG_OPTIONS' => 'Options',
'CREATE_NEW_FIELD' => 'Create New Field',
'COLUMNS' => 'Columns',
@ -53,15 +53,16 @@ $lang = array_merge($lang, array(
'DEFAULT_VALUE' => 'Default Value',
'DELETE_PROFILE_FIELD' => 'Remove profile field',
'DELETE_PROFILE_FIELD_CONFIRM' => 'Are you sure you want to delete this profile field?',
'DISPLAY_AT_PROFILE' => 'Display at users profile',
'DISPLAY_AT_PROFILE' => 'Display in user control panel',
'DISPLAY_AT_PROFILE_EXPLAIN' => 'The user is able to change this profile field within the user control panel.',
'DISPLAY_AT_REGISTER' => 'Display at registration screen',
'DISPLAY_AT_REGISTER_EXPLAIN' => 'If this option is enabled, the field will be additionally displayed on registration.',
'DISPLAY_AT_REGISTER_EXPLAIN' => 'If this option is enabled, the field will be displayed on registration and able to be changed within the user control panel.',
'DISPLAY_PROFILE_FIELD' => 'Display profile field',
'DISPLAY_PROFILE_FIELD_EXPLAIN' => 'The profile field will be shown on viewtopic/viewprofile/memberlist/etc.',
'DROPDOWN_ENTRIES_EXPLAIN' => 'Enter your options now, every option in one line',
'EMPTY_FIELD_IDENT' => 'Empty field name',
'EMPTY_USER_FIELD_NAME' => 'Empty Field Name presented to the user',
'EMPTY_FIELD_IDENT' => 'Empty field identification',
'EMPTY_USER_FIELD_NAME' => 'Please enter a field name/title',
'ENTRIES' => 'Entries',
'EVERYTHING_OK' => 'Everything OK',
@ -70,8 +71,8 @@ $lang = array_merge($lang, array(
'FIELD_DESCRIPTION' => 'Field Description',
'FIELD_DESCRIPTION_EXPLAIN' => 'The Explanation for this field presented to the user',
'FIELD_DROPDOWN' => 'Dropdown Box',
'FIELD_IDENT' => 'Field Name',
'FIELD_IDENT_EXPLAIN' => 'The Field Name is a name for you to identify the profile field, it is not displayed to the user.',
'FIELD_IDENT' => 'Field Identification',
'FIELD_IDENT_EXPLAIN' => 'The field Identification is a name to identify the profile field within the database and the templates.',
'FIELD_INT' => 'Numbers',
'FIELD_LENGTH' => 'Length of input box',
'FIELD_NOT_FOUND' => 'Profile field not found',
@ -85,7 +86,7 @@ $lang = array_merge($lang, array(
'HIDE_PROFILE_FIELD' => 'Hide Profile Field',
'HIDE_PROFILE_FIELD_EXPLAIN' => 'Only Administrators and Moderators are able to see/fill out this profile field. If this option is enabled, the profile field will be only displayed in user profiles.',
'INVALID_CHARS_FIELD_IDENT' => 'Field name can only contain lowercase a-z and _',
'INVALID_CHARS_FIELD_IDENT' => 'Field identification can only contain lowercase a-z and _',
'ISO_LANGUAGE' => 'Language [%s]',
'LANG_SPECIFIC_OPTIONS' => 'Language specific options [<b>%s</b>]',
@ -112,7 +113,7 @@ $lang = array_merge($lang, array(
'RADIO_BUTTONS' => 'Radio Buttons',
'REMOVED_PROFILE_FIELD' => 'Successfully removed profile field.',
'REQUIRED_FIELD' => 'Required Field',
'REQUIRED_FIELD_EXPLAIN' => 'Force profile field to be filled out or specified by user. This will display the profile field at registration too.',
'REQUIRED_FIELD_EXPLAIN' => 'Force profile field to be filled out or specified by user. This will display the profile field at registration and within the user control panel.',
'ROWS' => 'Rows',
'SAVE' => 'Save',
@ -134,7 +135,7 @@ $lang = array_merge($lang, array(
'TEXT_DEFAULT_VALUE_EXPLAIN' => 'Enter a default text to be displayed, a default value. Leave empty if you want to show it empty at the first place.',
'UPDATE_PREVIEW' => 'Update Preview',
'USER_FIELD_NAME' => 'Field Name presented to the user',
'USER_FIELD_NAME' => 'Field Name/Title presented to the user',
'VISIBILITY_OPTION' => 'Visibility Option',
));

View file

@ -96,7 +96,7 @@ $lang = array_merge($lang, array(
'CANCEL' => 'Cancel',
'CHANGE' => 'Change',
'CLICK_VIEW_PRIVMSG' => '%sReturn to your Inbox%s',
'CLICK_VIEW_PRIVMSG' => '%sGo to your inbox%s',
'CLOSE_WINDOW' => 'Close window',
'COLOUR_SWATCH' => 'Colour swatch',
'CONFIRM' => 'Confirm',
@ -245,6 +245,7 @@ $lang = array_merge($lang, array(
'LAST_POST' => 'Last post',
'LAST_UPDATED' => 'Last updated',
'LAST_VISIT' => 'Last visit',
'LEGEND' => 'Legend',
'LOCATION' => 'Location',
'LOCK_POST' => 'Lock Post',

View file

@ -397,6 +397,21 @@ switch ($mode)
$profile_fields = (isset($profile_fields[$user_id])) ? $cp->generate_profile_fields_template('show', false, $profile_fields[$user_id]) : array();
}
// We need to check if the module 'zebra' is accessible
$zebra_enabled = false;
if ($user->data['user_id'] != $user_id && $user->data['is_registered'])
{
include_once($phpbb_root_path . 'includes/functions_module.' . $phpEx);
$module = new p_master();
$module->list_modules('ucp');
$module->set_active('zebra');
$zebra_enabled = ($module->active_module === false) ? false : true;
unset($module);
}
$template->assign_vars(array(
'POSTS_DAY' => sprintf($user->lang['POST_DAY'], $posts_per_day),
'POSTS_PCT' => sprintf($user->lang['POST_PCT'], $percentage),
@ -424,7 +439,7 @@ switch ($mode)
'U_USER_ADMIN' => ($auth->acl_get('a_user')) ? append_sid("{$phpbb_root_path}adm/index.$phpEx", 'i=users&amp;mode=overview&amp;u=' . $user_id, true, $user->session_id) : '',
'U_SWITCH_PERMISSIONS' => ($auth->acl_get('a_switchperm') && $user->data['user_id'] != $user_id) ? append_sid("{$phpbb_root_path}ucp.$phpEx", "mode=switch_perm&amp;u={$user_id}") : '',
'S_ZEBRA' => ($user->data['user_id'] != $user_id && $user->data['is_registered']) ? true : false,
'S_ZEBRA' => ($user->data['user_id'] != $user_id && $user->data['is_registered'] && $zebra_enabled) ? true : false,
'U_ADD_FRIEND' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;add=' . urlencode($member['username'])),
'U_ADD_FOE' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;mode=foes&amp;add=' . urlencode($member['username'])))
);
@ -598,53 +613,74 @@ switch ($mode)
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
$messenger = new messenger(false);
$email_tpl = ($user_id) ? 'profile_send_email' : 'email_notify';
$messenger->template($email_tpl, $email_lang);
$mail_to_users = array();
$messenger->replyto($user->data['user_email']);
$messenger->to($email, $name);
if ($user_id)
{
$messenger->subject(html_entity_decode($subject));
$messenger->im($row['user_jabber'], $row['username']);
$notify_type = $row['user_notify_type'];
}
else
{
$notify_type = NOTIFY_EMAIL;
}
if ($cc)
{
$messenger->cc($user->data['user_email'], $user->data['username']);
}
$messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
$messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
$messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
$messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
$messenger->assign_vars(array(
'SITENAME' => $config['sitename'],
'BOARD_EMAIL' => $config['board_contact'],
'TO_USERNAME' => html_entity_decode($name),
'FROM_USERNAME' => html_entity_decode($user->data['username']),
'MESSAGE' => html_entity_decode($message))
$mail_to_users[] = array(
'email_lang' => $email_lang,
'email' => $email,
'name' => $name,
'username' => $row['username'],
'to_name' => $name,
'user_jabber' => $row['user_jabber'],
'user_notify_type' => $row['user_notify_type'],
);
if ($topic_id)
// Ok, now the same email if CC specified, but without exposing the users email address
if ($cc)
{
$messenger->assign_vars(array(
'TOPIC_NAME' => html_entity_decode($row['topic_title']),
'U_TOPIC' => generate_board_url() . "/viewtopic.$phpEx?f=" . $row['forum_id'] . "&t=$topic_id")
$mail_to_users[] = array(
'email_lang' => $user->data['user_lang'],
'email' => $user->data['user_email'],
'name' => $user->data['username'],
'username' => $user->data['username'],
'to_name' => $name,
'user_jabber' => $user->data['user_jabber'],
'user_notify_type' => ($user_id) ? $user->data['user_notify_type'] : NOTIFY_EMAIL,
);
}
$messenger->send($notify_type);
$messenger->save_queue();
foreach ($mail_to_users as $row)
{
$messenger->template($email_tpl, $row['email_lang']);
$messenger->replyto($user->data['user_email']);
$messenger->to($row['email'], $row['name']);
if ($user_id)
{
$messenger->subject(html_entity_decode($subject));
$messenger->im($row['user_jabber'], $row['username']);
$notify_type = $row['user_notify_type'];
}
else
{
$notify_type = NOTIFY_EMAIL;
}
$messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
$messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
$messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
$messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
$messenger->assign_vars(array(
'SITENAME' => $config['sitename'],
'BOARD_EMAIL' => $config['board_contact'],
'TO_USERNAME' => html_entity_decode($row['to_name']),
'FROM_USERNAME' => html_entity_decode($user->data['username']),
'MESSAGE' => html_entity_decode($message))
);
if ($topic_id)
{
$messenger->assign_vars(array(
'TOPIC_NAME' => html_entity_decode($row['topic_title']),
'U_TOPIC' => generate_board_url() . "/viewtopic.$phpEx?f=" . $row['forum_id'] . "&t=$topic_id")
);
}
$messenger->send($notify_type);
}
meta_refresh(3, append_sid("{$phpbb_root_path}index.$phpEx"));
$message = ($user_id) ? sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a>') : sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$row['forum_id']}&amp;t=$topic_id") . '">', '</a>');

View file

@ -167,9 +167,51 @@ if (!$auth->acl_get('f_read', $forum_id))
}
// Permission to do the action asked?
$check_auth = ($mode == 'quote') ? 'reply' : $mode;
if (!$auth->acl_get('f_' . $check_auth, $forum_id))
$is_authed = false;
switch ($mode)
{
case 'post':
if ($auth->acl_get('f_post', $forum_id))
{
$is_authed = true;
}
break;
case 'bump':
if ($auth->acl_get('f_bump', $forum_id))
{
$is_authed = true;
}
break;
case 'quote':
case 'reply':
if ($auth->acl_get('f_reply', $forum_id))
{
$is_authed = true;
}
break;
case 'edit':
if ($user->data['is_registered'] && $auth->acl_gets('f_edit', 'm_edit', $forum_id))
{
$is_authed = true;
}
break;
case 'delete':
if ($user->data['is_registered'] && $auth->acl_gets('f_delete', 'm_delete', $forum_id))
{
$is_authed = true;
}
break;
}
if (!$is_authed)
{
$check_auth = ($mode == 'quote') ? 'reply' : $mode;
if ($user->data['is_registered'])
{
trigger_error('USER_CANNOT_' . strtoupper($check_auth));
@ -1020,7 +1062,7 @@ $lock_topic_checked = (isset($topic_lock)) ? $topic_lock : (($post_data['topic_s
$lock_post_checked = (isset($post_lock)) ? $post_lock : $post_data['post_edit_locked'];
// If in edit mode, and the user is not the poster, we do not take the notification into account
$notify_checked = (isset($notify)) ? $notify : (($mode != 'edit') ? $user->data['user_notify'] : $post_data['notify_set']);
$notify_checked = (isset($notify)) ? $notify : (($mode == 'post') ? $user->data['user_notify'] : $post_data['notify_set']);
// Page title & action URL, include session_id for security purpose
$s_action = append_sid("{$phpbb_root_path}posting.$phpEx", "mode=$mode&amp;f=$forum_id", true, $user->session_id);
@ -1092,7 +1134,7 @@ $template->assign_vars(array(
'FORUM_NAME' => $post_data['forum_name'],
'FORUM_DESC' => ($post_data['forum_desc']) ? generate_text_for_display($post_data['forum_desc'], $post_data['forum_desc_uid'], $post_data['forum_desc_bitfield']) : '',
'TOPIC_TITLE' => $post_data['topic_title'],
'TOPIC_TITLE' => censor_text($post_data['topic_title']),
'MODERATORS' => (sizeof($moderators)) ? implode(', ', $moderators[$forum_id]) : '',
'USERNAME' => ((!$preview && $mode != 'quote') || $preview) ? $post_data['username'] : '',
'SUBJECT' => $post_data['post_subject'],

View file

@ -56,7 +56,7 @@
<td class="row1" width="50" align="center"><p class="topicdetails">{topicrow.REPLIES}</p></td>
<td class="row2" width="50" align="center"><p class="topicdetails">{topicrow.VIEWS}</p></td>
<td class="row1" width="140" align="center">
<p class="topicdetails">{topicrow.LAST_POST_TIME}</p>
<p class="topicdetails" style="white-space: nowrap;">{topicrow.LAST_POST_TIME}</p>
<p class="topicdetails"><!-- IF topicrow.U_LAST_POST_AUTHOR --><a href="{topicrow.U_LAST_POST_AUTHOR}">{topicrow.LAST_POST_AUTHOR}</a><!-- ELSE -->{topicrow.LAST_POST_AUTHOR}<!-- ENDIF -->
<a href="{topicrow.U_LAST_POST}">{LAST_POST_IMG}</a>
</p>
@ -177,7 +177,7 @@
<td class="row1" width="50" align="center"><p class="topicdetails">{topicrow.REPLIES}</p></td>
<td class="row2" width="50" align="center"><p class="topicdetails">{topicrow.VIEWS}</p></td>
<td class="row1" width="140" align="center">
<p class="topicdetails">{topicrow.LAST_POST_TIME}</p>
<p class="topicdetails" style="white-space: nowrap;">{topicrow.LAST_POST_TIME}</p>
<p class="topicdetails"><!-- IF topicrow.U_LAST_POST_AUTHOR --><a href="{topicrow.U_LAST_POST_AUTHOR}">{topicrow.LAST_POST_AUTHOR}</a><!-- ELSE -->{topicrow.LAST_POST_AUTHOR}<!-- ENDIF -->
<a href="{topicrow.U_LAST_POST}">{LAST_POST_IMG}</a>
</p>

View file

@ -198,7 +198,21 @@ else
$sql_array['FROM'][POSTS_TABLE] = 'p';
}
$sql_array['WHERE'] .= ' AND (f.forum_id = t.forum_id ' . ((!$forum_id) ? 'OR t.topic_type = ' . POST_GLOBAL : 'OR (t.topic_type = ' . POST_GLOBAL . " AND f.forum_id = $forum_id)") . ')';
$sql_array['WHERE'] .= ' AND (f.forum_id = t.forum_id';
if (!$forum_id)
{
// If it is a global announcement make sure to set the forum id to a postable forum
$sql_array['WHERE'] .= ' OR (t.topic_type = ' . POST_GLOBAL . '
AND f.forum_type = ' . FORUM_POST . ')';
}
else
{
$sql_array['WHERE'] .= ' OR (t.topic_type = ' . POST_GLOBAL . "
AND f.forum_id = $forum_id)";
}
$sql_array['WHERE'] .= ')';
$sql_array['FROM'][TOPICS_TABLE] = 't';
// Join to forum table on topic forum_id unless topic forum_id is zero
@ -1359,7 +1373,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
'U_REPORT' => ($auth->acl_get('f_report', $forum_id)) ? append_sid("{$phpbb_root_path}report.$phpEx", 'f=' . $forum_id . '&amp;p=' . $row['post_id']) : '',
'U_MCP_REPORT' => ($auth->acl_get('m_report', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=report_details&amp;f=' . $forum_id . '&amp;p=' . $row['post_id'], true, $user->session_id) : '',
'U_MCP_APPROVE' => ($auth->acl_get('m_approve', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=approve_details&amp;f=' . $forum_id . '&amp;p=' . $row['post_id'], true, $user->session_id) : '',
'U_MINI_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . '#p' . $row['post_id'],
'U_MINI_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . (($topic_data['topic_type'] == POST_GLOBAL) ? '&amp;f=' . $forum_id : '') . '#p' . $row['post_id'],
'U_NEXT_POST_ID' => ($i < $i_total && isset($rowset[$post_list[$i + 1]])) ? $rowset[$post_list[$i + 1]]['post_id'] : '',
'U_PREV_POST_ID' => $prev_post_id,
'U_NOTES' => ($auth->acl_getf_global('m_')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&amp;mode=user_notes&amp;u=' . $poster_id, true, $user->session_id) : '',