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

Rails Sessions Generator #69

Merged
merged 10 commits into from
Dec 22, 2024
13 changes: 13 additions & 0 deletions app/channels/application_cable/connection.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user

def connect
set_current_user || reject_unauthorized_connection
end

private

def set_current_user
if session ||= Session.find_by(id: cookies.signed[:session_id])
self.current_user = session.user
end
end
end
end
20 changes: 2 additions & 18 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,28 +1,12 @@
class ApplicationController < ActionController::Base
include Authentication
# Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
allow_browser versions: :modern

include Pagy::Backend
add_flash_types :success, :notice
helper_method :current_user

rescue_from CanCan::AccessDenied do
flash[:alert] = t("flash.un_authorize")

if current_user.nil?
redirect_to login_path
else
redirect_to request.referer || thaalis_all_path(CURR_YR)
end
end

private

def current_user
@current_user ||= User.select(:id, :slug).find(session[:user_id]) if session[:user_id]
end

def logged_in?
redirect_to thaalis_all_path(CURR_YR), notice: t("flash.active_session") if session[:user_id]
return_to_default_path(type: :alert, msg: "flash.un_authorize")
end
end
64 changes: 64 additions & 0 deletions app/controllers/concerns/authentication.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module Authentication
extend ActiveSupport::Concern

included do
before_action :require_authentication
helper_method :authenticated?, :current_user
end

class_methods do
def allow_unauthenticated_access(**options)
skip_before_action :require_authentication, **options
end
end

private

def authenticated?
resume_session
end

def require_authentication
resume_session || request_authentication
end

def resume_session
Current.session ||= find_session_by_cookie
end

def find_session_by_cookie
Session.find_by(id: cookies.signed[:session_id]) if cookies.signed[:session_id]
end

def request_authentication
session[:return_to_after_authenticating] = request.url
redirect_to login_path, alert: t("flash.un_authorize")
end

def after_authentication_url
return_to_url = session.delete(:return_to_after_authenticating)
return_to_url.present? ? "#{return_to_url}.html" : thaalis_all_path(CURR_YR, format: :html)
end

def start_new_session_for(user)
user.sessions.create!(user_agent: request.user_agent, ip_address: request.remote_ip).tap do |session|
Current.session = session
cookies.signed.permanent[:session_id] = {value: session.id, httponly: true, same_site: :lax}
end
end

def terminate_session
Rails.cache.delete("user_#{current_user.id}_role")
Current.session.destroy
cookies.delete(:session_id)
end

def return_to_default_path(type: :notice, msg: "flash.active_session")
flash[type] = t(msg)
redirect_to thaalis_all_path(CURR_YR)
end

def current_user
@current_user ||= Current.user
end
end
3 changes: 2 additions & 1 deletion app/controllers/pages_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class PagesController < ApplicationController
before_action :logged_in?
allow_unauthenticated_access
before_action :return_to_default_path, if: -> { authenticated? }

def home
end
Expand Down
17 changes: 8 additions & 9 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
class SessionsController < ApplicationController
before_action :logged_in?, only: :new
allow_unauthenticated_access only: %i[new create]
before_action :return_to_default_path, only: %i[new create], if: -> { authenticated? }
# rate_limit to: 10, within: 3.minutes, only: :create, with: -> { redirect_to new_session_url, alert: "Try again later." }

def new
end

def create
user = User.authenticate_by(user_params)
if user
session[:user_id] = user.id
if user ||= User.authenticate_by(user_params)
start_new_session_for user

respond_to do |format|
format.all { redirect_to thaalis_all_path(CURR_YR, format: :html), success: t(".success") }
format.all { redirect_to after_authentication_url, success: t(".success") }
end
else
flash.now.alert = t(".error")
render :new, status: :not_found
redirect_to login_path, alert: t(".error")
end
end

def destroy
Rails.cache.delete("user_#{current_user.id}_role")
session[:user_id] = nil
terminate_session
redirect_to login_path, success: t(".success")
end

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def destroy
if current_user.is?("admin") && current_user.id != @user&.id
redirect_to users_path, success: t(".success")
else
session[:user_id] = nil
terminate_session
redirect_to login_path, success: t(".success")
end
end
Expand Down
4 changes: 4 additions & 0 deletions app/models/current.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Current < ActiveSupport::CurrentAttributes
attribute :session
delegate :user, to: :session, allow_nil: true
end
3 changes: 3 additions & 0 deletions app/models/session.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Session < ApplicationRecord
belongs_to :user
end
1 change: 1 addition & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class User < ApplicationRecord
rolify
has_secure_password
has_many :sessions, dependent: :destroy

# * Callbacks
include NameCallback
Expand Down
4 changes: 2 additions & 2 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<body onselectstart="return false">
<%= render "shared/flash_messages" if flash.present? %>

<% if current_user.present? %>
<% if authenticated? %>
<header class="heading">
<%= render "shared/navbar/navbar" %>

Expand All @@ -39,6 +39,6 @@
<%= yield %>
</main>

<%= render "shared/footer" if current_user.blank? %>
<%= render "shared/footer" unless authenticated? %>
</body>
</html>
11 changes: 11 additions & 0 deletions db/migrate/20241220050110_create_sessions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateSessions < ActiveRecord::Migration[8.0]
def change
create_table :sessions do |t|
t.references :user, null: false, foreign_key: true
t.string :ip_address
t.string :user_agent

t.timestamps
end
end
end
12 changes: 11 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions spec/factories/sessions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

FactoryBot.define do
factory :session do
user
ip_address { Faker::Internet.public_ip_v4_address }
user_agent { Faker::Internet.user_agent }
end
end
4 changes: 2 additions & 2 deletions spec/features/layout/navbar_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
require "rails_helper"

RSpec.describe "Navbar" do
# * Accessibile by logged-in user
# * Accessible by logged-in user
describe "logged in" do
before do
page.set_rack_session(user_id: user.id)
sign_in(user)
visit thaalis_all_path(CURR_YR)
end

Expand Down
2 changes: 1 addition & 1 deletion spec/features/sabeels/active_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
let!(:sabeels) { create_list(:burhani_sabeel_taking_thaali, 2) }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
visit sabeels_active_path(apt.downcase)
end

Expand Down
2 changes: 1 addition & 1 deletion spec/features/sabeels/destroy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let(:sabeel) { create(:sabeel) }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
visit sabeel_path(sabeel)
click_on "Delete"
end
Expand Down
2 changes: 1 addition & 1 deletion spec/features/sabeels/edit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let(:sabeel) { create(:sabeel) }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
visit edit_sabeel_path(sabeel)
end

Expand Down
2 changes: 1 addition & 1 deletion spec/features/sabeels/inactive_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# rubocop:enable RSpec/LetSetup

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
visit sabeels_inactive_path(apt.downcase)
end

Expand Down
2 changes: 1 addition & 1 deletion spec/features/sabeels/index_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let(:user) { create(:user) }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
create_list(:sabeel, 2)
visit sabeels_path
end
Expand Down
2 changes: 1 addition & 1 deletion spec/features/sabeels/new_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

RSpec.describe "Sabeel New template" do
before do
page.set_rack_session(user_id: user.id)
sign_in(user)
visit new_sabeel_path
end

Expand Down
2 changes: 1 addition & 1 deletion spec/features/sabeels/show_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
let(:thaali) { sabeel.thaalis.first }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
visit sabeel_path(sabeel)
end

Expand Down
2 changes: 1 addition & 1 deletion spec/features/sessions/destroy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
let(:user) { create(:user) }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
visit thaalis_all_path(CURR_YR)
click_on "Log out"
end
Expand Down
2 changes: 1 addition & 1 deletion spec/features/statistics/sabeels_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
let(:user) { create(:user) }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
create_list(:burhani_sabeel_taking_thaali, 2)
create_list(:burhani_sabeel_took_thaali, 2)
visit statistics_sabeels_path
Expand Down
2 changes: 1 addition & 1 deletion spec/features/statistics/thaalis_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let(:thaalis) { Thaali.for_year(CURR_YR) }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
create_list(:taking_thaali, 2)
create_list(:taking_thaali_dues_cleared, 2)
visit statistics_thaalis_path
Expand Down
2 changes: 1 addition & 1 deletion spec/features/thaalis/all_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
let(:thaalis) { Thaali.first(2) }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
create_list(:thaali, 2, year:)

visit thaalis_all_path(year)
Expand Down
2 changes: 1 addition & 1 deletion spec/features/thaalis/complete_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
let(:thaalis) { Thaali.dues_cleared_in(CURR_YR) }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
create_list(:taking_thaali_dues_cleared, 2)

visit thaalis_complete_path(CURR_YR)
Expand Down
2 changes: 1 addition & 1 deletion spec/features/thaalis/destroy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let(:thaali) { create(:thaali) }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
visit thaali_path(thaali)
click_on "Delete"
end
Expand Down
2 changes: 1 addition & 1 deletion spec/features/thaalis/edit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
let(:thaali) { create(:thaali) }

before do
page.set_rack_session(user_id: user.id)
sign_in(user)
visit edit_thaali_path(thaali)
end

Expand Down
Loading
Loading