From 2b03661431f73c7721427fd95c3b14bdca4ddc35 Mon Sep 17 00:00:00 2001 From: songtianlun Date: Fri, 3 Jan 2025 13:48:59 +0800 Subject: [PATCH] feat: add user authentication and authorization - Implement friendly forwarding for user login - Add correct_user method to ensure users can only edit their own profiles - Update sessions_controller to handle forwarding URL - Enhance user controller tests to verify redirection for unauthorized access These changes improve user experience by allowing users to be redirected back to their intended page after logging in. Additionally, the new correct_user method enhances security by preventing users from editing other users' profiles, ensuring proper authorization checks are in place. --- app/controllers/sessions_controller.rb | 3 ++- app/controllers/users_controller.rb | 9 ++++++++- app/helpers/sessions_helper.rb | 8 ++++++++ test/controllers/users_controller_test.rb | 19 +++++++++++++++++++ test/integration/users_edit_test.rb | 15 +++++++++++++-- 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index bf8fe07..f951c73 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -7,10 +7,11 @@ class SessionsController < ApplicationController user = User.find_by(email: params[:session][:email].downcase) # if user && user.authenticate(params[:session][:password]) if user&.authenticate(params[:session][:password]) + forwarding_url = session[:forwarding_url] reset_session params[:session][:remember_me] == '1' ? remember(user) : forget(user) log_in user - redirect_to user + redirect_to forwarding_url || user else flash.now[:danger] = 'Invalid email/password combination' render 'new' diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index b095df5..30ca851 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,6 +1,7 @@ class UsersController < ApplicationController include SessionsHelper - before_action :logged_in_user, only: [:edit, :update] + before_action :logged_in_user, only: [:edit, :update] + before_action :correct_user, only: [:edit, :update] def show @user = User.find(params[:id]) # debugger @@ -47,8 +48,14 @@ class UsersController < ApplicationController def logged_in_user unless logged_in? + store_location flash[:danger] = "Please log in." redirect_to login_url end end + + def correct_user + @user = User.find(params[:id]) + redirect_to(root_url) unless current_user?(@user) + end end diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb index fc1dcf2..c5ad1b0 100644 --- a/app/helpers/sessions_helper.rb +++ b/app/helpers/sessions_helper.rb @@ -41,4 +41,12 @@ module SessionsHelper reset_session @current_user = nil end + + def current_user?(user) + user && user == current_user + end + + def store_location + session[:forwarding_url] = request.original_url if request.get? + end end diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb index 8d9af29..79ed837 100644 --- a/test/controllers/users_controller_test.rb +++ b/test/controllers/users_controller_test.rb @@ -1,6 +1,10 @@ require "test_helper" class UsersControllerTest < ActionDispatch::IntegrationTest + def setup + @user = users(:michael) + @other_user = users(:archer) + end test "should get new" do get signup_path assert_response :success @@ -11,4 +15,19 @@ class UsersControllerTest < ActionDispatch::IntegrationTest assert_response :success assert_select "title", full_title("Sign up") end + + test "should redirect edit when logged in as wrong user" do + log_in_as(@other_user) + get edit_user_path(@user) + assert flash.empty? + assert_redirected_to root_url + end + + test "should redirect update when logged in as wrong user" do + log_in_as(@other_user) + patch user_path(@user), params: { user: { name: @user.name, + email: @user.email } } + assert flash.empty? + assert_redirected_to root_url + end end diff --git a/test/integration/users_edit_test.rb b/test/integration/users_edit_test.rb index 6d0e549..87a5ce5 100644 --- a/test/integration/users_edit_test.rb +++ b/test/integration/users_edit_test.rb @@ -5,9 +5,20 @@ class UsersEditTest < ActionDispatch::IntegrationTest @user = users(:michael) end - test "successful edit" do - log_in_as(@user) + test "friendly forwarding just in first login" do get edit_user_path(@user) + log_in_as(@user) + assert_redirected_to edit_user_url(@user) + delete logout_path + assert_redirected_to root_url + log_in_as(@user) + assert_redirected_to user_url(@user) + end + + test "successful edit with friendly forwarding" do + get edit_user_path(@user) + log_in_as(@user) + assert_redirected_to edit_user_url(@user) assert_template 'users/edit' name = "Foo Bae" email = "foo@bar.com"