From 6eff64007f6b6166a6590e6ce6cd7ed2a7ea903f Mon Sep 17 00:00:00 2001 From: flashwave Date: Sat, 9 Jan 2016 22:57:54 +0100 Subject: [PATCH] r20160109 --- libraries/ActionCode.php | 64 +++++++++++++------------- libraries/Forum/Post.php | 40 ++++++++++++++-- libraries/Main.php | 58 ----------------------- libraries/Urls.php | 8 ++++ libraries/Users.php | 58 ++++++++--------------- public/authenticate.php | 8 +--- public/posting.php | 40 ++++++++++++++-- sakura.php | 2 +- templates/misaki/global/master.twig | 2 +- templates/yuuno/elements/editor.twig | 2 +- templates/yuuno/elements/newsPost.twig | 4 +- templates/yuuno/forum/viewtopic.twig | 2 +- templates/yuuno/global/master.twig | 2 +- templates/yuuno/main/authenticate.twig | 2 +- 14 files changed, 141 insertions(+), 151 deletions(-) diff --git a/libraries/ActionCode.php b/libraries/ActionCode.php index 683208e..5eabe4e 100644 --- a/libraries/ActionCode.php +++ b/libraries/ActionCode.php @@ -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. - */ diff --git a/libraries/Forum/Post.php b/libraries/Forum/Post.php index eb243f2..2f76a5e 100644 --- a/libraries/Forum/Post.php +++ b/libraries/Forum/Post.php @@ -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() { diff --git a/libraries/Main.php b/libraries/Main.php index 7617872..86184df 100644 --- a/libraries/Main.php +++ b/libraries/Main.php @@ -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) { diff --git a/libraries/Urls.php b/libraries/Urls.php index 5e62f8f..8ad2816 100644 --- a/libraries/Urls.php +++ b/libraries/Urls.php @@ -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', diff --git a/libraries/Users.php b/libraries/Users.php index f3b7d73..9d15016 100644 --- a/libraries/Users.php +++ b/libraries/Users.php @@ -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']; diff --git a/public/authenticate.php b/public/authenticate.php index 6bff689..4f9c923 100644 --- a/public/authenticate.php +++ b/public/authenticate.php @@ -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 diff --git a/public/posting.php b/public/posting.php index 3c84197..a1f69e7 100644 --- a/public/posting.php +++ b/public/posting.php @@ -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'] = [ diff --git a/sakura.php b/sakura.php index e1fa01c..096c036 100644 --- a/sakura.php +++ b/sakura.php @@ -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'); diff --git a/templates/misaki/global/master.twig b/templates/misaki/global/master.twig index a789803..175053b 100644 --- a/templates/misaki/global/master.twig +++ b/templates/misaki/global/master.twig @@ -5,7 +5,7 @@ {% block title %}{{ sakura.siteName }}{% endblock %} - + diff --git a/templates/yuuno/elements/editor.twig b/templates/yuuno/elements/editor.twig index c30abe1..52700f1 100644 --- a/templates/yuuno/elements/editor.twig +++ b/templates/yuuno/elements/editor.twig @@ -25,7 +25,7 @@ {% if posting.id %} - + {% endif %} diff --git a/templates/yuuno/elements/newsPost.twig b/templates/yuuno/elements/newsPost.twig index 7098f36..f2490ae 100644 --- a/templates/yuuno/elements/newsPost.twig +++ b/templates/yuuno/elements/newsPost.twig @@ -1,4 +1,4 @@ -{% if not (viewPost and postExists) %}{{ post.news_title }}{% endif %} +{% if not (viewPost and postExists) %}{{ post.news_title }}{% endif %}
@@ -12,5 +12,5 @@
- Posted on {{ post.news_timestamp|date(sakura.dateFormat) }}{% if not (viewPost and postExists) %} {{ post.news_comments.count }} comment{% if post.news_comments.count != 1 %}s{% endif %}{% endif %} + Posted on {{ post.news_timestamp|date(sakura.dateFormat) }}{% if not (viewPost and postExists) %} {{ post.news_comments.count }} comment{% if post.news_comments.count != 1 %}s{% endif %}{% endif %}
diff --git a/templates/yuuno/forum/viewtopic.twig b/templates/yuuno/forum/viewtopic.twig index d052369..8d0837d 100644 --- a/templates/yuuno/forum/viewtopic.twig +++ b/templates/yuuno/forum/viewtopic.twig @@ -80,7 +80,7 @@
{{ post.parsed|raw }}
- {% if post.poster.signature and post.signature %} + {% if post.poster.signature and post.poster.permission(constant('Sakura\\Perms\\Site::CHANGE_SIGNATURE')) %}
{{ post.poster.signature|raw|nl2br }} diff --git a/templates/yuuno/global/master.twig b/templates/yuuno/global/master.twig index ea6cc32..20d0186 100644 --- a/templates/yuuno/global/master.twig +++ b/templates/yuuno/global/master.twig @@ -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...' diff --git a/templates/yuuno/main/authenticate.twig b/templates/yuuno/main/authenticate.twig index 173baf2..c95779f 100644 --- a/templates/yuuno/main/authenticate.twig +++ b/templates/yuuno/main/authenticate.twig @@ -147,7 +147,7 @@
{% endif %}
- {% if not sakura.requireActivation %} + {% if sakura.requireActivation %}
Resend Activation E-mail