diff --git a/Gemfile b/Gemfile index 7e64ac5a6a..abe7e80d49 100644 --- a/Gemfile +++ b/Gemfile @@ -45,6 +45,9 @@ gem 'jwt' # 2FA/TOTP gem 'rotp', '~> 6.2' +# SSO +gem 'workos' + # Scopes and pagination gem 'has_scope' gem 'kaminari', '~> 1.2.0' diff --git a/Gemfile.lock b/Gemfile.lock index ebae0cf271..d853b3bb30 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -500,6 +500,7 @@ GEM websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) + workos (5.2.1) xpath (3.2.0) nokogiri (~> 1.8) zeitwerk (2.6.15) @@ -579,6 +580,7 @@ DEPENDENCIES typed_params (~> 1.2.5) uri (>= 0.12.2) webmock (~> 3.14.0) + workos RUBY VERSION ruby 3.3.4p94 diff --git a/README.md b/README.md index 546a65df96..0c0de365e4 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,8 @@ Keygen Enterprise Edition: - **Environments**: manage separate environments within a Keygen account, from test environments, to a sandbox, to QA, to production. - **Permissions**: enterprise-grade roles and permissions. -- **SSO/SAML**: support for SSO/SAML coming soon. +- **Import/export**: migrate from Keygen Cloud to Keygen EE. +- **SSO/SAML**: support for SSO/SAML/OAuth. Keygen uses Keygen EE in production to run Keygen Cloud, which is used to license Keygen EE. It's ~~turtles~~ Keygens all the way down (we love diff --git a/app/controllers/api/v1/accounts/actions/subscription_controller.rb b/app/controllers/api/v1/accounts/actions/subscription_controller.rb index 6e43674078..b850b5eaca 100644 --- a/app/controllers/api/v1/accounts/actions/subscription_controller.rb +++ b/app/controllers/api/v1/accounts/actions/subscription_controller.rb @@ -3,7 +3,7 @@ module Api::V1::Accounts::Actions class SubscriptionController < Api::V1::BaseController before_action :scope_to_current_account! - before_action :authenticate_with_token! + before_action :authenticate! def manage authorize! with: Accounts::SubscriptionPolicy diff --git a/app/controllers/api/v1/accounts/relationships/billings_controller.rb b/app/controllers/api/v1/accounts/relationships/billings_controller.rb index ac2183d88d..dd96fa8c00 100644 --- a/app/controllers/api/v1/accounts/relationships/billings_controller.rb +++ b/app/controllers/api/v1/accounts/relationships/billings_controller.rb @@ -3,7 +3,7 @@ module Api::V1::Accounts::Relationships class BillingsController < Api::V1::BaseController before_action :scope_to_current_account! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_billing def show diff --git a/app/controllers/api/v1/accounts/relationships/plans_controller.rb b/app/controllers/api/v1/accounts/relationships/plans_controller.rb index 54856a0a50..25e6e17b1e 100644 --- a/app/controllers/api/v1/accounts/relationships/plans_controller.rb +++ b/app/controllers/api/v1/accounts/relationships/plans_controller.rb @@ -3,7 +3,7 @@ module Api::V1::Accounts::Relationships class PlansController < Api::V1::BaseController before_action :scope_to_current_account! - before_action :authenticate_with_token! + before_action :authenticate! def show plan = current_account.plan diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index a9d751572d..5fb12ca254 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -3,7 +3,7 @@ module Api::V1 class AccountsController < Api::V1::BaseController before_action :scope_to_current_account!, only: %i[show update destroy] - before_action :authenticate_with_token!, only: %i[show update destroy] + before_action :authenticate!, only: %i[show update destroy] before_action :set_account, only: %i[show update destroy] def show diff --git a/app/controllers/api/v1/analytics/actions/counts_controller.rb b/app/controllers/api/v1/analytics/actions/counts_controller.rb index 1c5b9413df..4c06c939ec 100644 --- a/app/controllers/api/v1/analytics/actions/counts_controller.rb +++ b/app/controllers/api/v1/analytics/actions/counts_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Analytics::Actions class CountsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! def count authorize! to: :show?, with: Accounts::AnalyticsPolicy diff --git a/app/controllers/api/v1/entitlements_controller.rb b/app/controllers/api/v1/entitlements_controller.rb index f755a7ee9d..1984c0ab5d 100644 --- a/app/controllers/api/v1/entitlements_controller.rb +++ b/app/controllers/api/v1/entitlements_controller.rb @@ -4,7 +4,7 @@ module Api::V1 class EntitlementsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_entitlement, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/environments/relationships/tokens_controller.rb b/app/controllers/api/v1/environments/relationships/tokens_controller.rb index 5b8b51da47..1498bbcfb5 100644 --- a/app/controllers/api/v1/environments/relationships/tokens_controller.rb +++ b/app/controllers/api/v1/environments/relationships/tokens_controller.rb @@ -5,7 +5,7 @@ class TokensController < Api::V1::BaseController before_action :require_ee! before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_environment def index diff --git a/app/controllers/api/v1/environments_controller.rb b/app/controllers/api/v1/environments_controller.rb index f1a0055841..3ed9498959 100644 --- a/app/controllers/api/v1/environments_controller.rb +++ b/app/controllers/api/v1/environments_controller.rb @@ -5,7 +5,7 @@ class EnvironmentsController < Api::V1::BaseController before_action :require_ee! before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_environment, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/event_logs_controller.rb b/app/controllers/api/v1/event_logs_controller.rb index 8726a291e8..3a54bc9a5b 100644 --- a/app/controllers/api/v1/event_logs_controller.rb +++ b/app/controllers/api/v1/event_logs_controller.rb @@ -12,7 +12,7 @@ class EventLogsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! before_action :require_ent_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_event_log, only: %i[show] def index diff --git a/app/controllers/api/v1/groups/relationships/group_owners_controller.rb b/app/controllers/api/v1/groups/relationships/group_owners_controller.rb index 0a1bfc642f..845fc78433 100644 --- a/app/controllers/api/v1/groups/relationships/group_owners_controller.rb +++ b/app/controllers/api/v1/groups/relationships/group_owners_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Groups::Relationships class GroupOwnersController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_group authorize :group diff --git a/app/controllers/api/v1/groups/relationships/licenses_controller.rb b/app/controllers/api/v1/groups/relationships/licenses_controller.rb index caa67d7493..76c2c902b8 100644 --- a/app/controllers/api/v1/groups/relationships/licenses_controller.rb +++ b/app/controllers/api/v1/groups/relationships/licenses_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Groups::Relationships class LicensesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_group authorize :group diff --git a/app/controllers/api/v1/groups/relationships/machines_controller.rb b/app/controllers/api/v1/groups/relationships/machines_controller.rb index 9d2d11adbd..1151b8c691 100644 --- a/app/controllers/api/v1/groups/relationships/machines_controller.rb +++ b/app/controllers/api/v1/groups/relationships/machines_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Groups::Relationships class MachinesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_group authorize :group diff --git a/app/controllers/api/v1/groups/relationships/users_controller.rb b/app/controllers/api/v1/groups/relationships/users_controller.rb index b82121afe7..232f33ae9e 100644 --- a/app/controllers/api/v1/groups/relationships/users_controller.rb +++ b/app/controllers/api/v1/groups/relationships/users_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Groups::Relationships class UsersController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_group authorize :group diff --git a/app/controllers/api/v1/groups_controller.rb b/app/controllers/api/v1/groups_controller.rb index 14d57557c6..5d805fc763 100644 --- a/app/controllers/api/v1/groups_controller.rb +++ b/app/controllers/api/v1/groups_controller.rb @@ -4,7 +4,7 @@ module Api::V1 class GroupsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_group, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/keys/relationships/policies_controller.rb b/app/controllers/api/v1/keys/relationships/policies_controller.rb index 04cd9f16ac..18ded4693f 100644 --- a/app/controllers/api/v1/keys/relationships/policies_controller.rb +++ b/app/controllers/api/v1/keys/relationships/policies_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Keys::Relationships class PoliciesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_key authorize :key diff --git a/app/controllers/api/v1/keys/relationships/products_controller.rb b/app/controllers/api/v1/keys/relationships/products_controller.rb index b58f6a8d5d..daf14a1667 100644 --- a/app/controllers/api/v1/keys/relationships/products_controller.rb +++ b/app/controllers/api/v1/keys/relationships/products_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Keys::Relationships class ProductsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_key authorize :key diff --git a/app/controllers/api/v1/keys_controller.rb b/app/controllers/api/v1/keys_controller.rb index 0e91c061c7..636311fb95 100644 --- a/app/controllers/api/v1/keys_controller.rb +++ b/app/controllers/api/v1/keys_controller.rb @@ -7,7 +7,7 @@ class KeysController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_key, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/licenses/actions/checkouts_controller.rb b/app/controllers/api/v1/licenses/actions/checkouts_controller.rb index 90ccaa4e6e..2fcc50b86f 100644 --- a/app/controllers/api/v1/licenses/actions/checkouts_controller.rb +++ b/app/controllers/api/v1/licenses/actions/checkouts_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Licenses::Actions class CheckoutsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license authorize :license diff --git a/app/controllers/api/v1/licenses/actions/permits_controller.rb b/app/controllers/api/v1/licenses/actions/permits_controller.rb index 4062dcb9a5..ca15628318 100644 --- a/app/controllers/api/v1/licenses/actions/permits_controller.rb +++ b/app/controllers/api/v1/licenses/actions/permits_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Licenses::Actions class PermitsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license def check_in diff --git a/app/controllers/api/v1/licenses/actions/uses_controller.rb b/app/controllers/api/v1/licenses/actions/uses_controller.rb index 4eb7a468c5..17b64ac1e7 100644 --- a/app/controllers/api/v1/licenses/actions/uses_controller.rb +++ b/app/controllers/api/v1/licenses/actions/uses_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Licenses::Actions class UsesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license authorize :license diff --git a/app/controllers/api/v1/licenses/actions/validations_controller.rb b/app/controllers/api/v1/licenses/actions/validations_controller.rb index f65ae973a6..f92219526a 100644 --- a/app/controllers/api/v1/licenses/actions/validations_controller.rb +++ b/app/controllers/api/v1/licenses/actions/validations_controller.rb @@ -4,8 +4,8 @@ module Api::V1::Licenses::Actions class ValidationsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token!, except: %i[validate_by_key] - before_action :authenticate_with_token, only: %i[validate_by_key] + before_action :authenticate!, except: %i[validate_by_key] + before_action :authenticate, only: %i[validate_by_key] before_action :set_license, only: %i[quick_validate_by_id validate_by_id] def quick_validate_by_id diff --git a/app/controllers/api/v1/licenses/relationships/entitlements_controller.rb b/app/controllers/api/v1/licenses/relationships/entitlements_controller.rb index 8f2294369a..9e55771fcd 100644 --- a/app/controllers/api/v1/licenses/relationships/entitlements_controller.rb +++ b/app/controllers/api/v1/licenses/relationships/entitlements_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Licenses::Relationships class EntitlementsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license authorize :license diff --git a/app/controllers/api/v1/licenses/relationships/groups_controller.rb b/app/controllers/api/v1/licenses/relationships/groups_controller.rb index f499926730..5b644771ac 100644 --- a/app/controllers/api/v1/licenses/relationships/groups_controller.rb +++ b/app/controllers/api/v1/licenses/relationships/groups_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Licenses::Relationships class GroupsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license authorize :license diff --git a/app/controllers/api/v1/licenses/relationships/machines_controller.rb b/app/controllers/api/v1/licenses/relationships/machines_controller.rb index 99d7dc0125..6ebb45e799 100644 --- a/app/controllers/api/v1/licenses/relationships/machines_controller.rb +++ b/app/controllers/api/v1/licenses/relationships/machines_controller.rb @@ -8,7 +8,7 @@ class MachinesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license authorize :license diff --git a/app/controllers/api/v1/licenses/relationships/owners_controller.rb b/app/controllers/api/v1/licenses/relationships/owners_controller.rb index 763f0c12b0..e32d519960 100644 --- a/app/controllers/api/v1/licenses/relationships/owners_controller.rb +++ b/app/controllers/api/v1/licenses/relationships/owners_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Licenses::Relationships class OwnersController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license authorize :license diff --git a/app/controllers/api/v1/licenses/relationships/policies_controller.rb b/app/controllers/api/v1/licenses/relationships/policies_controller.rb index 88c3c9e5af..4b98cb0b5b 100644 --- a/app/controllers/api/v1/licenses/relationships/policies_controller.rb +++ b/app/controllers/api/v1/licenses/relationships/policies_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Licenses::Relationships class PoliciesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license authorize :license diff --git a/app/controllers/api/v1/licenses/relationships/products_controller.rb b/app/controllers/api/v1/licenses/relationships/products_controller.rb index 5c2719caf1..cb2ee0c76b 100644 --- a/app/controllers/api/v1/licenses/relationships/products_controller.rb +++ b/app/controllers/api/v1/licenses/relationships/products_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Licenses::Relationships class ProductsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license authorize :license diff --git a/app/controllers/api/v1/licenses/relationships/tokens_controller.rb b/app/controllers/api/v1/licenses/relationships/tokens_controller.rb index 9ce82fb78f..78297c45a2 100644 --- a/app/controllers/api/v1/licenses/relationships/tokens_controller.rb +++ b/app/controllers/api/v1/licenses/relationships/tokens_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Licenses::Relationships class TokensController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license authorize :license diff --git a/app/controllers/api/v1/licenses/relationships/users_controller.rb b/app/controllers/api/v1/licenses/relationships/users_controller.rb index 15bb0b8214..70cf9bdade 100644 --- a/app/controllers/api/v1/licenses/relationships/users_controller.rb +++ b/app/controllers/api/v1/licenses/relationships/users_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Licenses::Relationships class UsersController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license authorize :license diff --git a/app/controllers/api/v1/licenses/relationships/v1x5/users_controller.rb b/app/controllers/api/v1/licenses/relationships/v1x5/users_controller.rb index 906bd973ca..09538929de 100644 --- a/app/controllers/api/v1/licenses/relationships/v1x5/users_controller.rb +++ b/app/controllers/api/v1/licenses/relationships/v1x5/users_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Licenses::Relationships::V1x5 class UsersController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license authorize :license diff --git a/app/controllers/api/v1/licenses_controller.rb b/app/controllers/api/v1/licenses_controller.rb index 9a525865bf..1a698932c4 100644 --- a/app/controllers/api/v1/licenses_controller.rb +++ b/app/controllers/api/v1/licenses_controller.rb @@ -25,7 +25,7 @@ class LicensesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_license, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/machine_components/relationships/licenses_controller.rb b/app/controllers/api/v1/machine_components/relationships/licenses_controller.rb index 9eccc4945e..3271817c6f 100644 --- a/app/controllers/api/v1/machine_components/relationships/licenses_controller.rb +++ b/app/controllers/api/v1/machine_components/relationships/licenses_controller.rb @@ -4,7 +4,7 @@ module Api::V1::MachineComponents::Relationships class LicensesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine_component authorize :machine_component diff --git a/app/controllers/api/v1/machine_components/relationships/machines_controller.rb b/app/controllers/api/v1/machine_components/relationships/machines_controller.rb index 255e960965..9565473cb3 100644 --- a/app/controllers/api/v1/machine_components/relationships/machines_controller.rb +++ b/app/controllers/api/v1/machine_components/relationships/machines_controller.rb @@ -4,7 +4,7 @@ module Api::V1::MachineComponents::Relationships class MachinesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine_component authorize :machine_component diff --git a/app/controllers/api/v1/machine_components/relationships/products_controller.rb b/app/controllers/api/v1/machine_components/relationships/products_controller.rb index 9cffa96b39..12442bc8a1 100644 --- a/app/controllers/api/v1/machine_components/relationships/products_controller.rb +++ b/app/controllers/api/v1/machine_components/relationships/products_controller.rb @@ -4,7 +4,7 @@ module Api::V1::MachineComponents::Relationships class ProductsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine_component authorize :machine_component diff --git a/app/controllers/api/v1/machine_components_controller.rb b/app/controllers/api/v1/machine_components_controller.rb index 1ab2516c65..5b0bbc6f5b 100644 --- a/app/controllers/api/v1/machine_components_controller.rb +++ b/app/controllers/api/v1/machine_components_controller.rb @@ -10,7 +10,7 @@ class MachineComponentsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine_component, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/machine_processes/actions/heartbeats_controller.rb b/app/controllers/api/v1/machine_processes/actions/heartbeats_controller.rb index 0cc376d33e..41f1d141de 100644 --- a/app/controllers/api/v1/machine_processes/actions/heartbeats_controller.rb +++ b/app/controllers/api/v1/machine_processes/actions/heartbeats_controller.rb @@ -4,7 +4,7 @@ module Api::V1::MachineProcesses::Actions class HeartbeatsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine_process authorize :machine_process diff --git a/app/controllers/api/v1/machine_processes/relationships/licenses_controller.rb b/app/controllers/api/v1/machine_processes/relationships/licenses_controller.rb index 7bfecd25d5..1134d88bb0 100644 --- a/app/controllers/api/v1/machine_processes/relationships/licenses_controller.rb +++ b/app/controllers/api/v1/machine_processes/relationships/licenses_controller.rb @@ -4,7 +4,7 @@ module Api::V1::MachineProcesses::Relationships class LicensesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine_process authorize :machine_process diff --git a/app/controllers/api/v1/machine_processes/relationships/machines_controller.rb b/app/controllers/api/v1/machine_processes/relationships/machines_controller.rb index 6433a3ae92..7b3910debe 100644 --- a/app/controllers/api/v1/machine_processes/relationships/machines_controller.rb +++ b/app/controllers/api/v1/machine_processes/relationships/machines_controller.rb @@ -4,7 +4,7 @@ module Api::V1::MachineProcesses::Relationships class MachinesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine_process authorize :machine_process diff --git a/app/controllers/api/v1/machine_processes/relationships/products_controller.rb b/app/controllers/api/v1/machine_processes/relationships/products_controller.rb index c73c4bfd1c..3fa4757a20 100644 --- a/app/controllers/api/v1/machine_processes/relationships/products_controller.rb +++ b/app/controllers/api/v1/machine_processes/relationships/products_controller.rb @@ -4,7 +4,7 @@ module Api::V1::MachineProcesses::Relationships class ProductsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine_process authorize :machine_process diff --git a/app/controllers/api/v1/machine_processes_controller.rb b/app/controllers/api/v1/machine_processes_controller.rb index c5aa7934c8..0a7e1057fc 100644 --- a/app/controllers/api/v1/machine_processes_controller.rb +++ b/app/controllers/api/v1/machine_processes_controller.rb @@ -11,7 +11,7 @@ class MachineProcessesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine_process, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/machines/actions/checkouts_controller.rb b/app/controllers/api/v1/machines/actions/checkouts_controller.rb index 461ea32f22..bc32e520e9 100644 --- a/app/controllers/api/v1/machines/actions/checkouts_controller.rb +++ b/app/controllers/api/v1/machines/actions/checkouts_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Machines::Actions class CheckoutsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine authorize :machine diff --git a/app/controllers/api/v1/machines/actions/heartbeats_controller.rb b/app/controllers/api/v1/machines/actions/heartbeats_controller.rb index 0c6fe53425..bc7be2d0d0 100644 --- a/app/controllers/api/v1/machines/actions/heartbeats_controller.rb +++ b/app/controllers/api/v1/machines/actions/heartbeats_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Machines::Actions class HeartbeatsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine authorize :machine diff --git a/app/controllers/api/v1/machines/actions/v1x0/proofs_controller.rb b/app/controllers/api/v1/machines/actions/v1x0/proofs_controller.rb index 2fcb807cc5..7e0ab632b1 100644 --- a/app/controllers/api/v1/machines/actions/v1x0/proofs_controller.rb +++ b/app/controllers/api/v1/machines/actions/v1x0/proofs_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Machines::Actions::V1x0 class ProofsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine authorize :machine diff --git a/app/controllers/api/v1/machines/relationships/groups_controller.rb b/app/controllers/api/v1/machines/relationships/groups_controller.rb index 499e97243f..4dfe10c2b9 100644 --- a/app/controllers/api/v1/machines/relationships/groups_controller.rb +++ b/app/controllers/api/v1/machines/relationships/groups_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Machines::Relationships class GroupsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine authorize :machine diff --git a/app/controllers/api/v1/machines/relationships/licenses_controller.rb b/app/controllers/api/v1/machines/relationships/licenses_controller.rb index 9a2b7a0c7d..8f04046755 100644 --- a/app/controllers/api/v1/machines/relationships/licenses_controller.rb +++ b/app/controllers/api/v1/machines/relationships/licenses_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Machines::Relationships class LicensesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine authorize :machine diff --git a/app/controllers/api/v1/machines/relationships/machine_components_controller.rb b/app/controllers/api/v1/machines/relationships/machine_components_controller.rb index f5e94f646a..fc49eb7ea3 100644 --- a/app/controllers/api/v1/machines/relationships/machine_components_controller.rb +++ b/app/controllers/api/v1/machines/relationships/machine_components_controller.rb @@ -6,7 +6,7 @@ class MachineComponentsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine authorize :machine diff --git a/app/controllers/api/v1/machines/relationships/machine_processes_controller.rb b/app/controllers/api/v1/machines/relationships/machine_processes_controller.rb index d8ec053045..3106a5017e 100644 --- a/app/controllers/api/v1/machines/relationships/machine_processes_controller.rb +++ b/app/controllers/api/v1/machines/relationships/machine_processes_controller.rb @@ -6,7 +6,7 @@ class MachineProcessesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine authorize :machine diff --git a/app/controllers/api/v1/machines/relationships/owners_controller.rb b/app/controllers/api/v1/machines/relationships/owners_controller.rb index 39f5e28364..c3a8eaf783 100644 --- a/app/controllers/api/v1/machines/relationships/owners_controller.rb +++ b/app/controllers/api/v1/machines/relationships/owners_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Machines::Relationships class OwnersController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine authorize :machine diff --git a/app/controllers/api/v1/machines/relationships/products_controller.rb b/app/controllers/api/v1/machines/relationships/products_controller.rb index 18cc688e3c..f00cd7a44d 100644 --- a/app/controllers/api/v1/machines/relationships/products_controller.rb +++ b/app/controllers/api/v1/machines/relationships/products_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Machines::Relationships class ProductsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine authorize :machine diff --git a/app/controllers/api/v1/machines/relationships/v1x5/users_controller.rb b/app/controllers/api/v1/machines/relationships/v1x5/users_controller.rb index 66bbeab709..0691de9e3d 100644 --- a/app/controllers/api/v1/machines/relationships/v1x5/users_controller.rb +++ b/app/controllers/api/v1/machines/relationships/v1x5/users_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Machines::Relationships::V1x5 class UsersController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine authorize :machine diff --git a/app/controllers/api/v1/machines_controller.rb b/app/controllers/api/v1/machines_controller.rb index 836481f2de..a926178625 100644 --- a/app/controllers/api/v1/machines_controller.rb +++ b/app/controllers/api/v1/machines_controller.rb @@ -17,7 +17,7 @@ class MachinesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_machine, only: [:show, :update, :destroy] def index diff --git a/app/controllers/api/v1/metrics/actions/counts_controller.rb b/app/controllers/api/v1/metrics/actions/counts_controller.rb index 0742058ca1..022d08d88a 100644 --- a/app/controllers/api/v1/metrics/actions/counts_controller.rb +++ b/app/controllers/api/v1/metrics/actions/counts_controller.rb @@ -6,7 +6,7 @@ class CountsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! def count authorize! with: MetricPolicy diff --git a/app/controllers/api/v1/metrics_controller.rb b/app/controllers/api/v1/metrics_controller.rb index 76464061af..bf25bad7f1 100644 --- a/app/controllers/api/v1/metrics_controller.rb +++ b/app/controllers/api/v1/metrics_controller.rb @@ -8,7 +8,7 @@ class MetricsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_metric, only: %i[show] def index diff --git a/app/controllers/api/v1/policies/relationships/entitlements_controller.rb b/app/controllers/api/v1/policies/relationships/entitlements_controller.rb index 9336c3980a..ebcb5bf1e5 100644 --- a/app/controllers/api/v1/policies/relationships/entitlements_controller.rb +++ b/app/controllers/api/v1/policies/relationships/entitlements_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Policies::Relationships class EntitlementsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_policy authorize :policy diff --git a/app/controllers/api/v1/policies/relationships/licenses_controller.rb b/app/controllers/api/v1/policies/relationships/licenses_controller.rb index bceccf4567..9e2105add5 100644 --- a/app/controllers/api/v1/policies/relationships/licenses_controller.rb +++ b/app/controllers/api/v1/policies/relationships/licenses_controller.rb @@ -8,7 +8,7 @@ class LicensesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_policy authorize :policy diff --git a/app/controllers/api/v1/policies/relationships/pool_controller.rb b/app/controllers/api/v1/policies/relationships/pool_controller.rb index 999356d20e..694fb0b82e 100644 --- a/app/controllers/api/v1/policies/relationships/pool_controller.rb +++ b/app/controllers/api/v1/policies/relationships/pool_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Policies::Relationships class PoolController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_policy, only: %i[index show pop] authorize :policy diff --git a/app/controllers/api/v1/policies/relationships/products_controller.rb b/app/controllers/api/v1/policies/relationships/products_controller.rb index b0c8b92095..63fd815bb1 100644 --- a/app/controllers/api/v1/policies/relationships/products_controller.rb +++ b/app/controllers/api/v1/policies/relationships/products_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Policies::Relationships class ProductsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_policy authorize :policy diff --git a/app/controllers/api/v1/policies_controller.rb b/app/controllers/api/v1/policies_controller.rb index ad53db1ff9..aef8fbabe5 100644 --- a/app/controllers/api/v1/policies_controller.rb +++ b/app/controllers/api/v1/policies_controller.rb @@ -6,7 +6,7 @@ class PoliciesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_policy, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/products/relationships/licenses_controller.rb b/app/controllers/api/v1/products/relationships/licenses_controller.rb index 4d45d20417..95b6766c55 100644 --- a/app/controllers/api/v1/products/relationships/licenses_controller.rb +++ b/app/controllers/api/v1/products/relationships/licenses_controller.rb @@ -8,7 +8,7 @@ class LicensesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product authorize :product diff --git a/app/controllers/api/v1/products/relationships/machines_controller.rb b/app/controllers/api/v1/products/relationships/machines_controller.rb index 2fe37c2364..dcbff9fe9d 100644 --- a/app/controllers/api/v1/products/relationships/machines_controller.rb +++ b/app/controllers/api/v1/products/relationships/machines_controller.rb @@ -8,7 +8,7 @@ class MachinesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product authorize :product diff --git a/app/controllers/api/v1/products/relationships/policies_controller.rb b/app/controllers/api/v1/products/relationships/policies_controller.rb index 1f47fa735e..3df1bd20f5 100644 --- a/app/controllers/api/v1/products/relationships/policies_controller.rb +++ b/app/controllers/api/v1/products/relationships/policies_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Products::Relationships class PoliciesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product authorize :product diff --git a/app/controllers/api/v1/products/relationships/release_arches_controller.rb b/app/controllers/api/v1/products/relationships/release_arches_controller.rb index 050e98f652..054fe6ec74 100644 --- a/app/controllers/api/v1/products/relationships/release_arches_controller.rb +++ b/app/controllers/api/v1/products/relationships/release_arches_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Products::Relationships class ReleaseArchesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product authorize :product diff --git a/app/controllers/api/v1/products/relationships/release_artifacts_controller.rb b/app/controllers/api/v1/products/relationships/release_artifacts_controller.rb index 108bd58761..54671b7991 100644 --- a/app/controllers/api/v1/products/relationships/release_artifacts_controller.rb +++ b/app/controllers/api/v1/products/relationships/release_artifacts_controller.rb @@ -12,7 +12,7 @@ class ReleaseArtifactsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product, only: %i[index show] before_action :set_artifact, only: %i[show] diff --git a/app/controllers/api/v1/products/relationships/release_channels_controller.rb b/app/controllers/api/v1/products/relationships/release_channels_controller.rb index 40c0accae7..c3a6aba38c 100644 --- a/app/controllers/api/v1/products/relationships/release_channels_controller.rb +++ b/app/controllers/api/v1/products/relationships/release_channels_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Products::Relationships class ReleaseChannelsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product authorize :product diff --git a/app/controllers/api/v1/products/relationships/release_engines_controller.rb b/app/controllers/api/v1/products/relationships/release_engines_controller.rb index 7eacfabe8a..f64aea1d0c 100644 --- a/app/controllers/api/v1/products/relationships/release_engines_controller.rb +++ b/app/controllers/api/v1/products/relationships/release_engines_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Products::Relationships class ReleaseEnginesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product authorize :product diff --git a/app/controllers/api/v1/products/relationships/release_packages_controller.rb b/app/controllers/api/v1/products/relationships/release_packages_controller.rb index 66015b4b2f..0a531784e1 100644 --- a/app/controllers/api/v1/products/relationships/release_packages_controller.rb +++ b/app/controllers/api/v1/products/relationships/release_packages_controller.rb @@ -6,7 +6,7 @@ class ReleasePackagesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product authorize :product diff --git a/app/controllers/api/v1/products/relationships/release_platforms_controller.rb b/app/controllers/api/v1/products/relationships/release_platforms_controller.rb index 833dcd47c5..411f821397 100644 --- a/app/controllers/api/v1/products/relationships/release_platforms_controller.rb +++ b/app/controllers/api/v1/products/relationships/release_platforms_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Products::Relationships class ReleasePlatformsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product authorize :product diff --git a/app/controllers/api/v1/products/relationships/releases_controller.rb b/app/controllers/api/v1/products/relationships/releases_controller.rb index 75762996b9..3ccb310c5c 100644 --- a/app/controllers/api/v1/products/relationships/releases_controller.rb +++ b/app/controllers/api/v1/products/relationships/releases_controller.rb @@ -16,7 +16,7 @@ class ReleasesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product authorize :product diff --git a/app/controllers/api/v1/products/relationships/tokens_controller.rb b/app/controllers/api/v1/products/relationships/tokens_controller.rb index 272b268a34..c987b678bd 100644 --- a/app/controllers/api/v1/products/relationships/tokens_controller.rb +++ b/app/controllers/api/v1/products/relationships/tokens_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Products::Relationships class TokensController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product authorize :product diff --git a/app/controllers/api/v1/products/relationships/users_controller.rb b/app/controllers/api/v1/products/relationships/users_controller.rb index ed3c3b00cf..5d74b3544a 100644 --- a/app/controllers/api/v1/products/relationships/users_controller.rb +++ b/app/controllers/api/v1/products/relationships/users_controller.rb @@ -6,7 +6,7 @@ class UsersController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product authorize :product diff --git a/app/controllers/api/v1/products_controller.rb b/app/controllers/api/v1/products_controller.rb index 9382eea5f6..e0f29bbf06 100644 --- a/app/controllers/api/v1/products_controller.rb +++ b/app/controllers/api/v1/products_controller.rb @@ -4,7 +4,7 @@ module Api::V1 class ProductsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_product, only: [:show, :update, :destroy] def index diff --git a/app/controllers/api/v1/profiles_controller.rb b/app/controllers/api/v1/profiles_controller.rb index 53d8f7c654..26e8f4da4f 100644 --- a/app/controllers/api/v1/profiles_controller.rb +++ b/app/controllers/api/v1/profiles_controller.rb @@ -3,7 +3,7 @@ module Api::V1 class ProfilesController < Api::V1::BaseController before_action :scope_to_current_account! - before_action :authenticate_with_token! + before_action :authenticate! def show authorize! current_bearer diff --git a/app/controllers/api/v1/release_arches_controller.rb b/app/controllers/api/v1/release_arches_controller.rb index daff8b1fce..f438ba89f4 100644 --- a/app/controllers/api/v1/release_arches_controller.rb +++ b/app/controllers/api/v1/release_arches_controller.rb @@ -4,7 +4,7 @@ module Api::V1 class ReleaseArchesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token + before_action :authenticate before_action :set_arch, only: %i[show] def index diff --git a/app/controllers/api/v1/release_artifacts_controller.rb b/app/controllers/api/v1/release_artifacts_controller.rb index 97d8f4ea8c..54e3e2a777 100644 --- a/app/controllers/api/v1/release_artifacts_controller.rb +++ b/app/controllers/api/v1/release_artifacts_controller.rb @@ -14,8 +14,8 @@ class ReleaseArtifactsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token!, except: %i[index show] - before_action :authenticate_with_token, only: %i[index show] + before_action :authenticate!, except: %i[index show] + before_action :authenticate, only: %i[index show] before_action :set_artifact, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/release_channels_controller.rb b/app/controllers/api/v1/release_channels_controller.rb index ad9b1fc637..cf147ee93f 100644 --- a/app/controllers/api/v1/release_channels_controller.rb +++ b/app/controllers/api/v1/release_channels_controller.rb @@ -4,7 +4,7 @@ module Api::V1 class ReleaseChannelsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token + before_action :authenticate before_action :set_channel, only: %i[show] def index diff --git a/app/controllers/api/v1/release_engines/pypi/simple_controller.rb b/app/controllers/api/v1/release_engines/pypi/simple_controller.rb index 9fb34399de..524acfc482 100644 --- a/app/controllers/api/v1/release_engines/pypi/simple_controller.rb +++ b/app/controllers/api/v1/release_engines/pypi/simple_controller.rb @@ -6,7 +6,7 @@ class Pypi::SimpleController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token + before_action :authenticate before_action :set_package, only: %i[show] def index diff --git a/app/controllers/api/v1/release_engines/tauri/upgrades_controller.rb b/app/controllers/api/v1/release_engines/tauri/upgrades_controller.rb index bf0c77c653..e30a818d57 100644 --- a/app/controllers/api/v1/release_engines/tauri/upgrades_controller.rb +++ b/app/controllers/api/v1/release_engines/tauri/upgrades_controller.rb @@ -4,7 +4,7 @@ module Api::V1::ReleaseEngines class Tauri::UpgradesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token + before_action :authenticate before_action :set_package, only: %i[show] typed_query { diff --git a/app/controllers/api/v1/release_engines_controller.rb b/app/controllers/api/v1/release_engines_controller.rb index 3f4960aaf2..c6127a5e0a 100644 --- a/app/controllers/api/v1/release_engines_controller.rb +++ b/app/controllers/api/v1/release_engines_controller.rb @@ -4,7 +4,7 @@ module Api::V1 class ReleaseEnginesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token + before_action :authenticate before_action :set_engine, only: %i[show] def index diff --git a/app/controllers/api/v1/release_packages_controller.rb b/app/controllers/api/v1/release_packages_controller.rb index c7ab49af28..1abe62ee48 100644 --- a/app/controllers/api/v1/release_packages_controller.rb +++ b/app/controllers/api/v1/release_packages_controller.rb @@ -7,8 +7,8 @@ class ReleasePackagesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token!, except: %i[index show] - before_action :authenticate_with_token, only: %i[index show] + before_action :authenticate!, except: %i[index show] + before_action :authenticate, only: %i[index show] before_action :set_package, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/release_platforms_controller.rb b/app/controllers/api/v1/release_platforms_controller.rb index 4ab020ff55..f89d192640 100644 --- a/app/controllers/api/v1/release_platforms_controller.rb +++ b/app/controllers/api/v1/release_platforms_controller.rb @@ -4,7 +4,7 @@ module Api::V1 class ReleasePlatformsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token + before_action :authenticate before_action :set_platform, only: %i[show] def index diff --git a/app/controllers/api/v1/releases/actions/publishings_controller.rb b/app/controllers/api/v1/releases/actions/publishings_controller.rb index c2935137b1..1483ea40eb 100644 --- a/app/controllers/api/v1/releases/actions/publishings_controller.rb +++ b/app/controllers/api/v1/releases/actions/publishings_controller.rb @@ -2,7 +2,7 @@ module Api::V1::Releases::Actions class PublishingsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_release def publish diff --git a/app/controllers/api/v1/releases/actions/v1x0/upgrades_controller.rb b/app/controllers/api/v1/releases/actions/v1x0/upgrades_controller.rb index 7a461e8b1a..f6f095f217 100644 --- a/app/controllers/api/v1/releases/actions/v1x0/upgrades_controller.rb +++ b/app/controllers/api/v1/releases/actions/v1x0/upgrades_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Releases::Actions::V1x0 class UpgradesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token + before_action :authenticate before_action :set_release, only: %i[check_for_upgrade_by_id] skip_verify_authorized only: %i[ diff --git a/app/controllers/api/v1/releases/relationships/entitlements_controller.rb b/app/controllers/api/v1/releases/relationships/entitlements_controller.rb index 4322b6d1a1..494f25f03b 100644 --- a/app/controllers/api/v1/releases/relationships/entitlements_controller.rb +++ b/app/controllers/api/v1/releases/relationships/entitlements_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Releases::Relationships class EntitlementsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_release authorize :release diff --git a/app/controllers/api/v1/releases/relationships/products_controller.rb b/app/controllers/api/v1/releases/relationships/products_controller.rb index 7f6c638045..4ed6cd9ca1 100644 --- a/app/controllers/api/v1/releases/relationships/products_controller.rb +++ b/app/controllers/api/v1/releases/relationships/products_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Releases::Relationships class ProductsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_release authorize :release diff --git a/app/controllers/api/v1/releases/relationships/release_artifacts_controller.rb b/app/controllers/api/v1/releases/relationships/release_artifacts_controller.rb index 72cd9be810..4c54f7ace0 100644 --- a/app/controllers/api/v1/releases/relationships/release_artifacts_controller.rb +++ b/app/controllers/api/v1/releases/relationships/release_artifacts_controller.rb @@ -9,8 +9,8 @@ class ReleaseArtifactsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token!, except: %i[index show] - before_action :authenticate_with_token, only: %i[index show] + before_action :authenticate!, except: %i[index show] + before_action :authenticate, only: %i[index show] before_action :set_release, only: %i[index show] before_action :set_artifact, only: %i[show] diff --git a/app/controllers/api/v1/releases/relationships/release_entitlement_constraints_controller.rb b/app/controllers/api/v1/releases/relationships/release_entitlement_constraints_controller.rb index 6edea9f982..0a2f45ae42 100644 --- a/app/controllers/api/v1/releases/relationships/release_entitlement_constraints_controller.rb +++ b/app/controllers/api/v1/releases/relationships/release_entitlement_constraints_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Releases::Relationships class ReleaseEntitlementConstraintsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_release authorize :release diff --git a/app/controllers/api/v1/releases/relationships/release_packages_controller.rb b/app/controllers/api/v1/releases/relationships/release_packages_controller.rb index 4a1a2caf70..00d7d81d2a 100644 --- a/app/controllers/api/v1/releases/relationships/release_packages_controller.rb +++ b/app/controllers/api/v1/releases/relationships/release_packages_controller.rb @@ -4,8 +4,8 @@ module Api::V1::Releases::Relationships class ReleasePackagesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token!, except: %i[show] - before_action :authenticate_with_token, only: %i[show] + before_action :authenticate!, except: %i[show] + before_action :authenticate, only: %i[show] before_action :set_release authorize :release diff --git a/app/controllers/api/v1/releases/relationships/upgrades_controller.rb b/app/controllers/api/v1/releases/relationships/upgrades_controller.rb index c94ea14ac7..be11043698 100644 --- a/app/controllers/api/v1/releases/relationships/upgrades_controller.rb +++ b/app/controllers/api/v1/releases/relationships/upgrades_controller.rb @@ -7,7 +7,7 @@ class UpgradesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token + before_action :authenticate before_action :set_release typed_query { diff --git a/app/controllers/api/v1/releases/relationships/v1x0/release_artifacts_controller.rb b/app/controllers/api/v1/releases/relationships/v1x0/release_artifacts_controller.rb index 3981ebd748..68d5c7c630 100644 --- a/app/controllers/api/v1/releases/relationships/v1x0/release_artifacts_controller.rb +++ b/app/controllers/api/v1/releases/relationships/v1x0/release_artifacts_controller.rb @@ -4,8 +4,8 @@ module Api::V1::Releases::Relationships::V1x0 class ReleaseArtifactsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token!, except: %i[show] - before_action :authenticate_with_token, only: %i[show] + before_action :authenticate!, except: %i[show] + before_action :authenticate, only: %i[show] before_action :set_release typed_query { diff --git a/app/controllers/api/v1/releases_controller.rb b/app/controllers/api/v1/releases_controller.rb index d7eea26d79..b3c2894486 100644 --- a/app/controllers/api/v1/releases_controller.rb +++ b/app/controllers/api/v1/releases_controller.rb @@ -20,8 +20,8 @@ class ReleasesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token!, except: %i[index show] - before_action :authenticate_with_token, only: %i[index show] + before_action :authenticate!, except: %i[index show] + before_action :authenticate, only: %i[index show] before_action :set_release, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/request_logs/actions/counts_controller.rb b/app/controllers/api/v1/request_logs/actions/counts_controller.rb index 6154bf4c4a..387edf210d 100644 --- a/app/controllers/api/v1/request_logs/actions/counts_controller.rb +++ b/app/controllers/api/v1/request_logs/actions/counts_controller.rb @@ -4,7 +4,7 @@ module Api::V1::RequestLogs::Actions class CountsController < Api::V1::BaseController before_action :require_ee! before_action :scope_to_current_account! - before_action :authenticate_with_token! + before_action :authenticate! def count authorize! with: RequestLogPolicy diff --git a/app/controllers/api/v1/request_logs_controller.rb b/app/controllers/api/v1/request_logs_controller.rb index c9438d3471..5d78364720 100644 --- a/app/controllers/api/v1/request_logs_controller.rb +++ b/app/controllers/api/v1/request_logs_controller.rb @@ -15,7 +15,7 @@ class RequestLogsController < Api::V1::BaseController before_action :require_ee! before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_request_log, only: [:show] def index diff --git a/app/controllers/api/v1/searches_controller.rb b/app/controllers/api/v1/searches_controller.rb index 9fbde72f83..f411c116d3 100644 --- a/app/controllers/api/v1/searches_controller.rb +++ b/app/controllers/api/v1/searches_controller.rb @@ -21,7 +21,7 @@ class EmptyQueryError < StandardError; end before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! typed_params { format :jsonapi diff --git a/app/controllers/api/v1/tokens_controller.rb b/app/controllers/api/v1/tokens_controller.rb index fa599191c7..e6db7d0681 100644 --- a/app/controllers/api/v1/tokens_controller.rb +++ b/app/controllers/api/v1/tokens_controller.rb @@ -10,7 +10,7 @@ class TokensController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription!, only: %i[index regenerate regenerate_current] before_action :authenticate_with_password_or_token!, only: %i[generate] - before_action :authenticate_with_token!, except: %i[generate] + before_action :authenticate!, except: %i[generate] before_action :set_token, only: %i[show regenerate revoke] def index @@ -64,7 +64,8 @@ def show end end param :meta, type: :hash, optional: true do - param :otp, type: :string + param :provider, type: :string, optional: true, inclusion: { in: %w[AppleOAuth GitHubOAuth GoogleOAUth MicrosoftOAuth] } + param :otp, type: :string, optional: true end } def generate @@ -93,8 +94,6 @@ def generate else render_unprocessable_resource token end - rescue ArgumentError # Catch null bytes (Postgres throws an argument error) - render_bad_request end # FIXME(ezekg) Deprecate this route. diff --git a/app/controllers/api/v1/users/actions/bans_controller.rb b/app/controllers/api/v1/users/actions/bans_controller.rb index f60eacef7c..8303a84e36 100644 --- a/app/controllers/api/v1/users/actions/bans_controller.rb +++ b/app/controllers/api/v1/users/actions/bans_controller.rb @@ -3,7 +3,7 @@ module Api::V1::Users::Actions class BansController < Api::V1::BaseController before_action :scope_to_current_account! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_user def ban diff --git a/app/controllers/api/v1/users/actions/password_controller.rb b/app/controllers/api/v1/users/actions/password_controller.rb index 2ee21b3c4c..ae1a1b205e 100644 --- a/app/controllers/api/v1/users/actions/password_controller.rb +++ b/app/controllers/api/v1/users/actions/password_controller.rb @@ -3,7 +3,7 @@ module Api::V1::Users::Actions class PasswordController < Api::V1::BaseController before_action :scope_to_current_account! - before_action :authenticate_with_token!, only: %i[update] + before_action :authenticate!, only: %i[update] before_action :set_user, only: %i[update reset] authorize :user diff --git a/app/controllers/api/v1/users/relationships/groups_controller.rb b/app/controllers/api/v1/users/relationships/groups_controller.rb index 61acad3614..cd2e998c18 100644 --- a/app/controllers/api/v1/users/relationships/groups_controller.rb +++ b/app/controllers/api/v1/users/relationships/groups_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Users::Relationships class GroupsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_user authorize :user diff --git a/app/controllers/api/v1/users/relationships/licenses_controller.rb b/app/controllers/api/v1/users/relationships/licenses_controller.rb index e225c6d2e1..09ccfb27d9 100644 --- a/app/controllers/api/v1/users/relationships/licenses_controller.rb +++ b/app/controllers/api/v1/users/relationships/licenses_controller.rb @@ -8,7 +8,7 @@ class LicensesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_user authorize :user diff --git a/app/controllers/api/v1/users/relationships/machines_controller.rb b/app/controllers/api/v1/users/relationships/machines_controller.rb index 09f17a41e6..65ad0dcddb 100644 --- a/app/controllers/api/v1/users/relationships/machines_controller.rb +++ b/app/controllers/api/v1/users/relationships/machines_controller.rb @@ -8,7 +8,7 @@ class MachinesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_user authorize :user diff --git a/app/controllers/api/v1/users/relationships/products_controller.rb b/app/controllers/api/v1/users/relationships/products_controller.rb index 94a30ac417..10ace290d9 100644 --- a/app/controllers/api/v1/users/relationships/products_controller.rb +++ b/app/controllers/api/v1/users/relationships/products_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Users::Relationships class ProductsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_user authorize :user diff --git a/app/controllers/api/v1/users/relationships/second_factors_controller.rb b/app/controllers/api/v1/users/relationships/second_factors_controller.rb index 6776a7d6c0..90f5f362ca 100644 --- a/app/controllers/api/v1/users/relationships/second_factors_controller.rb +++ b/app/controllers/api/v1/users/relationships/second_factors_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Users::Relationships class SecondFactorsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_user authorize :user diff --git a/app/controllers/api/v1/users/relationships/tokens_controller.rb b/app/controllers/api/v1/users/relationships/tokens_controller.rb index 2f25b2d962..61e448e792 100644 --- a/app/controllers/api/v1/users/relationships/tokens_controller.rb +++ b/app/controllers/api/v1/users/relationships/tokens_controller.rb @@ -4,7 +4,7 @@ module Api::V1::Users::Relationships class TokensController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_user authorize :user diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index 390d9daf81..0171c40959 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -15,8 +15,8 @@ class UsersController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription!, only: %i[index create destroy] - before_action :authenticate_with_token!, only: %i[index show update destroy] - before_action :authenticate_with_token, only: %i[create] + before_action :authenticate!, only: %i[index show update destroy] + before_action :authenticate, only: %i[create] before_action :set_user, only: %i[show update destroy] def index diff --git a/app/controllers/api/v1/webhook_endpoints_controller.rb b/app/controllers/api/v1/webhook_endpoints_controller.rb index 3ba8e6de23..c285b1b06e 100644 --- a/app/controllers/api/v1/webhook_endpoints_controller.rb +++ b/app/controllers/api/v1/webhook_endpoints_controller.rb @@ -4,7 +4,7 @@ module Api::V1 class WebhookEndpointsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_endpoint, only: [:show, :update, :destroy] def index diff --git a/app/controllers/api/v1/webhook_events/actions/retries_controller.rb b/app/controllers/api/v1/webhook_events/actions/retries_controller.rb index d933ed349f..73b9c1d95e 100644 --- a/app/controllers/api/v1/webhook_events/actions/retries_controller.rb +++ b/app/controllers/api/v1/webhook_events/actions/retries_controller.rb @@ -4,7 +4,7 @@ module Api::V1::WebhookEvents::Actions class RetriesController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_event def retry diff --git a/app/controllers/api/v1/webhook_events_controller.rb b/app/controllers/api/v1/webhook_events_controller.rb index f60777d105..b9896beca8 100644 --- a/app/controllers/api/v1/webhook_events_controller.rb +++ b/app/controllers/api/v1/webhook_events_controller.rb @@ -6,7 +6,7 @@ class WebhookEventsController < Api::V1::BaseController before_action :scope_to_current_account! before_action :require_active_subscription! - before_action :authenticate_with_token! + before_action :authenticate! before_action :set_event, only: [:show, :destroy] def index diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5ad1d099f8..ecf6ba4873 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -385,6 +385,11 @@ def rescue_from_exceptions e.code.present? render_bad_request(**kwargs) + rescue Keygen::Error::InvalidSingleSignOnError => e + Keygen.logger.warn { "[sso] error=#{e.class.inspect} code=#{e.code.inspect} message=#{e.message.inspect}" } + + # we want to redirect to Portal to display the SSO error message in a helpful way + redirect_to portal_url('/sso/error', query: { code: e.code }), status: :see_other, allow_other_host: true rescue Keygen::Error::UnauthorizedError => e kwargs = { code: e.code } @@ -394,16 +399,19 @@ def rescue_from_exceptions kwargs[:source] = e.source if e.source.present? + kwargs[:links] = e.links if + e.links.present? + # Add additional properties based on code case e.code when 'LICENSE_NOT_ALLOWED', 'LICENSE_INVALID' - kwargs[:links] = { about: 'https://keygen.sh/docs/api/authentication/#license-authentication' } + kwargs.deep_merge(links: { about: docs_url(:authentication, anchor: 'license-authentication') }) when 'TOKEN_NOT_ALLOWED', 'TOKEN_INVALID' - kwargs[:links] = { about: 'https://keygen.sh/docs/api/authentication/#token-authentication' } + kwargs.deep_merge(links: { about: docs_url(:authentication, anchor: 'token-authentication') }) when 'TOKEN_MISSING' - kwargs[:links] = { about: 'https://keygen.sh/docs/api/authentication/' } + kwargs.deep_merge(links: { about: docs_url(:authentication) }) end render_unauthorized(**kwargs) diff --git a/app/controllers/auth/sso_controller.rb b/app/controllers/auth/sso_controller.rb new file mode 100644 index 0000000000..cbc120d3a7 --- /dev/null +++ b/app/controllers/auth/sso_controller.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Auth + class SsoController < Api::V1::BaseController + include ActionController::Cookies + + skip_verify_authorized + + def callback + Keygen::SSO.raise_on_request_error!(request) # handle errors + + code, state = request.query_parameters.values_at(:code, :state) + profile = Keygen::SSO.redeem_code(code:) + account = Keygen::SSO.lookup_account( + profile:, + ) + + # assert the authn state matches what we expect e.g. the original email + # equals actual authenticated email + Keygen::SSO.raise_on_state_error!(state, + profile:, + account:, + ) + + user = Keygen::SSO.lookup_or_provision_user(profile:, account:) + user.update!( + # Generate a nonce to assert that only 1 SSO-based session can be + # active for a user at any given time. + session_nonce: SecureRandom.random_number(2**32), + ) + + # We use encrypted session cookies for SSO authentication because we + # don't want to expose a token in the redirect URL, and we don't + # want the token used for an API integration. + session[:nonce] = user.session_nonce + session[:account_id] = account.id + session[:user_id] = user.id + + redirect_to portal_url(account), status: :see_other, allow_other_host: true + end + end +end diff --git a/app/controllers/concerns/authentication.rb b/app/controllers/concerns/authentication.rb index 5fc6d96d95..985c77c9e5 100644 --- a/app/controllers/concerns/authentication.rb +++ b/app/controllers/concerns/authentication.rb @@ -6,6 +6,28 @@ module Authentication include ActionController::HttpAuthentication::Token::ControllerMethods include ActionController::HttpAuthentication::Basic::ControllerMethods + def authenticate! + case + when has_password_credentials? + authenticate_with_password! + when has_session_credentials? + authenticate_with_session! + else + authenticate_with_token! + end + end + + def authenticate + case + when has_password_credentials? + authenticate_with_password + when has_session_credentials? + authenticate_with_session + else + authenticate_with_token + end + end + def authenticate_with_token! case when has_bearer_credentials? @@ -56,8 +78,24 @@ def authenticate_with_password_or_token end end + def authenticate_with_session! + authenticate_or_request_with_http_session(&method(:http_session_authenticator)) + end + + def authenticate_with_session + authenticate_with_http_session(&method(:http_session_authenticator)) + end + private + def authenticate_or_request_with_http_session(&auth_procedure) + authenticate_with_http_session(&auth_procedure) || request_http_token_authentication + end + + def authenticate_with_http_session(&auth_procedure) + auth_procedure.call(session) + end + def authenticate_or_request_with_query_token(&auth_procedure) authenticate_with_query_token(&auth_procedure) || request_http_token_authentication end @@ -79,6 +117,29 @@ def authenticate_with_http_license(&auth_procedure) auth_procedure.call(license_key) end + def http_session_authenticator(session) + return nil if + current_account.nil? || session.nil? + + @current_http_scheme = :session + @current_http_token = nil + @current_token = nil + + user = current_account.users.for_environment(current_environment, strict: current_environment.nil?) + .find_by(id: session[:user_id]) + + # Currently we only allow 1 session per-user, meaning if the session + # nonce doesn't match then the current session is outdated. + unless user.present? && user.account_id == session[:account_id] && + user.session_nonce == session[:nonce] + session.destroy # clear cookie + + raise Keygen::Error::InvalidSessionError.new + end + + @current_bearer = user + end + def query_token_authenticator(query_token) return nil if current_account.nil? || query_token.blank? @@ -96,43 +157,42 @@ def query_token_authenticator(query_token) end end - def http_password_authenticator(username = nil, password = nil) + def http_password_authenticator(email = nil, password = nil) + raise Keygen::Error::InvalidCredentialsError.new(header: 'Authorization') if + email.blank? + + if current_account.sso? && current_account.sso_for?(email) # for JIT-user-provisioning + redirect = sso_authorization_url_for(email) + + raise Keygen::Error::SingleSignOnRequiredError.new(links: { redirect: }) + end + user = current_account.users.for_environment(current_environment, strict: current_environment.nil?) - .find_by(email: "#{username}".downcase) + .find_by(email: "#{email}".downcase) unless user.present? - raise Keygen::Error::UnauthorizedError.new( - detail: 'email and password must be valid', - code: 'CREDENTIALS_INVALID', - header: 'Authorization', - ) + raise Keygen::Error::InvalidCredentialsError.new(header: 'Authorization') + end + + if user.single_sign_on_enabled? + redirect = sso_authorization_url_for(user) + + raise Keygen::Error::SingleSignOnRequiredError.new(links: { redirect: }) end if user.second_factor_enabled? otp = params.dig(:meta, :otp) if otp.nil? - raise Keygen::Error::UnauthorizedError.new( - detail: 'second factor is required', - code: 'OTP_REQUIRED', - pointer: '/meta/otp', - ) + raise Keygen::Error::SecondFactorRequiredError.new(pointer: '/meta/otp') end unless user.verify_second_factor(otp) - raise Keygen::Error::UnauthorizedError.new( - detail: 'second factor must be valid', - code: 'OTP_INVALID', - pointer: '/meta/otp', - ) + raise Keygen::Error::InvalidSecondFactorError.new(pointer: '/meta/otp') end end unless user.password? && user.authenticate(password) - raise Keygen::Error::UnauthorizedError.new( - detail: 'email and password must be valid', - code: 'CREDENTIALS_INVALID', - header: 'Authorization', - ) + raise Keygen::Error::InvalidCredentialsError.new(header: 'Authorization') end @current_bearer = user @@ -283,6 +343,10 @@ def has_license_credentials? authentication_scheme == 'license' end + def has_session_credentials? + session.key?(:user_id) + end + def has_password_credentials? return false unless has_basic_credentials? @@ -315,4 +379,15 @@ def authentication_value auth_value end + + def sso_authorization_url(email) = Keygen::SSO.authorization_url(account: current_account, provider: sso_provider, email:) + def sso_provider = request.filtered_parameters.dig(:meta, :provider) + def sso_authorization_url_for(user_or_email) + case user_or_email + in User => user + sso_authorization_url(user.email) + in String => email + sso_authorization_url(email) + end + end end diff --git a/app/models/account.rb b/app/models/account.rb index f1f90f73a2..185441943c 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -289,6 +289,16 @@ def protected? protected end + def sso? = sso_organization_id? + def sso_for?(email) + return false if email.blank? + + _, domain = email.downcase.match(/([^@]+)@(.+)/) + .captures + + domain.in?(sso_organization_domains) + end + def status billing&.state&.upcase end diff --git a/app/models/user.rb b/app/models/user.rb index 9c5255674f..df62e20fe2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -470,6 +470,8 @@ def status end end + def single_sign_on_enabled? = !role.user? && account.sso? + def second_factor_enabled? second_factors.enabled.exists? end diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb index cb1446dba3..cb975a732a 100644 --- a/app/services/resolve_account_service.rb +++ b/app/services/resolve_account_service.rb @@ -12,6 +12,7 @@ def call! case when Keygen.singleplayer? account_id = request.params[:account_id] || + request.session[:account_id] || ENV['KEYGEN_ACCOUNT_ID'] raise Keygen::Error::InvalidAccountIdError, 'account is required' unless account_id.present? @@ -22,7 +23,7 @@ def call! account when Keygen.multiplayer? - account_id = request.params[:account_id] + account_id = request.params[:account_id] || request.session[:account_id] account_host = request.host account = find_by_account_cname(account_host) || diff --git a/config/application.rb b/config/application.rb index e603143cd3..c53cadfcb7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -34,6 +34,17 @@ class Application < Rails::Application # Skip views, helpers and assets when generating a new resource. config.api_only = true + # Use cookies for sessions + config.session_store :cookie_store, key: '_keygen_session', + domain: Keygen::PORTAL_HOST, + expire_after: 1.day, + httponly: true, + secure: true + + # Re-add session middleware since we're an API-only app + config.middleware.use ActionDispatch::Cookies + config.middleware.use config.session_store, config.session_options + # Remove unneeded Rack middleware config.middleware.delete Rack::ConditionalGet config.middleware.delete Rack::ETag @@ -93,6 +104,9 @@ class Application < Rails::Application # FIXME(ezekg) Use 7.0 cache format until we can roll over to 7.1. config.active_support.cache_format_version 7.0 + # Use SHA256 for signed cookies + config.action_dispatch.signed_cookie_digest = 'SHA256' + # We don't need this: https://guides.rubyonrails.org/security.html#unsafe-query-generation config.action_dispatch.perform_deep_munge = false diff --git a/config/initializers/workos.rb b/config/initializers/workos.rb new file mode 100644 index 0000000000..8c519e57e3 --- /dev/null +++ b/config/initializers/workos.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +WORKOS_CLIENT_ID = ENV['WORKOS_CLIENT_ID'] +WORKOS_API_KEY = ENV['WORKOS_API_KEY'] + +WorkOS.configure do |config| + config.key = WORKOS_API_KEY +end diff --git a/config/initializers/zietwork.rb b/config/initializers/zietwork.rb index d1db06934a..29f4438261 100644 --- a/config/initializers/zietwork.rb +++ b/config/initializers/zietwork.rb @@ -3,8 +3,9 @@ Rails.autoloaders.each do |autoloader| # FIXME(ezekg) Should we rename these to follow conventions? autoloader.inflector.inflect( - "digest_io" => "DigestIO", - "jsonapi" => "JSONAPI", - "ee" => "EE", + 'digest_io' => 'DigestIO', + 'jsonapi' => 'JSONAPI', + 'ee' => 'EE', + 'sso' => 'SSO', ) end diff --git a/config/routes.rb b/config/routes.rb index cb30a6cc3e..48f8a6d472 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -54,10 +54,14 @@ concern :tauri do scope module: :tauri, constraints: MimeTypeConstraint.new(:binary, :json, raise_on_no_match: true), defaults: { format: :json } do - get ':package', to: 'upgrades#show' + get ':package', to: 'upgrades#show', as: :tauri_upgrade_package end end + concern :sso do + get :sso, to: 'sso#callback', as: :sso_callback + end + concern :v1 do get :ping, to: 'health#general_ping' @@ -477,6 +481,14 @@ end end + # Subdomains for authentication (i.e. SSO) + scope constraints: { subdomain: 'auth' }, **domain_constraints do + # SSO + scope module: :auth do + concerns :sso + end + end + scope module: :api do namespace :v1 do # Health checks @@ -538,6 +550,16 @@ end end + # Route helper for redirecting to Portal + direct :portal do |segment, options| + Keygen.portal_url(segment, **options) + end + + # Route helpers for redirecting to docs + direct :docs do |segment, options| + Keygen.docs_url(segment, **options) + end + %w[500 503].each do |code| match code, to: 'errors#show', code: code.to_i, via: :all end diff --git a/db/migrate/20240712202229_add_sso_organization_id_to_accounts.rb b/db/migrate/20240712202229_add_sso_organization_id_to_accounts.rb new file mode 100644 index 0000000000..024577961e --- /dev/null +++ b/db/migrate/20240712202229_add_sso_organization_id_to_accounts.rb @@ -0,0 +1,8 @@ +class AddSsoOrganizationIdToAccounts < ActiveRecord::Migration[7.1] + disable_ddl_transaction! + + def change + add_column :accounts, :sso_organization_id, :string, null: true + add_index :accounts, :sso_organization_id, unique: true, algorithm: :concurrently + end +end diff --git a/db/migrate/20240715164737_add_sso_profile_id_to_users.rb b/db/migrate/20240715164737_add_sso_profile_id_to_users.rb new file mode 100644 index 0000000000..269807b630 --- /dev/null +++ b/db/migrate/20240715164737_add_sso_profile_id_to_users.rb @@ -0,0 +1,8 @@ +class AddSsoProfileIdToUsers < ActiveRecord::Migration[7.1] + disable_ddl_transaction! + + def change + add_column :users, :sso_profile_id, :string, null: true + add_index :users, %i[account_id sso_profile_id], unique: true, algorithm: :concurrently + end +end diff --git a/db/migrate/20240715174443_add_sso_idp_id_to_users.rb b/db/migrate/20240715174443_add_sso_idp_id_to_users.rb new file mode 100644 index 0000000000..040368ff08 --- /dev/null +++ b/db/migrate/20240715174443_add_sso_idp_id_to_users.rb @@ -0,0 +1,8 @@ +class AddSsoIdpIdToUsers < ActiveRecord::Migration[7.1] + disable_ddl_transaction! + + def change + add_column :users, :sso_idp_id, :string, null: true + add_index :users, %i[account_id sso_idp_id], unique: true, algorithm: :concurrently + end +end diff --git a/db/migrate/20240715210732_add_session_nonce_to_users.rb b/db/migrate/20240715210732_add_session_nonce_to_users.rb new file mode 100644 index 0000000000..716b335697 --- /dev/null +++ b/db/migrate/20240715210732_add_session_nonce_to_users.rb @@ -0,0 +1,5 @@ +class AddSessionNonceToUsers < ActiveRecord::Migration[7.1] + def change + add_column :users, :session_nonce, :integer, limit: 8 + end +end diff --git a/db/migrate/20240716153309_add_sso_connection_id_to_users.rb b/db/migrate/20240716153309_add_sso_connection_id_to_users.rb new file mode 100644 index 0000000000..150acdae1b --- /dev/null +++ b/db/migrate/20240716153309_add_sso_connection_id_to_users.rb @@ -0,0 +1,7 @@ +class AddSsoConnectionIdToUsers < ActiveRecord::Migration[7.1] + disable_ddl_transaction! + + def change + add_column :users, :sso_connection_id, :string, null: true + end +end diff --git a/db/migrate/20240716174322_add_sso_organization_domain_to_accounts.rb b/db/migrate/20240716174322_add_sso_organization_domain_to_accounts.rb new file mode 100644 index 0000000000..ace43ecc65 --- /dev/null +++ b/db/migrate/20240716174322_add_sso_organization_domain_to_accounts.rb @@ -0,0 +1,5 @@ +class AddSsoOrganizationDomainToAccounts < ActiveRecord::Migration[7.1] + def change + add_column :accounts, :sso_organization_domains, :string, array: true, default: [] + end +end diff --git a/db/schema.rb b/db/schema.rb index c375d1c850..2b0b9c3eb6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -39,6 +39,8 @@ t.string "api_version" t.string "cname" t.string "backend" + t.string "sso_organization_id" + t.string "sso_organization_domains", default: [], array: true t.index ["cname"], name: "index_accounts_on_cname", unique: true t.index ["created_at"], name: "index_accounts_on_created_at", order: :desc t.index ["domain"], name: "index_accounts_on_domain", unique: true @@ -46,6 +48,7 @@ t.index ["plan_id", "created_at"], name: "index_accounts_on_plan_id_and_created_at" t.index ["slug", "created_at"], name: "index_accounts_on_slug_and_created_at", unique: true t.index ["slug"], name: "index_accounts_on_slug", unique: true + t.index ["sso_organization_id"], name: "index_accounts_on_sso_organization_id", unique: true t.index ["subdomain"], name: "index_accounts_on_subdomain", unique: true end @@ -794,11 +797,17 @@ t.datetime "banned_at", precision: nil t.uuid "group_id" t.uuid "environment_id" + t.string "sso_profile_id" + t.string "sso_idp_id" + t.bigint "session_nonce" + t.string "sso_connection_id" t.index "to_tsvector('simple'::regconfig, COALESCE((first_name)::text, ''::text))", name: "users_tsv_first_name_idx", using: :gist t.index "to_tsvector('simple'::regconfig, COALESCE((id)::text, ''::text))", name: "users_tsv_id_idx", using: :gist t.index "to_tsvector('simple'::regconfig, COALESCE((last_name)::text, ''::text))", name: "users_tsv_last_name_idx", using: :gist t.index "to_tsvector('simple'::regconfig, COALESCE((metadata)::text, ''::text))", name: "users_tsv_metadata_idx", using: :gist t.index ["account_id", "created_at"], name: "index_users_on_account_id_and_created_at" + t.index ["account_id", "sso_idp_id"], name: "index_users_on_account_id_and_sso_idp_id", unique: true + t.index ["account_id", "sso_profile_id"], name: "index_users_on_account_id_and_sso_profile_id", unique: true t.index ["banned_at"], name: "index_users_on_banned_at" t.index ["created_at"], name: "index_users_on_created_at", order: :desc t.index ["email", "account_id"], name: "index_users_on_email_and_account_id", unique: true diff --git a/lib/keygen.rb b/lib/keygen.rb index 638ee4babd..7bc4255db1 100644 --- a/lib/keygen.rb +++ b/lib/keygen.rb @@ -10,8 +10,12 @@ require_relative 'keygen/portable_class' require_relative 'keygen/exporter' require_relative 'keygen/importer' +require_relative 'keygen/sso' +require_relative 'keygen/url_for' module Keygen + include UrlFor + PUBLIC_KEY = %(\xB8\xF3\xEBL\xD2`\x13_g\xA5\tn\x8D\xC1\xC9\xB9\xDC\xB8\x1E\xE9\xFEP\xD1,\xDC\xD9A\xF6`z\x901).freeze class << self diff --git a/lib/keygen/error.rb b/lib/keygen/error.rb index 0c0cef02ea..1653a0c574 100644 --- a/lib/keygen/error.rb +++ b/lib/keygen/error.rb @@ -5,12 +5,14 @@ module Error class JSONAPIError < StandardError attr_reader :code, :detail, - :source + :source, + :links - def initialize(message, code: nil, detail: nil, parameter: nil, pointer: nil, header: nil) + def initialize(message, code: nil, detail: nil, parameter: nil, pointer: nil, header: nil, links: nil) @code = code @detail = detail @source = { parameter:, pointer:, header: }.compact + @links = links super(message) end @@ -20,6 +22,30 @@ class UnauthorizedError < JSONAPIError def initialize(message = 'is unauthorized', code:, **) = super(message, code:, **) end + class InvalidCredentialsError < UnauthorizedError + def initialize(*, **) = super(*, detail: 'email and password must be valid', code: 'CREDENTIALS_INVALID', **) + end + + class SingleSignOnRequiredError < UnauthorizedError + def initialize(*, **) = super(*, detail: 'single sign on is required', code: 'SSO_REQUIRED', **) + end + + class InvalidSingleSignOnError < UnauthorizedError + def initialize(*, **) = super(*, detail: 'single sign on is invalid', code: 'SSO_INVALID', **) + end + + class SecondFactorRequiredError < UnauthorizedError + def initialize(*, **) = super(*, detail: 'second factor is required', code: 'OTP_REQUIRED', **) + end + + class InvalidSecondFactorError < UnauthorizedError + def initialize(*, **) = super(*, detail: 'second factor must be valid', code: 'OTP_INVALID', **) + end + + class InvalidSessionError < UnauthorizedError + def initialize(*, **) = super(*, detail: 'session is invalid', code: 'SESSION_INVALID', **) + end + class ForbiddenError < JSONAPIError def initialize(message = 'is forbidden', code:, **) = super(message, code:, **) end diff --git a/lib/keygen/sso.rb b/lib/keygen/sso.rb new file mode 100644 index 0000000000..412827a0ef --- /dev/null +++ b/lib/keygen/sso.rb @@ -0,0 +1,121 @@ +# frozen_string_literal: true + +module Keygen + module SSO + class << self + def authorization_url(account:, email:, provider: nil) + state = { email: } # used to assert redeemer matches requestor + + WorkOS::SSO.authorization_url( + client_id: WORKOS_CLIENT_ID, + organization: account.sso_organization_id, + state: encrypt(state, secret_key: account.secret_key), + redirect_uri:, + provider:, + ) + end + + # Redeem an authentication code for a user profile. + def redeem_code(code:) + WorkOS::SSO.profile_and_token(client_id: WORKOS_CLIENT_ID, code:) + .profile + rescue WorkOS::APIError => e + raise Keygen::Error::InvalidSingleSignOnError.new(e.message) + end + + # Lookup the account for a user profile. + def lookup_account(profile:) + Account.where.not(sso_organization_id: nil) # sanity-check + .find_by!( + sso_organization_id: profile.organization_id, + ) + rescue ActiveRecord::RecordNotFound + raise Keygen::Error::InvalidSingleSignOnError.new('account is invalid') + end + + # WorkOS recommends JIT-user-provisioning: https://workos.com/docs/sso/jit-provisioning + # + # 1. First, we attempt to lookup the user by their profile ID. + # 2. Next, we attempt to lookup the user by their email. + # 3. Otherwise, initialize a new user. + # + # Lastly, we keep the user's attributes up-to-date. + def lookup_or_provision_user(profile:, account:, save: false, validate: false) + user = account.users.then do |users| + users.find_by(sso_profile_id: profile.id) || users.find_or_initialize_by(email: profile.email) do |u| + u.sso_profile_id = profile.id + u.sso_connection_id = profile.connection_id + u.sso_idp_id = profile.idp_id + u.first_name = profile.first_name + u.last_name = profile.last_name + u.email = profile.email + + # TODO(ezekg) eventually implement workos groups? + u.grant_role! :admin + end + end + + # keep the user's attributes up-to-date with the IdP + user.assign_attributes( + sso_profile_id: profile.id, + sso_connection_id: profile.connection_id, + sso_idp_id: profile.idp_id, + first_name: profile.first_name, + last_name: profile.last_name, + email: profile.email, + ) + + user.save!(validate:) if save + + user + end + + def raise_on_request_error!(request) + if (code, message = request.query_parameters.values_at(:error, :error_description)).any? + raise Keygen::Error::InvalidSingleSignOnError.new(message, code: "SSO_#{code.upcase}") + end + end + + def raise_on_state_error!(state, account:, profile:) + unless state.blank? + value = decrypt(state, secret_key: account.secret_key).with_indifferent_access + + # assert the profile's email matches the email that initiated the authn + unless profile.email == value[:email] + raise Keygen::Error::InvalidSingleSignOnError.new('email is invalid') + end + end + end + + private + + def redirect_uri = Rails.application.routes.url_helpers.sso_callback_url + + def encrypt(plaintext, secret_key:) + crypt = ActiveSupport::MessageEncryptor.new(derive_key(secret_key), serializer: JSON) + enc = crypt.encrypt_and_sign(plaintext) + .split('--') + .map { |s| Base64.urlsafe_encode64(Base64.strict_decode64(s), padding: false) } + .join('.') + + enc + end + + def decrypt(ciphertext, secret_key:) + crypt = ActiveSupport::MessageEncryptor.new(derive_key(secret_key), serializer: JSON) + enc = ciphertext.split('.') + .map { |s| Base64.strict_encode64(Base64.urlsafe_decode64(s)) } + .join('--') + + crypt.decrypt_and_verify(enc) + end + + def derive_key(secret_key) + keygen = ActiveSupport::KeyGenerator.new(secret_key) + salt = 'sso'.freeze + + keygen.generate_key(salt, 32) + end + end + end +end diff --git a/lib/keygen/url_for.rb b/lib/keygen/url_for.rb new file mode 100644 index 0000000000..9d99183db2 --- /dev/null +++ b/lib/keygen/url_for.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module Keygen + module UrlFor + extend ActiveSupport::Concern + + PORTAL_HOST = ENV.fetch('KEYGEN_PORTAL_HOST') { 'portal.keygen.sh' }.freeze + PORTAL_BASE_URL = "https://#{PORTAL_HOST}".freeze + DOCS_BASE_URL = 'https://keygen.sh/docs/api'.freeze + + class_methods do + def portal_url(record_or_path = nil, **) = case record_or_path + in Account => account + url_for(PORTAL_BASE_URL, path: account.slug, **) + in String | Symbol => path + url_for(PORTAL_BASE_URL, path:, **) + else + url_for(PORTAL_BASE_URL, **) + end + + def docs_url(topic = nil, **) = url_for(DOCS_BASE_URL, trailing_slash: true, path: topic.presence, **) + + private + + def url_for(base_url, path: nil, query: nil, anchor: nil, trailing_slash: false) + url = URI.parse(base_url) + + unless path.nil? + url.path += '/' unless path.to_s.starts_with?('/') + url.path += path.to_s + url.path += '/' if trailing_slash + end + + url.query = query.to_query unless query.nil? + url.fragment = anchor.to_s unless anchor.nil? + + url.to_s + end + end + end +end diff --git a/spec/lib/union_of_spec.rb b/spec/lib/union_of_spec.rb index 0760734827..38c27d45ca 100644 --- a/spec/lib/union_of_spec.rb +++ b/spec/lib/union_of_spec.rb @@ -935,7 +935,11 @@ "users"."stdout_last_sent_at" AS t1_r12, "users"."banned_at" AS t1_r13, "users"."group_id" AS t1_r14, - "users"."environment_id" AS t1_r15 + "users"."environment_id" AS t1_r15, + "users"."sso_profile_id" AS t1_r16, + "users"."sso_idp_id" AS t1_r17, + "users"."session_nonce" AS t1_r18, + "users"."sso_connection_id" AS t1_r19 FROM "licenses" LEFT OUTER JOIN "license_users" ON "license_users"."license_id" = "licenses"."id" @@ -979,6 +983,10 @@ "users"."banned_at" AS t0_r13, "users"."group_id" AS t0_r14, "users"."environment_id" AS t0_r15, + "users"."sso_profile_id" AS t0_r16, + "users"."sso_idp_id" AS t0_r17, + "users"."session_nonce" AS t0_r18, + "users"."sso_connection_id" AS t0_r19, "machines"."id" AS t1_r0, "machines"."fingerprint" AS t1_r1, "machines"."ip" AS t1_r2,