From 8e0cb930af27162cce7407db7ae18ee2c75ed9ed Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Fri, 3 Oct 2025 13:35:36 -0400 Subject: [PATCH] Delete SignalId concerns from the codebase including Signup for now, will rebuild it with just QB --- Gemfile.lock | 76 ------ app/models/account.rb | 15 ++ bin/setup | 4 +- config/ci.rb | 1 - db/seeds.rb | 22 +- gems/fizzy-saas/Gemfile | 6 - gems/fizzy-saas/Gemfile.lock | 243 ------------------ .../controllers/signup/accounts_controller.rb | 30 --- .../app/controllers/signup/base_controller.rb | 36 --- .../signup/completions_controller.rb | 23 -- .../controllers/signup/sessions_controller.rb | 9 - .../app/models/account/signal_account.rb | 30 --- gems/fizzy-saas/app/models/launchpad.rb | 24 -- gems/fizzy-saas/app/models/signup.rb | 159 ------------ .../views/sessions/launchpad/show.html.erb | 3 - .../app/views/signup/accounts/new.html.erb | 58 ----- .../app/views/signup/completions/new.html.erb | 1 - gems/fizzy-saas/config/routes.rb | 7 - gems/fizzy-saas/fizzy-saas.gemspec | 1 - gems/fizzy-saas/lib/fizzy/saas/engine.rb | 28 -- .../signup/accounts_controller_test.rb | 103 -------- .../models/account/signal_account_test.rb | 41 --- gems/fizzy-saas/test/models/signup_test.rb | 149 ----------- gems/fizzy-saas/test/test_helper.rb | 7 - script/load-prod-db-in-dev.rb | 31 ++- .../202510-migrate-to-local-authentication.rb | 53 ---- script/migrations/bootstrap-signal-id.rb | 117 --------- test/models/account_test.rb | 23 ++ 28 files changed, 61 insertions(+), 1239 deletions(-) delete mode 100644 gems/fizzy-saas/app/controllers/signup/accounts_controller.rb delete mode 100644 gems/fizzy-saas/app/controllers/signup/base_controller.rb delete mode 100644 gems/fizzy-saas/app/controllers/signup/completions_controller.rb delete mode 100644 gems/fizzy-saas/app/controllers/signup/sessions_controller.rb delete mode 100644 gems/fizzy-saas/app/models/account/signal_account.rb delete mode 100644 gems/fizzy-saas/app/models/launchpad.rb delete mode 100644 gems/fizzy-saas/app/models/signup.rb delete mode 100644 gems/fizzy-saas/app/views/sessions/launchpad/show.html.erb delete mode 100644 gems/fizzy-saas/app/views/signup/accounts/new.html.erb delete mode 100644 gems/fizzy-saas/app/views/signup/completions/new.html.erb delete mode 100644 gems/fizzy-saas/test/controllers/signup/accounts_controller_test.rb delete mode 100644 gems/fizzy-saas/test/models/account/signal_account_test.rb delete mode 100644 gems/fizzy-saas/test/models/signup_test.rb delete mode 100755 script/migrations/202510-migrate-to-local-authentication.rb delete mode 100755 script/migrations/bootstrap-signal-id.rb diff --git a/Gemfile.lock b/Gemfile.lock index 16dca130d..bd82778c6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,19 +1,3 @@ -GIT - remote: https://github.com/basecamp/file_repository - revision: 8c8d1594f3ec7e8c0938e6a7f7def521692344e4 - ref: 8c8d1594f3ec7e8c0938e6a7f7def521692344e4 - specs: - file_repository (1.4.6) - -GIT - remote: https://github.com/basecamp/portfolio - revision: 86411a53d19a42ce44705a50ebe7c22828597991 - ref: 86411a53d19a42ce44705a50ebe7c22828597991 - specs: - portfolio (5.2.0) - activesupport - file_repository (>= 1.4.4) - GIT remote: https://github.com/basecamp/queenbee-plugin revision: eb01c697de1ad028afc65cc7d9b5345a7a8e849f @@ -24,16 +8,6 @@ GIT builder rexml -GIT - remote: https://github.com/basecamp/queuety - revision: bf7e2a552fb674533d3e092f06dbf9b5d1ebc753 - ref: bf7e2a552fb674533d3e092f06dbf9b5d1ebc753 - branch: rails4 - specs: - queuety (4.0.2) - activerecord - service_concurrency_prevention - GIT remote: https://github.com/basecamp/rails-structured-logging revision: 76960cb5c15fc2b6b5f7542e05d7dcc031cef9e6 @@ -42,31 +16,6 @@ GIT json rails (>= 6.0.0) -GIT - remote: https://github.com/basecamp/service_concurrency_prevention - revision: 320da99431718615ed86f8723e8b9d3259c602a3 - ref: 320da99431718615ed86f8723e8b9d3259c602a3 - specs: - service_concurrency_prevention (1.1.1) - activesupport - -GIT - remote: https://github.com/basecamp/signal_id - revision: d6c2a5ceed7bb57bf7dcdebdb439e7cd526fca09 - ref: d6c2a5ceed7bb57bf7dcdebdb439e7cd526fca09 - branch: rails4 - specs: - signal_id (4.3.2) - bcrypt-ruby (>= 3.0.0) - google-id-token (>= 1.4.0) - mocha - multi_json - portfolio (>= 4.0) - pwned (~> 2.0) - queuety (>= 3.0) - rails (>= 4.0.2) - rails-controller-testing - GIT remote: https://github.com/crmne/ruby_llm.git revision: 32611afc114c5f40696dd42f8a1eaee6b6b81330 @@ -81,14 +30,6 @@ GIT marcel (~> 1.0) zeitwerk (~> 2) -GIT - remote: https://github.com/jeremy/mysql2.git - revision: b5766f5d296745d6aed014c8c0b7d82ef149ade1 - ref: b5766f5d296745d6aed014c8c0b7d82ef149ade1 - branch: force_latin1_to_utf8 - specs: - mysql2 (0.5.4.latin1utf8) - GIT remote: https://github.com/rails/rails.git revision: d8795bd762ab2716b6e7fd07a403566b28159cdc @@ -206,7 +147,6 @@ PATH queenbee rails (>= 8.1.0.beta1) rails_structured_logging - signal_id GEM remote: https://rubygems.org/ @@ -251,8 +191,6 @@ GEM aws-eventstream (~> 1, >= 1.0.2) base64 (0.3.0) bcrypt (3.1.20) - bcrypt-ruby (3.1.5) - bcrypt (>= 3.1.3) bcrypt_pbkdf (1.1.1) benchmark (0.4.1) bigdecimal (3.2.3) @@ -317,8 +255,6 @@ GEM addressable (>= 2.5.0) globalid (1.2.1) activesupport (>= 6.1) - google-id-token (1.4.2) - jwt (>= 1) hashdiff (1.2.1) i18n (1.14.7) concurrent-ruby (~> 1.0) @@ -391,7 +327,6 @@ GEM mocha (2.7.1) ruby2_keywords (>= 0.0.5) msgpack (1.8.0) - multi_json (1.17.0) multipart-post (2.4.1) net-http (0.6.0) uri @@ -464,7 +399,6 @@ GEM public_suffix (6.0.2) puma (7.0.3) nio4r (~> 2.0) - pwned (2.4.1) raabro (1.4.0) racc (1.8.1) rack (3.2.1) @@ -475,10 +409,6 @@ GEM rack (>= 1.3) rackup (2.2.1) rack (>= 3) - rails-controller-testing (1.0.5) - actionpack (>= 5.0.1.rc1) - actionview (>= 5.0.1.rc1) - activesupport (>= 5.0.1.rc1) rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest @@ -670,7 +600,6 @@ DEPENDENCIES bundler-audit capybara debug - file_repository (~> 1.4.5)! fizzy-saas! geared_pagination (~> 1.2) image_processing (~> 1.14) @@ -681,15 +610,12 @@ DEPENDENCIES lexxy mission_control-jobs mocha - mysql2! net-http-persistent platform_agent - portfolio (>= 4.6)! prometheus-client-mmap (~> 1.1) propshaft puma (>= 5.0) queenbee! - queuety! rails! rails_structured_logging! redcarpet @@ -700,8 +626,6 @@ DEPENDENCIES selenium-webdriver sentry-rails sentry-ruby - service_concurrency_prevention! - signal_id! solid_cable (>= 3.0) solid_cache (~> 1.0) solid_queue (~> 1.1) diff --git a/app/models/account.rb b/app/models/account.rb index c29f61005..5ee007e0e 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -3,6 +3,21 @@ class Account < ApplicationRecord has_many_attached :uploads + class << self + def create_with_admin_user(tenant_id:, account_name:, owner_name:, owner_email:) + account = create!(tenant_id:, name: account_name) + + User.create!( + name: owner_name, + email_address: owner_email, + role: "admin", + password: SecureRandom.hex(16) + ) + + account + end + end + def slug "/#{tenant}" end diff --git a/bin/setup b/bin/setup index 329858c5b..f1407fb90 100755 --- a/bin/setup +++ b/bin/setup @@ -15,9 +15,7 @@ load File.expand_path("../gems/fizzy-saas/bin/setup", __dir__) unless Bootstrap. puts "\n== Preparing database ==" if ARGV.include?("--reset") - system! "bin/rails db:drop db:create db:schema:load db:prepare" - system! "bin/rails db:fixtures:load" # load signal id fixtures before running fizzy seeds - system! "bin/rails db:seed" + system! "bin/rails db:drop db:create db:schema:load db:prepare db:seed" else system! "bin/rails db:prepare" end diff --git a/config/ci.rb b/config/ci.rb index 304d4cd49..be81c58c9 100644 --- a/config/ci.rb +++ b/config/ci.rb @@ -11,7 +11,6 @@ CI.run do step "Tests: Rails: SaaS config", "bin/rails test" step "Tests: Rails: OSS config", "OSS_CONFIG=1 bin/rails test" - step "Tests: 37id", "bin/rails 37id:test:units" step "Tests: System", "bin/rails test:system" if success? diff --git a/db/seeds.rb b/db/seeds.rb index 32532d258..5542dd3d1 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -13,26 +13,18 @@ end def create_tenant(signal_account_name, bare: false) if bare tenant_id = Digest::SHA256.hexdigest(signal_account_name)[0..8].to_i(16) - elsif Rails.application.config.x.oss_config - tenant_id = ActiveRecord::FixtureSet.identify signal_account_name else - signal_account = SignalId::Account.find_by_product_and_name!("fizzy", signal_account_name) - tenant_id = signal_account.queenbee_id + tenant_id = ActiveRecord::FixtureSet.identify signal_account_name end ApplicationRecord.destroy_tenant tenant_id ApplicationRecord.create_tenant(tenant_id) do - account = if bare || Rails.application.config.x.oss_config - Account.create(name: signal_account_name, tenant_id: tenant_id).tap do - User.create!( - name: "David Heinemeier Hansson", - email_address: "david@37signals.com", - password: "secret123456" - ) - end - else - Account.create_with_admin_user(tenant_id: tenant_id) - end + account = Account.create_with_admin_user( + tenant_id: tenant_id, + account_name: signal_account_name, + owner_name: "David Heinemeier Hansson", + owner_email: "david@37signals.com", + ) account.setup_basic_template end diff --git a/gems/fizzy-saas/Gemfile b/gems/fizzy-saas/Gemfile index 9f8dfd669..396a3192e 100644 --- a/gems/fizzy-saas/Gemfile +++ b/gems/fizzy-saas/Gemfile @@ -2,11 +2,5 @@ source "https://rubygems.org" git_source(:bc) { |repo| "https://github.com/basecamp/#{repo}" } # 37id and Queenbee integration -gem "signal_id", bc: "signal_id", branch: "rails4", ref: "d6c2a5ceed7bb57bf7dcdebdb439e7cd526fca09" -gem "mysql2", github: "jeremy/mysql2", branch: "force_latin1_to_utf8", ref: "b5766f5d296745d6aed014c8c0b7d82ef149ade1" # needed by signal_id -gem "queuety", bc: "queuety", branch: "rails4", ref: "bf7e2a552fb674533d3e092f06dbf9b5d1ebc753" # needed by signal_id -gem "service_concurrency_prevention", bc: "service_concurrency_prevention", ref: "320da99431718615ed86f8723e8b9d3259c602a3" # needed by queuety -gem "portfolio", ">= 4.6", bc: "portfolio", ref: "86411a53d19a42ce44705a50ebe7c22828597991" # needed by signal_id -gem "file_repository", "~> 1.4.5", bc: "file_repository", ref: "8c8d1594f3ec7e8c0938e6a7f7def521692344e4" # needed by portfolio gem "queenbee", bc: "queenbee-plugin", ref: "eb01c697de1ad028afc65cc7d9b5345a7a8e849f" gem "activeresource", require: "active_resource" # needed by queenbee diff --git a/gems/fizzy-saas/Gemfile.lock b/gems/fizzy-saas/Gemfile.lock index f5c6c0ef5..5d83987cd 100644 --- a/gems/fizzy-saas/Gemfile.lock +++ b/gems/fizzy-saas/Gemfile.lock @@ -1,19 +1,3 @@ -GIT - remote: https://github.com/basecamp/file_repository - revision: 8c8d1594f3ec7e8c0938e6a7f7def521692344e4 - ref: 8c8d1594f3ec7e8c0938e6a7f7def521692344e4 - specs: - file_repository (1.4.6) - -GIT - remote: https://github.com/basecamp/portfolio - revision: 86411a53d19a42ce44705a50ebe7c22828597991 - ref: 86411a53d19a42ce44705a50ebe7c22828597991 - specs: - portfolio (5.2.0) - activesupport - file_repository (>= 1.4.4) - GIT remote: https://github.com/basecamp/queenbee-plugin revision: eb01c697de1ad028afc65cc7d9b5345a7a8e849f @@ -24,118 +8,19 @@ GIT builder rexml -GIT - remote: https://github.com/basecamp/queuety - revision: bf7e2a552fb674533d3e092f06dbf9b5d1ebc753 - ref: bf7e2a552fb674533d3e092f06dbf9b5d1ebc753 - branch: rails4 - specs: - queuety (4.0.2) - activerecord - service_concurrency_prevention - -GIT - remote: https://github.com/basecamp/service_concurrency_prevention - revision: 320da99431718615ed86f8723e8b9d3259c602a3 - ref: 320da99431718615ed86f8723e8b9d3259c602a3 - specs: - service_concurrency_prevention (1.1.1) - activesupport - -GIT - remote: https://github.com/basecamp/signal_id - revision: d6c2a5ceed7bb57bf7dcdebdb439e7cd526fca09 - ref: d6c2a5ceed7bb57bf7dcdebdb439e7cd526fca09 - branch: rails4 - specs: - signal_id (4.3.2) - bcrypt-ruby (>= 3.0.0) - google-id-token (>= 1.4.0) - mocha - multi_json - portfolio (>= 4.0) - pwned (~> 2.0) - queuety (>= 3.0) - rails (>= 4.0.2) - rails-controller-testing - -GIT - remote: https://github.com/jeremy/mysql2.git - revision: b5766f5d296745d6aed014c8c0b7d82ef149ade1 - ref: b5766f5d296745d6aed014c8c0b7d82ef149ade1 - branch: force_latin1_to_utf8 - specs: - mysql2 (0.5.4.latin1utf8) - GEM remote: https://rubygems.org/ specs: - actioncable (8.0.2.1) - actionpack (= 8.0.2.1) - activesupport (= 8.0.2.1) - nio4r (~> 2.0) - websocket-driver (>= 0.6.1) - zeitwerk (~> 2.6) - actionmailbox (8.0.2.1) - actionpack (= 8.0.2.1) - activejob (= 8.0.2.1) - activerecord (= 8.0.2.1) - activestorage (= 8.0.2.1) - activesupport (= 8.0.2.1) - mail (>= 2.8.0) - actionmailer (8.0.2.1) - actionpack (= 8.0.2.1) - actionview (= 8.0.2.1) - activejob (= 8.0.2.1) - activesupport (= 8.0.2.1) - mail (>= 2.8.0) - rails-dom-testing (~> 2.2) - actionpack (8.0.2.1) - actionview (= 8.0.2.1) - activesupport (= 8.0.2.1) - nokogiri (>= 1.8.5) - rack (>= 2.2.4) - rack-session (>= 1.0.1) - rack-test (>= 0.6.3) - rails-dom-testing (~> 2.2) - rails-html-sanitizer (~> 1.6) - useragent (~> 0.16) - actiontext (8.0.2.1) - actionpack (= 8.0.2.1) - activerecord (= 8.0.2.1) - activestorage (= 8.0.2.1) - activesupport (= 8.0.2.1) - globalid (>= 0.6.0) - nokogiri (>= 1.8.5) - actionview (8.0.2.1) - activesupport (= 8.0.2.1) - builder (~> 3.1) - erubi (~> 1.11) - rails-dom-testing (~> 2.2) - rails-html-sanitizer (~> 1.6) - activejob (8.0.2.1) - activesupport (= 8.0.2.1) - globalid (>= 0.3.6) activemodel (8.0.2.1) activesupport (= 8.0.2.1) activemodel-serializers-xml (1.0.3) activemodel (>= 5.0.0.a) activesupport (>= 5.0.0.a) builder (~> 3.1) - activerecord (8.0.2.1) - activemodel (= 8.0.2.1) - activesupport (= 8.0.2.1) - timeout (>= 0.4.0) activeresource (6.1.4) activemodel (>= 6.0) activemodel-serializers-xml (~> 1.0) activesupport (>= 6.0) - activestorage (8.0.2.1) - actionpack (= 8.0.2.1) - activejob (= 8.0.2.1) - activerecord (= 8.0.2.1) - activesupport (= 8.0.2.1) - marcel (~> 1.0) activesupport (8.0.2.1) base64 benchmark (>= 0.3) @@ -150,143 +35,21 @@ GEM tzinfo (~> 2.0, >= 2.0.5) uri (>= 0.13.1) base64 (0.3.0) - bcrypt (3.1.20) - bcrypt-ruby (3.1.5) - bcrypt (>= 3.1.3) benchmark (0.4.1) bigdecimal (3.2.3) builder (3.3.0) concurrent-ruby (1.3.5) connection_pool (2.5.4) - crass (1.0.6) - date (3.4.1) drb (2.2.3) - erb (5.0.2) - erubi (1.13.1) - globalid (1.2.1) - activesupport (>= 6.1) - google-id-token (1.4.2) - jwt (>= 1) i18n (1.14.7) concurrent-ruby (~> 1.0) - io-console (0.8.1) - irb (1.15.2) - pp (>= 0.6.0) - rdoc (>= 4.0.0) - reline (>= 0.4.2) - jwt (3.1.2) - base64 logger (1.7.0) - loofah (2.24.1) - crass (~> 1.0.2) - nokogiri (>= 1.12.0) - mail (2.8.1) - mini_mime (>= 0.1.1) - net-imap - net-pop - net-smtp - marcel (1.0.4) - mini_mime (1.1.5) minitest (5.25.5) - mocha (2.7.1) - ruby2_keywords (>= 0.0.5) - multi_json (1.17.0) - net-imap (0.5.10) - date - net-protocol - net-pop (0.1.2) - net-protocol - net-protocol (0.2.2) - timeout - net-smtp (0.5.1) - net-protocol - nio4r (2.7.4) - nokogiri (1.18.9-aarch64-linux-gnu) - racc (~> 1.4) - nokogiri (1.18.9-aarch64-linux-musl) - racc (~> 1.4) - nokogiri (1.18.9-arm-linux-gnu) - racc (~> 1.4) - nokogiri (1.18.9-arm-linux-musl) - racc (~> 1.4) - nokogiri (1.18.9-arm64-darwin) - racc (~> 1.4) - nokogiri (1.18.9-x86_64-darwin) - racc (~> 1.4) - nokogiri (1.18.9-x86_64-linux-gnu) - racc (~> 1.4) - nokogiri (1.18.9-x86_64-linux-musl) - racc (~> 1.4) - pp (0.6.2) - prettyprint - prettyprint (0.2.0) - psych (5.2.6) - date - stringio - pwned (2.4.1) - racc (1.8.1) - rack (3.2.1) - rack-session (2.1.1) - base64 (>= 0.1.0) - rack (>= 3.0.0) - rack-test (2.2.0) - rack (>= 1.3) - rackup (2.2.1) - rack (>= 3) - rails (8.0.2.1) - actioncable (= 8.0.2.1) - actionmailbox (= 8.0.2.1) - actionmailer (= 8.0.2.1) - actionpack (= 8.0.2.1) - actiontext (= 8.0.2.1) - actionview (= 8.0.2.1) - activejob (= 8.0.2.1) - activemodel (= 8.0.2.1) - activerecord (= 8.0.2.1) - activestorage (= 8.0.2.1) - activesupport (= 8.0.2.1) - bundler (>= 1.15.0) - railties (= 8.0.2.1) - rails-controller-testing (1.0.5) - actionpack (>= 5.0.1.rc1) - actionview (>= 5.0.1.rc1) - activesupport (>= 5.0.1.rc1) - rails-dom-testing (2.3.0) - activesupport (>= 5.0.0) - minitest - nokogiri (>= 1.6) - rails-html-sanitizer (1.6.2) - loofah (~> 2.21) - nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) - railties (8.0.2.1) - actionpack (= 8.0.2.1) - activesupport (= 8.0.2.1) - irb (~> 1.13) - rackup (>= 1.0.0) - rake (>= 12.2) - thor (~> 1.0, >= 1.2.2) - zeitwerk (~> 2.6) - rake (13.3.0) - rdoc (6.14.2) - erb - psych (>= 4.0.0) - reline (0.6.2) - io-console (~> 0.5) rexml (3.4.4) - ruby2_keywords (0.0.5) securerandom (0.4.1) - stringio (3.1.7) - thor (1.4.0) - timeout (0.4.3) tzinfo (2.0.6) concurrent-ruby (~> 1.0) uri (1.0.3) - useragent (0.16.11) - websocket-driver (0.8.0) - base64 - websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.5) - zeitwerk (2.7.3) PLATFORMS aarch64-linux-gnu @@ -300,13 +63,7 @@ PLATFORMS DEPENDENCIES activeresource - file_repository (~> 1.4.5)! - mysql2! - portfolio (>= 4.6)! queenbee! - queuety! - service_concurrency_prevention! - signal_id! BUNDLED WITH 2.7.0 diff --git a/gems/fizzy-saas/app/controllers/signup/accounts_controller.rb b/gems/fizzy-saas/app/controllers/signup/accounts_controller.rb deleted file mode 100644 index f61baa289..000000000 --- a/gems/fizzy-saas/app/controllers/signup/accounts_controller.rb +++ /dev/null @@ -1,30 +0,0 @@ -class Signup::AccountsController < Signup::BaseController - before_action :reset_signup_storage - rate_limit to: 10, within: 3.minutes, only: :create, with: -> { redirect_to saas.new_signup_account_path, alert: "Try again later." } - - def new - @signup = Signup.new - end - - def create - @signup = Signup.new(signup_params) - - if @signup.recognized? - store_signup - redirect_to Launchpad.authentication_url(purpose: "signup", login_hint: @signup.email_address, redirect_uri: saas.signup_session_url), allow_other_host: true - elsif @signup.process - redirect_to_account(@signup.account) - else - render :new, status: :unprocessable_entity - end - end - - private - def signup_params - params.require(:signup).permit(*Signup::PERMITTED_KEYS) - end - - def store_signup - @signup.to_h.each { |key, value| signup_storage[key.to_s] = value } - end -end diff --git a/gems/fizzy-saas/app/controllers/signup/base_controller.rb b/gems/fizzy-saas/app/controllers/signup/base_controller.rb deleted file mode 100644 index ed884fffa..000000000 --- a/gems/fizzy-saas/app/controllers/signup/base_controller.rb +++ /dev/null @@ -1,36 +0,0 @@ -class Signup::BaseController < ApplicationController - require_untenanted_access - - # TODO: Remove this auth before launch. - http_basic_authenticate_with( - name: Rails.env.test? ? "testname" : Rails.application.credentials.account_signup_http_basic_auth.name, - password: Rails.env.test? ? "testpassword" : Rails.application.credentials.account_signup_http_basic_auth.password - ) - - attr_reader :authenticated_identity - - private - def signup_storage - session[:signup] ||= {} - end - - def reset_signup_storage - session.delete(:signup) - end - - def authenticated_identity=(identity) - @authenticated_identity = identity - signup_storage["identity_id"] = identity.try(:id) - end - - def set_authenticated_identity - if identity_id = signup_storage["identity_id"] - @authenticated_identity = SignalId::Identity.find_by(id: identity_id) - end - end - - def redirect_to_account(account) - redirect_to account.external_account.owner.remote_login_url(proceed_to: root_path), - allow_other_host: true - end -end diff --git a/gems/fizzy-saas/app/controllers/signup/completions_controller.rb b/gems/fizzy-saas/app/controllers/signup/completions_controller.rb deleted file mode 100644 index 4f97055a0..000000000 --- a/gems/fizzy-saas/app/controllers/signup/completions_controller.rb +++ /dev/null @@ -1,23 +0,0 @@ -class Signup::CompletionsController < Signup::BaseController - before_action :set_authenticated_identity, only: :create - - def new - end - - def create - @signup = Signup.new(signup_params) - @signup.signal_identity = authenticated_identity - - if @signup.process - reset_signup_storage - redirect_to_account(@signup.account) - else - render plain: "Could not complete signup. This is probably a bug.", status: :unprocessable_entity, layout: false - end - end - - private - def signup_params - signup_storage.slice(*Signup::PERMITTED_KEYS.map(&:to_s)) - end -end diff --git a/gems/fizzy-saas/app/controllers/signup/sessions_controller.rb b/gems/fizzy-saas/app/controllers/signup/sessions_controller.rb deleted file mode 100644 index 20ab7c2c0..000000000 --- a/gems/fizzy-saas/app/controllers/signup/sessions_controller.rb +++ /dev/null @@ -1,9 +0,0 @@ -class Signup::SessionsController < Signup::BaseController - def create - if self.authenticated_identity = SignalId::Identity.authenticate(params.permit(:sig)) - redirect_to saas.new_signup_completion_url - else - render plain: "Authentication failed. This is probably a bug.", status: :unauthorized - end - end -end diff --git a/gems/fizzy-saas/app/models/account/signal_account.rb b/gems/fizzy-saas/app/models/account/signal_account.rb deleted file mode 100644 index f117347dd..000000000 --- a/gems/fizzy-saas/app/models/account/signal_account.rb +++ /dev/null @@ -1,30 +0,0 @@ -module Account::SignalAccount - extend ActiveSupport::Concern - - prepended do - # the tenant_id column is the SignalId::Account's queenbee_id - belongs_to :external_account, class_name: "SignalId::Account", primary_key: :queenbee_id, foreign_key: :tenant_id, optional: true - end - - class_methods do - def find_by_queenbee_id(queenbee_id) - find_by(tenant_id: queenbee_id) - end - - def create_with_admin_user(tenant_id:) - new(tenant_id:).tap do |account| - SignalId::Database.on_master do - account.name = account.external_account.name - account.save! - - User.create!( - name: account.external_account.owner.name, - email_address: account.external_account.owner.email_address, - role: "admin", - password: SecureRandom.hex(16) - ) - end - end - end - end -end diff --git a/gems/fizzy-saas/app/models/launchpad.rb b/gems/fizzy-saas/app/models/launchpad.rb deleted file mode 100644 index 268d6e1d1..000000000 --- a/gems/fizzy-saas/app/models/launchpad.rb +++ /dev/null @@ -1,24 +0,0 @@ -# lifted from bc3 app/models/launchpad.rb -module Launchpad - extend self - - delegate :url, to: "SignalId.launchpad" - - def login_url(product: false, account: nil, **params) - url product_account_path("/signin", product: product, account: account), params - end - - def logout_url - url "/signout" - end - - def authentication_url(**params) - url "/authenticate", params.merge(product: :fizzy) - end - - def product_account_path(path = nil, product: false, account: nil) - product_path = "/fizzy" if product || account - account_path = "/#{account.external_account.id}" if account - [ product_path, account_path, path ].compact.join - end -end diff --git a/gems/fizzy-saas/app/models/signup.rb b/gems/fizzy-saas/app/models/signup.rb deleted file mode 100644 index 7e3d54531..000000000 --- a/gems/fizzy-saas/app/models/signup.rb +++ /dev/null @@ -1,159 +0,0 @@ -class Signup - include ActiveModel::Model - include ActiveModel::Attributes - include ActiveModel::Validations - - PERMITTED_KEYS = %i[ full_name email_address password company_name ] - - # Input attribute - attr_accessor :company_name - - # Input attributes when not using an existing identity - attr_accessor :full_name, :email_address, :password - - # Input attribute when using an existing identity, output when creating new identity - attr_accessor :signal_identity - - # Output attributes - attr_reader :queenbee_account, :signal_account, :account, :user - - validate :validate_new_identity - - def initialize(...) - @full_name = nil - @email_address = nil - @password = nil - @company_name = nil - @signal_identity = nil - @queenbee_account = nil - @account = nil - @user = nil - - super - end - - def process(destroy_existing_tenant: false) - return false unless valid? - - create_signal_identity - create_queenbee_account - create_tenant(destroy_existing_tenant:) - - true - rescue => error - destroy_tenant - destroy_queenbee_account - destroy_signal_identity - - errors.add(:base, "An error occurred during signup: #{error.message}") - - false - end - - def recognized? - SignalId::Identity.find_by_email_address(email_address).present? - end - - def tenant_name - @tenant_name ||= @queenbee_account.id.to_s - end - - def to_h - { - full_name: full_name, - email_address: email_address, - company_name: company_name - }.compact_blank - end - - private - def create_signal_identity - unless signal_identity.present? - SignalId::Database.on_master do - @signal_identity = build_new_identity.tap(&:save!) - end - end - end - - def create_queenbee_account - @queenbee_account = Queenbee::Remote::Account.create!(queenbee_account_attributes) - SignalId::Database.on_master do - @signal_account = SignalId::Account.find_by(queenbee_id: @queenbee_account.id) - end - end - - def create_tenant(destroy_existing_tenant: false, &block) - ApplicationRecord.destroy_tenant(tenant_name) if destroy_existing_tenant - ApplicationRecord.create_tenant(tenant_name) do - @account = Account.create_with_admin_user(tenant_id: queenbee_account.id) - @account.setup_basic_template - @user = User.first - end - end - - def destroy_tenant - if queenbee_account && ApplicationRecord.tenant_exist?(tenant_name) - ApplicationRecord.destroy_tenant(tenant_name) - @account = nil - @user = nil - end - end - - def destroy_queenbee_account - queenbee_account&.cancel - @queenbee_account = nil - end - - def destroy_signal_identity - SignalId::Database.on_master do - signal_identity&.destroy - end - @signal_identity = nil - end - - def validate_new_identity - unless signal_identity.present? - build_new_identity.tap do |identity| - unless identity.valid? - identity.errors.each { |error| errors.add(error.attribute, error.message) } - end - end - end - end - - def build_new_identity - SignalId::Identity.new do |identity| - identity.name = full_name || email_address - identity.email_address = email_address - identity.username = email_address - identity.password = password - end - end - - def queenbee_account_attributes - { - skip_remote: true, # Fizzy creates its own local account - product_name: "fizzy", - name: queenbee_account_name, - owner_identity_id: signal_identity.id, - trial: false, - subscription: subscription_attributes, - remote_request: request_attributes - } - end - - def subscription_attributes - subscription = FreeV1Subscription - { name: subscription.to_param, price: subscription.price } - end - - def request_attributes - { remote_address: Current.ip_address, user_agent: Current.user_agent, referrer: Current.referrer } - end - - def queenbee_account_name - name = company_name.presence || signal_identity.name - name += " (Beta)" if Rails.env.beta? - name - end -end diff --git a/gems/fizzy-saas/app/views/sessions/launchpad/show.html.erb b/gems/fizzy-saas/app/views/sessions/launchpad/show.html.erb deleted file mode 100644 index 077cb5b42..000000000 --- a/gems/fizzy-saas/app/views/sessions/launchpad/show.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= auto_submit_form_with(method: :put, url: saas.session_launchpad_path) do |form| %> - <%= form.hidden_field(:sig, value: @sig) %> -<% end %> diff --git a/gems/fizzy-saas/app/views/signup/accounts/new.html.erb b/gems/fizzy-saas/app/views/signup/accounts/new.html.erb deleted file mode 100644 index 6ddba7c36..000000000 --- a/gems/fizzy-saas/app/views/signup/accounts/new.html.erb +++ /dev/null @@ -1,58 +0,0 @@ -<% @page_title = "Sign up for Fizzy" %> - -
" style="--panel-size: 65ch;"> -

Fizzy

-

Create your account

- - <%= form_with model: @signup, url: saas.signup_accounts_path, scope: "signup", class: "flex flex-column gap txt-large", data: { turbo: false } do |form| %> -
- -
- -
- -
- -
- -
- -
- -
- - <% if @signup.errors.any? %> -
-
    - <% @signup.errors.full_messages.each do |message| %> -
  • <%= message %>
  • - <% end %> -
-
- <% end %> - - - <% end %> - - -
diff --git a/gems/fizzy-saas/app/views/signup/completions/new.html.erb b/gems/fizzy-saas/app/views/signup/completions/new.html.erb deleted file mode 100644 index 3f073432a..000000000 --- a/gems/fizzy-saas/app/views/signup/completions/new.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= auto_submit_form_with url: saas.signup_completions_path, data: { turbo: false } %> diff --git a/gems/fizzy-saas/config/routes.rb b/gems/fizzy-saas/config/routes.rb index 6fff83e03..cb130af4f 100644 --- a/gems/fizzy-saas/config/routes.rb +++ b/gems/fizzy-saas/config/routes.rb @@ -1,10 +1,3 @@ Fizzy::Saas::Engine.routes.draw do - namespace :signup do - get "/" => "accounts#new" - resources :accounts, only: %i[ new create ] - get "/session" => "sessions#create" # redirect from Launchpad after mid-signup authentication - resources :completions, only: %i[ new create ] - end - Queenbee.routes(self) end diff --git a/gems/fizzy-saas/fizzy-saas.gemspec b/gems/fizzy-saas/fizzy-saas.gemspec index b16247fd0..f1b28de00 100644 --- a/gems/fizzy-saas/fizzy-saas.gemspec +++ b/gems/fizzy-saas/fizzy-saas.gemspec @@ -22,7 +22,6 @@ Gem::Specification.new do |spec| end spec.add_dependency "rails", ">= 8.1.0.beta1" - spec.add_dependency "signal_id" spec.add_dependency "queenbee" spec.add_dependency "rails_structured_logging" end diff --git a/gems/fizzy-saas/lib/fizzy/saas/engine.rb b/gems/fizzy-saas/lib/fizzy/saas/engine.rb index 4e5e93489..db24c8557 100644 --- a/gems/fizzy-saas/lib/fizzy/saas/engine.rb +++ b/gems/fizzy-saas/lib/fizzy/saas/engine.rb @@ -1,13 +1,6 @@ -require "signal_id" - module Fizzy module Saas class Engine < ::Rails::Engine - # extend application models - config.to_prepare do - Account.prepend Account::SignalAccount - end - # moved from config/initializers/queenbee.rb Queenbee.host_app = Fizzy @@ -21,27 +14,6 @@ module Fizzy ::Object.const_set const_name, Subscription.const_get(short_name, false) end end - - # moved from config/initializers/signal_id.rb - config.before_initialize do - ENV["SIGNAL_ID_SECRET"] = Rails.application.credentials.signal_id_secret - end - - config.to_prepare do - SignalId.product = "fizzy" - - db_config = SignalId::Database.default_configuration - SignalId::Database.load_configuration db_config - SignalId::Database.enable_rw_splitting! - - silence_warnings do - SignalId::Account::Peer = Account - end - end - - config.after_initialize do - ActiveRecord.yaml_column_permitted_classes << SignalId::PersonName - end end end end diff --git a/gems/fizzy-saas/test/controllers/signup/accounts_controller_test.rb b/gems/fizzy-saas/test/controllers/signup/accounts_controller_test.rb deleted file mode 100644 index cb2664489..000000000 --- a/gems/fizzy-saas/test/controllers/signup/accounts_controller_test.rb +++ /dev/null @@ -1,103 +0,0 @@ -require "test_helper" - -class Signup::AccountsControllerTest < ActionDispatch::IntegrationTest - test "new under a tenanted URL redirects to the root" do - get saas.new_signup_account_url - - assert_redirected_to root_url - end - - test "new under an untenanted URL is OK" do - integration_session.default_url_options[:script_name] = "" # no tenant - - get saas.new_signup_account_url, headers: auth_headers - - assert_response :success - end - - test "create with invalid params" do - integration_session.default_url_options[:script_name] = "" # no tenant - - post saas.signup_accounts_url, - headers: auth_headers, - params: { signup: { full_name: "Jim", email_address: "jim@example.com", password: "", company_name: "" } } - - assert_response :unprocessable_entity - assert_select "div.alert--error", text: /you need to choose a password/i - end - - test "create for a new identity" do - integration_session.default_url_options[:script_name] = "" # no tenant - - assert_difference -> { SignalId::Identity.count }, +1 do - assert_difference -> { SignalId::Account.count }, +1 do - post saas.signup_accounts_url, headers: auth_headers, - params: { - signup: { - full_name: "Jim", - email_address: "jim@example.com", - password: SecureRandom.hex(12), - company_name: "signup-accounts-controller-test-1" - } - } - end - end - - signal_account = SignalId::Account.last - assert_redirected_to(/#{signal_account.login_url}/) - end - - test "create for an existing identity" do - integration_session.default_url_options[:script_name] = "" # no tenant - - identity = signal_identities(:david) - - post saas.signup_accounts_url, headers: auth_headers, - params: { signup: { email_address: identity.email_address, company_name: "signup-accounts-controller-test-2" } } - - assert_authentication_requested_for identity - - assert_no_difference -> { SignalId::Identity.count } do - assert_difference -> { SignalId::Account.count } do - authenticate_via_launchpad_as(identity) - assert_redirected_to_account - assert_nil session[:signup] - end - end - - signal_account = SignalId::Account.last - ApplicationRecord.with_tenant(signal_account.queenbee_id) do - assert_equal Account.last, signal_account.peer - end - end - - test "actions require HTTP basic authentication while we're in internal-only mode" do - integration_session.default_url_options[:script_name] = "" # no tenant - - get saas.new_signup_account_url - - assert_response :unauthorized - end - - private - def auth_headers - { "HTTP_AUTHORIZATION" => ActionController::HttpAuthentication::Basic.encode_credentials("testname", "testpassword") } - end - - def assert_authentication_requested_for(identity) - assert_response :redirect - assert_match(/#{Regexp.escape(Launchpad.url("/authenticate", login_hint: identity.email_address))}.*&purpose=signup/, redirect_to_url) - end - - def authenticate_via_launchpad_as(identity) - get saas.signup_session_url, headers: auth_headers, params: { sig: identity.perishable_signature } - assert_equal identity.id, session[:signup]["identity_id"] - assert_redirected_to saas.new_signup_completion_url - post saas.signup_completions_url, headers: auth_headers - end - - def assert_redirected_to_account(signal_account = SignalId::Account.last) - assert_response :redirect - assert_match(/#{Regexp.escape(signal_account.url("/session/launchpad"))}.*&sig=/, redirect_to_url) - end -end diff --git a/gems/fizzy-saas/test/models/account/signal_account_test.rb b/gems/fizzy-saas/test/models/account/signal_account_test.rb deleted file mode 100644 index ad43e45cb..000000000 --- a/gems/fizzy-saas/test/models/account/signal_account_test.rb +++ /dev/null @@ -1,41 +0,0 @@ -require "test_helper" - -class Account::SignalAccountTest < ActiveSupport::TestCase - # # TODO(MIKE): Queenbee client API compliance tests - # include Queenbee::Testing::Client - - setup do - @account = accounts("37s") - end - - test "belongs to a signal_account via a shared queenbee_id" do - assert_not_nil @account.tenant_id - assert_equal @account.tenant_id, Account.new(external_account: @account.external_account).tenant_id - assert_equal @account.external_account, Account.new(tenant_id: @account.tenant_id).external_account - end - - test "peering" do - assert_equal @account, @account.external_account.peer - end - - test ".create_with_admin_user creates a new local account" do - ApplicationRecord.create_tenant("account-create-with-dependents") do - signal_account = signal_accounts(:honcho_fizzy) - account = Account.create_with_admin_user(tenant_id: signal_account.queenbee_id) - - assert_not_nil account - assert account.persisted? - assert_equal 1, Account.count - assert_equal signal_account.queenbee_id, account.tenant_id - assert_equal signal_account.name, account.name - assert_equal account, signal_account.peer - - assert_equal 1, User.count - User.first.tap do |user| - assert_equal signal_account.owner.name, user.name - assert_equal signal_account.owner.email_address, user.email_address - assert_equal "admin", user.role - end - end - end -end diff --git a/gems/fizzy-saas/test/models/signup_test.rb b/gems/fizzy-saas/test/models/signup_test.rb deleted file mode 100644 index e64dbf801..000000000 --- a/gems/fizzy-saas/test/models/signup_test.rb +++ /dev/null @@ -1,149 +0,0 @@ -require "test_helper" - -class SignupTest < ActiveSupport::TestCase - setup do - @signup = Signup.new( - email_address: "brian@example.com", - full_name: "Brian Wilson", - company_name: "Beach Boys", - password: SecureRandom.hex(16) - ) - end - - test "#to_h allows persistence of the signup data" do - actual = @signup.to_h - expected = { - email_address: @signup.email_address, - full_name: @signup.full_name, - company_name: @signup.company_name - } - assert_equal expected, actual - end - - test "#process creates all the necessary objects for a new identity" do - Account.any_instance.expects(:setup_basic_template).once - - assert @signup.process, @signup.errors.full_messages.to_sentence(words_connector: ". ") - assert_empty @signup.errors - - assert @signup.signal_identity - assert @signup.signal_identity.persisted? - - assert @signup.queenbee_account - assert @signup.queenbee_account.id - - assert @signup.signal_account - assert @signup.signal_account.persisted? - assert_equal @signup.signal_identity, @signup.signal_account.owner.identity - assert_equal @signup.company_name, @signup.signal_account.name - - assert @signup.account - assert @signup.account.persisted? - - assert @signup.user - assert @signup.user.persisted? - - assert_equal @signup.queenbee_account.id.to_s, @signup.tenant_name - assert_includes ApplicationRecord.tenants, @signup.tenant_name - end - - test "the new account is named with company name if present" do - assert_equal @signup.company_name, @signup.send(:queenbee_account_name) - end - - test "in beta, the new account is named distinctly" do - Rails.stubs(:env).returns(stub(beta?: true)) - - assert_equal "#{@signup.company_name} (Beta)", @signup.send(:queenbee_account_name) - end - - test "#process creates all the necessary objects for an existing identity" do - signal_identity = SignalId::Identity.find_by_email_address("david@37signals.com") - - @signup = Signup.new( - signal_identity: signal_identity, - company_name: "Team LeMans", - ) - - Account.any_instance.expects(:setup_basic_template).once - - assert @signup.process, @signup.errors.full_messages.to_sentence(words_connector: ". ") - assert_empty @signup.errors - - assert @signup.signal_identity - assert_equal signal_identity, @signup.signal_identity - - assert @signup.queenbee_account - assert @signup.queenbee_account.id - - assert @signup.signal_account - assert @signup.signal_account.persisted? - assert_equal @signup.signal_identity, @signup.signal_account.owner.identity - - assert @signup.account - assert @signup.account.persisted? - - assert @signup.user - assert @signup.user.persisted? - - assert_equal @signup.queenbee_account.id.to_s, @signup.tenant_name - assert_includes ApplicationRecord.tenants, @signup.tenant_name - end - - test "#process does nothing if a validation error occurs creating identity" do - @signup.password = "" - - assert_not @signup.process - assert_not_empty @signup.errors[:password] - - assert_nil @signup.signal_identity - assert_nil @signup.queenbee_account - assert_nil @signup.account - assert_nil @signup.user - end - - test "#process does nothing if a validation error occurs creating the queenbee account" do - Queenbee::Remote::Account.stubs(:create!).raises(RuntimeError, "Invalid account data") - - SignalId::Identity.any_instance.expects(:destroy).once - - assert_not @signup.process - assert_not_empty @signup.errors[:base] - - assert_nil @signup.signal_identity - assert_nil @signup.queenbee_account - assert_nil @signup.account - assert_nil @signup.user - end - - test "#process does nothing if a validation error occurs creating the tenant" do - ApplicationRecord.stubs(:create_tenant).raises(RuntimeError, "Tenant already exists") - - Queenbee::Remote::Account.any_instance.expects(:cancel).once - SignalId::Identity.any_instance.expects(:destroy).once - - assert_not @signup.process - assert_not_empty @signup.errors[:base] - - assert_nil @signup.signal_identity - assert_nil @signup.queenbee_account - assert_nil @signup.account - assert_nil @signup.user - end - - test "#process does nothing if a validation error occurs creating the account" do - Account.stubs(:create_with_admin_user).raises(RuntimeError, "Account creation failed") - - ApplicationRecord.expects(:destroy_tenant).once - Queenbee::Remote::Account.any_instance.expects(:cancel).once - SignalId::Identity.any_instance.expects(:destroy).once - - assert_not @signup.process - assert_not_empty @signup.errors[:base] - - assert_nil @signup.signal_identity - assert_nil @signup.queenbee_account - assert_nil @signup.account - assert_nil @signup.user - end -end diff --git a/gems/fizzy-saas/test/test_helper.rb b/gems/fizzy-saas/test/test_helper.rb index 648afa3ee..eeaf24954 100644 --- a/gems/fizzy-saas/test/test_helper.rb +++ b/gems/fizzy-saas/test/test_helper.rb @@ -1,12 +1,5 @@ -require "signal_id/testing" require "queenbee/testing/mocks" -module ActiveSupport - class TestCase - include SignalId::Testing - end -end - Queenbee::Remote::Account.class_eval do # because we use the account ID as the tenant name, we need it to be unique in each test to avoid # parallelized tests clobbering each other. diff --git a/script/load-prod-db-in-dev.rb b/script/load-prod-db-in-dev.rb index da0db12ba..13264d2b6 100755 --- a/script/load-prod-db-in-dev.rb +++ b/script/load-prod-db-in-dev.rb @@ -13,27 +13,26 @@ unless Rails.env.local? end identifier = SecureRandom.hex(4) -signup = Signup.new( - email_address: "dev-#{identifier}@example.com", - full_name: "Developer #{identifier}", - company_name: "Company #{identifier}", - password: "secret123456" -) +tenant = ActiveRecord::FixtureSet.identify(identifier) -puts "Creating signal identity for #{signup.email_address}..." -signup.send(:create_signal_identity) - -puts "Creating queenbee account ..." -signup.send(:create_queenbee_account) - -path = ApplicationRecord.tenanted_root_config.database_path_for(signup.tenant_name) +path = ApplicationRecord.tenanted_root_config.database_path_for(tenant) FileUtils.mkdir_p(File.dirname(path), verbose: true) FileUtils.cp original_dbfile, path, verbose: true ActiveRecord::Tenanted::DatabaseTasks.migrate_all -ApplicationRecord.with_tenant(signup.tenant_name) do |tenant| - Account.sole.update! external_account: signup.signal_account +ApplicationRecord.with_tenant(tenant) do |tenant| + Account.sole.destroy! - puts "\n\nLogin to http://launchpad.localhost:3011/ as #{signup.email_address} / #{signup.password}" + Account.create_with_admin_user( + tenant_id: tenant, + account_name: "Company #{identifier}", + owner_name: "Developer #{identifier}", + owner_email: "dev-#{identifier}@example.com") + + user = User.last + user.update! password: "secret123456" + + url = Rails.application.routes.url_helpers.root_url(Rails.application.config.action_controller.default_url_options.merge(script_name: Account.sole.slug)) + puts "\n\nLogin to #{url} as #{user.email_address} / #{user.password}" end diff --git a/script/migrations/202510-migrate-to-local-authentication.rb b/script/migrations/202510-migrate-to-local-authentication.rb deleted file mode 100755 index cd8788092..000000000 --- a/script/migrations/202510-migrate-to-local-authentication.rb +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env ruby - -# -# set up a temporary password for all users -# while we migrate away from Launchpad and 37id. -# -# the password is unguessable but generated based on the email address and a seed, -# so each user will have the same password across all tenants. -# -require_relative "../../config/environment" - -seed = ARGV[0] || "temporary-password-seed" -puts "Using seed: #{seed.inspect}" - -TENANTS = Hash.new -USERS = Hash.new { |h, k| h[k] = Hash.new } - -ApplicationRecord.with_each_tenant do |tenant| - TENANTS[tenant] = Account.sole.name - - User.find_each do |user| - putc "." - next if user.system? - - if user.external_user_id - suser = SignalId::User.find_by_id(user.external_user_id) - if suser && suser.email_address != user.email_address - puts "\nWarning: fixing email address for user #{user.id} in tenant #{tenant}:" - puts " local: #{user.email_address}" - puts " signal: #{suser.email_address}" - user.update! email_address: suser.email_address - end - end - - password = Digest::SHA256.hexdigest("#{seed}-#{user.email_address}")[0..16] - user.update! password: password - - USERS[user.email_address][tenant] = password - end -end - -puts - -USERS.each do |email, hash| - puts "\n#{email}:" - puts " password: #{hash.first.last}" - puts " fizzies:" - hash.each do |tenant, _| - url = Rails.application.routes.url_helpers.root_url(Rails.application.config.action_controller.default_url_options.merge(script_name: "/#{tenant}")) - - puts " #{TENANTS[tenant]}: #{url}" - end -end diff --git a/script/migrations/bootstrap-signal-id.rb b/script/migrations/bootstrap-signal-id.rb deleted file mode 100755 index 4ccf2c792..000000000 --- a/script/migrations/bootstrap-signal-id.rb +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env ruby - -require_relative "../config/environment" - -ActiveRecord::Base.logger = Logger.new(File::NULL) - -class BootstrapSignalId - def initialize(dry_run: false) - @dry_run = dry_run - end - - def run - SignalId::Database.on_master do - ApplicationRecord.with_each_tenant do |tenant| - puts "\n# tenant: #{tenant}" - - next unless check_account_preconditions - create_signal_id_account if Account.sole.queenbee_id.nil? - - create_signal_id_users - end - end - end - - def check_account_preconditions - unless Account.count == 1 - puts "There are #{Account.count} accounts, but exactly one is expected." - false - else - true - end - end - - def create_signal_id_account - owner = SignalId::Identity.find_by_email_address!("kevin@37signals.com") - print_identity("New owner is:", owner) - - unless @dry_run - qbattr = queenbee_account_attributes(owner) - queenbee_account = Queenbee::Remote::Account.create!(qbattr) - - signal_id_account = SignalId::Account.find_by!(queenbee_id: queenbee_account.id) - signal_id_account.update_column :subdomain, ApplicationRecord.current_tenant - - account = Account.sole - account.queenbee_id = queenbee_account.id - account.name = ApplicationRecord.current_tenant - account.save! - end - end - - def create_signal_id_users - signal_account = Account.sole.signal_account - - User.find_each do |user| - if !user.system? && user.signal_user_id.nil? - signal_identities = SignalId::Identity.where(email_address: user.email_address) - if signal_identities.length > 1 - puts "Multiple identities found for #{user.email_address}:" - signal_identities.each { |identity| print_identity(" - ", identity) } - signal_identity = signal_identities.first - elsif signal_identities.length == 1 - signal_identity = signal_identities.first - print_identity("Identity for #{user.email_address}:", signal_identity) - else - puts "No identity found for #{user.name} (#{user.email_address})" - signal_identity = nil - end - - if signal_identity - unless @dry_run - signal_user = SignalId::User.find_or_create_by!(identity: signal_identity, account: signal_account) - - user.signal_user_id = signal_user.id - user.save! - end - end - end - end - end - - def print_identity(message = "Identity:", identity) - pad = " " * message.length - puts "#{message} #{identity.name} (#{identity.email_address})" - puts "#{pad } ID: #{identity.id}" - puts "#{pad } Username: #{identity.username}" - end - - def queenbee_account_attributes(signal_identity) - { - skip_remote: true, # Fizzy creates its own local account - product_name: "fizzy", - name: account_name, - owner_identity_id: signal_identity.id, - trial: false, - subscription: subscription_attributes, - remote_request: request_attributes - } - end - - def subscription_attributes - subscription = FreeV1Subscription - { name: subscription.to_param, price: subscription.price } - end - - def request_attributes - { user_agent: "script/bootstrap-signal-id.rb" } - end - - def account_name - name = ApplicationRecord.current_tenant - name += " (Beta)" if Rails.env.beta? - name - end -end - -BootstrapSignalId.new(dry_run: false).run diff --git a/test/models/account_test.rb b/test/models/account_test.rb index 78554b997..446af4623 100644 --- a/test/models/account_test.rb +++ b/test/models/account_test.rb @@ -5,4 +5,27 @@ class AccountTest < ActiveSupport::TestCase account = Account.sole assert_equal "/#{ApplicationRecord.current_tenant}", account.slug end + + test ".create_with_admin_user creates a new local account" do + ApplicationRecord.create_tenant("account-create-with-dependents") do + account = Account.create_with_admin_user( + tenant_id: ActiveRecord::FixtureSet.identify("account-create-with-admin-user-test"), + account_name: "Account Create With Admin", + owner_name: "David", + owner_email: "david@37signals.com") + + assert_not_nil account + assert account.persisted? + assert_equal 1, Account.count + assert_equal ActiveRecord::FixtureSet.identify("account-create-with-admin-user-test"), account.tenant_id + assert_equal "Account Create With Admin", account.name + + assert_equal 1, User.count + User.first.tap do |user| + assert_equal "David", user.name + assert_equal "david@37signals.com", user.email_address + assert_equal "admin", user.role + end + end + end end