From b4ee24368ce127de8f8a153acfaec264d653982f Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Tue, 13 Feb 2024 15:39:28 +1100 Subject: [PATCH] Add model for OIDC accounts The provider name and uid are currently stored on the user model but it's better to move them to their own table. They are only needed in certain situations, only some users have an account and we are now storing a lot more. --- app/models/oidc_account.rb | 9 +++++++++ .../20240213042618_create_oidc_accounts.rb | 18 ++++++++++++++++++ db/schema.rb | 15 ++++++++++++++- spec/models/oidc_account_spec.rb | 18 ++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 app/models/oidc_account.rb create mode 100644 db/migrate/20240213042618_create_oidc_accounts.rb create mode 100644 spec/models/oidc_account_spec.rb diff --git a/app/models/oidc_account.rb b/app/models/oidc_account.rb new file mode 100644 index 0000000000..9d1eb8b752 --- /dev/null +++ b/app/models/oidc_account.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class OidcAccount < ApplicationRecord + belongs_to :user, class_name: "Spree::User" + + # When a user authenticates via token, the `uid` should be mapped to only one + # OFN user and therefore it needs to be unique. + validates :uid, presence: true, uniqueness: true +end diff --git a/db/migrate/20240213042618_create_oidc_accounts.rb b/db/migrate/20240213042618_create_oidc_accounts.rb new file mode 100644 index 0000000000..7a77e8b716 --- /dev/null +++ b/db/migrate/20240213042618_create_oidc_accounts.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class CreateOidcAccounts < ActiveRecord::Migration[7.0] + def change + create_table :oidc_accounts do |t| + # We may allow multiple OIDC accounts per user in the future but for now + # we assume only one and therefore make this unique. + t.belongs_to :user, null: false, foreign_key: { to_table: :spree_users }, + index: { unique: true } + t.string :provider + t.string :uid, null: false, index: { unique: true } + t.string :token + t.string :refresh_token + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 312cf4e23e..0aad1ebf69 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_01_15_022359) do +ActiveRecord::Schema[7.0].define(version: 2024_02_13_042618) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" enable_extension "plpgsql" @@ -308,6 +308,18 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_15_022359) do t.index ["order_id"], name: "index_invoices_on_order_id" end + create_table "oidc_accounts", force: :cascade do |t| + t.bigint "user_id", null: false + t.string "provider" + t.string "uid", null: false + t.string "token" + t.string "refresh_token" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["uid"], name: "index_oidc_accounts_on_uid", unique: true + t.index ["user_id"], name: "index_oidc_accounts_on_user_id", unique: true + end + create_table "order_cycle_schedules", id: :serial, force: :cascade do |t| t.integer "order_cycle_id", null: false t.integer "schedule_id", null: false @@ -1146,6 +1158,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_01_15_022359) do add_foreign_key "inventory_items", "enterprises" add_foreign_key "inventory_items", "spree_variants", column: "variant_id" add_foreign_key "invoices", "spree_orders", column: "order_id" + add_foreign_key "oidc_accounts", "spree_users", column: "user_id" add_foreign_key "order_cycle_schedules", "order_cycles", name: "oc_schedules_order_cycle_id_fk" add_foreign_key "order_cycle_schedules", "schedules", name: "oc_schedules_schedule_id_fk" add_foreign_key "order_cycles", "enterprises", column: "coordinator_id", name: "order_cycles_coordinator_id_fk" diff --git a/spec/models/oidc_account_spec.rb b/spec/models/oidc_account_spec.rb new file mode 100644 index 0000000000..4e70d550b2 --- /dev/null +++ b/spec/models/oidc_account_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe OidcAccount, type: :model do + describe "associations and validations" do + subject { + OidcAccount.new( + user: build(:user), + provider: "openid_connect", + uid: "user@example.net" + ) + } + + it { is_expected.to belong_to :user } + it { is_expected.to validate_uniqueness_of :uid } + end +end