diff --git a/app/controllers/registrar/current_user_controller.rb b/app/controllers/registrar/current_user_controller.rb
index 4661318e7..266e4b915 100644
--- a/app/controllers/registrar/current_user_controller.rb
+++ b/app/controllers/registrar/current_user_controller.rb
@@ -3,10 +3,16 @@ class Registrar
skip_authorization_check
def switch
- new_user = ApiUser.find(params[:new_user_id])
- sign_in(new_user) if new_user.identity_code == current_user.identity_code
+ raise 'Cannot switch to unlinked user' unless current_user.linked_with?(new_user)
+ sign_in(new_user)
redirect_to :back, notice: t('.switched', new_user: new_user)
end
+
+ private
+
+ def new_user
+ @new_user ||= ApiUser.find(params[:new_user_id])
+ end
end
end
diff --git a/app/controllers/registrar/profile_controller.rb b/app/controllers/registrar/profile_controller.rb
new file mode 100644
index 000000000..5f202a894
--- /dev/null
+++ b/app/controllers/registrar/profile_controller.rb
@@ -0,0 +1,17 @@
+class Registrar
+ class ProfileController < BaseController
+ skip_authorization_check
+
+ helper_method :linked_users
+
+ def show
+ @user = current_user
+ end
+
+ private
+
+ def linked_users
+ current_user.linked_users
+ end
+ end
+end
diff --git a/app/models/api_user.rb b/app/models/api_user.rb
index a5030c096..5e20db24a 100644
--- a/app/models/api_user.rb
+++ b/app/models/api_user.rb
@@ -23,9 +23,9 @@ class ApiUser < User
validates :password, length: { minimum: min_password_length }
validates :username, uniqueness: true
- # TODO: probably cache, because it's requested on every EPP
- delegate :code, to: :registrar, prefix: true
+ delegate :code, :name, to: :registrar, prefix: true
+ alias_attribute :login, :username
attr_accessor :registrar_typeahead
SUPER = 'super'
@@ -91,7 +91,11 @@ class ApiUser < User
def linked_users
self.class.where(identity_code: identity_code)
- .where("identity_code is NOT NULL and identity_code != ''")
+ .where("identity_code IS NOT NULL AND identity_code != ''")
.where.not(id: id)
end
+
+ def linked_with?(another_api_user)
+ another_api_user.identity_code == self.identity_code
+ end
end
diff --git a/app/presenters/user_presenter.rb b/app/presenters/user_presenter.rb
new file mode 100644
index 000000000..29aeaa187
--- /dev/null
+++ b/app/presenters/user_presenter.rb
@@ -0,0 +1,19 @@
+class UserPresenter
+ def initialize(user:, view:)
+ @user = user
+ @view = view
+ end
+
+ def login_with_role
+ "#{user.login} (#{role_name}) - #{user.registrar_name}"
+ end
+
+ private
+
+ def role_name
+ user.roles.first
+ end
+
+ attr_reader :user
+ attr_reader :view
+end
diff --git a/app/views/registrar/base/_current_user.html.erb b/app/views/registrar/base/_current_user.html.erb
index 9c82b37f0..01dc5262b 100644
--- a/app/views/registrar/base/_current_user.html.erb
+++ b/app/views/registrar/base/_current_user.html.erb
@@ -1,3 +1,4 @@
-<%= "#{current_user} (#{current_user.roles.first}) - #{current_user.registrar}" %>
+<% current_user_presenter = UserPresenter.new(user: current_user, view: self) %>
+<%= link_to current_user_presenter.login_with_role, registrar_profile_path, id: 'registrar-profile-btn' %>
|
<%= link_to t('.sign_out'), registrar_destroy_user_session_path, method: :delete %>
diff --git a/app/views/registrar/profile/_linked_users.html.erb b/app/views/registrar/profile/_linked_users.html.erb
new file mode 100644
index 000000000..fa8d868b4
--- /dev/null
+++ b/app/views/registrar/profile/_linked_users.html.erb
@@ -0,0 +1,18 @@
+
+
<%= t '.header' %>
+
+
+ <% linked_users.each do |user| %>
+ <% user_presenter = UserPresenter.new(user: user, view: self) %>
+ - <%= user_presenter.login_with_role %>
+ <%= link_to t('.switch_btn'),
+ registrar_switch_current_user_path(user),
+ method: :put,
+ id: "switch-current-user-#{user.id}-btn",
+ class: 'btn btn-primary btn-xs' %>
+
+ <% end %>
+
+
+
+
diff --git a/app/views/registrar/profile/show.html.erb b/app/views/registrar/profile/show.html.erb
new file mode 100644
index 000000000..d6a90d64c
--- /dev/null
+++ b/app/views/registrar/profile/show.html.erb
@@ -0,0 +1,9 @@
+
+
+
+
+ <%= render 'linked_users', linked_users: linked_users %>
+
+
diff --git a/config/locales/registrar/profile.en.yml b/config/locales/registrar/profile.en.yml
new file mode 100644
index 000000000..2ccec1406
--- /dev/null
+++ b/config/locales/registrar/profile.en.yml
@@ -0,0 +1,9 @@
+en:
+ registrar:
+ profile:
+ show:
+ header: My profile
+
+ linked_users:
+ header: Linked users
+ switch_btn: Switch
diff --git a/config/routes.rb b/config/routes.rb
index 0f83e9aef..9a513b434 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -43,11 +43,11 @@ Rails.application.routes.draw do
post 'sessions' => 'sessions#create'
post 'id' => 'sessions#id'
post 'mid' => 'sessions#mid'
- get 'switch_user/:id' => 'sessions#switch_user'
delete 'logout', to: '/devise/sessions#destroy', as: :destroy_user_session
end
- get 'current_user/switch/:new_user_id', to: 'current_user#switch', as: :switch_current_user
+ put 'current_user/switch/:new_user_id', to: 'current_user#switch', as: :switch_current_user
+ resource :profile, controller: :profile, only: :show
resources :domains do
collection do
diff --git a/spec/features/registrar/linked_users_spec.rb b/spec/features/registrar/linked_users_spec.rb
new file mode 100644
index 000000000..2f5fbbd28
--- /dev/null
+++ b/spec/features/registrar/linked_users_spec.rb
@@ -0,0 +1,18 @@
+require 'rails_helper'
+
+RSpec.feature 'Registrar area linked users', settings: false do
+ given!(:current_user) { create(:api_user_with_unlimited_balance, id: 1, identity_code: 'test') }
+ given!(:linked_user) { create(:api_user_with_unlimited_balance, id: 2, identity_code: 'test',
+ username: 'new-user-name') }
+
+ background do
+ Setting.registrar_ip_whitelist_enabled = false
+ sign_in_to_registrar_area(user: current_user)
+ end
+
+ scenario 'switches current user to a linked one' do
+ visit registrar_profile_path
+ click_link_or_button 'switch-current-user-2-btn'
+ expect(page).to have_text('You are now signed in as a user "new-user-name"')
+ end
+end
diff --git a/spec/features/registrar/profile_spec.rb b/spec/features/registrar/profile_spec.rb
new file mode 100644
index 000000000..195458576
--- /dev/null
+++ b/spec/features/registrar/profile_spec.rb
@@ -0,0 +1,14 @@
+require 'rails_helper'
+
+RSpec.feature 'Registrar area profile', settings: false do
+ background do
+ Setting.registrar_ip_whitelist_enabled = false
+ sign_in_to_registrar_area(user: create(:api_user_with_unlimited_balance))
+ end
+
+ scenario 'shows profile' do
+ visit registrar_root_path
+ click_on 'registrar-profile-btn'
+ expect(page).to have_text(t('registrar.profile.show.header'))
+ end
+end
diff --git a/spec/features/registrar/user_switch_spec.rb b/spec/features/registrar/user_switch_spec.rb
deleted file mode 100644
index 0927a908a..000000000
--- a/spec/features/registrar/user_switch_spec.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require 'rails_helper'
-
-RSpec.feature 'Registrar area user switch', settings: false do
- given!(:current_user) { create(:api_user, id: 1, identity_code: 'test') }
- given!(:new_user) { create(:api_user, id: 2, identity_code: 'test', username: 'new-user-name') }
-
- background do
- sign_in_to_registrar_area(user: current_user)
- end
-
- scenario 'successful user switch' do
- visit registrar_root_path
- click_link_or_button 'switch-current-user-2-btn'
- expect(page).to have_text('You are now signed in as a user "new-user-name"')
- end
-end
diff --git a/spec/models/api_user_spec.rb b/spec/models/api_user_spec.rb
index fc5388b8c..12213c819 100644
--- a/spec/models/api_user_spec.rb
+++ b/spec/models/api_user_spec.rb
@@ -93,4 +93,36 @@ RSpec.describe ApiUser do
expect(api_user.linked_users).to be_empty
end
end
+
+ describe '#linked_with?', db: false do
+ it 'returns true if identity codes match' do
+ api_user = described_class.new(identity_code: 'test')
+ another_api_user = described_class.new(identity_code: 'test')
+
+ expect(api_user.linked_with?(another_api_user)).to be true
+ end
+
+ it 'returns false if identity codes do not match' do
+ api_user = described_class.new(identity_code: 'test')
+ another_api_user = described_class.new(identity_code: 'another-test')
+
+ expect(api_user.linked_with?(another_api_user)).to be false
+ end
+ end
+
+ describe '#login', db: false do
+ it 'is alias to #username' do
+ user = described_class.new(username: 'test-username')
+ expect(user.login).to eq('test-username')
+ end
+ end
+
+ describe '#registrar_name', db: false do
+ it 'delegates to registrar' do
+ registrar = Registrar.new(name: 'test name')
+ user = described_class.new(registrar: registrar)
+
+ expect(user.registrar_name).to eq('test name')
+ end
+ end
end
diff --git a/spec/presenters/user_presenter_spec.rb b/spec/presenters/user_presenter_spec.rb
new file mode 100644
index 000000000..ba9e1673f
--- /dev/null
+++ b/spec/presenters/user_presenter_spec.rb
@@ -0,0 +1,16 @@
+require 'rails_helper'
+
+RSpec.describe UserPresenter do
+ let(:presenter) { described_class.new(user: user, view: view) }
+
+ describe '#login_with_role' do
+ let(:user) { instance_double(ApiUser,
+ login: 'login',
+ roles: %w[role],
+ registrar_name: 'registrar') }
+
+ it 'returns username with role and registrar' do
+ expect(presenter.login_with_role).to eq('login (role) - registrar')
+ end
+ end
+end
diff --git a/spec/requests/registrar/current_user_spec.rb b/spec/requests/registrar/current_user_spec.rb
deleted file mode 100644
index 0d5f22eb0..000000000
--- a/spec/requests/registrar/current_user_spec.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe 'Registrar current user', db: false do
- describe 'GET /registrar/current_user/switch/2' do
- context 'when user is authenticated', db: true do
- let!(:current_user) { create(:api_user, id: 1, identity_code: 'test') }
- let!(:new_user) { create(:api_user, id: 2, identity_code: 'test') }
-
- before do
- sign_in_to_registrar_area(user: current_user)
- end
-
- context 'when ip is allowed' do
- let(:restricted_ip) { instance_double(Authorization::RestrictedIP,
- can_access_registrar_area?: true) }
-
- before do
- allow(Authorization::RestrictedIP).to receive(:new).and_return(restricted_ip)
- end
-
- specify do
- get '/registrar/current_user/switch/2', nil, { HTTP_REFERER: 'http://previous.url' }
- expect(response).to redirect_to('http://previous.url')
- end
- end
-
- context 'when ip is not allowed' do
- let(:restricted_ip) { instance_double(Authorization::RestrictedIP,
- can_access_registrar_area?: false) }
-
- before do
- allow(Authorization::RestrictedIP).to receive(:new).and_return(restricted_ip)
- end
-
- specify do
- get '/registrar/current_user/switch/2'
- expect(response).to redirect_to(registrar_login_url)
- end
- end
- end
-
- context 'when user is not authenticated' do
- specify do
- get '/registrar/current_user/switch/2'
- expect(response).to redirect_to(registrar_login_url)
- end
- end
- end
-end
diff --git a/spec/requests/registrar/linked_users_spec.rb b/spec/requests/registrar/linked_users_spec.rb
new file mode 100644
index 000000000..d5d51e3c6
--- /dev/null
+++ b/spec/requests/registrar/linked_users_spec.rb
@@ -0,0 +1,77 @@
+require 'rails_helper'
+
+RSpec.describe 'Registrar area linked users', db: false do
+ describe 'user switch' do
+ context 'when user is authenticated', db: true do
+ let!(:current_user) { create(:api_user, id: 1, identity_code: 'code') }
+
+ before do
+ sign_in_to_registrar_area(user: current_user)
+ end
+
+ context 'when ip is allowed' do
+ let(:restricted_ip) { instance_double(Authorization::RestrictedIP,
+ can_access_registrar_area?: true) }
+
+ before do
+ allow(Authorization::RestrictedIP).to receive(:new).and_return(restricted_ip)
+ end
+
+ context 'when new user is linked' do
+ let!(:new_user) { create(:api_user, id: 2, identity_code: 'code') }
+
+ it 'signs in as a new user' do
+ put '/registrar/current_user/switch/2', nil, { HTTP_REFERER: registrar_contacts_url }
+ follow_redirect!
+ expect(controller.current_user.id).to eq(2)
+ end
+
+ it 'redirects back' do
+ put '/registrar/current_user/switch/2', nil, { HTTP_REFERER: 'http://previous.url' }
+ expect(response).to redirect_to('http://previous.url')
+ end
+ end
+
+ context 'when new user is unlinked' do
+ let!(:new_user) { create(:api_user, id: 2, identity_code: 'another-code') }
+
+ it 'throws exception' do
+ expect do
+ put '/registrar/current_user/switch/2', nil, { HTTP_REFERER: registrar_contacts_path }
+ end.to raise_error('Cannot switch to unlinked user')
+ end
+
+ it 'does not sign in as a new user' do
+ suppress StandardError do
+ put '/registrar/current_user/switch/2', nil, { HTTP_REFERER: registrar_contacts_path }
+ end
+
+ follow_redirect!
+ expect(controller.current_user.id).to eq(1)
+ end
+ end
+ end
+
+ context 'when ip is not allowed' do
+ let(:restricted_ip) { instance_double(Authorization::RestrictedIP,
+ can_access_registrar_area?: false) }
+
+ before do
+ allow(Authorization::RestrictedIP).to receive(:new).and_return(restricted_ip)
+ end
+
+ specify do
+ put '/registrar/current_user/switch/2'
+ expect(response).to redirect_to(registrar_login_url)
+ end
+ end
+ end
+
+ context 'when user is not authenticated' do
+ specify do
+ put '/registrar/current_user/switch/2'
+ expect(response).to redirect_to(registrar_login_url)
+ end
+ end
+ end
+end