From 0b938a83751abac7e903044c7e1ec8ac2d1c78e8 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 6 Aug 2025 14:04:42 -0400 Subject: [PATCH 1/2] Account.signal_account is optional again Also delete the no-op user password migration that I accidentally committed last month. --- app/models/account/signal_account.rb | 2 +- db/migrate/20250702154620_remove_password_from_users.rb | 5 ----- .../20250806174718_allow_null_for_accounts_queenbee_id.rb | 5 +++++ db/schema.rb | 4 ++-- db/schema_cache.yml | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 db/migrate/20250702154620_remove_password_from_users.rb create mode 100644 db/migrate/20250806174718_allow_null_for_accounts_queenbee_id.rb diff --git a/app/models/account/signal_account.rb b/app/models/account/signal_account.rb index a01af7ad2..55dc43e33 100644 --- a/app/models/account/signal_account.rb +++ b/app/models/account/signal_account.rb @@ -2,7 +2,7 @@ module Account::SignalAccount extend ActiveSupport::Concern included do - belongs_to :signal_account, class_name: "SignalId::Account", primary_key: :queenbee_id, foreign_key: :queenbee_id + belongs_to :signal_account, class_name: "SignalId::Account", primary_key: :queenbee_id, foreign_key: :queenbee_id, optional: true end class_methods do diff --git a/db/migrate/20250702154620_remove_password_from_users.rb b/db/migrate/20250702154620_remove_password_from_users.rb deleted file mode 100644 index 75173ad1a..000000000 --- a/db/migrate/20250702154620_remove_password_from_users.rb +++ /dev/null @@ -1,5 +0,0 @@ -class RemovePasswordFromUsers < ActiveRecord::Migration[8.1] - def change - remove_column :users, :password, :string - end -end diff --git a/db/migrate/20250806174718_allow_null_for_accounts_queenbee_id.rb b/db/migrate/20250806174718_allow_null_for_accounts_queenbee_id.rb new file mode 100644 index 000000000..d9cc0c58e --- /dev/null +++ b/db/migrate/20250806174718_allow_null_for_accounts_queenbee_id.rb @@ -0,0 +1,5 @@ +class AllowNullForAccountsQueenbeeId < ActiveRecord::Migration[8.1] + def change + change_column_null :accounts, :queenbee_id, true + end +end diff --git a/db/schema.rb b/db/schema.rb index ac37f9d27..7b2e27f91 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.1].define(version: 2025_07_23_165724) do +ActiveRecord::Schema[8.1].define(version: 2025_08_06_174718) do create_table "accesses", force: :cascade do |t| t.datetime "accessed_at" t.integer "collection_id", null: false @@ -28,7 +28,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_07_23_165724) do t.datetime "created_at", null: false t.string "join_code" t.string "name", null: false - t.integer "queenbee_id", null: false + t.integer "queenbee_id" t.datetime "updated_at", null: false t.index ["queenbee_id"], name: "index_accounts_on_queenbee_id", unique: true end diff --git a/db/schema_cache.yml b/db/schema_cache.yml index 4927d6ce2..9bff2e19f 100644 --- a/db/schema_cache.yml +++ b/db/schema_cache.yml @@ -128,7 +128,7 @@ columns: name: queenbee_id cast_type: *3 sql_type_metadata: *4 - 'null': false + 'null': true default: default_function: collation: @@ -2703,4 +2703,4 @@ indexes: comment: valid: true workflows: [] -version: 20250723165724 +version: 20250806174718 From 57269b1b9c8ddd335904cc578d2201cbde674b18 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 6 Aug 2025 14:10:33 -0400 Subject: [PATCH 2/2] Allow local authentication with LOCAL_AUTHENTICATION=1 You can touch `tmp/local-auth.txt` to persist this setting. --- app/controllers/concerns/authentication.rb | 8 +-- app/controllers/sessions_controller.rb | 23 +++++++- app/controllers/signup/base_controller.rb | 5 ++ app/helpers/login_helper.rb | 17 ++++++ app/models/account/signal_account.rb | 4 +- app/models/user/signal_user.rb | 4 +- app/views/sessions/new.html.erb | 30 +++++++++++ app/views/signup/accounts/new.html.erb | 2 +- app/views/users/new.html.erb | 2 +- bin/dev | 4 ++ config/initializers/signal_id.rb | 7 +++ config/routes.rb | 2 +- .../controller_authentication_test.rb | 18 +++++++ test/controllers/sessions_controller_test.rb | 53 ++++++++++++++++++- test/test_helper.rb | 10 ++++ 15 files changed, 178 insertions(+), 11 deletions(-) create mode 100644 app/helpers/login_helper.rb create mode 100644 app/views/sessions/new.html.erb diff --git a/app/controllers/concerns/authentication.rb b/app/controllers/concerns/authentication.rb index e6d3b7ddd..0cd5aa422 100644 --- a/app/controllers/concerns/authentication.rb +++ b/app/controllers/concerns/authentication.rb @@ -7,6 +7,8 @@ module Authentication before_action :require_authentication helper_method :authenticated? + + include LoginHelper end class_methods do @@ -53,11 +55,9 @@ module Authentication def request_authentication(untenanted: false) if ApplicationRecord.current_tenant.present? session[:return_to_after_authenticating] = request.url - redirect_to Launchpad.login_url(product: true, account: Account.sole), allow_other_host: true - else - # Don't save the current untenanted URL, because it's just going to bounce back to Launchpad after login anyway. - redirect_to Launchpad.login_url(product: true), allow_other_host: true end + + redirect_to_login_url end def after_authentication_url diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index fa7d98974..8993d8c9a 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,6 +1,27 @@ class SessionsController < ApplicationController + before_action :require_local_auth, only: %i[ new create ] + require_unauthenticated_access only: %i[ new create ] + rate_limit to: 10, within: 3.minutes, only: :create, with: -> { redirect_to new_session_path, alert: "Try again later." } + + def new + end + + def create + if user = User.active.authenticate_by(params.permit(:email_address, :password)) + start_new_session_for user + redirect_to after_authentication_url + else + redirect_to new_session_path, alert: "Try another email address or password." + end + end + def destroy terminate_session - redirect_to Launchpad.login_url, allow_other_host: true + redirect_to_login_url end + + private + def require_local_auth + head :forbidden unless Rails.application.config.x.local_authentication + end end diff --git a/app/controllers/signup/base_controller.rb b/app/controllers/signup/base_controller.rb index 088937b04..40ae83e92 100644 --- a/app/controllers/signup/base_controller.rb +++ b/app/controllers/signup/base_controller.rb @@ -1,5 +1,6 @@ class Signup::BaseController < ApplicationController require_untenanted_access + before_action :redirect_if_local_auth # TODO: Remove this auth before launch. http_basic_authenticate_with( @@ -33,4 +34,8 @@ class Signup::BaseController < ApplicationController redirect_to account.signal_account.owner.remote_login_url(proceed_to: root_path), allow_other_host: true end + + def redirect_if_local_auth + render plain: "Unauthorized", status: :unauthorized if Rails.application.config.x.local_authentication + end end diff --git a/app/helpers/login_helper.rb b/app/helpers/login_helper.rb new file mode 100644 index 000000000..717ed3711 --- /dev/null +++ b/app/helpers/login_helper.rb @@ -0,0 +1,17 @@ +module LoginHelper + def login_url + if ApplicationRecord.current_tenant + if Rails.application.config.x.local_authentication + new_session_path + else + Launchpad.login_url(product: true, account: Account.sole) + end + else + Launchpad.login_url(product: true) + end + end + + def redirect_to_login_url + redirect_to login_url, allow_other_host: true + end +end diff --git a/app/models/account/signal_account.rb b/app/models/account/signal_account.rb index 55dc43e33..dbacfd04e 100644 --- a/app/models/account/signal_account.rb +++ b/app/models/account/signal_account.rb @@ -2,7 +2,9 @@ module Account::SignalAccount extend ActiveSupport::Concern included do - belongs_to :signal_account, class_name: "SignalId::Account", primary_key: :queenbee_id, foreign_key: :queenbee_id, optional: true + unless Rails.application.config.x.local_authentication + belongs_to :signal_account, class_name: "SignalId::Account", primary_key: :queenbee_id, foreign_key: :queenbee_id, optional: true + end end class_methods do diff --git a/app/models/user/signal_user.rb b/app/models/user/signal_user.rb index 16bee49bc..924cfe87d 100644 --- a/app/models/user/signal_user.rb +++ b/app/models/user/signal_user.rb @@ -2,6 +2,8 @@ module User::SignalUser extend ActiveSupport::Concern included do - belongs_to :signal_user, dependent: :destroy, class_name: "SignalId::User", optional: true + unless Rails.application.config.x.local_authentication + belongs_to :signal_user, dependent: :destroy, class_name: "SignalId::User", optional: true + end end end diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb new file mode 100644 index 000000000..d806a904f --- /dev/null +++ b/app/views/sessions/new.html.erb @@ -0,0 +1,30 @@ +<% @page_title = "Sign in" %> + +
" style="--panel-size: 55ch;"> +

Fizzy

+ + <%= form_with url: session_path, class: "flex flex-column gap txt-large" do |form| %> +
+ +
+ +
+ +
+ + + <% end %> +
+ +<% content_for :footer do %> +
Fizzy™ version 0
+<% end %> diff --git a/app/views/signup/accounts/new.html.erb b/app/views/signup/accounts/new.html.erb index 9f69eba4b..361a75bcf 100644 --- a/app/views/signup/accounts/new.html.erb +++ b/app/views/signup/accounts/new.html.erb @@ -52,7 +52,7 @@

Already have an account? - <%= link_to "Sign in", Launchpad.login_url(product: true), class: "decorated" %> + <%= link_to "Sign in", login_url, class: "decorated" %>

diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index f7d407389..2e8442da3 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -4,7 +4,7 @@