Skip to content

Commit

Permalink
Replace Devise with has_secure_password (#992)
Browse files Browse the repository at this point in the history
* Remove Devise & related configuration/files that are not used or unneeded

* Rename devise styles to login (not used yet)

Also remove use of devise-ish styles that are never used from onboarding.

* Use has_secure_password

---------

Co-authored-by: Laura Mosher <lauramosher@users.noreply.github.com>
  • Loading branch information
lauramosher and lauramosher committed Apr 12, 2024
1 parent e0dbdd6 commit 687abea
Show file tree
Hide file tree
Showing 34 changed files with 122 additions and 561 deletions.
6 changes: 1 addition & 5 deletions rails/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,13 @@ gem 'rack-cors'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use devise for authentication
gem 'devise', '~> 4.9.0'
gem 'bcrypt', '~> 3.1.7'

# Use pundit for policy based authorization
gem 'pundit', '~> 2.3.0'

# Internationalization
gem 'rails-i18n', '~> 7.0.3'
gem 'devise-i18n', '~> 1.11.0'

# S3 backed Active Storage
gem 'aws-sdk-s3', '~> 1.119.0'
Expand Down
17 changes: 1 addition & 16 deletions rails/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,6 @@ GEM
railties (>= 6.0.0)
date (3.3.4)
debug_inspector (1.2.0)
devise (4.9.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
devise-i18n (1.11.1)
devise (>= 4.9.0)
diff-lcs (1.5.1)
docile (1.4.0)
erubi (1.12.0)
Expand Down Expand Up @@ -205,7 +197,6 @@ GEM
notiffany (0.1.3)
nenv (~> 0.1)
shellany (~> 0.0)
orm_adapter (0.5.0)
pg (1.5.6)
pry (0.14.2)
coderay (~> 1.1)
Expand Down Expand Up @@ -267,9 +258,6 @@ GEM
railties (>= 3.2)
tilt
regexp_parser (2.9.0)
responders (3.1.1)
actionpack (>= 5.2)
railties (>= 5.2)
rexml (3.2.6)
rgeo (2.4.0)
rgeo-geojson (2.1.1)
Expand Down Expand Up @@ -332,8 +320,6 @@ GEM
timeout (0.4.1)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
warden (1.2.9)
rack (>= 2.0.9)
web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
Expand All @@ -358,14 +344,13 @@ DEPENDENCIES
active_storage_validations (~> 1.0)
annotate
aws-sdk-s3 (~> 1.119.0)
bcrypt (~> 3.1.7)
better_errors
binding_of_caller
bundler-audit
byebug
capybara (>= 2.15, < 4.0)
cssbundling-rails (~> 1.1.2)
devise (~> 4.9.0)
devise-i18n (~> 1.11.0)
factory_bot_rails
flipper (~> 0.26.0)
flipper-active_record (~> 0.26.0)
Expand Down
2 changes: 1 addition & 1 deletion rails/app/assets/stylesheets/application.sass.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
@import "core/media";
@import "core/typography";

@import "features/devise";
@import "features/login";
@import "features/onboarding";
@import "features/welcome";
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.devise {
.login {
background: url('welcome-bg.jpg') no-repeat center center fixed;
background-size: cover;
height: 100vh;
Expand Down Expand Up @@ -121,7 +121,7 @@
display: none;
}

.devise-card {
.login-card {
margin-bottom: 0;
}
}
Expand Down
4 changes: 0 additions & 4 deletions rails/app/assets/stylesheets/features/onboarding.scss
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,6 @@
.logo {
display: none;
}

.devise-card {
margin-bottom: 0;
}
}

&-links {
Expand Down
2 changes: 1 addition & 1 deletion rails/app/constraints/role_routing_constraint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ def matches?(request)
end

def current_user(request)
User.find_by(id: request.session["warden.user.user.key"][0][0])
User.find_by(id: request.session["user_id"])
end
end
2 changes: 0 additions & 2 deletions rails/app/controllers/api/base_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
module Api
class BaseController < ActionController::Base
respond_to :json

rescue_from ActiveRecord::RecordNotFound, with: :not_found


Expand Down
1 change: 1 addition & 0 deletions rails/app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class ApplicationController < ActionController::Base
include Sessions::Helpers
include Pundit::Authorization
include Locale

Expand Down
27 changes: 27 additions & 0 deletions rails/app/controllers/concerns/sessions/helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Sessions::Helpers
extend ActiveSupport::Concern

included do
helper_method :current_user
helper_method :user_signed_in?
end

def authenticate_user!
if !user_signed_in?
flash[:alert] = t("devise.failure.unauthenticated")
redirect_to login_path
end
end

private

def user_signed_in?
current_user.present?
end

# Define the current_user method:
def current_user
# Look up the current user based on user_id in the session cookie:
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
1 change: 1 addition & 0 deletions rails/app/controllers/home_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def index
def community_search_index
# This will eventually be a searchable action for the public maps and stories of
# communities within this app. For now, it's just a placeholder.
render layout: "application"
end

def show
Expand Down
9 changes: 7 additions & 2 deletions rails/app/controllers/passwords_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ def edit
def update
@user = current_user
if @user.update(password_params)
bypass_sign_in(@user)
flash.notice = t("devise.passwords.updated_not_active")
redirect_to root_path
if @user.super_admin
redirect_to super_admin_root_path
elsif @user.community.present?
redirect_to member_root_path
else
redirect_to root_path
end
else
@user.password = nil
@user.password_confirmation = nil
Expand Down
12 changes: 0 additions & 12 deletions rails/app/controllers/registrations_controller.rb

This file was deleted.

35 changes: 35 additions & 0 deletions rails/app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class SessionsController < ApplicationController
skip_before_action :authenticate_user!

def new
# render login form
end

# Create session
def create
user = User.where(username: login_params[:login]).or(User.where(email: login_params[:login])).first

if session[:user_id] == user&.id
redirect_to root_path, notice: t("devise.failure.already_authenticated")
elsif user.authenticate(login_params[:password])
session[:user_id] = user.id
user.update_tracked_fields(request)
redirect_to root_path, notice: t("devise.sessions.signed_in")
else
flash.now.alert = t("devise.failure.not_found_in_database", authentication_keys: "login")
render :new
end
end

# Delete sessions
def destroy
session.delete(:user_id)
redirect_to login_path, notice: t("devise.sessions.signed_out")
end

private

def login_params
params.require(:user).permit(:login, :password)
end
end
32 changes: 16 additions & 16 deletions rails/app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
class User < ApplicationRecord
# Include default devise modules. Others available are: :registerable,
# :recoverable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :rememberable, :trackable, :validatable
has_secure_password

attr_accessor :login

belongs_to :community, optional: true, touch: true
has_one_attached :photo

validates :photo, content_type: [:png, :jpeg], size: { less_than_or_equal_to: 5.megabytes }
# Username is required for logging in with Devise. Email is optional.
# Remove email_required? override if username changes to optional.
validates :username, uniqueness: true, presence: true, format: {without: /\s/, message: :invalid_username_format}

enum role: {
Expand All @@ -30,21 +27,24 @@ def display_name
name.presence || username
end

# Override Devise authentication to allow lookup via username or email
def self.find_first_by_auth_conditions(tainted_conditions)
if (login = tainted_conditions.delete(:login))
where(username: login).or(where(email: login)).first
else
super
end
def update_tracked_fields(request)
old_current, new_current = self.current_sign_in_at, Time.now.utc
self.last_sign_in_at = old_current || new_current
self.current_sign_in_at = new_current

old_current, new_current = self.current_sign_in_ip, request.remote_ip
self.last_sign_in_ip = old_current || new_current
self.current_sign_in_ip = new_current

self.sign_in_count ||= 0
self.sign_in_count += 1
end

protected

# Override Devise Validatable: email is not required (username is)
def email_required?
false
end
# :password_digest is required for has_secure_password;
# mapped to :encrypted_password since that's what Devise used previously.
alias_attribute :password_digest, :encrypted_password
end

# == Schema Information
Expand Down

This file was deleted.

7 changes: 0 additions & 7 deletions rails/app/views/devise/mailer/email_changed.html.erb

This file was deleted.

3 changes: 0 additions & 3 deletions rails/app/views/devise/mailer/password_change.html.erb

This file was deleted.

This file was deleted.

7 changes: 0 additions & 7 deletions rails/app/views/devise/mailer/unlock_instructions.html.erb

This file was deleted.

57 changes: 0 additions & 57 deletions rails/app/views/devise/registrations/edit.html.erb

This file was deleted.

0 comments on commit 687abea

Please sign in to comment.