Merge pull request #39 from torrentpier/develop

Версия 2.1.4 ALPHA-4

Четвертый ALPHA-билд.

Основные изменения:

- интегрирован Zend Framework 2;
- перенос файлов из папки upload в корень проекта;
- перенос необходимых файлов для установки в папку install;
- обновление часовых поясов для России;
- исправление поддержки ssl;
- исправление подавления ошибок с помощью @;
- исправления ссылок на форум проекта;
- обновление примера конфигурации nginx, редиректы для apache;
- обновление sql-дампа (чистка мусора от xbtt, обновление формата);
- обновление bootstrap, добавление .gitignore;
- упрощение функции вывода аватара;
- перенос классов кеширования в отдельные файлы;
- исправление ошибки с начислением сидбонусов (строгая типизация);
- изменение метода поисковой строки (заработает "поисковость" в Яндекс.Браузер и т.п.);
- исправление ошибок с редиректом и редирект на главную страницу для отсутствующей темы;
- прочие мелкие исправления.
This commit is contained in:
Exile 2014-11-26 21:31:09 +03:00
commit e37312cfab
3095 changed files with 302326 additions and 5547 deletions

35
.gitignore vendored Normal file
View file

@ -0,0 +1,35 @@
### TorrentPier ###
.idea/
data/avatars/**/
data/old_files/
data/torrent_files/
internal_data/ajax_html/*.html
internal_data/atom/
internal_data/cache/
internal_data/captcha/**/
internal_data/log/
internal_data/sitemap/*.xml
internal_data/triggers/
library/config.local.php
### Archives ###
*.log
*.zip
*.rar
*.tar
*.gz
*.torrent
### Windows ###
Thumbs.db
Desktop.ini
$RECYCLE.BIN/
*.lnk
### OSX ###
.DS_Store
.AppleDouble
.LSOverride
._*
.Spotlight-V100
.Trashes

18
.htaccess Normal file
View file

@ -0,0 +1,18 @@
## set default server charset
AddDefaultCharset UTF-8
## folder listing access control
Options All -Indexes
## sitemap and atom rewrite
RewriteEngine On
RewriteRule ^sitemap.xml$ internal_data/sitemap/sitemap.xml [L]
RewriteRule ^/internal_data/atom/(.*) /atom$1 [L]
## deny access to git folder
RedirectMatch 404 /\\.git(/|$)
## deny access to system files
<FilesMatch "\.(.*sql|tpl|db|inc|log|md)|(config|common).php$">
deny from all
</FilesMatch>

View file

@ -36,6 +36,7 @@ nord51
Вася Вася
Alexander.S (http://torrent.dchub.ws/) Alexander.S (http://torrent.dchub.ws/)
sasha20072007 sasha20072007
gerhanovn
***************************** *****************************
** Прочая информация ** ** Прочая информация **

View file

@ -7,7 +7,7 @@ TorrentPier II - движок торрент-трекера, написанны
Для установки вам необходимо выполнить несколько простых шагов: Для установки вам необходимо выполнить несколько простых шагов:
1. Распаковываем на сервер содержимое папки **upload** 1. Распаковываем на сервер содержимое скачанной вами папки
2. Создаем базу данных, в которую при помощи phpmyadmin (или любого другого удобного инструмента) импортируем дамп, расположенный в папке **install/sql/mysql.sql** 2. Создаем базу данных, в которую при помощи phpmyadmin (или любого другого удобного инструмента) импортируем дамп, расположенный в папке **install/sql/mysql.sql**
3. Правим файл конфигурации **library/config.php**, загруженный на сервер: 3. Правим файл конфигурации **library/config.php**, загруженный на сервер:
@ -66,6 +66,10 @@ TorrentPier II - движок торрент-трекера, написанны
Инструкция по сборке приведена на нашем форуме: https://torrentpier.me/threads/sborka-ocelot-pod-debian-7-1.26078/ Инструкция по сборке приведена на нашем форуме: https://torrentpier.me/threads/sborka-ocelot-pod-debian-7-1.26078/
Для работы анонсера требуется замена двух таблиц в базе данных - дамп в файле: **install/sql/ocelot.sql** Для работы анонсера требуется замена двух таблиц в базе данных - дамп в файле: **install/sql/ocelot.sql**
## Папка install
В корне движка присутствует папка **install**, в которой находятся служебные файлы, необходимые для его установки (дамп базы, примеры конфигов) и обновления (дамперы, скрипты конвертации). Доступ к данной папке по-умолчанию закрыт, но если ее присутствие вам мешает - вы можете ее удалить. На файлы **README.md** и **CONTRIBUTORS.md** это также распространяется.
## Полезные ссылки ## Полезные ссылки
+ Наш форум https://torrentpier.me/ + Наш форум https://torrentpier.me/

View file

@ -187,7 +187,7 @@ function msg_die ($msg)
// Start announcer // Start announcer
define('TR_ROOT', './'); define('TR_ROOT', './');
require(TR_ROOT .'includes/init_tr.php'); require(TR_ROOT . 'includes/init_tr.php');
$seeder = ($left == 0) ? 1 : 0; $seeder = ($left == 0) ? 1 : 0;
$stopped = ($event === 'stopped'); $stopped = ($event === 'stopped');

View file

@ -33,7 +33,7 @@ function msg_die ($msg)
} }
define('TR_ROOT', './'); define('TR_ROOT', './');
require(TR_ROOT .'includes/init_tr.php'); require(TR_ROOT . 'includes/init_tr.php');
$info_hash_sql = rtrim(DB()->escape($info_hash), ' '); $info_hash_sql = rtrim(DB()->escape($info_hash), ' ');

507
common.php Normal file
View file

@ -0,0 +1,507 @@
<?php
if (isset($_REQUEST['GLOBALS'])) die();
ignore_user_abort(true);
define('TIMESTART', utime());
define('TIMENOW', time());
if (empty($_SERVER['REMOTE_ADDR'])) $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
if (empty($_SERVER['HTTP_USER_AGENT'])) $_SERVER['HTTP_USER_AGENT'] = '';
if (empty($_SERVER['HTTP_REFERER'])) $_SERVER['HTTP_REFERER'] = '';
if (empty($_SERVER['SERVER_NAME'])) $_SERVER['SERVER_NAME'] = '';
if (!defined('BB_ROOT')) define('BB_ROOT', './');
if (!defined('IN_FORUM') && !defined('IN_TRACKER')) define('IN_FORUM', true);
header('X-Frame-Options: SAMEORIGIN');
// Get initial config
require(BB_ROOT . 'library/config.php');
// Load Zend Framework
use Zend\Loader\StandardAutoloader;
require(BB_ROOT . 'library/Zend/Loader/StandardAutoloader.php');
$loader = new StandardAutoloader(array('autoregister_zf' => true));
$loader->register();
$server_protocol = ($bb_cfg['cookie_secure']) ? 'https://' : 'http://';
$server_port = (in_array($bb_cfg['server_port'], array(80, 443))) ? '' : ':' . $bb_cfg['server_port'];
define('FORUM_PATH', $bb_cfg['script_path']);
define('FULL_URL', $server_protocol . $bb_cfg['server_name'] . $server_port . $bb_cfg['script_path']);
unset($server_protocol, $server_port);
// Debug options
define('DBG_USER', (isset($_COOKIE[COOKIE_DBG])));
// Board/Tracker shared constants and functions
define('BB_BT_TORRENTS', 'bb_bt_torrents');
define('BB_BT_TRACKER', 'bb_bt_tracker');
define('BB_BT_TRACKER_SNAP', 'bb_bt_tracker_snap');
define('BB_BT_USERS', 'bb_bt_users');
define('BT_AUTH_KEY_LENGTH', 10);
define('PEER_HASH_PREFIX', 'peer_');
define('PEERS_LIST_PREFIX', 'peers_list_');
define('PEER_HASH_EXPIRE', round($bb_cfg['announce_interval'] * (0.85 * $tr_cfg['expire_factor']))); // sec
define('PEERS_LIST_EXPIRE', round($bb_cfg['announce_interval'] * 0.7)); // sec
define('DL_STATUS_RELEASER', -1);
define('DL_STATUS_DOWN', 0);
define('DL_STATUS_COMPLETE', 1);
define('DL_STATUS_CANCEL', 3);
define('DL_STATUS_WILL', 4);
define('TOR_TYPE_GOLD', 1);
define('TOR_TYPE_SILVER', 2);
define('GUEST_UID', -1);
define('BOT_UID', -746);
/**
* Database
*/
// Core DB class
require(CORE_DIR . 'dbs.php');
$DBS = new DBS($bb_cfg);
function DB ($db_alias = 'db1')
{
global $DBS;
return $DBS->get_db_obj($db_alias);
}
/**
* Cache
*/
// Main cache class
require(INC_DIR . 'cache/common.php');
// Main datastore class
require(INC_DIR . 'datastore/common.php');
// Core CACHE class
require(CORE_DIR . 'caches.php');
$CACHES = new CACHES($bb_cfg);
function CACHE ($cache_name)
{
global $CACHES;
return $CACHES->get_cache_obj($cache_name);
}
// Common cache classes
require(INC_DIR . 'cache/memcache.php');
require(INC_DIR . 'cache/sqlite.php');
require(INC_DIR . 'cache/redis.php');
require(INC_DIR . 'cache/apc.php');
require(INC_DIR . 'cache/xcache.php');
require(INC_DIR . 'cache/file.php');
/**
* Datastore
*/
// Common datastore classes
require(INC_DIR . 'datastore/memcache.php');
require(INC_DIR . 'datastore/sqlite.php');
require(INC_DIR . 'datastore/redis.php');
require(INC_DIR . 'datastore/apc.php');
require(INC_DIR . 'datastore/xcache.php');
require(INC_DIR . 'datastore/file.php');
// Initialize datastore
switch ($bb_cfg['datastore_type'])
{
case 'memcache':
$datastore = new datastore_memcache($bb_cfg['cache']['memcache'], $bb_cfg['cache']['prefix']);
break;
case 'sqlite':
$default_cfg = array(
'db_file_path' => $bb_cfg['cache']['db_dir'] .'datastore.sqlite.db',
'pconnect' => true,
'con_required' => true,
);
$datastore = new datastore_sqlite($default_cfg, $bb_cfg['cache']['prefix']);
break;
case 'redis':
$datastore = new datastore_redis($bb_cfg['cache']['redis'], $bb_cfg['cache']['prefix']);
break;
case 'apc':
$datastore = new datastore_apc($bb_cfg['cache']['prefix']);
break;
case 'xcache':
$datastore = new datastore_xcache($bb_cfg['cache']['prefix']);
break;
case 'filecache':
default: $datastore = new datastore_file($bb_cfg['cache']['db_dir'] . 'datastore/', $bb_cfg['cache']['prefix']);
}
function sql_dbg_enabled ()
{
return (SQL_DEBUG && DBG_USER && !empty($_COOKIE['sql_log']));
}
function short_query ($sql, $esc_html = false)
{
$max_len = 100;
$sql = str_compact($sql);
if (!empty($_COOKIE['sql_log_full']))
{
if (mb_strlen($sql, 'UTF-8') > $max_len)
{
$sql = mb_substr($sql, 0, 50) .' [...cut...] '. mb_substr($sql, -50);
}
}
return ($esc_html) ? htmlCHR($sql, true) : $sql;
}
// Functions
function utime ()
{
return array_sum(explode(' ', microtime()));
}
function bb_log ($msg, $file_name)
{
if (is_array($msg))
{
$msg = join(LOG_LF, $msg);
}
$file_name .= (LOG_EXT) ? '.'. LOG_EXT : '';
return file_write($msg, LOG_DIR . $file_name);
}
function file_write ($str, $file, $max_size = LOG_MAX_SIZE, $lock = true, $replace_content = false)
{
$bytes_written = false;
if ($max_size && @filesize($file) >= $max_size)
{
$old_name = $file; $ext = '';
if (preg_match('#^(.+)(\.[^\\/]+)$#', $file, $matches))
{
$old_name = $matches[1]; $ext = $matches[2];
}
$new_name = $old_name .'_[old]_'. date('Y-m-d_H-i-s_') . getmypid() . $ext;
clearstatcache();
if (@file_exists($file) && @filesize($file) >= $max_size && !@file_exists($new_name))
{
@rename($file, $new_name);
}
}
if (!$fp = @fopen($file, 'ab'))
{
if ($dir_created = bb_mkdir(dirname($file)))
{
$fp = @fopen($file, 'ab');
}
}
if ($fp)
{
if ($lock)
{
@flock($fp, LOCK_EX);
}
if ($replace_content)
{
@ftruncate($fp, 0);
@fseek($fp, 0, SEEK_SET);
}
$bytes_written = @fwrite($fp, $str);
@fclose($fp);
}
return $bytes_written;
}
function bb_mkdir ($path, $mode = 0777)
{
$old_um = umask(0);
$dir = mkdir_rec($path, $mode);
umask($old_um);
return $dir;
}
function mkdir_rec ($path, $mode)
{
if (is_dir($path))
{
return ($path !== '.' && $path !== '..') ? is_writable($path) : false;
}
else
{
return (mkdir_rec(dirname($path), $mode)) ? @mkdir($path, $mode) : false;
}
}
function verify_id ($id, $length)
{
return (is_string($id) && preg_match('#^[a-zA-Z0-9]{'. $length .'}$#', $id));
}
function clean_filename ($fname)
{
static $s = array('\\', '/', ':', '*', '?', '"', '<', '>', '|', ' ');
return str_replace($s, '_', str_compact($fname));
}
function encode_ip ($ip)
{
$d = explode('.', $ip);
return sprintf('%02x%02x%02x%02x', $d[0], $d[1], $d[2], $d[3]);
}
function decode_ip ($ip)
{
return long2ip("0x{$ip}");
}
function ip2int ($ip)
{
return (float) sprintf('%u', ip2long($ip)); // для совместимости с 32 битными системами
}
// long2ip( mask_ip_int(ip2int('1.2.3.4'), 24) ) = '1.2.3.255'
function mask_ip_int ($ip, $mask)
{
$ip_int = is_numeric($ip) ? $ip : ip2int($ip);
$ip_masked = $ip_int | ((1 << (32 - $mask)) - 1);
return (float) sprintf('%u', $ip_masked);
}
function bb_crc32 ($str)
{
return (float) sprintf('%u', crc32($str));
}
function hexhex ($value)
{
return dechex(hexdec($value));
}
function verify_ip ($ip)
{
return preg_match('#^(\d{1,3}\.){3}\d{1,3}$#', $ip);
}
function str_compact ($str)
{
return preg_replace('#\s+#u', ' ', trim($str));
}
function make_rand_str ($len = 10)
{
$str = '';
while (strlen($str) < $len)
{
$str .= str_shuffle(preg_replace('#[^0-9a-zA-Z]#', '', crypt(uniqid(mt_rand(), true))));
}
return substr($str, 0, $len);
}
// bencode: based on OpenTracker
function bencode ($var)
{
if (is_string($var))
{
return strlen($var) .':'. $var;
}
else if (is_int($var))
{
return 'i'. $var .'e';
}
else if (is_float($var))
{
return 'i'. sprintf('%.0f', $var) .'e';
}
else if (is_array($var))
{
if (count($var) == 0)
{
return 'de';
}
else
{
$assoc = false;
foreach ($var as $key => $val)
{
if (!is_int($key))
{
$assoc = true;
break;
}
}
if ($assoc)
{
ksort($var, SORT_REGULAR);
$ret = 'd';
foreach ($var as $key => $val)
{
$ret .= bencode($key) . bencode($val);
}
return $ret .'e';
}
else
{
$ret = 'l';
foreach ($var as $val)
{
$ret .= bencode($val);
}
return $ret .'e';
}
}
}
else
{
trigger_error('bencode error: wrong data type', E_USER_ERROR);
}
}
function array_deep (&$var, $fn, $one_dimensional = false, $array_only = false)
{
if (is_array($var))
{
foreach ($var as $k => $v)
{
if (is_array($v))
{
if ($one_dimensional)
{
unset($var[$k]);
}
else if ($array_only)
{
$var[$k] = $fn($v);
}
else
{
array_deep($var[$k], $fn);
}
}
else if (!$array_only)
{
$var[$k] = $fn($v);
}
}
}
else if (!$array_only)
{
$var = $fn($var);
}
}
function hide_bb_path ($path)
{
return ltrim(str_replace(BB_PATH, '', $path), '/\\');
}
function sys ($param)
{
switch ($param)
{
case 'la':
return function_exists('sys_getloadavg') ? join(' ', sys_getloadavg()) : 0;
break;
case 'mem':
return function_exists('memory_get_usage') ? memory_get_usage() : 0;
break;
case 'mem_peak':
return function_exists('memory_get_peak_usage') ? memory_get_peak_usage() : 0;
break;
default:
trigger_error("invalid param: $param", E_USER_ERROR);
}
}
function ver_compare ($version1, $operator, $version2)
{
return version_compare($version1, $version2, $operator);
}
function dbg_log ($str, $file)
{
$dir = LOG_DIR . (defined('IN_TRACKER') ? 'dbg_tr/' : 'dbg_bb/') . date('m-d_H') .'/';
return file_write($str, $dir . $file, false, false);
}
function log_get ($file = '', $prepend_str = false)
{
log_request($file, $prepend_str, false);
}
function log_post ($file = '', $prepend_str = false)
{
log_request($file, $prepend_str, true);
}
function log_request ($file = '', $prepend_str = false, $add_post = true)
{
global $user;
$file = ($file) ? $file : 'req/'. date('m-d');
$str = array();
$str[] = date('m-d H:i:s');
if ($prepend_str !== false) $str[] = $prepend_str;
if (!empty($user->data)) $str[] = $user->id ."\t". html_entity_decode($user->name);
$str[] = sprintf('%-15s', $_SERVER['REMOTE_ADDR']);
if (isset($_SERVER['REQUEST_URI'])) {
$str[] = $_SERVER['REQUEST_URI'];
}
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$str[] = $_SERVER['HTTP_USER_AGENT'];
}
if (isset($_SERVER['HTTP_REFERER'])) {
$str[] = $_SERVER['HTTP_REFERER'];
}
if (!empty($_POST) && $add_post) $str[] = "post: ". str_compact(urldecode(http_build_query($_POST)));
$str = join("\t", $str) . "\n";
bb_log($str, $file);
}
// Board init
if (defined('IN_FORUM'))
{
require(INC_DIR .'init_bb.php');
}
// Tracker init
else if (defined('IN_TRACKER'))
{
define('DUMMY_PEER', pack('Nn', ip2long($_SERVER['REMOTE_ADDR']), !empty($_GET['port']) ? intval($_GET['port']) : mt_rand(1000, 65000)));
function dummy_exit ($interval = 1800)
{
$output = bencode(array(
'interval' => (int) $interval,
'min interval' => (int) $interval,
'peers' => (string) DUMMY_PEER,
));
die($output);
}
header('Content-Type: text/plain');
header('Pragma: no-cache');
if (!defined('IN_ADMIN'))
{
// Exit if tracker is disabled via ON/OFF trigger
if (file_exists(BB_DISABLED))
{
dummy_exit(mt_rand(60, 2400));
}
}
}

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Before After
Before After

View file

@ -207,7 +207,7 @@ else
{ {
global $template; global $template;
$redirect_url = !empty($_POST['redirect_url']) ? $_POST['redirect_url'] : @$_SERVER['HTTP_REFERER']; $redirect_url = isset($_POST['redirect_url']) ? $_POST['redirect_url'] : (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/');
$message = '<form action="'. DOWNLOAD_URL . $attachment['attach_id'] .'" method="post">'; $message = '<form action="'. DOWNLOAD_URL . $attachment['attach_id'] .'" method="post">';
$message .= $lang['CONFIRM_CODE']; $message .= $lang['CONFIRM_CODE'];
$message .= '<div class="mrg_10">'. CAPTCHA()->get_html() .'</div>'; $message .= '<div class="mrg_10">'. CAPTCHA()->get_html() .'</div>';

View file

@ -5,9 +5,9 @@ define('BB_SCRIPT', 'dl_list');
define('BB_ROOT', './'); define('BB_ROOT', './');
require(BB_ROOT .'common.php'); require(BB_ROOT .'common.php');
$forum_id = (@$_REQUEST[POST_FORUM_URL]) ? (int) $_REQUEST[POST_FORUM_URL] : 0; $forum_id = isset($_REQUEST[POST_FORUM_URL]) ? (int) $_REQUEST[POST_FORUM_URL] : 0;
$topic_id = (@$_REQUEST[POST_TOPIC_URL]) ? (int) $_REQUEST[POST_TOPIC_URL] : 0; $topic_id = isset($_REQUEST[POST_TOPIC_URL]) ? (int) $_REQUEST[POST_TOPIC_URL] : 0;
$mode = (@$_REQUEST['mode']) ? (string) $_REQUEST['mode'] : ''; $mode = isset($_REQUEST['mode']) ? (string) $_REQUEST['mode'] : '';
$confirmed = isset($_POST['confirm']); $confirmed = isset($_POST['confirm']);
// Get new DL-status // Get new DL-status
@ -40,9 +40,9 @@ if ($mode == 'set_dl_status' || $mode == 'set_topics_dl_status')
} }
// Define redirect URL // Define redirect URL
$full_url = (@$_POST['full_url']) ? str_replace('&amp;', '&', htmlspecialchars($_POST['full_url'])) : ''; $full_url = isset($_POST['full_url']) ? str_replace('&amp;', '&', htmlspecialchars($_POST['full_url'])) : '';
if (@$_POST['redirect_type'] == 'search') if (isset($_POST['redirect_type']) && $_POST['redirect_type'] == 'search')
{ {
$redirect_type = "search.php"; $redirect_type = "search.php";
$redirect = ($full_url) ? $full_url : "$dl_key=1"; $redirect = ($full_url) ? $full_url : "$dl_key=1";
@ -65,7 +65,7 @@ if (!$userdata['session_logged_in'])
} }
// Check if user did not confirm // Check if user did not confirm
if (@$_POST['cancel']) if (isset($_POST['cancel']) && $_POST['cancel'])
{ {
redirect("$redirect_type?$redirect"); redirect("$redirect_type?$redirect");
} }

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

View file

@ -7,9 +7,9 @@ require(BB_ROOT .'common.php');
$user->session_start(array('req_login' => true)); $user->session_start(array('req_login' => true));
$mode = (string) @$_REQUEST['mode']; $mode = isset($_REQUEST['mode']) ? $_REQUEST['mode'] : '';
$type = (string) @$_POST['type']; $type = isset($_POST['type']) ? $_POST['type'] : '';
$id = (int) @$_POST['id']; $id = isset($_POST['id']) ? $_POST['id'] : 0;
$timecheck = TIMENOW - 600; $timecheck = TIMENOW - 600;
if (!$mode) bb_simple_die($lang['ATOM_NO_MODE']); if (!$mode) bb_simple_die($lang['ATOM_NO_MODE']);

View file

@ -188,7 +188,7 @@ if (!$group_id)
else bb_die($lang['NO_GROUPS_EXIST']); else bb_die($lang['NO_GROUPS_EXIST']);
} }
} }
else if (@$_POST['joingroup']) else if (isset($_POST['joingroup']) && $_POST['joingroup'])
{ {
if ($group_info['group_type'] != GROUP_OPEN) if ($group_info['group_type'] != GROUP_OPEN)
{ {
@ -263,7 +263,7 @@ else
if (!empty($_POST['add'])) if (!empty($_POST['add']))
{ {
if (!$row = get_userdata(@$_POST['username'], true)) if (isset($_POST['username']) && !($row = get_userdata($_POST['username'], true)))
{ {
bb_die($lang['COULD_NOT_ADD_USER']); bb_die($lang['COULD_NOT_ADD_USER']);
} }

View file

@ -78,6 +78,7 @@ if ($is_moderator)
'GROUP_DESCRIPTION' => htmlCHR($group_info['group_description']), 'GROUP_DESCRIPTION' => htmlCHR($group_info['group_description']),
'GROUP_SIGNATURE' => htmlCHR($group_info['group_signature']), 'GROUP_SIGNATURE' => htmlCHR($group_info['group_signature']),
'U_GROUP_URL' => GROUP_URL . $group_id, 'U_GROUP_URL' => GROUP_URL . $group_id,
'RELEASE_GROUP' => ($group_info['release_group']) ? true : false,
'GROUP_TYPE' => $group_type, 'GROUP_TYPE' => $group_type,
'S_GROUP_OPEN_TYPE' => GROUP_OPEN, 'S_GROUP_OPEN_TYPE' => GROUP_OPEN,
'S_GROUP_CLOSED_TYPE' => GROUP_CLOSED, 'S_GROUP_CLOSED_TYPE' => GROUP_CLOSED,
@ -89,9 +90,7 @@ if ($is_moderator)
'S_GROUP_CONFIG_ACTION' => "group_edit.php?" . POST_GROUPS_URL . "=$group_id", 'S_GROUP_CONFIG_ACTION' => "group_edit.php?" . POST_GROUPS_URL . "=$group_id",
'AVATAR_EXPLAIN' => sprintf($lang['AVATAR_EXPLAIN'], $bb_cfg['group_avatars']['max_width'], $bb_cfg['group_avatars']['max_height'], (round($bb_cfg['group_avatars']['max_size'] / 1024))), 'AVATAR_EXPLAIN' => sprintf($lang['AVATAR_EXPLAIN'], $bb_cfg['group_avatars']['max_width'], $bb_cfg['group_avatars']['max_height'], (round($bb_cfg['group_avatars']['max_size'] / 1024))),
'AVATAR_URL_PATH' => ($group_info['avatar_ext_id']) ? get_avatar_path(GROUP_AVATAR_MASK . $group_id, $group_info['avatar_ext_id']) : '', 'AVATAR_IMG' => get_avatar(GROUP_AVATAR_MASK . $group_id, $group_info['avatar_ext_id']),
'RELEASE_GROUP' => ($group_info['release_group']) ? true : false,
)); ));
$template->set_filenames(array('body' => 'group_edit.tpl')); $template->set_filenames(array('body' => 'group_edit.tpl'));

View file

@ -373,15 +373,14 @@ if ($bb_cfg['birthday_check_day'] && $bb_cfg['birthday_enabled'])
if ($stats['birthday_week_list']) if ($stats['birthday_week_list'])
{ {
shuffle($stats['birthday_week_list']); shuffle($stats['birthday_week_list']);
foreach($stats['birthday_week_list'] as $i => $week) foreach ($stats['birthday_week_list'] as $i => $week)
{ {
if($i >= 5) if ($i >= 5)
{ {
$week_all = true; $week_all = true;
continue; continue;
} }
$week_list[] = profile_url($week) .' <span class="small">('. birthday_age($week['user_birthday']-1) .')</span>';
$week_list[] = profile_url($week) .' <span class="small">('. birthday_age($week['user_birthday']) .')</span>';
} }
$week_all = ($week_all) ? '&nbsp;<a class="txtb" href="#" onclick="ajax.exec({action: \'index_data\', mode: \'birthday_week\'}); return false;" title="'. $lang['ALL'] .'">...</a>' : ''; $week_all = ($week_all) ? '&nbsp;<a class="txtb" href="#" onclick="ajax.exec({action: \'index_data\', mode: \'birthday_week\'}); return false;" title="'. $lang['ALL'] .'">...</a>' : '';
$week_list = sprintf($lang['BIRTHDAY_WEEK'], $bb_cfg['birthday_check_day'], join(', ', $week_list)) . $week_all; $week_list = sprintf($lang['BIRTHDAY_WEEK'], $bb_cfg['birthday_check_day'], join(', ', $week_list)) . $week_all;
@ -391,14 +390,13 @@ if ($bb_cfg['birthday_check_day'] && $bb_cfg['birthday_enabled'])
if ($stats['birthday_today_list']) if ($stats['birthday_today_list'])
{ {
shuffle($stats['birthday_today_list']); shuffle($stats['birthday_today_list']);
foreach($stats['birthday_today_list'] as $i => $today) foreach ($stats['birthday_today_list'] as $i => $today)
{ {
if($i >= 5) if ($i >= 5)
{ {
$today_all = true; $today_all = true;
continue; continue;
} }
$today_list[] = profile_url($today) .' <span class="small">('. birthday_age($today['user_birthday']) .')</span>'; $today_list[] = profile_url($today) .' <span class="small">('. birthday_age($today['user_birthday']) .')</span>';
} }
$today_all = ($today_all) ? '&nbsp;<a class="txtb" href="#" onclick="ajax.exec({action: \'index_data\', mode: \'birthday_today\'}); return false;" title="'. $lang['ALL'] .'">...</a>' : ''; $today_all = ($today_all) ? '&nbsp;<a class="txtb" href="#" onclick="ajax.exec({action: \'index_data\', mode: \'birthday_today\'}); return false;" title="'. $lang['ALL'] .'">...</a>' : '';

View file

@ -46,7 +46,7 @@ $require = file_exists($html_dir . $info['src']) ? $html_dir . $info['src'] : $h
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Style-Type" content="text/css" /> <meta http-equiv="Content-Style-Type" content="text/css" />
<link rel="stylesheet" href="./styles/templates/default/css/main.css" type="text/css"> <link rel="stylesheet" href="styles/templates/default/css/main.css" type="text/css">
</head> </head>
<body> <body>
<style type="text/css"> <style type="text/css">

View file

@ -59,4 +59,4 @@ unset($res, $user, $dbpasswd, $passkey, $user_id);
// Execute TP's announce // Execute TP's announce
chdir(TP_ROOT .'bt/'); chdir(TP_ROOT .'bt/');
require ('announce.php'); require('announce.php');

View file

@ -3,9 +3,9 @@
define ('IN_FORUM', true); define ('IN_FORUM', true);
define ('BB_ROOT', './'); define ('BB_ROOT', './');
require (BB_ROOT .'common.php'); require (BB_ROOT .'common.php');
require (BB_ROOT .'converter/constants.php'); require(BB_ROOT . 'converter/constants.php');
require (BB_ROOT .'converter/settings.php'); require(BB_ROOT . 'converter/settings.php');
require (BB_ROOT .'converter/functions.php'); require(BB_ROOT . 'converter/functions.php');
// Start session management // Start session management
$user->session_start(); $user->session_start();

View file

@ -4,8 +4,8 @@ define('IN_FORUM', true);
define('BB_ROOT', './'); define('BB_ROOT', './');
require(BB_ROOT .'common.php'); require(BB_ROOT .'common.php');
require(INC_DIR .'functions_torrent.php'); require(INC_DIR .'functions_torrent.php');
require(BB_ROOT .'converter/settings.php'); require(BB_ROOT . 'converter/settings.php');
require(BB_ROOT .'converter/functions.php'); require(BB_ROOT . 'converter/functions.php');
// Init userdata // Init userdata
$user->session_start(); $user->session_start();

View file

@ -4,8 +4,8 @@ define('IN_FORUM', true);
define('BB_ROOT', './'); define('BB_ROOT', './');
require(BB_ROOT .'common.php'); require(BB_ROOT .'common.php');
require(INC_DIR .'functions_torrent.php'); require(INC_DIR .'functions_torrent.php');
require(BB_ROOT .'converter/settings.php'); require(BB_ROOT . 'converter/settings.php');
require(BB_ROOT .'converter/functions.php'); require(BB_ROOT . 'converter/functions.php');
// Init userdata // Init userdata
$user->session_start(); $user->session_start();

View file

@ -1,5 +1,5 @@
user www www; user www www;
worker_processes 4; worker_processes auto;
#error_log /var/log/nginx/error.log; #error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice; #error_log /var/log/nginx/error.log notice;
@ -69,14 +69,13 @@ http {
location / { location / {
root /var/www; root /var/www;
index index.html index.htm index.php; index index.php index.html index.htm;
} }
error_page 404 /404.html; error_page 404 /404.html;
error_page 500 502 503 504 /50x.html; error_page 500 502 503 504 /50x.html;
# pass the PHP scripts to FastCGI server listening on /tmp/php.sock; # pass the PHP scripts to FastCGI server listening on /tmp/php.sock
#
location ~ \.php$ { location ~ \.php$ {
#limit_req zone=one burst=20 nodelay; #limit_req zone=one burst=20 nodelay;
#limit_req_log_level info; #limit_req_log_level info;
@ -97,7 +96,7 @@ http {
include fastcgi_params; include fastcgi_params;
} }
# Old XBTT config # rewrite to XBTT (old)
# location ^~ /bt/ { # location ^~ /bt/ {
# access_log off; # access_log off;
# if ( $query_string ~ "^uk=([^&?]{10})[&?]+(.*)$" ) { # if ( $query_string ~ "^uk=([^&?]{10})[&?]+(.*)$" ) {
@ -115,7 +114,7 @@ http {
# proxy_pass http://127.0.0.1:2710/; # proxy_pass http://127.0.0.1:2710/;
# } # }
# Cached Images # cache static files
location ~* \.(jpg|jpeg|gif|png|css|js|ico)$ { location ~* \.(jpg|jpeg|gif|png|css|js|ico)$ {
root /var/www; root /var/www;
access_log off; access_log off;
@ -123,25 +122,32 @@ http {
add_header Cache-Control public; add_header Cache-Control public;
} }
# sitemap rewrite
rewrite ^/sitemap.xml$ /internal_data/sitemap/sitemap.xml;
# deny access to admin folder
location ~ \/admin|backup\/ { location ~ \/admin|backup\/ {
deny all; deny all;
#allow YOUR_IP; #allow YOUR_IP;
} }
# Deny folder (Sec. lvl1)
location ~ \/(internal_data|library)\/ { # deny access to system folder
location ~ \/(install|internal_data|library)\/ {
deny all; deny all;
} }
# sitemap rewrite # deny access to git folder
rewrite ^/sitemap.xml$ /internal_data/sitemap/sitemap.xml; location ~ /\.git {
deny all;
}
# deny access to .htaccess files, if Apache's document root # deny access to .htaccess, if apache's document root concurs with nginx's one
# concurs with nginx's one
# deny sql,tpl,db,inc,log
location ~ /\.ht { location ~ /\.ht {
deny all; deny all;
} }
location ~ \.(.*sql|tpl|db|inc|log)$ {
# deny access to critical files
location ~ \.(.*sql|tpl|db|inc|log|md)$ {
deny all; deny all;
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -1,25 +1,18 @@
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; SET SQL_MODE = "";
--
-- Удаление старых таблиц
--
-- ----------------------------
-- Table structure for `bb_bt_tracker`
-- ----------------------------
DROP TABLE IF EXISTS `bb_bt_tracker`; DROP TABLE IF EXISTS `bb_bt_tracker`;
DROP TABLE IF EXISTS `bb_bt_tracker_snap`;
--
-- Структура таблицы `bb_bt_tracker`
--
CREATE TABLE IF NOT EXISTS `bb_bt_tracker` ( CREATE TABLE IF NOT EXISTS `bb_bt_tracker` (
`peer_hash` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `peer_hash` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`topic_id` mediumint(8) unsigned NOT NULL DEFAULT '0', `topic_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
`peer_id` varchar(20) NOT NULL, `peer_id` varchar(20) NOT NULL,
`user_id` mediumint(9) NOT NULL DEFAULT '0', `user_id` mediumint(9) NOT NULL DEFAULT '0',
`ip` varchar(15) NOT NULL DEFAULT '0', `ip` varchar(15) NOT NULL DEFAULT '0',
`client` varchar(51) NOT NULL DEFAULT 'Unknown',
`ipv6` varchar(32) DEFAULT NULL, `ipv6` varchar(32) DEFAULT NULL,
`port` smallint(5) unsigned NOT NULL DEFAULT '0', `port` smallint(5) unsigned NOT NULL DEFAULT '0',
`client` varchar(51) NOT NULL DEFAULT 'Unknown',
`seeder` tinyint(1) NOT NULL DEFAULT '0', `seeder` tinyint(1) NOT NULL DEFAULT '0',
`releaser` tinyint(1) NOT NULL DEFAULT '0', `releaser` tinyint(1) NOT NULL DEFAULT '0',
`tor_type` tinyint(1) NOT NULL DEFAULT '0', `tor_type` tinyint(1) NOT NULL DEFAULT '0',
@ -37,18 +30,24 @@ CREATE TABLE IF NOT EXISTS `bb_bt_tracker` (
KEY `user_id` (`user_id`) KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- -------------------------------------------------------- -- ----------------------------
-- Records of bb_bt_tracker
-- -- ----------------------------
-- Структура таблицы `bb_bt_tracker_snap`
--
-- ----------------------------
-- Table structure for `bb_bt_tracker_snap`
-- ----------------------------
DROP TABLE IF EXISTS `bb_bt_tracker_snap`;
CREATE TABLE IF NOT EXISTS `bb_bt_tracker_snap` ( CREATE TABLE IF NOT EXISTS `bb_bt_tracker_snap` (
`topic_id` mediumint(8) unsigned NOT NULL DEFAULT '0', `topic_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
`seeders` mediumint(8) unsigned NOT NULL DEFAULT '0', `seeders` mediumint(8) unsigned NOT NULL DEFAULT '0',
`leechers` mediumint(8) unsigned NOT NULL DEFAULT '0', `leechers` mediumint(8) unsigned NOT NULL DEFAULT '0',
`speed_up` int(10) unsigned NOT NULL DEFAULT '0', `speed_up` int(10) unsigned NOT NULL DEFAULT '0',
`speed_down` int(10) unsigned NOT NULL DEFAULT '0', `speed_down` int(10) unsigned NOT NULL DEFAULT '0',
`complete` int(11) NOT NULL, `complete` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`topic_id`) PRIMARY KEY (`topic_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of bb_bt_tracker_snap
-- ----------------------------

View file

View file

@ -0,0 +1,71 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Authentication\Adapter;
abstract class AbstractAdapter implements ValidatableAdapterInterface
{
/**
* @var mixed
*/
protected $credential;
/**
* @var mixed
*/
protected $identity;
/**
* Returns the credential of the account being authenticated, or
* NULL if none is set.
*
* @return mixed
*/
public function getCredential()
{
return $this->credential;
}
/**
* Sets the credential for binding
*
* @param mixed $credential
* @return AbstractAdapter
*/
public function setCredential($credential)
{
$this->credential = $credential;
return $this;
}
/**
* Returns the identity of the account being authenticated, or
* NULL if none is set.
*
* @return mixed
*/
public function getIdentity()
{
return $this->identity;
}
/**
* Sets the identity for binding
*
* @param mixed $identity
* @return AbstractAdapter
*/
public function setIdentity($identity)
{
$this->identity = $identity;
return $this;
}
}

View file

@ -0,0 +1,21 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Authentication\Adapter;
interface AdapterInterface
{
/**
* Performs an authentication attempt
*
* @return \Zend\Authentication\Result
* @throws \Zend\Authentication\Adapter\Exception\ExceptionInterface If authentication cannot be performed
*/
public function authenticate();
}

View file

@ -0,0 +1,17 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Authentication\Adapter;
/**
* @deprecated
*/
class DbTable extends DbTable\CredentialTreatmentAdapter
{
}

View file

@ -0,0 +1,378 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Authentication\Adapter\DbTable;
use stdClass;
use Zend\Authentication\Result as AuthenticationResult;
use Zend\Authentication\Adapter\AbstractAdapter as BaseAdapter;
use Zend\Db\Adapter\Adapter as DbAdapter;
use Zend\Db\Sql;
abstract class AbstractAdapter extends BaseAdapter
{
/**
* Database Connection
*
* @var DbAdapter
*/
protected $zendDb = null;
/**
* @var Sql\Select
*/
protected $dbSelect = null;
/**
* $tableName - the table name to check
*
* @var string
*/
protected $tableName = null;
/**
* $identityColumn - the column to use as the identity
*
* @var string
*/
protected $identityColumn = null;
/**
* $credentialColumns - columns to be used as the credentials
*
* @var string
*/
protected $credentialColumn = null;
/**
* $authenticateResultInfo
*
* @var array
*/
protected $authenticateResultInfo = null;
/**
* $resultRow - Results of database authentication query
*
* @var array
*/
protected $resultRow = null;
/**
* $ambiguityIdentity - Flag to indicate same Identity can be used with
* different credentials. Default is FALSE and need to be set to true to
* allow ambiguity usage.
*
* @var bool
*/
protected $ambiguityIdentity = false;
/**
* __construct() - Sets configuration options
*
* @param DbAdapter $zendDb
* @param string $tableName Optional
* @param string $identityColumn Optional
* @param string $credentialColumn Optional
*/
public function __construct(
DbAdapter $zendDb,
$tableName = null,
$identityColumn = null,
$credentialColumn = null
) {
$this->zendDb = $zendDb;
if (null !== $tableName) {
$this->setTableName($tableName);
}
if (null !== $identityColumn) {
$this->setIdentityColumn($identityColumn);
}
if (null !== $credentialColumn) {
$this->setCredentialColumn($credentialColumn);
}
}
/**
* setTableName() - set the table name to be used in the select query
*
* @param string $tableName
* @return self Provides a fluent interface
*/
public function setTableName($tableName)
{
$this->tableName = $tableName;
return $this;
}
/**
* setIdentityColumn() - set the column name to be used as the identity column
*
* @param string $identityColumn
* @return self Provides a fluent interface
*/
public function setIdentityColumn($identityColumn)
{
$this->identityColumn = $identityColumn;
return $this;
}
/**
* setCredentialColumn() - set the column name to be used as the credential column
*
* @param string $credentialColumn
* @return self Provides a fluent interface
*/
public function setCredentialColumn($credentialColumn)
{
$this->credentialColumn = $credentialColumn;
return $this;
}
/**
* setAmbiguityIdentity() - sets a flag for usage of identical identities
* with unique credentials. It accepts integers (0, 1) or boolean (true,
* false) parameters. Default is false.
*
* @param int|bool $flag
* @return self Provides a fluent interface
*/
public function setAmbiguityIdentity($flag)
{
if (is_int($flag)) {
$this->ambiguityIdentity = (1 === $flag ? true : false);
} elseif (is_bool($flag)) {
$this->ambiguityIdentity = $flag;
}
return $this;
}
/**
* getAmbiguityIdentity() - returns TRUE for usage of multiple identical
* identities with different credentials, FALSE if not used.
*
* @return bool
*/
public function getAmbiguityIdentity()
{
return $this->ambiguityIdentity;
}
/**
* getDbSelect() - Return the preauthentication Db Select object for userland select query modification
*
* @return Sql\Select
*/
public function getDbSelect()
{
if ($this->dbSelect == null) {
$this->dbSelect = new Sql\Select();
}
return $this->dbSelect;
}
/**
* getResultRowObject() - Returns the result row as a stdClass object
*
* @param string|array $returnColumns
* @param string|array $omitColumns
* @return stdClass|bool
*/
public function getResultRowObject($returnColumns = null, $omitColumns = null)
{
if (!$this->resultRow) {
return false;
}
$returnObject = new stdClass();
if (null !== $returnColumns) {
$availableColumns = array_keys($this->resultRow);
foreach ((array) $returnColumns as $returnColumn) {
if (in_array($returnColumn, $availableColumns)) {
$returnObject->{$returnColumn} = $this->resultRow[$returnColumn];
}
}
return $returnObject;
} elseif (null !== $omitColumns) {
$omitColumns = (array) $omitColumns;
foreach ($this->resultRow as $resultColumn => $resultValue) {
if (!in_array($resultColumn, $omitColumns)) {
$returnObject->{$resultColumn} = $resultValue;
}
}
return $returnObject;
}
foreach ($this->resultRow as $resultColumn => $resultValue) {
$returnObject->{$resultColumn} = $resultValue;
}
return $returnObject;
}
/**
* This method is called to attempt an authentication. Previous to this
* call, this adapter would have already been configured with all
* necessary information to successfully connect to a database table and
* attempt to find a record matching the provided identity.
*
* @throws Exception\RuntimeException if answering the authentication query is impossible
* @return AuthenticationResult
*/
public function authenticate()
{
$this->authenticateSetup();
$dbSelect = $this->authenticateCreateSelect();
$resultIdentities = $this->authenticateQuerySelect($dbSelect);
if (($authResult = $this->authenticateValidateResultSet($resultIdentities)) instanceof AuthenticationResult) {
return $authResult;
}
// At this point, ambiguity is already done. Loop, check and break on success.
foreach ($resultIdentities as $identity) {
$authResult = $this->authenticateValidateResult($identity);
if ($authResult->isValid()) {
break;
}
}
return $authResult;
}
/**
* _authenticateValidateResult() - This method attempts to validate that
* the record in the resultset is indeed a record that matched the
* identity provided to this adapter.
*
* @param array $resultIdentity
* @return AuthenticationResult
*/
abstract protected function authenticateValidateResult($resultIdentity);
/**
* _authenticateCreateSelect() - This method creates a Zend\Db\Sql\Select object that
* is completely configured to be queried against the database.
*
* @return Sql\Select
*/
abstract protected function authenticateCreateSelect();
/**
* _authenticateSetup() - This method abstracts the steps involved with
* making sure that this adapter was indeed setup properly with all
* required pieces of information.
*
* @throws Exception\RuntimeException in the event that setup was not done properly
* @return bool
*/
protected function authenticateSetup()
{
$exception = null;
if ($this->tableName == '') {
$exception = 'A table must be supplied for the DbTable authentication adapter.';
} elseif ($this->identityColumn == '') {
$exception = 'An identity column must be supplied for the DbTable authentication adapter.';
} elseif ($this->credentialColumn == '') {
$exception = 'A credential column must be supplied for the DbTable authentication adapter.';
} elseif ($this->identity == '') {
$exception = 'A value for the identity was not provided prior to authentication with DbTable.';
} elseif ($this->credential === null) {
$exception = 'A credential value was not provided prior to authentication with DbTable.';
}
if (null !== $exception) {
throw new Exception\RuntimeException($exception);
}
$this->authenticateResultInfo = array(
'code' => AuthenticationResult::FAILURE,
'identity' => $this->identity,
'messages' => array()
);
return true;
}
/**
* _authenticateQuerySelect() - This method accepts a Zend\Db\Sql\Select object and
* performs a query against the database with that object.
*
* @param Sql\Select $dbSelect
* @throws Exception\RuntimeException when an invalid select object is encountered
* @return array
*/
protected function authenticateQuerySelect(Sql\Select $dbSelect)
{
$sql = new Sql\Sql($this->zendDb);
$statement = $sql->prepareStatementForSqlObject($dbSelect);
try {
$result = $statement->execute();
$resultIdentities = array();
// iterate result, most cross platform way
foreach ($result as $row) {
// ZF-6428 - account for db engines that by default return uppercase column names
if (isset($row['ZEND_AUTH_CREDENTIAL_MATCH'])) {
$row['zend_auth_credential_match'] = $row['ZEND_AUTH_CREDENTIAL_MATCH'];
unset($row['ZEND_AUTH_CREDENTIAL_MATCH']);
}
$resultIdentities[] = $row;
}
} catch (\Exception $e) {
throw new Exception\RuntimeException(
'The supplied parameters to DbTable failed to '
. 'produce a valid sql statement, please check table and column names '
. 'for validity.',
0,
$e
);
}
return $resultIdentities;
}
/**
* _authenticateValidateResultSet() - This method attempts to make
* certain that only one record was returned in the resultset
*
* @param array $resultIdentities
* @return bool|\Zend\Authentication\Result
*/
protected function authenticateValidateResultSet(array $resultIdentities)
{
if (count($resultIdentities) < 1) {
$this->authenticateResultInfo['code'] = AuthenticationResult::FAILURE_IDENTITY_NOT_FOUND;
$this->authenticateResultInfo['messages'][] = 'A record with the supplied identity could not be found.';
return $this->authenticateCreateAuthResult();
} elseif (count($resultIdentities) > 1 && false === $this->getAmbiguityIdentity()) {
$this->authenticateResultInfo['code'] = AuthenticationResult::FAILURE_IDENTITY_AMBIGUOUS;
$this->authenticateResultInfo['messages'][] = 'More than one record matches the supplied identity.';
return $this->authenticateCreateAuthResult();
}
return true;
}
/**
* Creates a Zend\Authentication\Result object from the information that
* has been collected during the authenticate() attempt.
*
* @return AuthenticationResult
*/
protected function authenticateCreateAuthResult()
{
return new AuthenticationResult(
$this->authenticateResultInfo['code'],
$this->authenticateResultInfo['identity'],
$this->authenticateResultInfo['messages']
);
}
}

View file

@ -0,0 +1,117 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Authentication\Adapter\DbTable;
use Zend\Authentication\Result as AuthenticationResult;
use Zend\Db\Adapter\Adapter as DbAdapter;
use Zend\Db\Sql;
use Zend\Db\Sql\Predicate\Operator as SqlOp;
class CallbackCheckAdapter extends AbstractAdapter
{
/**
* $credentialValidationCallback - This overrides the Treatment usage to provide a callback
* that allows for validation to happen in code
*
* @var callable
*/
protected $credentialValidationCallback = null;
/**
* __construct() - Sets configuration options
*
* @param DbAdapter $zendDb
* @param string $tableName Optional
* @param string $identityColumn Optional
* @param string $credentialColumn Optional
* @param callable $credentialValidationCallback Optional
*/
public function __construct(
DbAdapter $zendDb,
$tableName = null,
$identityColumn = null,
$credentialColumn = null,
$credentialValidationCallback = null
) {
parent::__construct($zendDb, $tableName, $identityColumn, $credentialColumn);
if (null !== $credentialValidationCallback) {
$this->setCredentialValidationCallback($credentialValidationCallback);
} else {
$this->setCredentialValidationCallback(function ($a, $b) {
return $a === $b;
});
}
}
/**
* setCredentialValidationCallback() - allows the developer to use a callback as a way of checking the
* credential.
*
* @param callable $validationCallback
* @return self
* @throws Exception\InvalidArgumentException
*/
public function setCredentialValidationCallback($validationCallback)
{
if (!is_callable($validationCallback)) {
throw new Exception\InvalidArgumentException('Invalid callback provided');
}
$this->credentialValidationCallback = $validationCallback;
return $this;
}
/**
* _authenticateCreateSelect() - This method creates a Zend\Db\Sql\Select object that
* is completely configured to be queried against the database.
*
* @return Sql\Select
*/
protected function authenticateCreateSelect()
{
// get select
$dbSelect = clone $this->getDbSelect();
$dbSelect->from($this->tableName)
->columns(array(Sql\Select::SQL_STAR))
->where(new SqlOp($this->identityColumn, '=', $this->identity));
return $dbSelect;
}
/**
* _authenticateValidateResult() - This method attempts to validate that
* the record in the resultset is indeed a record that matched the
* identity provided to this adapter.
*
* @param array $resultIdentity
* @return AuthenticationResult
*/
protected function authenticateValidateResult($resultIdentity)
{
try {
$callbackResult = call_user_func($this->credentialValidationCallback, $resultIdentity[$this->credentialColumn], $this->credential);
} catch (\Exception $e) {
$this->authenticateResultInfo['code'] = AuthenticationResult::FAILURE_UNCATEGORIZED;
$this->authenticateResultInfo['messages'][] = $e->getMessage();
return $this->authenticateCreateAuthResult();
}
if ($callbackResult !== true) {
$this->authenticateResultInfo['code'] = AuthenticationResult::FAILURE_CREDENTIAL_INVALID;
$this->authenticateResultInfo['messages'][] = 'Supplied credential is invalid.';
return $this->authenticateCreateAuthResult();
}
$this->resultRow = $resultIdentity;
$this->authenticateResultInfo['code'] = AuthenticationResult::SUCCESS;
$this->authenticateResultInfo['messages'][] = 'Authentication successful.';
return $this->authenticateCreateAuthResult();
}
}

View file

@ -0,0 +1,124 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Authentication\Adapter\DbTable;
use Zend\Authentication\Result as AuthenticationResult;
use Zend\Db\Adapter\Adapter as DbAdapter;
use Zend\Db\Sql;
use Zend\Db\Sql\Expression as SqlExpr;
use Zend\Db\Sql\Predicate\Operator as SqlOp;
class CredentialTreatmentAdapter extends AbstractAdapter
{
/**
* $credentialTreatment - Treatment applied to the credential, such as MD5() or PASSWORD()
*
* @var string
*/
protected $credentialTreatment = null;
/**
* __construct() - Sets configuration options
*
* @param DbAdapter $zendDb
* @param string $tableName Optional
* @param string $identityColumn Optional
* @param string $credentialColumn Optional
* @param string $credentialTreatment Optional
*/
public function __construct(
DbAdapter $zendDb,
$tableName = null,
$identityColumn = null,
$credentialColumn = null,
$credentialTreatment = null
) {
parent::__construct($zendDb, $tableName, $identityColumn, $credentialColumn);
if (null !== $credentialTreatment) {
$this->setCredentialTreatment($credentialTreatment);
}
}
/**
* setCredentialTreatment() - allows the developer to pass a parametrized string that is
* used to transform or treat the input credential data.
*
* In many cases, passwords and other sensitive data are encrypted, hashed, encoded,
* obscured, or otherwise treated through some function or algorithm. By specifying a
* parametrized treatment string with this method, a developer may apply arbitrary SQL
* upon input credential data.
*
* Examples:
*
* 'PASSWORD(?)'
* 'MD5(?)'
*
* @param string $treatment
* @return self Provides a fluent interface
*/
public function setCredentialTreatment($treatment)
{
$this->credentialTreatment = $treatment;
return $this;
}
/**
* _authenticateCreateSelect() - This method creates a Zend\Db\Sql\Select object that
* is completely configured to be queried against the database.
*
* @return Sql\Select
*/
protected function authenticateCreateSelect()
{
// build credential expression
if (empty($this->credentialTreatment) || (strpos($this->credentialTreatment, '?') === false)) {
$this->credentialTreatment = '?';
}
$credentialExpression = new SqlExpr(
'(CASE WHEN ?' . ' = ' . $this->credentialTreatment . ' THEN 1 ELSE 0 END) AS ?',
array($this->credentialColumn, $this->credential, 'zend_auth_credential_match'),
array(SqlExpr::TYPE_IDENTIFIER, SqlExpr::TYPE_VALUE, SqlExpr::TYPE_IDENTIFIER)
);
// get select
$dbSelect = clone $this->getDbSelect();
$dbSelect->from($this->tableName)
->columns(array('*', $credentialExpression))
->where(new SqlOp($this->identityColumn, '=', $this->identity));
return $dbSelect;
}
/**
* _authenticateValidateResult() - This method attempts to validate that
* the record in the resultset is indeed a record that matched the
* identity provided to this adapter.
*
* @param array $resultIdentity
* @return AuthenticationResult
*/
protected function authenticateValidateResult($resultIdentity)
{
if ($resultIdentity['zend_auth_credential_match'] != '1') {
$this->authenticateResultInfo['code'] = AuthenticationResult::FAILURE_CREDENTIAL_INVALID;
$this->authenticateResultInfo['messages'][] = 'Supplied credential is invalid.';
return $this->authenticateCreateAuthResult();
}
unset($resultIdentity['zend_auth_credential_match']);
$this->resultRow = $resultIdentity;
$this->authenticateResultInfo['code'] = AuthenticationResult::SUCCESS;
$this->authenticateResultInfo['messages'][] = 'Authentication successful.';
return $this->authenticateCreateAuthResult();
}
}

View file

@ -0,0 +1,16 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Authentication\Adapter\DbTable\Exception;
use Zend\Authentication\Adapter\Exception\ExceptionInterface as Exception;
interface ExceptionInterface extends Exception
{
}

View file

@ -0,0 +1,16 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Authentication\Adapter\DbTable\Exception;
use Zend\Authentication\Adapter\Exception;
class InvalidArgumentException extends Exception\InvalidArgumentException implements ExceptionInterface
{
}

View file

@ -0,0 +1,17 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Zend\Authentication\Adapter\DbTable\Exception;
use Zend\Authentication\Adapter\Exception;
class RuntimeException extends Exception\RuntimeException implements
ExceptionInterface
{
}

Some files were not shown because too many files have changed in this diff Show more