r20160109
This commit is contained in:
parent
fe66f79693
commit
6eff64007f
14 changed files with 141 additions and 151 deletions
|
@ -11,49 +11,47 @@ namespace Sakura;
|
|||
*/
|
||||
class ActionCode
|
||||
{
|
||||
private $actions = []; // Contains the action methods
|
||||
private $code = null; // Contains the action code we're working with
|
||||
|
||||
// Constructor
|
||||
public function __construct($code = null)
|
||||
{
|
||||
// Populate $actions, sets $code (if not null)
|
||||
}
|
||||
|
||||
// Generating an action code
|
||||
public function generate($action, $instructions, $user = 0)
|
||||
public static function generate($action, $user = 0)
|
||||
{
|
||||
// Takes an action, specifies instructions and optionally adds a target user
|
||||
// stores this code in the database and assigns it to $this->code
|
||||
// This function should only work if $code is null
|
||||
}
|
||||
// Generate a code
|
||||
$code = uniqid();
|
||||
|
||||
// Execute the procedure for this action code
|
||||
public function execute()
|
||||
{
|
||||
// Looks for the code in the database and executes the procedure
|
||||
// This and all functions below should only work if $this->code isn't null for obvious reasons
|
||||
// Insert it
|
||||
Database::insert('actioncodes', [
|
||||
'code_action' => $action,
|
||||
'user_id' => $user,
|
||||
'action_code' => $code,
|
||||
]);
|
||||
|
||||
// Return the code
|
||||
return $code;
|
||||
}
|
||||
|
||||
// Checking if a code is still valid
|
||||
public function validate()
|
||||
public static function validate($action, $code, $user = 0, $invalidate = true)
|
||||
{
|
||||
// Checks if $this->code is still valid
|
||||
// Fetch the code from the db
|
||||
$get = Database::count('actioncodes', [
|
||||
'code_action' => [$action, '='],
|
||||
'action_code' => [$code, '='],
|
||||
'user_id' => [$user, '='],
|
||||
]);
|
||||
|
||||
// Invalidate the code if requested
|
||||
if ($invalidate) {
|
||||
self::invalidate($code);
|
||||
}
|
||||
|
||||
// Return the result
|
||||
return $get[0] > 0;
|
||||
}
|
||||
|
||||
// Make a code invalid
|
||||
public function invalidate()
|
||||
public static function invalidate($code)
|
||||
{
|
||||
// Invalidates the set action code
|
||||
Database::delete('actioncodes', [
|
||||
'code_action' => [$code, '='],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Concept
|
||||
* =======
|
||||
* Action codes are a thing to have the system or something related generate an
|
||||
* md5(?) hashed string that they can enter into a box and have the system respond
|
||||
* by doing something.
|
||||
* Said actions are stored in a database table and can be added, removed and
|
||||
* changed if needed. These actions will probably be stored using JSON.
|
||||
*/
|
||||
|
|
|
@ -33,7 +33,6 @@ class Post
|
|||
public $editTime = 0;
|
||||
public $editReason = "";
|
||||
public $editUser = [];
|
||||
private $_permissions;
|
||||
|
||||
// Constructor
|
||||
public function __construct($postId)
|
||||
|
@ -49,7 +48,6 @@ class Post
|
|||
$this->poster = User::construct($postRow['poster_id']);
|
||||
$this->ip = $postRow['poster_ip'];
|
||||
$this->time = $postRow['post_time'];
|
||||
$this->signature = $postRow['post_signature'];
|
||||
$this->subject = $postRow['post_subject'];
|
||||
$this->text = $postRow['post_text'];
|
||||
$this->editTime = $postRow['post_edit_time'];
|
||||
|
@ -91,7 +89,6 @@ class Post
|
|||
'poster_id' => $poster->id(),
|
||||
'poster_ip' => Main::getRemoteIP(),
|
||||
'post_time' => time(),
|
||||
'post_signature' => '1',
|
||||
'post_subject' => $subject,
|
||||
'post_text' => $text,
|
||||
]);
|
||||
|
@ -106,6 +103,43 @@ class Post
|
|||
return new Post($id);
|
||||
}
|
||||
|
||||
// Update a post
|
||||
public function update() {
|
||||
// Check if the data meets the requirements
|
||||
if (strlen($this->subject) < Config::get('forum_title_min')
|
||||
|| strlen($this->subject) > Config::get('forum_title_max')
|
||||
|| strlen($this->text) < Config::get('forum_text_min')
|
||||
|| strlen($this->text) > Config::get('forum_text_max')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create a thread object
|
||||
$thread = new Thread($this->thread);
|
||||
|
||||
// Update the post
|
||||
Database::update('posts', [
|
||||
[
|
||||
'post_id' => $this->id,
|
||||
'topic_id' => $thread->id,
|
||||
'forum_id' => $thread->forum,
|
||||
'poster_id' => $this->poster->id(),
|
||||
'poster_ip' => Main::getRemoteIP(),
|
||||
'post_time' => $this->time,
|
||||
'post_subject' => $this->subject,
|
||||
'post_text' => $this->text,
|
||||
'post_edit_time' => $this->editTime,
|
||||
'post_edit_reason' => $this->editReason,
|
||||
'post_edit_user' => $this->editUser->id(),
|
||||
],
|
||||
[
|
||||
'post_id' => [$this->id, '='],
|
||||
]
|
||||
]);
|
||||
|
||||
// Return a new post object
|
||||
return new Post($this->id);
|
||||
}
|
||||
|
||||
// Time elapsed since creation
|
||||
public function timeElapsed()
|
||||
{
|
||||
|
|
|
@ -510,64 +510,6 @@ class Main
|
|||
return 'XX';
|
||||
}
|
||||
|
||||
// Create a new action code
|
||||
public static function newActionCode($action, $userid, $instruct)
|
||||
{
|
||||
|
||||
// Make sure the user we're working with exists
|
||||
if (Users::getUser($userid)['id'] == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert the instruction array to a JSON
|
||||
$instruct = json_encode($instruct);
|
||||
|
||||
// Generate a key
|
||||
$key = sha1(date("r") . time() . $userid . $action . rand(0, 9999));
|
||||
|
||||
// Insert the key into the database
|
||||
Database::insert('actioncodes', [
|
||||
'action' => $action,
|
||||
'userid' => $userid,
|
||||
'actkey' => $key,
|
||||
'instruction' => $instruct,
|
||||
]);
|
||||
|
||||
// Return the key
|
||||
return $key;
|
||||
}
|
||||
|
||||
// Use an action code
|
||||
public static function useActionCode($action, $key, $uid = 0)
|
||||
{
|
||||
|
||||
// Retrieve the row from the database
|
||||
$keyRow = Database::fetch('actioncodes', false, [
|
||||
'actkey' => [$key, '='],
|
||||
'action' => [$action, '='],
|
||||
]);
|
||||
|
||||
// Check if the code exists
|
||||
if (count($keyRow) <= 1) {
|
||||
return [0, 'INVALID_CODE'];
|
||||
}
|
||||
|
||||
// Check if the code was intended for the user that's using this code
|
||||
if ($keyRow['userid'] != 0) {
|
||||
if ($keyRow['userid'] != $uid) {
|
||||
return [0, 'INVALID_USER'];
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the key from the database
|
||||
Database::delete('actioncodes', [
|
||||
'id' => [$keyRow['id'], '='],
|
||||
]);
|
||||
|
||||
// Return success
|
||||
return [1, 'SUCCESS', $keyRow['instruction']];
|
||||
}
|
||||
|
||||
// Calculate password entropy
|
||||
public static function pwdEntropy($pw)
|
||||
{
|
||||
|
|
|
@ -27,6 +27,14 @@ class Urls
|
|||
'/news.php?id=%u',
|
||||
'/news/%u',
|
||||
],
|
||||
'SITE_NEWS_CAT' => [
|
||||
'/news.php?cat=$s',
|
||||
'/news/%s',
|
||||
],
|
||||
'SITE_NEWS_CAT_POST' => [
|
||||
'/news.php?cat=$s&id=%u',
|
||||
'/news/%s/%u',
|
||||
],
|
||||
'SITE_SEARCH' => [
|
||||
'/search.php',
|
||||
'/search',
|
||||
|
|
|
@ -258,6 +258,11 @@ class Users
|
|||
return [0, 'INVALID_MX'];
|
||||
}
|
||||
|
||||
// Check if the e-mail has already been used
|
||||
if (Database::count('users', ['email' => [$email, '=']])[0] > 0) {
|
||||
return [0, 'EMAIL_EXISTS'];
|
||||
}
|
||||
|
||||
// Check password entropy
|
||||
if (Main::pwdEntropy($password) < Config::get('min_entropy')) {
|
||||
return [0, 'PASS_TOO_SHIT'];
|
||||
|
@ -317,11 +322,7 @@ class Users
|
|||
}
|
||||
|
||||
// Generate the verification key
|
||||
$verk = Main::newActionCode('LOST_PASS', $user['user_id'], [
|
||||
'meta' => [
|
||||
'password_change' => 1,
|
||||
],
|
||||
]);
|
||||
$verk = ActionCode::generate('LOST_PASS', $userObj->id());
|
||||
|
||||
// Create new urls object
|
||||
$urls = new Urls();
|
||||
|
@ -363,11 +364,11 @@ class Users
|
|||
}
|
||||
|
||||
// Check the verification key
|
||||
$action = Main::useActionCode('LOST_PASS', $verk, $uid);
|
||||
$action = ActionCode::validate('LOST_PASS', $verk, $uid);
|
||||
|
||||
// Check if we got a negative return
|
||||
if (!$action[0]) {
|
||||
return [0, $action[1]];
|
||||
if (!$action) {
|
||||
return [0, 'INVALID_CODE'];
|
||||
}
|
||||
|
||||
// Hash the password
|
||||
|
@ -442,12 +443,7 @@ class Users
|
|||
}
|
||||
|
||||
// Generate activation key
|
||||
$activate = ($customKey ? $customKey : Main::newActionCode('ACTIVATE', $user->id(), [
|
||||
'user' => [
|
||||
'rank_main' => 2,
|
||||
'user_ranks' => json_encode([2]),
|
||||
],
|
||||
]));
|
||||
$activate = ActionCode::generate('ACTIVATE', $user->id());
|
||||
|
||||
// Create new urls object
|
||||
$urls = new Urls();
|
||||
|
@ -495,37 +491,21 @@ class Users
|
|||
return [0, 'USER_ALREADY_ACTIVE'];
|
||||
}
|
||||
|
||||
// Set default values for activation
|
||||
$rank = 2;
|
||||
$ranks = json_encode([2]);
|
||||
|
||||
/* Check if a key is set (there's an option to not set one for user
|
||||
management reasons but you can't really get around this anyway) */
|
||||
// Check if a key is set
|
||||
if ($requireKey) {
|
||||
// Check the action code
|
||||
$action = Main::useActionCode('ACTIVATE', $key, $user->id());
|
||||
$action = ActionCode::validate('ACTIVATE', $key, $user->id());
|
||||
|
||||
// Check if we got a negative return
|
||||
if (!$action[0]) {
|
||||
return [0, $action[1]];
|
||||
if (!$action) {
|
||||
return [0, 'INVALID_CODE'];
|
||||
}
|
||||
|
||||
// Assign the special values
|
||||
$instructionData = json_decode($action[2], true);
|
||||
$rank = $instructionData['user']['rank_main'];
|
||||
$ranks = $instructionData['user']['user_ranks'];
|
||||
}
|
||||
|
||||
// Activate the account
|
||||
Database::update('users', [
|
||||
[
|
||||
'rank_main' => $rank,
|
||||
'user_ranks' => $ranks,
|
||||
],
|
||||
[
|
||||
'user_id' => [$user->id(), '='],
|
||||
],
|
||||
]);
|
||||
// Add normal user, remove deactivated and set normal as default
|
||||
$user->addRanks([2]);
|
||||
$user->removeRanks([1]);
|
||||
$user->setMainRank(2);
|
||||
|
||||
// Return success
|
||||
return [1, 'SUCCESS'];
|
||||
|
|
|
@ -223,17 +223,11 @@ if (isset($_REQUEST['mode'])) {
|
|||
Config::get('recaptcha') ?
|
||||
$_REQUEST['g-recaptcha-response'] :
|
||||
null
|
||||
),
|
||||
(
|
||||
Config::get('require_registration_code') ?
|
||||
$_REQUEST['registercode'] :
|
||||
null
|
||||
)
|
||||
);
|
||||
|
||||
// Array containing "human understandable" messages
|
||||
$messages = [
|
||||
|
||||
'AUTH_LOCKED' => 'Authentication is currently not allowed, try again later.',
|
||||
'DISABLED' => 'Registration is currently disabled.',
|
||||
'INVALID_REG_KEY' => 'The given registration code was invalid.',
|
||||
|
@ -244,11 +238,11 @@ if (isset($_REQUEST['mode'])) {
|
|||
'NAME_TOO_LONG' => 'Your name can\'t be longer than 16 characters.',
|
||||
'PASS_TOO_SHIT' => 'Your password is too weak, try adding some special characters.',
|
||||
'PASS_NOT_MATCH' => 'Passwords do not match.',
|
||||
'EMAIL_EXISTS' => 'Someone already registered using this email!', // HOW DID I MISS THIS?!
|
||||
'INVALID_EMAIL' => 'Your e-mail address is formatted incorrectly.',
|
||||
'INVALID_MX' => 'No valid MX-Record found on the e-mail address you supplied.',
|
||||
'EMAILSENT' => 'Your registration went through! An activation e-mail has been sent.',
|
||||
'SUCCESS' => 'Your registration went through! Welcome to ' . Config::get('sitename') . '!',
|
||||
|
||||
];
|
||||
|
||||
// Add page specific things
|
||||
|
|
|
@ -121,7 +121,23 @@ if ($mode != 'f') {
|
|||
// Post deletion
|
||||
} elseif ($mode == 'p' && isset($_GET['delete']) && $_GET['delete'] == $_GET['p'] && array_key_exists($_GET['p'], $thread->posts())) {
|
||||
// Checks
|
||||
if ($thread->posts()[$_GET['p']]->poster->id() != $currentUser->id()) {
|
||||
if ($thread->posts()[$_GET['p']]->poster->id() != $currentUser->id() || !$forum->permission(ForumPerms::DELETE_ANY, $currentUser->id())) {
|
||||
// Add page specific things
|
||||
$renderData['page'] = [
|
||||
'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('FORUM_INDEX')),
|
||||
'message' => 'You can only delete your own posts!',
|
||||
];
|
||||
|
||||
// Set parse variables
|
||||
$template->setVariables($renderData);
|
||||
|
||||
// Print page contents
|
||||
echo $template->render('global/information');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Permissions
|
||||
if ($currentUser->permission(ForumPerms::DELETE_OWN, Perms::FORUM)) {
|
||||
// Add page specific things
|
||||
$renderData['page'] = [
|
||||
'redirect' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : $urls->format('FORUM_INDEX')),
|
||||
|
@ -198,8 +214,26 @@ if ($mode != 'f') {
|
|||
|
||||
// Check if a post is being made
|
||||
if (isset($_POST['post'])) {
|
||||
// Attempt to make the post
|
||||
$post = Forum\Post::create($_POST['subject'], $_POST['text'], $currentUser, $topicId, $forumId);
|
||||
// Check if an ID is set
|
||||
if (isset($_POST['id'])) {
|
||||
// Attempt to create a post object
|
||||
$post = new Forum\Post($_POST['id']);
|
||||
|
||||
// Check if the post israel
|
||||
if ($post->id == $_POST['id']) {
|
||||
$post->subject = $_POST['subject'];
|
||||
$post->text = $_POST['text'];
|
||||
$post->editTime = time();
|
||||
$post->editReason = '';
|
||||
$post->editUser = $currentUser;
|
||||
$post->update();
|
||||
} else {
|
||||
$post = null;
|
||||
}
|
||||
} else {
|
||||
// Attempt to make the post
|
||||
$post = Forum\Post::create($_POST['subject'], $_POST['text'], $currentUser, $topicId, $forumId);
|
||||
}
|
||||
|
||||
// Add page specific things
|
||||
$renderData['page'] = [
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
namespace Sakura;
|
||||
|
||||
// Define Sakura version
|
||||
define('SAKURA_VERSION', '20160106');
|
||||
define('SAKURA_VERSION', '20160109');
|
||||
define('SAKURA_VLABEL', 'Eminence');
|
||||
define('SAKURA_COLOUR', '#6C3082');
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<meta charset="{{ sakura.charset }}" />
|
||||
<title>{% block title %}{{ sakura.siteName }}{% endblock %}</title>
|
||||
<meta name="description" content="{{ sakura.siteDesc }}" />
|
||||
<meta name="keywords" content="{{ sakura.siteTags }}" />
|
||||
<meta name="keywords" content="{{ sakura.siteTags|join(', ') }}" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
||||
<meta name="msapplication-TileColor" content="#9475b2" />
|
||||
<meta name="msapplication-TileImage" content="/content/images/icons/ms-icon-144x144.png" />
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<input class="inputStyling" type="button" onclick="{{ cancelTarget }}" value="Cancel" />
|
||||
</div>
|
||||
{% if posting.id %}
|
||||
<input type="hidden" name="id" value="posting.id" />
|
||||
<input type="hidden" name="id" value="{{ posting.id }}" />
|
||||
{% endif %}
|
||||
<input type="hidden" name="sessionid" value="{{ php.sessionid }}" />
|
||||
<input type="hidden" name="timestamp" value="{{ php.time }}" />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% if not (viewPost and postExists) %}<a href="{{ urls.format('SITE_NEWS_POST', [post.news_id]) }}" class="news-head" id="{{ post.news_category }}_{{ post.news_id }}">{{ post.news_title }}</a>{% endif %}
|
||||
{% if not (viewPost and postExists) %}<a href="{{ urls.format('SITE_NEWS_CAT_POST', [post.news_category, post.news_id]) }}" class="news-head" id="{{ post.news_category }}_{{ post.news_id }}">{{ post.news_title }}</a>{% endif %}
|
||||
<div class="news-body">
|
||||
<a class="no-underline" href="{{ urls.format('USER_PROFILE', [post.news_poster.id]) }}">
|
||||
<div class="news-poster">
|
||||
|
@ -12,5 +12,5 @@
|
|||
</div>
|
||||
<div class="clear"></div>
|
||||
<div class="news-post-time">
|
||||
Posted on {{ post.news_timestamp|date(sakura.dateFormat) }}{% if not (viewPost and postExists) %} <a class="default" href="{{ urls.format('SITE_NEWS_POST', [post.news_id]) }}#comments">{{ post.news_comments.count }} comment{% if post.news_comments.count != 1 %}s{% endif %}</a>{% endif %}
|
||||
Posted on {{ post.news_timestamp|date(sakura.dateFormat) }}{% if not (viewPost and postExists) %} <a class="default" href="{{ urls.format('SITE_NEWS_CAT_POST', [post.news_category, post.news_id]) }}#comments">{{ post.news_comments.count }} comment{% if post.news_comments.count != 1 %}s{% endif %}</a>{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
<div class="post-text bbcode">
|
||||
{{ post.parsed|raw }}
|
||||
</div>
|
||||
{% if post.poster.signature and post.signature %}
|
||||
{% if post.poster.signature and post.poster.permission(constant('Sakura\\Perms\\Site::CHANGE_SIGNATURE')) %}
|
||||
<div class="clear"></div>
|
||||
<div class="signature bbcode">
|
||||
{{ post.poster.signature|raw|nl2br }}
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
{% if not sakura.disableRegistration %}
|
||||
"registerForm": 'Processing registration...',
|
||||
{% endif %}
|
||||
{% if not sakura.requireActivation %}
|
||||
{% if sakura.requireActivation %}
|
||||
"resendForm": 'Attempting to resend activation...',
|
||||
{% endif %}
|
||||
"passwordForm": 'Sending password recovery mail...'
|
||||
|
|
|
@ -147,7 +147,7 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if not sakura.requireActivation %}
|
||||
{% if sakura.requireActivation %}
|
||||
<div class="resendForm">
|
||||
<div class="head">
|
||||
Resend Activation E-mail
|
||||
|
|
Reference in a new issue