diff --git a/application/config/texts.php b/application/config/texts.php index f304617..693a151 100644 --- a/application/config/texts.php +++ b/application/config/texts.php @@ -38,7 +38,7 @@ return array( "FEEDBACK_PASSWORD_REPEAT_WRONG" => "Password and password repeat are not the same.", "FEEDBACK_PASSWORD_TOO_SHORT" => "Password has a minimum length of 6 characters.", "FEEDBACK_USERNAME_TOO_SHORT_OR_TOO_LONG" => "Username cannot be shorter than 2 or longer than 64 characters.", - "FEEDBACK_ACCOUNT_SUCCESSFULLY_CREATED" => "Your account has been created successfully and we have sent you an email. Please click the VERIFICATION LINK within that mail.", + "FEEDBACK_ACCOUNT_SUCCESSFULLY_CREATED" => "The account has been created successfully.", "FEEDBACK_VERIFICATION_MAIL_SENDING_FAILED" => "Sorry, we could not send you an verification mail. Your account has NOT been created.", "FEEDBACK_ACCOUNT_CREATION_FAILED" => "Sorry, your registration failed. Please go back and try again.", "FEEDBACK_VERIFICATION_MAIL_SENDING_ERROR" => "Verification mail could not be sent due to: ", diff --git a/application/controller/AdminController.php b/application/controller/AdminController.php index 6cd7614..aef4c76 100644 --- a/application/controller/AdminController.php +++ b/application/controller/AdminController.php @@ -32,4 +32,25 @@ class AdminController extends Controller Redirect::to("admin"); } + + public function registerUser() + { + // Ensure the user is logged in and is an admin + if (!LoginModel::isUserLoggedIn() || !LoginModel::isAdmin()) { + Session::add('feedback_negative', Text::get('FEEDBACK_ADMIN_ONLY')); + Redirect::to('admin/index'); + return; + } + + // Validate and register the new user + $registration_successful = RegistrationModel::registerNewUser(true); + + if ($registration_successful) { + Session::add('feedback_positive', Text::get('FEEDBACK_USER_REGISTERED_SUCCESSFULLY')); + } else { + Session::add('feedback_negative', Text::get('FEEDBACK_USER_REGISTRATION_FAILED')); + } + + Redirect::to('admin/index'); + } } diff --git a/application/controller/RegisterController.php b/application/controller/RegisterController.php index 3240897..9e052bd 100644 --- a/application/controller/RegisterController.php +++ b/application/controller/RegisterController.php @@ -22,11 +22,13 @@ class RegisterController extends Controller */ public function index() { - if (LoginModel::isUserLoggedIn()) { - Redirect::home(); - } else { - $this->View->render('register/index'); + // Redirect non-logged-in users to the login page + if (!LoginModel::isUserLoggedIn()) { + Redirect::to('login/index'); + return; } + + $this->View->render('register/index'); } /** @@ -35,6 +37,13 @@ class RegisterController extends Controller */ public function register_action() { + // Restrict registration to admins only + if (!LoginModel::isAdmin()) { + Session::add('feedback_negative', Text::get('FEEDBACK_ADMIN_ONLY')); + Redirect::to('login/index'); + return; + } + $registration_successful = RegistrationModel::registerNewUser(); if ($registration_successful) { @@ -62,13 +71,12 @@ class RegisterController extends Controller /** * Generate a captcha, write the characters into $_SESSION['captcha'] and returns a real image which will be used * like this: - * IMPORTANT: As this action is called via AFTER the real application has finished executing (!), the - * SESSION["captcha"] has no content when the application is loaded. The SESSION["captcha"] gets filled at the - * moment the end-user requests the - * Maybe refactor this sometime. + * + * This method is now deprecated as Captcha is no longer used in the registration process. */ public function showCaptcha() { - CaptchaModel::generateAndShowCaptcha(); + Session::add('feedback_negative', Text::get('FEEDBACK_CAPTCHA_NOT_USED')); + Redirect::to('register/index'); } } diff --git a/application/core/Text.php b/application/core/Text.php index 24ec988..e0c3fc6 100644 --- a/application/core/Text.php +++ b/application/core/Text.php @@ -19,7 +19,7 @@ class Text // load config file (this is only done once per application lifecycle) if (!self::$texts) { - self::$texts = require('../application/config/texts.php'); + self::$texts = require(__DIR__ . '/../config/texts.php'); } // check if array key exists diff --git a/application/model/LoginModel.php b/application/model/LoginModel.php index 0e57ba0..2883c45 100644 --- a/application/model/LoginModel.php +++ b/application/model/LoginModel.php @@ -379,4 +379,15 @@ class LoginModel { return Session::userIsLoggedIn(); } + + /** + * Check if the logged-in user is an admin + * + * @return bool True if the user is an admin, false otherwise + */ + public static function isAdmin() + { + $user_role = Session::get('user_role'); // Assuming user role is stored in session + return $user_role === 'admin'; + } } diff --git a/application/model/RegistrationModel.php b/application/model/RegistrationModel.php index 044e00f..f3d0adb 100644 --- a/application/model/RegistrationModel.php +++ b/application/model/RegistrationModel.php @@ -13,101 +13,61 @@ class RegistrationModel * * @return boolean Gives back the success status of the registration */ - public static function registerNewUser() + public static function registerNewUser($isAdmin = false) { // clean the input $user_name = strip_tags(Request::post('user_name')); $user_email = strip_tags(Request::post('user_email')); - $user_email_repeat = strip_tags(Request::post('user_email_repeat')); - $user_password_new = Request::post('user_password_new'); - $user_password_repeat = Request::post('user_password_repeat'); + // Use 'user_password' if provided (admin registration), otherwise 'user_password_new' + $user_password_new = $isAdmin ? Request::post('user_password') : Request::post('user_password_new'); - // stop registration flow if registrationInputValidation() returns false (= anything breaks the input check rules) - $validation_result = self::registrationInputValidation(Request::post('captcha'), $user_name, $user_password_new, $user_password_repeat, $user_email, $user_email_repeat); + // validate input (skip captcha validation) + $validation_result = self::registrationInputValidation($user_name, $user_password_new, $user_email); if (!$validation_result) { return false; } - // crypt the password with the PHP 5.5's password_hash() function, results in a 60 character hash string. - // @see php.net/manual/en/function.password-hash.php for more, especially for potential options + // hash the password $user_password_hash = password_hash($user_password_new, PASSWORD_DEFAULT); - // make return a bool variable, so both errors can come up at once if needed - $return = true; - - // check if username already exists - if (UserModel::doesUsernameAlreadyExist($user_name)) { - Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_ALREADY_TAKEN')); - $return = false; - } - - // check if email already exists - if (UserModel::doesEmailAlreadyExist($user_email)) { - Session::add('feedback_negative', Text::get('FEEDBACK_USER_EMAIL_ALREADY_TAKEN')); - $return = false; - } - - // if Username or Email were false, return false - if (!$return) return false; - - // generate random hash for email verification (40 bytes) - $user_activation_hash = bin2hex(random_bytes(40)); - - // write user data to database - if (!self::writeNewUserToDatabase($user_name, $user_password_hash, $user_email, time(), $user_activation_hash)) { - Session::add('feedback_negative', Text::get('FEEDBACK_ACCOUNT_CREATION_FAILED')); - return false; // no reason not to return false here - } - - // get user_id of the user that has been created, to keep things clean we DON'T use lastInsertId() here - $user_id = UserModel::getUserIdByUsername($user_name); - - if (!$user_id) { - Session::add('feedback_negative', Text::get('FEEDBACK_UNKNOWN_ERROR')); + // check if username or email already exists + if (UserModel::doesUsernameAlreadyExist($user_name) || UserModel::doesEmailAlreadyExist($user_email)) { + Session::add('feedback_negative', Text::get('FEEDBACK_USERNAME_OR_EMAIL_TAKEN')); return false; } - // send verification email - if (self::sendVerificationEmail($user_id, $user_email, $user_activation_hash)) { - Session::add('feedback_positive', Text::get('FEEDBACK_ACCOUNT_SUCCESSFULLY_CREATED')); - return true; + // directly activate user (skip email verification) + $user_active = 1; + + // write user data to database + if (!self::writeNewUserToDatabase($user_name, $user_password_hash, $user_email, time(), $user_active)) { + Session::add('feedback_negative', Text::get('FEEDBACK_ACCOUNT_CREATION_FAILED')); + return false; } - // if verification email sending failed: instantly delete the user - self::rollbackRegistrationByUserId($user_id); - Session::add('feedback_negative', Text::get('FEEDBACK_VERIFICATION_MAIL_SENDING_FAILED')); - return false; + Session::add('feedback_positive', Text::get('FEEDBACK_ACCOUNT_SUCCESSFULLY_CREATED')); + return true; } /** * Validates the registration input * - * @param $captcha * @param $user_name * @param $user_password_new - * @param $user_password_repeat * @param $user_email - * @param $user_email_repeat * * @return bool */ - public static function registrationInputValidation($captcha, $user_name, $user_password_new, $user_password_repeat, $user_email, $user_email_repeat) + public static function registrationInputValidation($user_name, $user_password_new, $user_email) { $return = true; - // perform all necessary checks - if (!CaptchaModel::checkCaptcha($captcha)) { - Session::add('feedback_negative', Text::get('FEEDBACK_CAPTCHA_WRONG')); + if (empty($user_name) || empty($user_password_new) || empty($user_email)) { + Session::add('feedback_negative', Text::get('FEEDBACK_FIELDS_EMPTY')); $return = false; } - // if username, email and password are all correctly validated, but make sure they all run on first sumbit - if (self::validateUserName($user_name) AND self::validateUserEmail($user_email, $user_email_repeat) AND self::validateUserPassword($user_password_new, $user_password_repeat) AND $return) { - return true; - } - - // otherwise, return false - return false; + return $return; } /** @@ -208,12 +168,20 @@ class RegistrationModel $sql = "INSERT INTO users (user_name, user_password_hash, user_email, user_creation_timestamp, user_activation_hash, user_provider_type) VALUES (:user_name, :user_password_hash, :user_email, :user_creation_timestamp, :user_activation_hash, :user_provider_type)"; $query = $database->prepare($sql); - $query->execute(array(':user_name' => $user_name, - ':user_password_hash' => $user_password_hash, - ':user_email' => $user_email, - ':user_creation_timestamp' => $user_creation_timestamp, - ':user_activation_hash' => $user_activation_hash, - ':user_provider_type' => 'DEFAULT')); + try { + $query->execute(array( + ':user_name' => $user_name, + ':user_password_hash' => $user_password_hash, + ':user_email' => $user_email, + ':user_creation_timestamp' => $user_creation_timestamp, + ':user_activation_hash' => $user_activation_hash, + ':user_provider_type' => 'DEFAULT' + )); + } catch (PDOException $e) { + error_log("Database error during user creation: " . $e->getMessage()); + Session::add('feedback_negative', "Database error: " . $e->getMessage()); + return false; + } $count = $query->rowCount(); if ($count == 1) { return true; diff --git a/application/view/_templates/header.php b/application/view/_templates/header.php index 67b9c38..5d91151 100644 --- a/application/view/_templates/header.php +++ b/application/view/_templates/header.php @@ -36,9 +36,6 @@
  • > Login
  • -
  • > - Register -
  • diff --git a/application/view/admin/index.php b/application/view/admin/index.php index cf3f6b0..0a23eef 100644 --- a/application/view/admin/index.php +++ b/application/view/admin/index.php @@ -53,5 +53,15 @@ + +

    Register a new user

    + +
    + + + + +
    + diff --git a/application/view/login/index.php b/application/view/login/index.php index 3f61fe6..a5bd2b0 100644 --- a/application/view/login/index.php +++ b/application/view/login/index.php @@ -38,13 +38,6 @@ I forgot my password - - -
    -

    No account yet ?

    - Register -
    - diff --git a/application/view/register/index.php b/application/view/register/index.php index 40fd18c..aa3db62 100644 --- a/application/view/register/index.php +++ b/application/view/register/index.php @@ -9,30 +9,12 @@
    - - - - - - - - Reload Captcha -
    -
    -

    - Please note: This captcha will be generated when the img tag requests the captcha-generation - (= a real image) from YOURURL/register/showcaptcha. As this is a client-side triggered request, a - $_SESSION["captcha"] dump will not show the captcha characters. The captcha generation - happens AFTER the request that generates THIS page has been finished. -

    -