diff --git a/.codeclimate.yml b/.codeclimate.yml
index 871a1abe5..03f849185 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -29,6 +29,9 @@ engines:
enabled: true
reek:
enabled: true
+ checks:
+ IrresponsibleModule:
+ enabled: false
ratings:
paths:
- Gemfile.lock
diff --git a/Gemfile b/Gemfile
index 0b4c4abc0..2f7587fc9 100644
--- a/Gemfile
+++ b/Gemfile
@@ -116,6 +116,7 @@ group :development do
end
group :development, :test do
+ gem 'factory_girl_rails'
gem 'capybara'
gem 'rspec-rails', '~> 3.6'
gem 'fabrication', '2.13.2' # Replacement for fixtures
@@ -144,7 +145,6 @@ end
group :test do
gem 'database_cleaner'
- gem 'factory_girl_rails'
gem 'codeclimate-test-reporter', "~> 1.0.0"
gem 'simplecov'
gem 'webmock'
diff --git a/app/api/repp/api.rb b/app/api/repp/api.rb
index 27d0322b0..394edfdad 100644
--- a/app/api/repp/api.rb
+++ b/app/api/repp/api.rb
@@ -15,7 +15,7 @@ module Repp
before do
webclient_request = ENV['webclient_ips'].split(',').map(&:strip).include?(request.ip)
unless webclient_request
- error! I18n.t('ip_is_not_whitelisted'), 401 unless @current_user.registrar.api_ip_white?(request.ip)
+ error! I18n.t('api.authorization.ip_not_allowed', ip: request.ip), 401 unless @current_user.registrar.api_ip_white?(request.ip)
end
if @current_user.cannot?(:view, :repp)
diff --git a/app/controllers/registrar/base_controller.rb b/app/controllers/registrar/base_controller.rb
index c91f2e075..90f2f5210 100644
--- a/app/controllers/registrar/base_controller.rb
+++ b/app/controllers/registrar/base_controller.rb
@@ -1,40 +1,38 @@
class Registrar
class BaseController < ApplicationController
- before_action :authenticate_user!, :check_ip
-
include Registrar::ApplicationHelper
+ before_action :authenticate_user!
+ before_action :check_ip_restriction
helper_method :depp_controller?
-
- def depp_controller?
- false
- end
-
- def check_ip
- return unless current_user
- unless current_user.is_a? ApiUser
- sign_out(current_user)
- return
- end
- return if Rails.env.development?
- registrar_ip_whitelisted = current_user.registrar.registrar_ip_white?(request.ip)
-
- return if registrar_ip_whitelisted
- flash[:alert] = t('ip_is_not_whitelisted')
- sign_out(current_user)
- redirect_to registrar_login_path and return
- end
-
helper_method :head_title_sufix
- def head_title_sufix
- t(:registrar_head_title_sufix)
- end
-
protected
def current_ability
@current_ability ||= Ability.new(current_user, request.remote_ip)
end
+
+ private
+
+ def check_ip_restriction
+ ip_restriction = Authorization::RestrictedIP.new(request.ip)
+ allowed = ip_restriction.can_access_registrar_area?(current_user.registrar)
+
+ return if allowed
+
+ sign_out current_user
+
+ flash[:alert] = t('registrar.authorization.ip_not_allowed', ip: request.ip)
+ redirect_to registrar_login_url
+ end
+
+ def depp_controller?
+ false
+ end
+
+ def head_title_sufix
+ t(:registrar_head_title_sufix)
+ end
end
end
diff --git a/app/controllers/registrar/current_user_controller.rb b/app/controllers/registrar/current_user_controller.rb
new file mode 100644
index 000000000..266e4b915
--- /dev/null
+++ b/app/controllers/registrar/current_user_controller.rb
@@ -0,0 +1,18 @@
+class Registrar
+ class CurrentUserController < BaseController
+ skip_authorization_check
+
+ def switch
+ 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/controllers/registrar/sessions_controller.rb b/app/controllers/registrar/sessions_controller.rb
index cd33590c2..8f9c71b1b 100644
--- a/app/controllers/registrar/sessions_controller.rb
+++ b/app/controllers/registrar/sessions_controller.rb
@@ -1,21 +1,12 @@
class Registrar
class SessionsController < Devise::SessionsController
+ before_action :check_ip_restriction
helper_method :depp_controller?
- def depp_controller?
- false
- end
-
- before_action :check_ip
-
def login
@depp_user = Depp::User.new
end
- # rubocop:disable Metrics/PerceivedComplexity
- # rubocop:disable Metrics/CyclomaticComplexity
- # rubocop:disable Metrics/MethodLength
- # rubocop:disable Metrics/AbcSize
def create
@depp_user = Depp::User.new(params[:depp_user].merge(pki: !(Rails.env.development? || Rails.env.test?)))
@@ -61,27 +52,6 @@ class Registrar
end
end
- # rubocop:enable Metrics/MethodLength
- # rubocop:enable Metrics/AbcSize
-
- def switch_user
- @api_user = ApiUser.find(params[:id])
-
- unless Rails.env.development?
- unless @api_user.registrar.registrar_ip_white?(request.ip)
- flash[:alert] = I18n.t(:ip_is_not_whitelisted)
- redirect_to :back and return
- end
- end
-
- sign_in @api_user if @api_user.identity_code == current_user.identity_code
-
- redirect_to registrar_root_url
- end
-
- # rubocop:enable Metrics/CyclomaticComplexity
- # rubocop:enable Metrics/PerceivedComplexity
-
def id
@user = ApiUser.find_by_idc_data(request.env['SSL_CLIENT_S_DN'])
@@ -98,7 +68,6 @@ class Registrar
@user = User.new
end
- # rubocop:disable Metrics/MethodLength
def mid
phone = params[:user][:phone]
endpoint = "#{ENV['sk_digi_doc_service_endpoint']}"
@@ -132,11 +101,6 @@ class Registrar
end
end
- # rubocop:enable Metrics/MethodLength
-
- # rubocop: disable Metrics/AbcSize
- # rubocop: disable Metrics/CyclomaticComplexity
- # rubocop: disable Metrics/MethodLength
def mid_status
endpoint = "#{ENV['sk_digi_doc_service_endpoint']}"
client = Digidoc::Client.new(endpoint)
@@ -174,21 +138,24 @@ class Registrar
end
end
- # rubocop: enable Metrics/AbcSize
- # rubocop: enable Metrics/CyclomaticComplexity
- # rubocop: enable Metrics/MethodLength
+ private
+
+ def depp_controller?
+ false
+ end
def find_user_by_idc(idc)
return User.new unless idc
ApiUser.find_by(identity_code: idc) || User.new
end
- private
+ def check_ip_restriction
+ ip_restriction = Authorization::RestrictedIP.new(request.ip)
+ allowed = ip_restriction.can_access_registrar_area_sign_in_page?
- def check_ip
- return if Rails.env.development?
- return if WhiteIp.registrar_ip_white?(request.ip)
- render text: t('access_denied') and return
+ return if allowed
+
+ render text: t('registrar.authorization.ip_not_allowed', ip: request.ip), status: :forbidden
end
end
end
diff --git a/app/helpers/registrant/application_helper.rb b/app/helpers/registrant/application_helper.rb
index c1b1de6fb..6451f91a2 100644
--- a/app/helpers/registrant/application_helper.rb
+++ b/app/helpers/registrant/application_helper.rb
@@ -3,11 +3,4 @@ module Registrant::ApplicationHelper
return '' if unstable_env.nil?
"background-image: url(#{image_path("registrar/bg-#{unstable_env}.png")});"
end
-
- def pagination_details
- params[:page] ||= 1
- limit = ENV['depp_records_on_page'] || 20
- offset = ((params[:page].to_i - 1) * limit.to_i)
- [limit, offset]
- end
end
diff --git a/app/helpers/registrar/application_helper.rb b/app/helpers/registrar/application_helper.rb
index 920260c4b..7710cf55c 100644
--- a/app/helpers/registrar/application_helper.rb
+++ b/app/helpers/registrar/application_helper.rb
@@ -3,11 +3,4 @@ module Registrar::ApplicationHelper
return '' if unstable_env.nil?
"background-image: url(#{image_path("registrar/bg-#{unstable_env}.png")});"
end
-
- def pagination_details
- params[:page] ||= 1
- limit = ENV['depp_records_on_page'] || 20
- offset = ((params[:page].to_i - 1) * limit.to_i)
- [limit, offset]
- end
end
diff --git a/app/models/api_user.rb b/app/models/api_user.rb
index 6928a933f..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'
@@ -51,11 +51,6 @@ class ApiUser < User
find_by(identity_code: identity_code)
end
-
- def all_by_identity_code(identity_code)
- ApiUser.where(identity_code: identity_code)
- .where("identity_code is NOT NULL and identity_code != ''").includes(:registrar)
- end
end
def registrar_typeahead
@@ -93,4 +88,14 @@ class ApiUser < User
md5 = OpenSSL::Digest::MD5.new(cert.to_der).to_s
certificates.api.exists?(md5: md5, common_name: cn)
end
+
+ def linked_users
+ self.class.where(identity_code: 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/models/authorization/restricted_ip.rb b/app/models/authorization/restricted_ip.rb
new file mode 100644
index 000000000..b3c7b7cdb
--- /dev/null
+++ b/app/models/authorization/restricted_ip.rb
@@ -0,0 +1,25 @@
+module Authorization
+ class RestrictedIP
+ def initialize(ip)
+ @ip = ip
+ end
+
+ def self.enabled?
+ Setting.registrar_ip_whitelist_enabled
+ end
+
+ def can_access_registrar_area?(registrar)
+ return true unless self.class.enabled?
+ registrar.white_ips.registrar_area.include_ip?(ip)
+ end
+
+ def can_access_registrar_area_sign_in_page?
+ return true unless self.class.enabled?
+ WhiteIp.registrar_area.include_ip?(ip)
+ end
+
+ private
+
+ attr_reader :ip
+ end
+end
diff --git a/app/models/registrar.rb b/app/models/registrar.rb
index 734e68898..b906beee3 100644
--- a/app/models/registrar.rb
+++ b/app/models/registrar.rb
@@ -162,9 +162,4 @@ class Registrar < ActiveRecord::Base
return true unless Setting.api_ip_whitelist_enabled
white_ips.api.pluck(:ipv4, :ipv6).flatten.include?(ip)
end
-
- def registrar_ip_white?(ip)
- return true unless Setting.registrar_ip_whitelist_enabled
- white_ips.registrar.pluck(:ipv4, :ipv6).flatten.include?(ip)
- end
end
diff --git a/app/models/version/api_user_version.rb b/app/models/version/api_user_version.rb
deleted file mode 100644
index 77d5bcf70..000000000
--- a/app/models/version/api_user_version.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class ApiUserVersion < PaperTrail::Version
- include VersionSession
- self.table_name = :log_api_users
- self.sequence_name = :log_api_users_id_seq
-end
diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb
index 918315004..251fc60ac 100644
--- a/app/models/white_ip.rb
+++ b/app/models/white_ip.rb
@@ -2,10 +2,8 @@ class WhiteIp < ActiveRecord::Base
include Versions
belongs_to :registrar
- # rubocop: disable Metrics/LineLength
validates :ipv4, format: { with: /\A(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\z/, allow_blank: true }
validates :ipv6, format: { with: /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/, allow_blank: true }
- # rubocop: enable Metrics/LineLength
validate :validate_ipv4_and_ipv6
def validate_ipv4_and_ipv6
@@ -18,16 +16,15 @@ class WhiteIp < ActiveRecord::Base
INTERFACES = [API, REGISTRAR]
scope :api, -> { where("interfaces @> ?::varchar[]", "{#{API}}") }
- scope :registrar, -> { where("interfaces @> ?::varchar[]", "{#{REGISTRAR}}") }
+ scope :registrar_area, -> { where("interfaces @> ?::varchar[]", "{#{REGISTRAR}}") }
def interfaces=(interfaces)
super(interfaces.reject(&:blank?))
end
class << self
- def registrar_ip_white?(ip)
- return true unless Setting.registrar_ip_whitelist_enabled
- WhiteIp.where(ipv4: ip).registrar.any?
+ def include_ip?(ip)
+ where('ipv4 = :ip OR ipv6 = :ip', ip: ip).any?
end
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/layouts/registrar/base.haml b/app/views/layouts/registrar/base.haml
index a2add9f20..e0bdd5f24 100644
--- a/app/views/layouts/registrar/base.haml
+++ b/app/views/layouts/registrar/base.haml
@@ -4,8 +4,6 @@
%meta{charset: "utf-8"}/
%meta{content: "IE=edge", "http-equiv" => "X-UA-Compatible"}/
%meta{content: "width=device-width, initial-scale=1", name: "viewport"}/
- %meta{content: "Full stack top-level domain (TLD) management.", name: "description"}/
- %meta{content: "Gitlab LTD", name: "author"}/
- if content_for? :head_title
= yield :head_title
- else
@@ -15,7 +13,6 @@
= javascript_include_tag 'registrar-manifest', 'data-turbolinks-track' => true
= favicon_link_tag 'favicon.ico'
%body
- / Fixed navbar
%nav.navbar.navbar-default.navbar-fixed-top
.container
.navbar-header
@@ -24,13 +21,12 @@
%span.icon-bar
%span.icon-bar
%span.icon-bar
- = link_to main_app.registrar_root_path, class: 'navbar-brand' do
+ = link_to registrar_root_path, class: 'navbar-brand' do
= t(:registrar_head_title)
- if unstable_env.present?
.text-center
%small{style: 'color: #0074B3;'}= unstable_env
- - if current_user
- = render 'navbar'
+ = render 'navbar'
.container
= render 'shared/flash'
@@ -40,7 +36,7 @@
%footer.footer
.container
- %row
+ .row
.col-md-6
= image_tag 'eis-logo-et.png'
.col-md-6.text-right
diff --git a/app/views/layouts/registrar/sessions.haml b/app/views/layouts/registrar/sessions.haml
index 974c47a40..49c71ab2c 100644
--- a/app/views/layouts/registrar/sessions.haml
+++ b/app/views/layouts/registrar/sessions.haml
@@ -37,7 +37,7 @@
%footer.footer
.container
- %row
+ .row
.col-md-6
= image_tag 'eis-logo-et.png'
.col-md-6.text-right
diff --git a/app/views/registrar/base/_current_user.html.erb b/app/views/registrar/base/_current_user.html.erb
new file mode 100644
index 000000000..75d159bfb
--- /dev/null
+++ b/app/views/registrar/base/_current_user.html.erb
@@ -0,0 +1,5 @@
+<% 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',
+ class: 'navbar-link' %>
+|
+<%= link_to t('.sign_out'), registrar_destroy_user_session_path, method: :delete, class: 'navbar-link' %>
diff --git a/app/views/registrar/base/_navbar.haml b/app/views/registrar/base/_navbar.haml
index 608fb9cb4..d94097bd3 100644
--- a/app/views/registrar/base/_navbar.haml
+++ b/app/views/registrar/base/_navbar.haml
@@ -1,5 +1,5 @@
.navbar-collapse.collapse
- %ul.nav.navbar-nav.public-nav
+ %ul.nav.navbar-nav
- if can? :view, Depp::Domain
- active_class = %w(registrar/domains registrar/check registrar/renew registrar/tranfer registrar/keyrelays).include?(params[:controller]) ? 'active' :nil
%li{class: active_class}= link_to t(:domains), registrar_domains_path
@@ -16,13 +16,5 @@
- active_class = ['registrar/xml_consoles'].include?(params[:controller]) ? 'active' :nil
%li{class: active_class}= link_to t(:xml_console), registrar_xml_console_path
- %ul.nav.navbar-nav.navbar-right
- %li.dropdown
- %a.dropdown-toggle{"data-toggle" => "dropdown", href: "#"}
- = "#{current_user} (#{current_user.roles.first}) - #{current_user.registrar}"
- %span.caret
- %ul.dropdown-menu{role: "menu"}
- - ApiUser.all_by_identity_code(current_user.identity_code).each do |x|
- %li= link_to "#{x} (#{x.roles.first}) - #{x.registrar}", "/registrar/switch_user/#{x.id}"
- - if user_signed_in?
- %li= link_to t(:log_out_), '/registrar/logout'
+ %div.navbar-text.navbar-right
+ = render 'current_user'
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/api/authorization.en.yml b/config/locales/api/authorization.en.yml
new file mode 100644
index 000000000..53c49d146
--- /dev/null
+++ b/config/locales/api/authorization.en.yml
@@ -0,0 +1,4 @@
+en:
+ api:
+ authorization:
+ ip_not_allowed: Access denied from IP %{ip}
diff --git a/config/locales/en.yml b/config/locales/en.yml
index acc559c29..ef8762917 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -784,7 +784,6 @@ en:
domain_delete_rejected_title: 'Domain deletion rejection has been received successfully'
domain_delete_rejected_body: 'You have rejected pending domain deletion. You will receive confirmation by email.'
no_permission: 'No permission'
- access_denied: 'Access denied'
common_name: 'Common name'
md5: 'Md5'
interface: 'Interface'
@@ -800,7 +799,6 @@ en:
create_bank_statement: 'Create bank statement'
create_bank_transaction: 'Create bank transaction'
create_new_invoice: 'Create new invoice'
- ip_is_not_whitelisted: 'IP is not whitelisted'
billing_failure_credit_balance_low: 'Billing failure - credit balance low'
create: 'Create'
activity_type: 'Activity type'
@@ -818,7 +816,6 @@ en:
notes: Notes
active_price_for_this_operation_is: 'Active price for this operation is %{price}'
active_price_missing_for_this_operation: 'Active price missing for this operation!'
- log_out_: 'Log out'
valid_to_from: 'Valid to from'
valid_to_until: 'Valid to until'
registrant_ident: 'Registrant ident'
diff --git a/config/locales/registrar/authorization.en.yml b/config/locales/registrar/authorization.en.yml
new file mode 100644
index 000000000..1e4395cb3
--- /dev/null
+++ b/config/locales/registrar/authorization.en.yml
@@ -0,0 +1,4 @@
+en:
+ registrar:
+ authorization:
+ ip_not_allowed: Access denied from IP %{ip}
diff --git a/config/locales/registrar/base.en.yml b/config/locales/registrar/base.en.yml
new file mode 100644
index 000000000..a00df6750
--- /dev/null
+++ b/config/locales/registrar/base.en.yml
@@ -0,0 +1,5 @@
+en:
+ registrar:
+ base:
+ current_user:
+ sign_out: Log out
diff --git a/config/locales/registrar/current_user.en.yml b/config/locales/registrar/current_user.en.yml
new file mode 100644
index 000000000..5f25cd81f
--- /dev/null
+++ b/config/locales/registrar/current_user.en.yml
@@ -0,0 +1,5 @@
+en:
+ registrar:
+ current_user:
+ switch:
+ switched: You are now signed in as a user "%{new_user}"
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 b232c235f..9a513b434 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -43,10 +43,12 @@ Rails.application.routes.draw do
post 'sessions' => 'sessions#create'
post 'id' => 'sessions#id'
post 'mid' => 'sessions#mid'
- get 'switch_user/:id' => 'sessions#switch_user'
- get 'logout' => '/devise/sessions#destroy'
+ delete 'logout', to: '/devise/sessions#destroy', as: :destroy_user_session
end
+ 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
post 'update', as: 'update'
diff --git a/db/migrate/20171009080822_add_user_registrar_id_fk.rb b/db/migrate/20171009080822_add_user_registrar_id_fk.rb
new file mode 100644
index 000000000..12bb2c92c
--- /dev/null
+++ b/db/migrate/20171009080822_add_user_registrar_id_fk.rb
@@ -0,0 +1,5 @@
+class AddUserRegistrarIdFk < ActiveRecord::Migration
+ def change
+ add_foreign_key :users, :registrars, name: 'user_registrar_id_fk'
+ end
+end
diff --git a/db/migrate/20171009082321_drop_api_users.rb b/db/migrate/20171009082321_drop_api_users.rb
new file mode 100644
index 000000000..dd1a9737b
--- /dev/null
+++ b/db/migrate/20171009082321_drop_api_users.rb
@@ -0,0 +1,6 @@
+class DropApiUsers < ActiveRecord::Migration
+ def change
+ drop_table :api_users
+ drop_table :log_api_users
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index be366e71a..ffce69261 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -357,44 +357,6 @@ CREATE SEQUENCE accounts_id_seq
ALTER SEQUENCE accounts_id_seq OWNED BY accounts.id;
---
--- Name: api_users; Type: TABLE; Schema: public; Owner: -; Tablespace:
---
-
-CREATE TABLE api_users (
- id integer NOT NULL,
- registrar_id integer,
- username character varying,
- password character varying,
- active boolean DEFAULT false,
- csr text,
- crt text,
- created_at timestamp without time zone,
- updated_at timestamp without time zone,
- creator_str character varying,
- updator_str character varying
-);
-
-
---
--- Name: api_users_id_seq; Type: SEQUENCE; Schema: public; Owner: -
---
-
-CREATE SEQUENCE api_users_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-
---
--- Name: api_users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
---
-
-ALTER SEQUENCE api_users_id_seq OWNED BY api_users.id;
-
-
--
-- Name: bank_statements; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@@ -1380,44 +1342,6 @@ CREATE SEQUENCE log_accounts_id_seq
ALTER SEQUENCE log_accounts_id_seq OWNED BY log_accounts.id;
---
--- Name: log_api_users; Type: TABLE; Schema: public; Owner: -; Tablespace:
---
-
-CREATE TABLE log_api_users (
- id integer NOT NULL,
- item_type character varying NOT NULL,
- item_id integer NOT NULL,
- event character varying NOT NULL,
- whodunnit character varying,
- object json,
- object_changes json,
- created_at timestamp without time zone,
- session character varying,
- children json,
- uuid character varying
-);
-
-
---
--- Name: log_api_users_id_seq; Type: SEQUENCE; Schema: public; Owner: -
---
-
-CREATE SEQUENCE log_api_users_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-
---
--- Name: log_api_users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
---
-
-ALTER SEQUENCE log_api_users_id_seq OWNED BY log_api_users.id;
-
-
--
-- Name: log_bank_statements; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
@@ -2868,13 +2792,6 @@ ALTER TABLE ONLY account_activities ALTER COLUMN id SET DEFAULT nextval('account
ALTER TABLE ONLY accounts ALTER COLUMN id SET DEFAULT nextval('accounts_id_seq'::regclass);
---
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY api_users ALTER COLUMN id SET DEFAULT nextval('api_users_id_seq'::regclass);
-
-
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -3043,13 +2960,6 @@ ALTER TABLE ONLY log_account_activities ALTER COLUMN id SET DEFAULT nextval('log
ALTER TABLE ONLY log_accounts ALTER COLUMN id SET DEFAULT nextval('log_accounts_id_seq'::regclass);
---
--- Name: id; Type: DEFAULT; Schema: public; Owner: -
---
-
-ALTER TABLE ONLY log_api_users ALTER COLUMN id SET DEFAULT nextval('log_api_users_id_seq'::regclass);
-
-
--
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
--
@@ -3325,14 +3235,6 @@ ALTER TABLE ONLY accounts
ADD CONSTRAINT accounts_pkey PRIMARY KEY (id);
---
--- Name: api_users_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
---
-
-ALTER TABLE ONLY api_users
- ADD CONSTRAINT api_users_pkey PRIMARY KEY (id);
-
-
--
-- Name: bank_statements_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@@ -3525,14 +3427,6 @@ ALTER TABLE ONLY log_accounts
ADD CONSTRAINT log_accounts_pkey PRIMARY KEY (id);
---
--- Name: log_api_users_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
---
-
-ALTER TABLE ONLY log_api_users
- ADD CONSTRAINT log_api_users_pkey PRIMARY KEY (id);
-
-
--
-- Name: log_bank_statements_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
@@ -3865,13 +3759,6 @@ CREATE INDEX index_account_activities_on_invoice_id ON account_activities USING
CREATE INDEX index_accounts_on_registrar_id ON accounts USING btree (registrar_id);
---
--- Name: index_api_users_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
---
-
-CREATE INDEX index_api_users_on_registrar_id ON api_users USING btree (registrar_id);
-
-
--
-- Name: index_blocked_domains_on_name; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@@ -4145,20 +4032,6 @@ CREATE INDEX index_log_accounts_on_item_type_and_item_id ON log_accounts USING b
CREATE INDEX index_log_accounts_on_whodunnit ON log_accounts USING btree (whodunnit);
---
--- Name: index_log_api_users_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
---
-
-CREATE INDEX index_log_api_users_on_item_type_and_item_id ON log_api_users USING btree (item_type, item_id);
-
-
---
--- Name: index_log_api_users_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace:
---
-
-CREATE INDEX index_log_api_users_on_whodunnit ON log_api_users USING btree (whodunnit);
-
-
--
-- Name: index_log_bank_statements_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@@ -4665,6 +4538,14 @@ ALTER TABLE ONLY account_activities
ADD CONSTRAINT fk_rails_d2cc3c2fa9 FOREIGN KEY (price_id) REFERENCES prices(id);
+--
+-- Name: user_registrar_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY users
+ ADD CONSTRAINT user_registrar_id_fk FOREIGN KEY (registrar_id) REFERENCES registrars(id);
+
+
--
-- PostgreSQL database dump complete
--
@@ -5167,3 +5048,7 @@ INSERT INTO schema_migrations (version) VALUES ('20170606150352');
INSERT INTO schema_migrations (version) VALUES ('20170606202859');
+INSERT INTO schema_migrations (version) VALUES ('20171009080822');
+
+INSERT INTO schema_migrations (version) VALUES ('20171009082321');
+
diff --git a/doc/controllers_complete.svg b/doc/controllers_complete.svg
index f48433540..1c9bc94ec 100644
--- a/doc/controllers_complete.svg
+++ b/doc/controllers_complete.svg
@@ -136,9 +136,6 @@
RegistrarController
-check_ip
-depp_controller?
-head_title_sufix
_layout
@@ -491,8 +488,6 @@
Registrar::SessionsController
create
-depp_controller?
-find_user_by_idc
id
login
login_mid
diff --git a/doc/models_brief.svg b/doc/models_brief.svg
index 6a2b3f428..76dd9a83f 100644
--- a/doc/models_brief.svg
+++ b/doc/models_brief.svg
@@ -304,17 +304,6 @@
-
-ApiUserVersion
-
-ApiUserVersion
-
-
-ApiUserVersion->VersionAssociation
-
-
-
-
DomainVersion
diff --git a/doc/models_complete.svg b/doc/models_complete.svg
index 2a67d0970..58b86b986 100644
--- a/doc/models_complete.svg
+++ b/doc/models_complete.svg
@@ -600,28 +600,6 @@
-
-ApiUserVersion
-
-ApiUserVersion
-
-id :integer
-item_type :string
-item_id :integer
-event :string
-whodunnit :string
-object :json
-object_changes :json
-created_at :datetime
-session :string
-children :json
-
-
-ApiUserVersion->VersionAssociation
-
-
-
-
DomainVersion
diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake
index 67cf856a2..470949c14 100644
--- a/lib/tasks/dev.rake
+++ b/lib/tasks/dev.rake
@@ -175,6 +175,8 @@ namespace :dev do
end
end
+ Setting.registrar_ip_whitelist_enabled = false
+
ActiveRecord::Base.transaction do
generate_default_data
generate_random_data if with_random_data
diff --git a/spec/fabricators/registrar_fabricator.rb b/spec/fabricators/registrar_fabricator.rb
index f3a3fdc59..37236cb87 100644
--- a/spec/fabricators/registrar_fabricator.rb
+++ b/spec/fabricators/registrar_fabricator.rb
@@ -9,7 +9,6 @@ Fabricator(:registrar) do
country_code 'EE'
code { sequence(:code) { |i| "REGISTRAR#{i}" } }
reference_no { sequence(:reference_no) { |i| "RF#{i}" } }
- white_ips { [Fabricate(:white_ip), Fabricate(:white_ip, interfaces: [WhiteIp::REGISTRAR])] }
end
Fabricator(:registrar_with_no_account_activities, from: :registrar) do
diff --git a/spec/fabricators/white_ip_fabricator.rb b/spec/fabricators/white_ip_fabricator.rb
deleted file mode 100644
index 6eb574893..000000000
--- a/spec/fabricators/white_ip_fabricator.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-Fabricator(:white_ip) do
- ipv4 '127.0.0.1'
- interfaces [WhiteIp::API]
-end
-
-Fabricator(:white_ip_registrar, from: :white_ip) do
- interfaces [WhiteIp::REGISTRAR]
-end
diff --git a/spec/factories/white_ip.rb b/spec/factories/white_ip.rb
new file mode 100644
index 000000000..eb4033fc9
--- /dev/null
+++ b/spec/factories/white_ip.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :white_ip do
+ ipv4 '127.0.0.1'
+ end
+end
diff --git a/spec/features/registrar/ip_restriction_spec.rb b/spec/features/registrar/ip_restriction_spec.rb
new file mode 100644
index 000000000..dc9631057
--- /dev/null
+++ b/spec/features/registrar/ip_restriction_spec.rb
@@ -0,0 +1,12 @@
+require 'rails_helper'
+
+RSpec.feature 'Registrar area IP restriction', settings: false do
+ background do
+ Setting.registrar_ip_whitelist_enabled = true
+ end
+
+ scenario 'notifies the user if his IP is not allowed' do
+ visit registrar_root_path
+ expect(page).to have_text('Access denied from IP 127.0.0.1')
+ end
+end
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/login/mobile_id_spec.rb b/spec/features/registrar/sign_in/mobile_id_spec.rb
similarity index 100%
rename from spec/features/registrar/login/mobile_id_spec.rb
rename to spec/features/registrar/sign_in/mobile_id_spec.rb
diff --git a/spec/features/registrar/sign_in/password_spec.rb b/spec/features/registrar/sign_in/password_spec.rb
new file mode 100644
index 000000000..f0cc3ed49
--- /dev/null
+++ b/spec/features/registrar/sign_in/password_spec.rb
@@ -0,0 +1,43 @@
+require 'rails_helper'
+
+RSpec.feature 'Registrar area password sign-in' do
+ background do
+ Setting.registrar_ip_whitelist_enabled = false
+ end
+
+ scenario 'signs in the user with valid credentials' do
+ create(:api_user_with_unlimited_balance,
+ active: true,
+ login: 'test',
+ password: 'testtest')
+
+ visit registrar_login_path
+ sign_in_with 'test', 'testtest'
+
+ expect(page).to have_text(t('registrar.base.current_user.sign_out'))
+ end
+
+ scenario 'notifies the user with invalid credentials' do
+ create(:api_user, login: 'test', password: 'testtest')
+
+ visit registrar_login_path
+ sign_in_with 'test', 'invalid'
+
+ expect(page).to have_text('No such user')
+ end
+
+ scenario 'notifies the user with inactive account' do
+ create(:api_user, active: false, login: 'test', password: 'testtest')
+
+ visit registrar_login_path
+ sign_in_with 'test', 'testtest'
+
+ expect(page).to have_text('User is not active')
+ end
+
+ def sign_in_with(username, password)
+ fill_in 'depp_user_tag', with: username
+ fill_in 'depp_user_password', with: password
+ click_button 'Login'
+ end
+end
diff --git a/spec/features/registrar/sign_out_spec.rb b/spec/features/registrar/sign_out_spec.rb
new file mode 100644
index 000000000..33acc52ab
--- /dev/null
+++ b/spec/features/registrar/sign_out_spec.rb
@@ -0,0 +1,15 @@
+require 'rails_helper'
+
+RSpec.feature 'Registrar area sign-out', 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 'signs the user out' do
+ visit registrar_root_path
+ click_on t('registrar.base.current_user.sign_out')
+
+ expect(page).to have_text('Signed out successfully.')
+ end
+end
diff --git a/spec/models/api_user_spec.rb b/spec/models/api_user_spec.rb
index 20ac4afff..12213c819 100644
--- a/spec/models/api_user_spec.rb
+++ b/spec/models/api_user_spec.rb
@@ -1,24 +1,8 @@
require 'rails_helper'
RSpec.describe ApiUser do
- context 'class methods' do
- before do
- Fabricate(:api_user, identity_code: '')
- Fabricate(:api_user, identity_code: 14212128025)
- end
-
- it 'should return all api users with given identity code' do
- ApiUser.all_by_identity_code('14212128025').size.should == 1
- ApiUser.all_by_identity_code(14212128025).size.should == 1
- end
-
- it 'should not return any api user with blank identity code' do
- ApiUser.all_by_identity_code('').size.should == 0
- end
- end
-
context 'with invalid attribute' do
- before :all do
+ before do
@api_user = ApiUser.new
end
@@ -43,7 +27,7 @@ RSpec.describe ApiUser do
end
context 'with valid attributes' do
- before :all do
+ before do
@api_user = Fabricate(:api_user)
end
@@ -74,4 +58,71 @@ RSpec.describe ApiUser do
expect(described_class.min_password_length).to eq(6)
end
end
+
+ describe '#linked_users' do
+ it 'returns users with the same identity code' do
+ api_user = create(:api_user, id: 1, identity_code: 'test')
+ create(:api_user, id: 2, identity_code: 'test')
+
+ expect(api_user.linked_users.ids).to include(2)
+ end
+
+ it 'does not return users with another identity code' do
+ api_user = create(:api_user, id: 1, identity_code: 'test')
+ create(:api_user, id: 2, identity_code: 'another')
+
+ expect(api_user.linked_users.ids).to_not include(2)
+ end
+
+ it 'does not return itself' do
+ api_user = create(:api_user)
+ expect(api_user.linked_users).to be_empty
+ end
+
+ it 'returns none if identity code is absent' do
+ api_user = create(:api_user, identity_code: nil)
+ create(:api_user, identity_code: nil)
+
+ expect(api_user.linked_users).to be_empty
+ end
+
+ it 'returns none if identity code is empty' do
+ api_user = create(:api_user, identity_code: '')
+ create(:api_user, identity_code: '')
+
+ 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/models/authorization/restricted_ip_spec.rb b/spec/models/authorization/restricted_ip_spec.rb
new file mode 100644
index 000000000..e64a1739f
--- /dev/null
+++ b/spec/models/authorization/restricted_ip_spec.rb
@@ -0,0 +1,94 @@
+require 'rails_helper'
+
+RSpec.describe Authorization::RestrictedIP do
+ describe '::enabled?', db: true, settings: false do
+ context 'when "registrar_ip_whitelist_enabled" is true' do
+ before do
+ Setting.registrar_ip_whitelist_enabled = true
+ end
+
+ specify do
+ expect(described_class).to be_enabled
+ end
+ end
+
+ context 'when "registrar_ip_whitelist_enabled" is false' do
+ before do
+ Setting.registrar_ip_whitelist_enabled = false
+ end
+
+ specify do
+ expect(described_class).to_not be_enabled
+ end
+ end
+ end
+
+ describe '#can_access_registrar_area?', db: true do
+ let(:registrar) { create(:registrar) }
+ subject(:allowed) { described_class.new('127.0.0.1').can_access_registrar_area?(registrar) }
+
+ context 'when enabled' do
+ before do
+ allow(described_class).to receive(:enabled?).and_return(true)
+ end
+
+ context 'when ip is whitelisted', db: true do
+ let!(:white_ip) { create(:white_ip, registrar: registrar, ipv4: '127.0.0.1', interfaces: [WhiteIp::REGISTRAR]) }
+
+ specify do
+ expect(allowed).to be true
+ end
+ end
+
+ context 'when ip is not whitelisted' do
+ specify do
+ expect(allowed).to be false
+ end
+ end
+ end
+
+ context 'when disabled' do
+ before do
+ allow(described_class).to receive(:enabled?).and_return(false)
+ end
+
+ specify do
+ expect(allowed).to be true
+ end
+ end
+ end
+
+ describe '#can_access_registrar_area_sign_in_page?' do
+ subject(:allowed) { described_class.new('127.0.0.1').can_access_registrar_area_sign_in_page? }
+
+ context 'when enabled' do
+ before do
+ allow(described_class).to receive(:enabled?).and_return(true)
+ end
+
+ context 'when ip is whitelisted', db: true do
+ let!(:white_ip) { create(:white_ip, ipv4: '127.0.0.1', interfaces: [WhiteIp::REGISTRAR]) }
+
+ specify do
+ expect(allowed).to be true
+ end
+ end
+
+ context 'when ip is not whitelisted' do
+ specify do
+ expect(allowed).to be false
+ end
+ end
+ end
+
+ context 'when disabled' do
+ before do
+ allow(described_class).to receive(:enabled?).and_return(false)
+ end
+
+ specify do
+ expect(allowed).to be true
+ end
+ end
+ end
+end
diff --git a/spec/models/white_ip_spec.rb b/spec/models/white_ip_spec.rb
index e824fbdd6..bb286c0ca 100644
--- a/spec/models/white_ip_spec.rb
+++ b/spec/models/white_ip_spec.rb
@@ -25,18 +25,7 @@ describe WhiteIp do
context 'with valid attributes' do
before :all do
- @white_ip = Fabricate(:white_ip)
- end
-
- it 'should be valid' do
- @white_ip.valid?
- @white_ip.errors.full_messages.should match_array([])
- end
-
- it 'should be valid twice' do
- @white_ip = Fabricate(:white_ip)
- @white_ip.valid?
- @white_ip.errors.full_messages.should match_array([])
+ @white_ip = create(:white_ip)
end
it 'should have one version' do
@@ -49,4 +38,32 @@ describe WhiteIp do
end
end
end
+
+ describe '#include_ip?' do
+ context 'when given ip v4 exists' do
+ before do
+ create(:white_ip, ipv4: '127.0.0.1')
+ end
+
+ specify do
+ expect(described_class.include_ip?('127.0.0.1')).to be true
+ end
+ end
+
+ context 'when given ip v6 exists' do
+ before do
+ create(:white_ip, ipv6: '::1')
+ end
+
+ specify do
+ expect(described_class.include_ip?('::1')).to be true
+ end
+ end
+
+ context 'when given ip does not exists', db: false do
+ specify do
+ expect(described_class.include_ip?('127.0.0.1')).to be false
+ end
+ 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/ip_restriction_spec.rb b/spec/requests/registrar/ip_restriction_spec.rb
new file mode 100644
index 000000000..bcde36b02
--- /dev/null
+++ b/spec/requests/registrar/ip_restriction_spec.rb
@@ -0,0 +1,90 @@
+require 'rails_helper'
+
+RSpec.describe 'Registrar area IP restriction', settings: false do
+ context 'when authenticated' do
+ before do
+ sign_in_to_registrar_area
+ end
+
+ context 'when IP restriction is enabled' do
+ before do
+ Setting.registrar_ip_whitelist_enabled = true
+ end
+
+ context 'when ip is allowed' do
+ let!(:white_ip) { create(:white_ip,
+ ipv4: '127.0.0.1',
+ registrar: controller.current_user.registrar,
+ interfaces: [WhiteIp::REGISTRAR]) }
+
+ specify do
+ get registrar_root_url
+ follow_redirect!
+ expect(response).to be_success
+ end
+ end
+
+ context 'when ip is not allowed' do
+ it 'signs the user out' do
+ get registrar_root_url
+ follow_redirect!
+ expect(controller.current_user).to be_nil
+ end
+
+ it 'redirects to login url' do
+ get registrar_root_url
+ expect(response).to redirect_to(registrar_login_url)
+ end
+ end
+ end
+
+ context 'when IP restriction is disabled' do
+ before do
+ Setting.registrar_ip_whitelist_enabled = false
+ end
+
+ specify do
+ get registrar_root_url
+ follow_redirect!
+ expect(response).to be_success
+ end
+ end
+ end
+
+ context 'when unauthenticated' do
+ context 'when IP restriction is enabled' do
+ before do
+ Setting.registrar_ip_whitelist_enabled = true
+ end
+
+ context 'when ip is allowed' do
+ let!(:white_ip) { create(:white_ip,
+ ipv4: '127.0.0.1',
+ interfaces: [WhiteIp::REGISTRAR]) }
+
+ specify do
+ get registrar_login_path
+ expect(response).to be_success
+ end
+ end
+
+ context 'when ip is not allowed' do
+ specify do
+ get registrar_login_path
+ expect(response).to be_forbidden
+ end
+ end
+ end
+
+ context 'when IP restriction is disabled' do
+ before do
+ Setting.registrar_ip_whitelist_enabled = false
+ end
+
+ specify do
+ get registrar_login_path
+ expect(response).to be_success
+ 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
diff --git a/spec/requests/registrar/sign_in/password_spec.rb b/spec/requests/registrar/sign_in/password_spec.rb
new file mode 100644
index 000000000..f419ffa01
--- /dev/null
+++ b/spec/requests/registrar/sign_in/password_spec.rb
@@ -0,0 +1,20 @@
+require 'rails_helper'
+
+RSpec.describe 'Registrar area password sign-in', settings: false do
+ let!(:user) { create(:api_user, active: true, login: 'test', password: 'testtest') }
+
+ before do
+ Setting.registrar_ip_whitelist_enabled = false
+ end
+
+ it 'signs the user in' do
+ post registrar_sessions_path, depp_user: { tag: 'test', password: 'testtest' }
+ follow_redirect!
+ expect(controller.current_user).to eq(user)
+ end
+
+ it 'redirects to root url' do
+ post registrar_sessions_path, depp_user: { tag: 'test', password: 'testtest' }
+ expect(response).to redirect_to(registrar_root_url)
+ end
+end
diff --git a/spec/requests/registrar/sign_out_spec.rb b/spec/requests/registrar/sign_out_spec.rb
new file mode 100644
index 000000000..086b95f64
--- /dev/null
+++ b/spec/requests/registrar/sign_out_spec.rb
@@ -0,0 +1,19 @@
+require 'rails_helper'
+
+RSpec.describe 'Registrar area sign-out', settings: false do
+ before do
+ Setting.registrar_ip_whitelist_enabled = false
+ sign_in_to_registrar_area
+ end
+
+ it 'signs the user out' do
+ delete registrar_destroy_user_session_path
+ follow_redirect!
+ expect(controller.current_user).to be_nil
+ end
+
+ it 'redirects to login url' do
+ delete registrar_destroy_user_session_path
+ expect(response).to redirect_to(registrar_login_url)
+ end
+end