Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LoginController only for login flow #747

Merged
merged 21 commits into from
Nov 29, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ have a value of `7` inside the database table field `user_account_type`. They ca
(as this wouldn't make sense).

2. Normal users don't have admin features for sure. But they can upgrade and downgrade their accounts (try it out via
/login/changeUserRole), which is basically a super-simple implementation of the basic-user / premium-user concept.
/user/changeUserRole), which is basically a super-simple implementation of the basic-user / premium-user concept.
Normal users have a value of `1` or `2` inside the database table field `user_account_type`. By default all new
registered users are normal users with user role 1 for sure.

Expand All @@ -375,7 +375,7 @@ the application puts a "random string" inside the form (as a hidden input field)
checks if the POST request contains exactly the form token that is inside the session.

This CSRF prevention feature is currently implemented on the login form process (see *application/view/login/index.php*)
and user name change form process (see *application/view/login/editUsername.php*), most other forms are not security-
and user name change form process (see *application/view/user/editUsername.php*), most other forms are not security-
critical and should stay as simple as possible.

A big thanks to OmarElGabry for implementing this!
Expand Down
2 changes: 1 addition & 1 deletion application/config/config.development.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
'EMAIL_PASSWORD_RESET_FROM_NAME' => 'My Project',
'EMAIL_PASSWORD_RESET_SUBJECT' => 'Password reset for PROJECT XY',
'EMAIL_PASSWORD_RESET_CONTENT' => 'Please click on this link to reset your password: ',
'EMAIL_VERIFICATION_URL' => 'login/verify',
'EMAIL_VERIFICATION_URL' => 'register/verify',
'EMAIL_VERIFICATION_FROM_EMAIL' => '[email protected]',
'EMAIL_VERIFICATION_FROM_NAME' => 'My Project',
'EMAIL_VERIFICATION_SUBJECT' => 'Account activation for PROJECT XY',
Expand Down
219 changes: 2 additions & 217 deletions application/controller/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ public function login()
Request::post('user_name'), Request::post('user_password'), Request::post('set_remember_me_cookie')
);

// check login status: if true, then redirect user login/showProfile, if false, then to login form again
// check login status: if true, then redirect user to user/index, if false, then to login form again
if ($login_successful) {
if (Request::post('redirect')) {
Redirect::to(ltrim(urldecode(Request::post('redirect')), '/'));
} else {
Redirect::to('login/showProfile');
Redirect::to('user/index');
}
} else {
Redirect::to('login/index');
Expand Down Expand Up @@ -87,181 +87,6 @@ public function loginWithCookie()
}
}

/**
* Show user's PRIVATE profile
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
*/
public function showProfile()
{
Auth::checkAuthentication();
$this->View->render('login/showProfile', array(
'user_name' => Session::get('user_name'),
'user_email' => Session::get('user_email'),
'user_gravatar_image_url' => Session::get('user_gravatar_image_url'),
'user_avatar_file' => Session::get('user_avatar_file'),
'user_account_type' => Session::get('user_account_type')
));
}

/**
* Show edit-my-username page
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
*/
public function editUsername()
{
Auth::checkAuthentication();
$this->View->render('login/editUsername');
}

/**
* Edit user name (perform the real action after form has been submitted)
* Auth::checkAuthentication() makes sure that only logged in users can use this action
*/
public function editUsername_action()
{
Auth::checkAuthentication();

// check if csrf token is valid
if (!Csrf::isTokenValid()) {
self::logout();
}

UserModel::editUserName(Request::post('user_name'));
Redirect::to('login/index');
}

/**
* Show edit-my-user-email page
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
*/
public function editUserEmail()
{
Auth::checkAuthentication();
$this->View->render('login/editUserEmail');
}

/**
* Edit user email (perform the real action after form has been submitted)
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
*/
// make this POST
public function editUserEmail_action()
{
Auth::checkAuthentication();
UserModel::editUserEmail(Request::post('user_email'));
Redirect::to('login/editUserEmail');
}

/**
* Edit avatar
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
*/
public function editAvatar()
{
Auth::checkAuthentication();
$this->View->render('login/editAvatar', array(
'avatar_file_path' => AvatarModel::getPublicUserAvatarFilePathByUserId(Session::get('user_id'))
));
}

/**
* Perform the upload of the avatar
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
* POST-request
*/
public function uploadAvatar_action()
{
Auth::checkAuthentication();
AvatarModel::createAvatar();
Redirect::to('login/editAvatar');
}

/**
* Delete the current user's avatar
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
*/
public function deleteAvatar_action()
{
Auth::checkAuthentication();
AvatarModel::deleteAvatar(Session::get("user_id"));
Redirect::to('login/editAvatar');
}

/**
* Show the change-account-type page
* Auth::checkAuthentication() makes sure that only logged in users can use this action and see this page
*/
public function changeUserRole()
{
Auth::checkAuthentication();
$this->View->render('login/changeUserRole');
}

/**
* Perform the account-type changing
* Auth::checkAuthentication() makes sure that only logged in users can use this action
* POST-request
*/
public function changeUserRole_action()
{
Auth::checkAuthentication();

if (Request::post('user_account_upgrade')) {
// "2" is quick & dirty account type 2, something like "premium user" maybe. you got the idea :)
UserRoleModel::changeUserRole(2);
}

if (Request::post('user_account_downgrade')) {
// "1" is quick & dirty account type 1, something like "basic user" maybe.
UserRoleModel::changeUserRole(1);
}

Redirect::to('login/changeUserRole');
}

/**
* Register page
* Show the register form, but redirect to main-page if user is already logged-in
*/
public function register()
{
if (LoginModel::isUserLoggedIn()) {
Redirect::home();
} else {
$this->View->render('login/register');
}
}

/**
* Register page action
* POST-request after form submit
*/
public function register_action()
{
$registration_successful = RegistrationModel::registerNewUser();

if ($registration_successful) {
Redirect::to('login/index');
} else {
Redirect::to('login/register');
}
}

/**
* Verify user after activation mail link opened
* @param int $user_id user's id
* @param string $user_activation_verification_code user's verification token
*/
public function verify($user_id, $user_activation_verification_code)
{
if (isset($user_id) && isset($user_activation_verification_code)) {
RegistrationModel::verifyNewUser($user_id, $user_activation_verification_code);
$this->View->render('login/verify');
} else {
Redirect::to('login/index');
}
}

/**
* Show the request-password-reset page
*/
Expand Down Expand Up @@ -315,44 +140,4 @@ public function setNewPassword()
);
Redirect::to('login/index');
}

/**
* Password Change Page
* Show the password form if user is logged in, otherwise redirect to login page
*/
public function changePassword()
{
Auth::checkAuthentication();
$this->View->render('login/changePassword');
}

/**
* Password Change Action
* Submit form, if retured positive redirect to index, otherwise show the changePassword page again
*/
public function changePassword_action()
{
$result = PasswordResetModel::changePassword(
Session::get('user_name'), Request::post('user_password_current'),
Request::post('user_password_new'), Request::post('user_password_repeat')
);

if($result)
Redirect::to('login/index');
else
Redirect::to('login/changePassword');
}

/**
* Generate a captcha, write the characters into $_SESSION['captcha'] and returns a real image which will be used
* like this: <img src="......./login/showCaptcha" />
* IMPORTANT: As this action is called via <img ...> 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 <img .. >
* Maybe refactor this sometime.
*/
public function showCaptcha()
{
CaptchaModel::generateAndShowCaptcha();
}
}
74 changes: 74 additions & 0 deletions application/controller/RegisterController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

/**
* RegisterController
* Register new user
*/
class RegisterController extends Controller
{
/**
* Construct this object by extending the basic Controller class. The parent::__construct thing is necessary to
* put checkAuthentication in here to make an entire controller only usable for logged-in users (for sure not
* needed in the RegisterController).
*/
public function __construct()
{
parent::__construct();
}

/**
* Register page
* Show the register form, but redirect to main-page if user is already logged-in
*/
public function index()
{
if (LoginModel::isUserLoggedIn()) {
Redirect::home();
} else {
$this->View->render('register/index');
}
}

/**
* Register page action
* POST-request after form submit
*/
public function register_action()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this be better as index_action() to fit the naming pattern used for action-action_post_handler theme used throughout this framework.

Corresponding change would be needed here: https://github.com/panique/huge/pull/747/files?diff=unified#diff-5ac2d5faa50e65202dd471632e2632f2R11 (application/view/register/index.php L11)

{
$registration_successful = RegistrationModel::registerNewUser();

if ($registration_successful) {
Redirect::to('login/index');
} else {
Redirect::to('register/index');
}
}

/**
* Verify user after activation mail link opened
* @param int $user_id user's id
* @param string $user_activation_verification_code user's verification token
*/
public function verify($user_id, $user_activation_verification_code)
{
if (isset($user_id) && isset($user_activation_verification_code)) {
RegistrationModel::verifyNewUser($user_id, $user_activation_verification_code);
$this->View->render('register/verify');
} else {
Redirect::to('login/index');
}
}

/**
* Generate a captcha, write the characters into $_SESSION['captcha'] and returns a real image which will be used
* like this: <img src="......./login/showCaptcha" />
* IMPORTANT: As this action is called via <img ...> 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 <img .. >
* Maybe refactor this sometime.
*/
public function showCaptcha()
{
CaptchaModel::generateAndShowCaptcha();
}
}
Loading