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