diff --git a/Gemfile b/Gemfile index a62f8ee..81b24ff 100644 --- a/Gemfile +++ b/Gemfile @@ -39,5 +39,3 @@ end gem 'chroma' gem 'solid_queue', '~> 1.0' - -gem "bcrypt", "~> 3.1" diff --git a/Gemfile.lock b/Gemfile.lock index ca48703..9ea8033 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -81,7 +81,6 @@ GEM babel-source (>= 4.0, < 6) execjs (~> 2.0) base64 (0.2.0) - bcrypt (3.1.20) benchmark (0.4.0) bigdecimal (3.1.8) bindex (0.8.1) @@ -364,7 +363,6 @@ PLATFORMS DEPENDENCIES annotaterb - bcrypt (~> 3.1) bootsnap chroma csv diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb index abaef27..1cc97c6 100644 --- a/app/channels/application_cable/connection.rb +++ b/app/channels/application_cable/connection.rb @@ -2,17 +2,5 @@ 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 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 54431ec..57926f3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,7 +1,6 @@ # Copyright (C) 2024 Manuel Bustillo class ApplicationController < ActionController::Base - include Authentication after_action :set_csrf_cookie skip_before_action :verify_authenticity_token, if: :development_swagger? diff --git a/app/controllers/concerns/authentication.rb b/app/controllers/concerns/authentication.rb deleted file mode 100644 index 5275e10..0000000 --- a/app/controllers/concerns/authentication.rb +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (C) 2024 Manuel Bustillo - -module Authentication - extend ActiveSupport::Concern - - included do - before_action :require_authentication - helper_method :authenticated? - 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]) - end - - - def request_authentication - session[:return_to_after_authenticating] = request.url - redirect_to new_session_path - end - - def after_authentication_url - session.delete(:return_to_after_authenticating) || root_url - 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 - Current.session.destroy - cookies.delete(:session_id) - end -end diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb deleted file mode 100644 index 1189710..0000000 --- a/app/controllers/passwords_controller.rb +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (C) 2024 Manuel Bustillo - -class PasswordsController < ApplicationController - allow_unauthenticated_access - before_action :set_user_by_token, only: :update - - def create - if user = User.find_by(email_address: params[:email_address]) - PasswordsMailer.reset(user).deliver_later - end - - render json: {}, status: :created - end - - def update - if @user.update(params.permit(:password, :password_confirmation)) - render json: {}, status: :ok - else - render json: { errors: @user.errors.full_messages }, status: :unprocessable_entity - end - end - - private - - def set_user_by_token - @user = User.find_by_password_reset_token!(params[:token]) - rescue ActiveSupport::MessageVerifier::InvalidSignature - render json: { errors: ['Password reset link is invalid or has expired.'] }, status: :unprocessable_entity - end -end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb deleted file mode 100644 index aa74562..0000000 --- a/app/controllers/sessions_controller.rb +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2024 Manuel Bustillo - -class SessionsController < ApplicationController - allow_unauthenticated_access only: :create - rate_limit to: 10, within: 3.minutes, only: :create, - with: -> { render json: { errors: ['Rate limit exceeded'] }, status: :too_many_requests } - - def create - if user = User.authenticate_by(params.permit(:email_address, :password)) - start_new_session_for user - render json: {}, status: :created - else - render json: { errors: ['Invalid email address or password'] }, status: :unauthorized - end - end - - def destroy - terminate_session - render json: {}, status: :ok - end -end diff --git a/app/mailers/passwords_mailer.rb b/app/mailers/passwords_mailer.rb deleted file mode 100644 index f3692f0..0000000 --- a/app/mailers/passwords_mailer.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) 2024 Manuel Bustillo - -class PasswordsMailer < ApplicationMailer - def reset(user) - @user = user - mail subject: "Reset your password", to: user.email_address - end -end diff --git a/app/models/current.rb b/app/models/current.rb deleted file mode 100644 index f7b1ab9..0000000 --- a/app/models/current.rb +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (C) 2024 Manuel Bustillo - -class Current < ActiveSupport::CurrentAttributes - attribute :session - delegate :user, to: :session, allow_nil: true -end diff --git a/app/models/session.rb b/app/models/session.rb deleted file mode 100644 index 9ba68b4..0000000 --- a/app/models/session.rb +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (C) 2024 Manuel Bustillo - -# == Schema Information -# -# Table name: sessions -# -# id :bigint not null, primary key -# ip_address :string -# user_agent :string -# created_at :datetime not null -# updated_at :datetime not null -# user_id :bigint not null -# -# Indexes -# -# index_sessions_on_user_id (user_id) -# -# Foreign Keys -# -# fk_rails_... (user_id => users.id) -# -class Session < ApplicationRecord - belongs_to :user -end diff --git a/app/models/user.rb b/app/models/user.rb deleted file mode 100644 index 6c752a9..0000000 --- a/app/models/user.rb +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (C) 2024 Manuel Bustillo - -# == Schema Information -# -# Table name: users -# -# id :bigint not null, primary key -# email_address :string not null -# password_digest :string not null -# created_at :datetime not null -# updated_at :datetime not null -# -# Indexes -# -# index_users_on_email_address (email_address) UNIQUE -# -class User < ApplicationRecord - has_secure_password - has_many :sessions, dependent: :destroy - - normalizes :email_address, with: ->(e) { e.strip.downcase } -end diff --git a/app/views/passwords_mailer/reset.html.erb b/app/views/passwords_mailer/reset.html.erb deleted file mode 100644 index 9b536ff..0000000 --- a/app/views/passwords_mailer/reset.html.erb +++ /dev/null @@ -1,6 +0,0 @@ -<%# Copyright (C) 2024 Manuel Bustillo %> - -

- You can reset your password within the next 15 minutes on - <%= link_to "this password reset page", edit_password_url(@user.password_reset_token) %>. -

diff --git a/app/views/passwords_mailer/reset.text.erb b/app/views/passwords_mailer/reset.text.erb deleted file mode 100644 index 0ce9c12..0000000 --- a/app/views/passwords_mailer/reset.text.erb +++ /dev/null @@ -1,4 +0,0 @@ -<%# Copyright (C) 2024 Manuel Bustillo %> - -You can reset your password within the next 15 minutes on this password reset page: -<%= edit_password_url(@user.password_reset_token) %> diff --git a/config/routes.rb b/config/routes.rb index ed59be2..c9d7ee6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,8 +1,6 @@ # Copyright (C) 2024 Manuel Bustillo Rails.application.routes.draw do - resource :session, only: %i[create destroy] - resources :passwords, param: :token, only: %w[create update] mount Rswag::Ui::Engine => '/api-docs' mount Rswag::Api::Engine => '/api-docs' resources :groups, only: :index diff --git a/db/migrate/20241118232609_create_users.rb b/db/migrate/20241118232609_create_users.rb deleted file mode 100644 index b1f1381..0000000 --- a/db/migrate/20241118232609_create_users.rb +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (C) 2024 Manuel Bustillo - -class CreateUsers < ActiveRecord::Migration[8.0] - def change - create_table :users do |t| - t.string :email_address, null: false - t.string :password_digest, null: false - - t.timestamps - end - add_index :users, :email_address, unique: true - end -end diff --git a/db/migrate/20241118232618_create_sessions.rb b/db/migrate/20241118232618_create_sessions.rb deleted file mode 100644 index 3cc4be3..0000000 --- a/db/migrate/20241118232618_create_sessions.rb +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (C) 2024 Manuel Bustillo - -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 diff --git a/db/schema.rb b/db/schema.rb index 02eeea6..c54ec05 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -12,7 +12,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2024_11_18_232618) do +ActiveRecord::Schema[8.0].define(version: 2024_11_11_063741) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -60,15 +60,6 @@ ActiveRecord::Schema[8.0].define(version: 2024_11_18_232618) do t.index ["tables_arrangement_id"], name: "index_seats_on_tables_arrangement_id" end - create_table "sessions", force: :cascade do |t| - t.bigint "user_id", null: false - t.string "ip_address" - t.string "user_agent" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["user_id"], name: "index_sessions_on_user_id" - end - create_table "solid_queue_blocked_executions", force: :cascade do |t| t.bigint "job_id", null: false t.string "queue_name", null: false @@ -197,19 +188,10 @@ ActiveRecord::Schema[8.0].define(version: 2024_11_18_232618) do t.string "name", null: false end - create_table "users", force: :cascade do |t| - t.string "email_address", null: false - t.string "password_digest", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["email_address"], name: "index_users_on_email_address", unique: true - end - add_foreign_key "groups", "groups", column: "parent_id" add_foreign_key "guests", "groups" add_foreign_key "seats", "guests" add_foreign_key "seats", "tables_arrangements", on_delete: :cascade - add_foreign_key "sessions", "users" add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_claimed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade add_foreign_key "solid_queue_failed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade diff --git a/spec/requests/passwords_spec.rb b/spec/requests/passwords_spec.rb deleted file mode 100644 index c83a450..0000000 --- a/spec/requests/passwords_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (C) 2024 Manuel Bustillo - -require 'swagger_helper' - -RSpec.describe 'passwords', type: :request do - path '/passwords' do - post('send a password (re)set email') do - tags 'Passwords' - consumes 'application/json' - produces 'application/json' - parameter name: :body, in: :body, schema: { - type: :object, - required: [:email_address], - properties: { - email_address: { type: :string, format: :email } - } - } - - response_empty_201 - end - end - - path '/passwords/{token}' do - parameter name: 'token', in: :path, type: :string, description: 'token' - put('update password') do - tags 'Passwords' - consumes 'application/json' - produces 'application/json' - parameter name: :body, in: :body, schema: { - type: :object, - required: %i[password password_confirmation], - properties: { - password: { type: :string }, - password_confirmation: { type: :string } - } - } - - response_empty_200 - response_422 - end - end -end diff --git a/spec/requests/sessions_spec.rb b/spec/requests/sessions_spec.rb deleted file mode 100644 index f836a93..0000000 --- a/spec/requests/sessions_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2024 Manuel Bustillo - -require 'swagger_helper' - -RSpec.describe 'sessions', type: :request do - path '/session' do - delete('delete session') do - tags 'Sessions' - produces 'application/json' - response_empty_200 - end - - post('create session') do - tags 'Sessions' - consumes 'application/json' - produces 'application/json' - parameter name: :body, in: :body, schema: { - type: :object, - required: %i[email_address password], - properties: { - email_address: { type: :string, format: :email }, - password: { type: :string } - } - } - - response_empty_201 - response_401 - response_429 - end - end -end diff --git a/spec/swagger_response_helper.rb b/spec/swagger_response_helper.rb index d0812dd..1f84ebd 100644 --- a/spec/swagger_response_helper.rb +++ b/spec/swagger_response_helper.rb @@ -9,22 +9,6 @@ module SwaggerResponseHelper end end - def response_429 - response(429, 'Rate limit exceeded') do - produces 'application/json' - error_schema - xit - end - end - - def response_401 - response(401, 'Unauthorized') do - produces 'application/json' - error_schema - xit - end - end - def response_empty_200 response(200, 'Success') do produces 'application/json'