diff --git a/app/controllers/staffs/people/account_connection_links_controller.rb b/app/controllers/staffs/people/account_connection_links_controller.rb index ffe7ca5..f120ade 100644 --- a/app/controllers/staffs/people/account_connection_links_controller.rb +++ b/app/controllers/staffs/people/account_connection_links_controller.rb @@ -11,6 +11,7 @@ class Staffs::People::AccountConnectionLinksController < ApplicationController # POST /staff/people/:person_id/account_connection_link def create authorize [:staff, @person, AccountConnectionLink.new(@person)] + @person.update! account_connection_token: SecureRandom.alphanumeric(32) end private diff --git a/app/helpers/people_helper.rb b/app/helpers/people_helper.rb index a981ec8..a8cdc9b 100644 --- a/app/helpers/people_helper.rb +++ b/app/helpers/people_helper.rb @@ -10,4 +10,8 @@ module PeopleHelper person.full_name end end + + def person_account_connection_link(person) + new_account_connection_link_url token: person.account_connection_token + end end diff --git a/app/models/person.rb b/app/models/person.rb index ad51b14..15ecff0 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -3,6 +3,8 @@ class Person < ApplicationRecord include Nameable + ACCOUNT_CONNECTION_TOKEN_RE = /\A\w+\z/.freeze + ################ # Associations # ################ @@ -35,6 +37,12 @@ class Person < ApplicationRecord validates :photo, allow_nil: true, image: true + validates :account_connection_token, + allow_nil: true, + allow_blank: false, + length: { is: 32 }, + format: { with: ACCOUNT_CONNECTION_TOKEN_RE } + ########### # Methods # ########### diff --git a/app/views/staffs/people/account_connection_links/create.html.erb b/app/views/staffs/people/account_connection_links/create.html.erb index 5627bd4..5a434b0 100644 --- a/app/views/staffs/people/account_connection_links/create.html.erb +++ b/app/views/staffs/people/account_connection_links/create.html.erb @@ -10,5 +10,12 @@

<%= translate '.description' %>

+ + diff --git a/config/routes.rb b/config/routes.rb index faed801..ad59af9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,6 +30,8 @@ Rails.application.routes.draw do # Account routes # ################## + resource :account_connection_link, only: :new + namespace :settings do resource :profile, only: %i[edit update] end diff --git a/spec/models/person_spec.rb b/spec/models/person_spec.rb index dcd43b5..82cc0b8 100644 --- a/spec/models/person_spec.rb +++ b/spec/models/person_spec.rb @@ -12,7 +12,31 @@ RSpec.describe Person do end describe '#account_connection_token' do + def allow_value(*) + super.for :account_connection_token + end + it { is_expected.not_to validate_presence_of :account_connection_token } + + it do + is_expected.to \ + validate_length_of(:account_connection_token).is_equal_to(32) + end + + it { is_expected.to allow_value nil } + it { is_expected.to allow_value SecureRandom.alphanumeric(32) } + it { is_expected.to allow_value '_' * 32 } + + it { is_expected.not_to allow_value '' } + it { is_expected.not_to allow_value 'q' } + it { is_expected.not_to allow_value SecureRandom.alphanumeric(31) } + it { is_expected.not_to allow_value SecureRandom.alphanumeric(33) } + + %w[ + ~ ` ! @ # $ % ^ & * ( ) - = + [ { ] } \ | ; : ' " , < . > / ? + ].each do |char| + it { is_expected.not_to allow_value char * 32 } + end end describe '#contact_list' do diff --git a/spec/requests/staff/people/account_connection_links/create_spec.rb b/spec/requests/staff/people/account_connection_links/create_spec.rb index 4ace1fd..ca4e7cd 100644 --- a/spec/requests/staff/people/account_connection_links/create_spec.rb +++ b/spec/requests/staff/people/account_connection_links/create_spec.rb @@ -7,13 +7,17 @@ RSpec.describe 'GET /staff/people/:person_id/account_connection_link' do let(:current_account) { create :superuser_account } - before do - sign_in current_account.user if current_account&.user - + def make_request post "/staff/people/#{person.to_param}/account_connection_link" end + before do + sign_in current_account.user if current_account&.user + end + for_account_types nil, :usual do + before { make_request } + specify do expect(response).to have_http_status :forbidden end @@ -21,7 +25,17 @@ RSpec.describe 'GET /staff/people/:person_id/account_connection_link' do for_account_types :superuser do specify do - expect(response).to have_http_status :ok + expect { make_request }.to( + change { person.reload.account_connection_token }, + ) + end + + context 'after request' do + before { make_request } + + specify do + expect(response).to have_http_status :ok + end end end @@ -29,7 +43,17 @@ RSpec.describe 'GET /staff/people/:person_id/account_connection_link' do let(:person) { create(:personal_account).person } specify do - expect(response).to have_http_status :forbidden + expect { make_request }.not_to( + change { person.reload.account_connection_token }, + ) + end + + context 'after request' do + before { make_request } + + specify do + expect(response).to have_http_status :forbidden + end end end end