Sessions!

This commit is contained in:
Trevor Vallender 2024-04-21 15:01:10 +01:00
parent 21547341c3
commit 8fe132f2d1
17 changed files with 125 additions and 8 deletions

View File

@ -1,4 +1,6 @@
class AccountVerificationsController < ApplicationController class AccountVerificationsController < ApplicationController
skip_before_action :authenticate, only: [ :show ]
def show def show
user = User.find_by_token_for(:email_verification, params[:id]) user = User.find_by_token_for(:email_verification, params[:id])
unless user unless user
@ -8,6 +10,6 @@ class AccountVerificationsController < ApplicationController
user.update(verified: true) user.update(verified: true)
UserMailer.with(user: user).email_verified.deliver_later UserMailer.with(user: user).email_verified.deliver_later
flash[:notice] = t(".success") flash[:notice] = t(".success")
redirect_to :root # TODO: New session path redirect_to login_path
end end
end end

View File

@ -1,2 +1,15 @@
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
before_action :authenticate
private
def authenticate
Rails.logger.error "Session: #{session.inspect}"
if authenticated_user = User.find_by(id: session[:user_id])
Current.user = authenticated_user
else
flash[:alert] = t("not_authenticated")
redirect_to login_path
end
end
end end

View File

@ -0,0 +1,28 @@
class SessionsController < ApplicationController
skip_before_action :authenticate, only: [ :new, :create ]
def new
end
def create
Current.user = User.authenticate_by(
username: params[:username],
password: params[:password],
)
if Current.user
session[:user_id] = Current.user.id
flash[:notice] = t(".success", name: Current.user.first_name)
redirect_to :root
else
flash[:alert] = t(".error")
render :new, status: :unprocessable_entity
end
end
def destroy
reset_session
Current.user = nil
flash[:notice] = t(".success")
redirect_to login_path
end
end

View File

@ -0,0 +1,4 @@
class TodosController < ApplicationController
def index
end
end

View File

@ -1,4 +1,6 @@
class UsersController < ApplicationController class UsersController < ApplicationController
skip_before_action :authenticate, only: [ :new, :create ]
def new def new
@user = User.new @user = User.new
end end
@ -9,7 +11,7 @@ class UsersController < ApplicationController
token = @user.generate_token_for(:email_verification) token = @user.generate_token_for(:email_verification)
UserMailer.with(user: @user, token: token).email_verification.deliver_later UserMailer.with(user: @user, token: token).email_verification.deliver_later
flash[:notice] = t(".success", name: @user.first_name) flash[:notice] = t(".success", name: @user.first_name)
redirect_to :root redirect_to login_path
else else
flash[:alert] = t(".error", error: @user.errors.full_messages.to_sentence) flash[:alert] = t(".error", error: @user.errors.full_messages.to_sentence)
render :new, status: :unprocessable_entity render :new, status: :unprocessable_entity

View File

@ -0,0 +1,5 @@
module SessionsHelper
def logged_in?
session[:user_id].present?
end
end

3
app/models/current.rb Normal file
View File

@ -0,0 +1,3 @@
class Current < ActiveSupport::CurrentAttributes
attribute :user
end

View File

@ -16,6 +16,15 @@
<header> <header>
<h1><%= link_to t("forg"), root_path %></h1> <h1><%= link_to t("forg"), root_path %></h1>
</header> </header>
<nav>
<ul>
<li><%= link_to t("forg"), root_path %></li>
<% if logged_in? %>
<li><%= link_to t("log_out"), logout_path, data: {turbo_method: :delete} %></li>
<% else %>
<li><%= link_to t("log_in"), login_path %></li>
<li><%= link_to t("sign_up"), new_user_path %></li>
<% end %>
<%= render partial: "shared/flash_messages" %> <%= render partial: "shared/flash_messages" %>
<main> <main>
<%= yield %> <%= yield %>

View File

@ -0,0 +1,16 @@
<% content_for :title, t(".log_in") %>
<h1><%= t(".log_in") %></h1>
<section class="inset">
<%= form_with url: sessions_path do |f| %>
<%= f.label :username %>
<%= f.text_field :username %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit t(".log_in") %>
<% end %>
</section>

View File

@ -0,0 +1 @@
<p>Hello</p>

View File

@ -1,6 +1,6 @@
<% content_for :title, "Sign up" %> <% content_for :title, t(".sign_up") %>
<h2><%= t(".sign_up") %></h2> <h1><%= t(".sign_up") %></h1>
<%= render partial: "users/form", <%= render partial: "users/form",
locals: { user: @user, button_text: t(".sign_up") } %> locals: { user: @user, button_text: t(".sign_up") } %>

View File

@ -1,5 +1,9 @@
en: en:
forg: Forg forg: Forg
log_in: Log in
log_out: Log out
sign_up: Sign up
not_authenticated: You need to log in to access this page.
layouts: layouts:
mailer: mailer:
greeting: "Hello, %{name}" greeting: "Hello, %{name}"
@ -11,6 +15,15 @@ en:
show: show:
success: "Thanks for verifying your email address! You can now log in." success: "Thanks for verifying your email address! You can now log in."
error: "Invalid token, could not verify your account." error: "Invalid token, could not verify your account."
sessions:
create:
success: "Hello, %{name}!"
error: "Could not sign in. Please check your email and password."
new:
log_in: Log in
destroy:
log_out: Log out
success: "You have signed out."
users: users:
validations: validations:
email_format: "must be a valid email address" email_format: "must be a valid email address"

View File

@ -1,9 +1,15 @@
Rails.application.routes.draw do Rails.application.routes.draw do
get 'todos/index'
default_url_options host: "forg-app.com" default_url_options host: "forg-app.com"
root "users#new" root "todos#index"
get "login" => "sessions#new", as: :login
delete "logout" => "sessions#destroy", as: :logout
resources :users, only: %i[new create] resources :users, only: %i[new create]
resources :account_verifications, only: %i[show] resources :account_verifications, only: %i[show]
resources :sessions, only: %i[new create destroy]
get "up" => "rails/health#show", as: :rails_health_check get "up" => "rails/health#show", as: :rails_health_check
end end

View File

@ -9,6 +9,6 @@ class AccountVerificationsControllerTest < ActionDispatch::IntegrationTest
end end
user.reload user.reload
assert user.verified assert user.verified
assert_redirected_to root_url assert_redirected_to login_path
end end
end end

View File

@ -10,7 +10,7 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
assert_changes("User.count", +1) do assert_changes("User.count", +1) do
post(users_url, params: { user: user_params }) post(users_url, params: { user: user_params })
end end
assert_redirected_to :root assert_redirected_to login_path
end end
test "should email user for confirmation" do test "should email user for confirmation" do

View File

@ -0,0 +1,15 @@
require "application_system_test_case"
class SignUpsTest < ApplicationSystemTestCase
test "can log in, then out" do
visit new_session_url
fill_in attr_name(User, :username), with: users(:trevor).username
fill_in attr_name(User, :password), with: "password"
click_button I18n.t("sessions.new.log_in")
assert_text I18n.t("sessions.create.success", name: users(:trevor).first_name)
click_on I18n.t("sessions.destroy.log_out")
assert_text I18n.t("sessions.destroy.success")
end
end

View File

@ -9,7 +9,7 @@ class SignUpsTest < ApplicationSystemTestCase
fill_in attr_name(User, :email), with: "awesome_user@example.com" fill_in attr_name(User, :email), with: "awesome_user@example.com"
fill_in attr_name(User, :password), with: "password" fill_in attr_name(User, :password), with: "password"
fill_in attr_name(User, :password_confirmation), with: "password" fill_in attr_name(User, :password_confirmation), with: "password"
click_on I18n.t("users.new.sign_up") click_button I18n.t("users.new.sign_up")
assert_text I18n.t("users.create.success", name: "Awesome") assert_text I18n.t("users.create.success", name: "Awesome")
end end