Merge pull request #599 from internetee/improve-registrar-access-denied-page

improve registrar portal access denied page
This commit is contained in:
Timo Võhmar 2017-10-12 13:14:45 +03:00 committed by GitHub
commit dcaf8b0126
52 changed files with 751 additions and 338 deletions

View file

@ -29,6 +29,9 @@ engines:
enabled: true enabled: true
reek: reek:
enabled: true enabled: true
checks:
IrresponsibleModule:
enabled: false
ratings: ratings:
paths: paths:
- Gemfile.lock - Gemfile.lock

View file

@ -116,6 +116,7 @@ group :development do
end end
group :development, :test do group :development, :test do
gem 'factory_girl_rails'
gem 'capybara' gem 'capybara'
gem 'rspec-rails', '~> 3.6' gem 'rspec-rails', '~> 3.6'
gem 'fabrication', '2.13.2' # Replacement for fixtures gem 'fabrication', '2.13.2' # Replacement for fixtures
@ -144,7 +145,6 @@ end
group :test do group :test do
gem 'database_cleaner' gem 'database_cleaner'
gem 'factory_girl_rails'
gem 'codeclimate-test-reporter', "~> 1.0.0" gem 'codeclimate-test-reporter', "~> 1.0.0"
gem 'simplecov' gem 'simplecov'
gem 'webmock' gem 'webmock'

View file

@ -15,7 +15,7 @@ module Repp
before do before do
webclient_request = ENV['webclient_ips'].split(',').map(&:strip).include?(request.ip) webclient_request = ENV['webclient_ips'].split(',').map(&:strip).include?(request.ip)
unless webclient_request 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 end
if @current_user.cannot?(:view, :repp) if @current_user.cannot?(:view, :repp)

View file

@ -1,40 +1,38 @@
class Registrar class Registrar
class BaseController < ApplicationController class BaseController < ApplicationController
before_action :authenticate_user!, :check_ip
include Registrar::ApplicationHelper include Registrar::ApplicationHelper
before_action :authenticate_user!
before_action :check_ip_restriction
helper_method :depp_controller? 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 helper_method :head_title_sufix
def head_title_sufix
t(:registrar_head_title_sufix)
end
protected protected
def current_ability def current_ability
@current_ability ||= Ability.new(current_user, request.remote_ip) @current_ability ||= Ability.new(current_user, request.remote_ip)
end 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
end end

View file

@ -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

View file

@ -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

View file

@ -1,21 +1,12 @@
class Registrar class Registrar
class SessionsController < Devise::SessionsController class SessionsController < Devise::SessionsController
before_action :check_ip_restriction
helper_method :depp_controller? helper_method :depp_controller?
def depp_controller?
false
end
before_action :check_ip
def login def login
@depp_user = Depp::User.new @depp_user = Depp::User.new
end end
# rubocop:disable Metrics/PerceivedComplexity
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/AbcSize
def create def create
@depp_user = Depp::User.new(params[:depp_user].merge(pki: !(Rails.env.development? || Rails.env.test?))) @depp_user = Depp::User.new(params[:depp_user].merge(pki: !(Rails.env.development? || Rails.env.test?)))
@ -61,27 +52,6 @@ class Registrar
end end
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 def id
@user = ApiUser.find_by_idc_data(request.env['SSL_CLIENT_S_DN']) @user = ApiUser.find_by_idc_data(request.env['SSL_CLIENT_S_DN'])
@ -98,7 +68,6 @@ class Registrar
@user = User.new @user = User.new
end end
# rubocop:disable Metrics/MethodLength
def mid def mid
phone = params[:user][:phone] phone = params[:user][:phone]
endpoint = "#{ENV['sk_digi_doc_service_endpoint']}" endpoint = "#{ENV['sk_digi_doc_service_endpoint']}"
@ -132,11 +101,6 @@ class Registrar
end end
end end
# rubocop:enable Metrics/MethodLength
# rubocop: disable Metrics/AbcSize
# rubocop: disable Metrics/CyclomaticComplexity
# rubocop: disable Metrics/MethodLength
def mid_status def mid_status
endpoint = "#{ENV['sk_digi_doc_service_endpoint']}" endpoint = "#{ENV['sk_digi_doc_service_endpoint']}"
client = Digidoc::Client.new(endpoint) client = Digidoc::Client.new(endpoint)
@ -174,21 +138,24 @@ class Registrar
end end
end end
# rubocop: enable Metrics/AbcSize private
# rubocop: enable Metrics/CyclomaticComplexity
# rubocop: enable Metrics/MethodLength def depp_controller?
false
end
def find_user_by_idc(idc) def find_user_by_idc(idc)
return User.new unless idc return User.new unless idc
ApiUser.find_by(identity_code: idc) || User.new ApiUser.find_by(identity_code: idc) || User.new
end 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 allowed
return if Rails.env.development?
return if WhiteIp.registrar_ip_white?(request.ip) render text: t('registrar.authorization.ip_not_allowed', ip: request.ip), status: :forbidden
render text: t('access_denied') and return
end end
end end
end end

View file

@ -3,11 +3,4 @@ module Registrant::ApplicationHelper
return '' if unstable_env.nil? return '' if unstable_env.nil?
"background-image: url(#{image_path("registrar/bg-#{unstable_env}.png")});" "background-image: url(#{image_path("registrar/bg-#{unstable_env}.png")});"
end 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 end

View file

@ -3,11 +3,4 @@ module Registrar::ApplicationHelper
return '' if unstable_env.nil? return '' if unstable_env.nil?
"background-image: url(#{image_path("registrar/bg-#{unstable_env}.png")});" "background-image: url(#{image_path("registrar/bg-#{unstable_env}.png")});"
end 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 end

View file

@ -23,9 +23,9 @@ class ApiUser < User
validates :password, length: { minimum: min_password_length } validates :password, length: { minimum: min_password_length }
validates :username, uniqueness: true validates :username, uniqueness: true
# TODO: probably cache, because it's requested on every EPP delegate :code, :name, to: :registrar, prefix: true
delegate :code, to: :registrar, prefix: true
alias_attribute :login, :username
attr_accessor :registrar_typeahead attr_accessor :registrar_typeahead
SUPER = 'super' SUPER = 'super'
@ -51,11 +51,6 @@ class ApiUser < User
find_by(identity_code: identity_code) find_by(identity_code: identity_code)
end 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 end
def registrar_typeahead def registrar_typeahead
@ -93,4 +88,14 @@ class ApiUser < User
md5 = OpenSSL::Digest::MD5.new(cert.to_der).to_s md5 = OpenSSL::Digest::MD5.new(cert.to_der).to_s
certificates.api.exists?(md5: md5, common_name: cn) certificates.api.exists?(md5: md5, common_name: cn)
end 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 end

View file

@ -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

View file

@ -162,9 +162,4 @@ class Registrar < ActiveRecord::Base
return true unless Setting.api_ip_whitelist_enabled return true unless Setting.api_ip_whitelist_enabled
white_ips.api.pluck(:ipv4, :ipv6).flatten.include?(ip) white_ips.api.pluck(:ipv4, :ipv6).flatten.include?(ip)
end 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 end

View file

@ -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

View file

@ -2,10 +2,8 @@ class WhiteIp < ActiveRecord::Base
include Versions include Versions
belongs_to :registrar 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 :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 } 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 validate :validate_ipv4_and_ipv6
def validate_ipv4_and_ipv6 def validate_ipv4_and_ipv6
@ -18,16 +16,15 @@ class WhiteIp < ActiveRecord::Base
INTERFACES = [API, REGISTRAR] INTERFACES = [API, REGISTRAR]
scope :api, -> { where("interfaces @> ?::varchar[]", "{#{API}}") } scope :api, -> { where("interfaces @> ?::varchar[]", "{#{API}}") }
scope :registrar, -> { where("interfaces @> ?::varchar[]", "{#{REGISTRAR}}") } scope :registrar_area, -> { where("interfaces @> ?::varchar[]", "{#{REGISTRAR}}") }
def interfaces=(interfaces) def interfaces=(interfaces)
super(interfaces.reject(&:blank?)) super(interfaces.reject(&:blank?))
end end
class << self class << self
def registrar_ip_white?(ip) def include_ip?(ip)
return true unless Setting.registrar_ip_whitelist_enabled where('ipv4 = :ip OR ipv6 = :ip', ip: ip).any?
WhiteIp.where(ipv4: ip).registrar.any?
end end
end end
end end

View file

@ -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

View file

@ -4,8 +4,6 @@
%meta{charset: "utf-8"}/ %meta{charset: "utf-8"}/
%meta{content: "IE=edge", "http-equiv" => "X-UA-Compatible"}/ %meta{content: "IE=edge", "http-equiv" => "X-UA-Compatible"}/
%meta{content: "width=device-width, initial-scale=1", name: "viewport"}/ %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 - if content_for? :head_title
= yield :head_title = yield :head_title
- else - else
@ -15,7 +13,6 @@
= javascript_include_tag 'registrar-manifest', 'data-turbolinks-track' => true = javascript_include_tag 'registrar-manifest', 'data-turbolinks-track' => true
= favicon_link_tag 'favicon.ico' = favicon_link_tag 'favicon.ico'
%body %body
/ Fixed navbar
%nav.navbar.navbar-default.navbar-fixed-top %nav.navbar.navbar-default.navbar-fixed-top
.container .container
.navbar-header .navbar-header
@ -24,13 +21,12 @@
%span.icon-bar %span.icon-bar
%span.icon-bar %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) = t(:registrar_head_title)
- if unstable_env.present? - if unstable_env.present?
.text-center .text-center
%small{style: 'color: #0074B3;'}= unstable_env %small{style: 'color: #0074B3;'}= unstable_env
- if current_user = render 'navbar'
= render 'navbar'
.container .container
= render 'shared/flash' = render 'shared/flash'
@ -40,7 +36,7 @@
%footer.footer %footer.footer
.container .container
%row .row
.col-md-6 .col-md-6
= image_tag 'eis-logo-et.png' = image_tag 'eis-logo-et.png'
.col-md-6.text-right .col-md-6.text-right

View file

@ -37,7 +37,7 @@
%footer.footer %footer.footer
.container .container
%row .row
.col-md-6 .col-md-6
= image_tag 'eis-logo-et.png' = image_tag 'eis-logo-et.png'
.col-md-6.text-right .col-md-6.text-right

View file

@ -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' %>
<span class="text-muted">|</span>
<%= link_to t('.sign_out'), registrar_destroy_user_session_path, method: :delete, class: 'navbar-link' %>

View file

@ -1,5 +1,5 @@
.navbar-collapse.collapse .navbar-collapse.collapse
%ul.nav.navbar-nav.public-nav %ul.nav.navbar-nav
- if can? :view, Depp::Domain - if can? :view, Depp::Domain
- active_class = %w(registrar/domains registrar/check registrar/renew registrar/tranfer registrar/keyrelays).include?(params[:controller]) ? 'active' :nil - 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 %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 - active_class = ['registrar/xml_consoles'].include?(params[:controller]) ? 'active' :nil
%li{class: active_class}= link_to t(:xml_console), registrar_xml_console_path %li{class: active_class}= link_to t(:xml_console), registrar_xml_console_path
%ul.nav.navbar-nav.navbar-right %div.navbar-text.navbar-right
%li.dropdown = render 'current_user'
%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'

View file

@ -0,0 +1,18 @@
<div class="panel panel-default">
<div class="panel-heading"><%= t '.header' %></div>
<div class="panel-body">
<ul>
<% linked_users.each do |user| %>
<% user_presenter = UserPresenter.new(user: user, view: self) %>
<li><%= 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' %>
</li>
<% end %>
</ul>
</div>
</div>

View file

@ -0,0 +1,9 @@
<div class="page-header">
<h1><%= t '.header' %></h1>
</div>
<div class="row">
<div class="col-sm-4">
<%= render 'linked_users', linked_users: linked_users %>
</div>
</div>

View file

@ -0,0 +1,4 @@
en:
api:
authorization:
ip_not_allowed: Access denied from IP %{ip}

View file

@ -784,7 +784,6 @@ en:
domain_delete_rejected_title: 'Domain deletion rejection has been received successfully' 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.' domain_delete_rejected_body: 'You have rejected pending domain deletion. You will receive confirmation by email.'
no_permission: 'No permission' no_permission: 'No permission'
access_denied: 'Access denied'
common_name: 'Common name' common_name: 'Common name'
md5: 'Md5' md5: 'Md5'
interface: 'Interface' interface: 'Interface'
@ -800,7 +799,6 @@ en:
create_bank_statement: 'Create bank statement' create_bank_statement: 'Create bank statement'
create_bank_transaction: 'Create bank transaction' create_bank_transaction: 'Create bank transaction'
create_new_invoice: 'Create new invoice' create_new_invoice: 'Create new invoice'
ip_is_not_whitelisted: 'IP is not whitelisted'
billing_failure_credit_balance_low: 'Billing failure - credit balance low' billing_failure_credit_balance_low: 'Billing failure - credit balance low'
create: 'Create' create: 'Create'
activity_type: 'Activity type' activity_type: 'Activity type'
@ -818,7 +816,6 @@ en:
notes: Notes notes: Notes
active_price_for_this_operation_is: 'Active price for this operation is %{price}' 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!' active_price_missing_for_this_operation: 'Active price missing for this operation!'
log_out_: 'Log out'
valid_to_from: 'Valid to from' valid_to_from: 'Valid to from'
valid_to_until: 'Valid to until' valid_to_until: 'Valid to until'
registrant_ident: 'Registrant ident' registrant_ident: 'Registrant ident'

View file

@ -0,0 +1,4 @@
en:
registrar:
authorization:
ip_not_allowed: Access denied from IP %{ip}

View file

@ -0,0 +1,5 @@
en:
registrar:
base:
current_user:
sign_out: Log out

View file

@ -0,0 +1,5 @@
en:
registrar:
current_user:
switch:
switched: You are now signed in as a user "%{new_user}"

View file

@ -0,0 +1,9 @@
en:
registrar:
profile:
show:
header: My profile
linked_users:
header: Linked users
switch_btn: Switch

View file

@ -43,10 +43,12 @@ Rails.application.routes.draw do
post 'sessions' => 'sessions#create' post 'sessions' => 'sessions#create'
post 'id' => 'sessions#id' post 'id' => 'sessions#id'
post 'mid' => 'sessions#mid' post 'mid' => 'sessions#mid'
get 'switch_user/:id' => 'sessions#switch_user' delete 'logout', to: '/devise/sessions#destroy', as: :destroy_user_session
get 'logout' => '/devise/sessions#destroy'
end 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 resources :domains do
collection do collection do
post 'update', as: 'update' post 'update', as: 'update'

View file

@ -0,0 +1,5 @@
class AddUserRegistrarIdFk < ActiveRecord::Migration
def change
add_foreign_key :users, :registrars, name: 'user_registrar_id_fk'
end
end

View file

@ -0,0 +1,6 @@
class DropApiUsers < ActiveRecord::Migration
def change
drop_table :api_users
drop_table :log_api_users
end
end

View file

@ -357,44 +357,6 @@ CREATE SEQUENCE accounts_id_seq
ALTER SEQUENCE accounts_id_seq OWNED BY accounts.id; 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: -- 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; 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: -- 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); 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: - -- 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); 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: - -- Name: id; Type: DEFAULT; Schema: public; Owner: -
-- --
@ -3325,14 +3235,6 @@ ALTER TABLE ONLY accounts
ADD CONSTRAINT accounts_pkey PRIMARY KEY (id); 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: -- 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); 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: -- 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); 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: -- 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); 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: -- 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); 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 -- 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 ('20170606202859');
INSERT INTO schema_migrations (version) VALUES ('20171009080822');
INSERT INTO schema_migrations (version) VALUES ('20171009082321');

View file

@ -136,9 +136,6 @@
<path fill="none" stroke="black" d="M-708,539.5C-708,539.5 -610,539.5 -610,539.5 -604,539.5 -598,533.5 -598,527.5 -598,527.5 -598,428.5 -598,428.5 -598,422.5 -604,416.5 -610,416.5 -610,416.5 -708,416.5 -708,416.5 -714,416.5 -720,422.5 -720,428.5 -720,428.5 -720,527.5 -720,527.5 -720,533.5 -714,539.5 -708,539.5"/> <path fill="none" stroke="black" d="M-708,539.5C-708,539.5 -610,539.5 -610,539.5 -604,539.5 -598,533.5 -598,527.5 -598,527.5 -598,428.5 -598,428.5 -598,422.5 -604,416.5 -610,416.5 -610,416.5 -708,416.5 -708,416.5 -714,416.5 -720,422.5 -720,428.5 -720,428.5 -720,527.5 -720,527.5 -720,533.5 -714,539.5 -708,539.5"/>
<text text-anchor="middle" x="-659" y="431.7" font-family="Times,serif" font-size="14.00">RegistrarController</text> <text text-anchor="middle" x="-659" y="431.7" font-family="Times,serif" font-size="14.00">RegistrarController</text>
<polyline fill="none" stroke="black" points="-720,439.5 -598,439.5 "/> <polyline fill="none" stroke="black" points="-720,439.5 -598,439.5 "/>
<text text-anchor="start" x="-712" y="454.7" font-family="Times,serif" font-size="14.00">check_ip</text>
<text text-anchor="start" x="-712" y="469.7" font-family="Times,serif" font-size="14.00">depp_controller?</text>
<text text-anchor="start" x="-712" y="484.7" font-family="Times,serif" font-size="14.00">head_title_sufix</text>
<polyline fill="none" stroke="black" points="-720,492.5 -598,492.5 "/> <polyline fill="none" stroke="black" points="-720,492.5 -598,492.5 "/>
<polyline fill="none" stroke="black" points="-720,516.5 -598,516.5 "/> <polyline fill="none" stroke="black" points="-720,516.5 -598,516.5 "/>
<text text-anchor="start" x="-712" y="531.7" font-family="Times,serif" font-size="14.00">_layout</text> <text text-anchor="start" x="-712" y="531.7" font-family="Times,serif" font-size="14.00">_layout</text>
@ -491,8 +488,6 @@
<text text-anchor="middle" x="-212" y="-513.8" font-family="Times,serif" font-size="14.00">Registrar::SessionsController</text> <text text-anchor="middle" x="-212" y="-513.8" font-family="Times,serif" font-size="14.00">Registrar::SessionsController</text>
<polyline fill="none" stroke="black" points="-300,-506 -124,-506 "/> <polyline fill="none" stroke="black" points="-300,-506 -124,-506 "/>
<text text-anchor="start" x="-292" y="-490.8" font-family="Times,serif" font-size="14.00">create</text> <text text-anchor="start" x="-292" y="-490.8" font-family="Times,serif" font-size="14.00">create</text>
<text text-anchor="start" x="-292" y="-475.8" font-family="Times,serif" font-size="14.00">depp_controller?</text>
<text text-anchor="start" x="-292" y="-460.8" font-family="Times,serif" font-size="14.00">find_user_by_idc</text>
<text text-anchor="start" x="-292" y="-445.8" font-family="Times,serif" font-size="14.00">id</text> <text text-anchor="start" x="-292" y="-445.8" font-family="Times,serif" font-size="14.00">id</text>
<text text-anchor="start" x="-292" y="-430.8" font-family="Times,serif" font-size="14.00">login</text> <text text-anchor="start" x="-292" y="-430.8" font-family="Times,serif" font-size="14.00">login</text>
<text text-anchor="start" x="-292" y="-415.8" font-family="Times,serif" font-size="14.00">login_mid</text> <text text-anchor="start" x="-292" y="-415.8" font-family="Times,serif" font-size="14.00">login_mid</text>

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Before After
Before After

View file

@ -304,17 +304,6 @@
<ellipse fill="none" stroke="#bd72c2" cx="1039.02" cy="-403.97" rx="4.00001" ry="4.00001"/> <ellipse fill="none" stroke="#bd72c2" cx="1039.02" cy="-403.97" rx="4.00001" ry="4.00001"/>
<polygon fill="#bd72c2" stroke="#bd72c2" points="1479.97,-21.3879 1490.14,-25.5002 1484.97,-21.1957 1489.96,-21.0036 1489.96,-21.0036 1489.96,-21.0036 1484.97,-21.1957 1489.79,-16.5069 1479.97,-21.3879 1479.97,-21.3879"/> <polygon fill="#bd72c2" stroke="#bd72c2" points="1479.97,-21.3879 1490.14,-25.5002 1484.97,-21.1957 1489.96,-21.0036 1489.96,-21.0036 1489.96,-21.0036 1484.97,-21.1957 1489.79,-16.5069 1479.97,-21.3879 1479.97,-21.3879"/>
</g> </g>
<!-- ApiUserVersion -->
<g id="node30" class="node"><title>ApiUserVersion</title>
<ellipse fill="none" stroke="black" cx="3567.99" cy="-91" rx="68.4888" ry="18"/>
<text text-anchor="middle" x="3567.99" y="-87.3" font-family="Times,serif" font-size="14.00">ApiUserVersion</text>
</g>
<!-- ApiUserVersion&#45;&gt;VersionAssociation -->
<g id="edge28" class="edge"><title>ApiUserVersion&#45;&gt;VersionAssociation</title>
<path fill="none" stroke="#d1286a" d="M3511.98,-76.3934C3504.95,-75.0519 3497.83,-73.8683 3490.99,-73 3254.96,-43.0068 3193.81,-61.2233 2955.99,-54 2466.29,-39.126 1879.19,-25.7933 1658.59,-20.942"/>
<ellipse fill="none" stroke="#d1286a" cx="3516.25" cy="-77.2469" rx="4.00001" ry="4.00001"/>
<polygon fill="#d1286a" stroke="#d1286a" points="1658.36,-20.9371 1648.46,-16.2185 1653.36,-20.8273 1648.36,-20.7174 1648.36,-20.7174 1648.36,-20.7174 1653.36,-20.8273 1648.26,-25.2164 1658.36,-20.9371 1658.36,-20.9371"/>
</g>
<!-- DomainVersion --> <!-- DomainVersion -->
<g id="node32" class="node"><title>DomainVersion</title> <g id="node32" class="node"><title>DomainVersion</title>
<ellipse fill="none" stroke="black" cx="1244.99" cy="-307" rx="67.6881" ry="18"/> <ellipse fill="none" stroke="black" cx="1244.99" cy="-307" rx="67.6881" ry="18"/>

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 129 KiB

Before After
Before After

View file

@ -600,28 +600,6 @@
<ellipse fill="none" stroke="#c72760" cx="1492.92" cy="-1936.9" rx="4.00001" ry="4.00001"/> <ellipse fill="none" stroke="#c72760" cx="1492.92" cy="-1936.9" rx="4.00001" ry="4.00001"/>
<polygon fill="#c72760" stroke="#c72760" points="1669.11,-22.7608 1679.32,-26.7787 1674.11,-22.5223 1679.1,-22.2838 1679.1,-22.2838 1679.1,-22.2838 1674.11,-22.5223 1678.89,-17.7889 1669.11,-22.7608 1669.11,-22.7608"/> <polygon fill="#c72760" stroke="#c72760" points="1669.11,-22.7608 1679.32,-26.7787 1674.11,-22.5223 1679.1,-22.2838 1679.1,-22.2838 1679.1,-22.2838 1674.11,-22.5223 1678.89,-17.7889 1669.11,-22.7608 1669.11,-22.7608"/>
</g> </g>
<!-- ApiUserVersion -->
<g id="node30" class="node"><title>ApiUserVersion</title>
<path fill="none" stroke="black" d="M3602,-73.5C3602,-73.5 3708,-73.5 3708,-73.5 3714,-73.5 3720,-79.5 3720,-85.5 3720,-85.5 3720,-242.5 3720,-242.5 3720,-248.5 3714,-254.5 3708,-254.5 3708,-254.5 3602,-254.5 3602,-254.5 3596,-254.5 3590,-248.5 3590,-242.5 3590,-242.5 3590,-85.5 3590,-85.5 3590,-79.5 3596,-73.5 3602,-73.5"/>
<text text-anchor="middle" x="3655" y="-239.3" font-family="Times,serif" font-size="14.00">ApiUserVersion</text>
<polyline fill="none" stroke="black" points="3590,-231.5 3720,-231.5 "/>
<text text-anchor="start" x="3598" y="-216.3" font-family="Times,serif" font-size="14.00">id :integer</text>
<text text-anchor="start" x="3598" y="-201.3" font-family="Times,serif" font-size="14.00">item_type :string</text>
<text text-anchor="start" x="3598" y="-186.3" font-family="Times,serif" font-size="14.00">item_id :integer</text>
<text text-anchor="start" x="3598" y="-171.3" font-family="Times,serif" font-size="14.00">event :string</text>
<text text-anchor="start" x="3598" y="-156.3" font-family="Times,serif" font-size="14.00">whodunnit :string</text>
<text text-anchor="start" x="3598" y="-141.3" font-family="Times,serif" font-size="14.00">object :json</text>
<text text-anchor="start" x="3598" y="-126.3" font-family="Times,serif" font-size="14.00">object_changes :json</text>
<text text-anchor="start" x="3598" y="-111.3" font-family="Times,serif" font-size="14.00">created_at :datetime</text>
<text text-anchor="start" x="3598" y="-96.3" font-family="Times,serif" font-size="14.00">session :string</text>
<text text-anchor="start" x="3598" y="-81.3" font-family="Times,serif" font-size="14.00">children :json</text>
</g>
<!-- ApiUserVersion&#45;&gt;VersionAssociation -->
<g id="edge28" class="edge"><title>ApiUserVersion&#45;&gt;VersionAssociation</title>
<path fill="none" stroke="#9131a9" d="M3582.68,-73.8472C3582.12,-73.5585 3581.56,-73.276 3581,-73 3458.08,-12.5996 3101.89,-58.0943 2965,-54 2546.29,-41.477 2045.93,-27.1989 1845.95,-21.5203"/>
<ellipse fill="none" stroke="#9131a9" cx="3586.29" cy="-75.9354" rx="4.00002" ry="4.00002"/>
<polygon fill="#9131a9" stroke="#9131a9" points="1845.79,-21.5158 1835.92,-16.7338 1840.79,-21.3739 1835.79,-21.232 1835.79,-21.232 1835.79,-21.232 1840.79,-21.3739 1835.67,-25.7301 1845.79,-21.5158 1845.79,-21.5158"/>
</g>
<!-- DomainVersion --> <!-- DomainVersion -->
<g id="node32" class="node"><title>DomainVersion</title> <g id="node32" class="node"><title>DomainVersion</title>
<path fill="none" stroke="black" d="M1277.5,-1158.5C1277.5,-1158.5 1400.5,-1158.5 1400.5,-1158.5 1406.5,-1158.5 1412.5,-1164.5 1412.5,-1170.5 1412.5,-1170.5 1412.5,-1372.5 1412.5,-1372.5 1412.5,-1378.5 1406.5,-1384.5 1400.5,-1384.5 1400.5,-1384.5 1277.5,-1384.5 1277.5,-1384.5 1271.5,-1384.5 1265.5,-1378.5 1265.5,-1372.5 1265.5,-1372.5 1265.5,-1170.5 1265.5,-1170.5 1265.5,-1164.5 1271.5,-1158.5 1277.5,-1158.5"/> <path fill="none" stroke="black" d="M1277.5,-1158.5C1277.5,-1158.5 1400.5,-1158.5 1400.5,-1158.5 1406.5,-1158.5 1412.5,-1164.5 1412.5,-1170.5 1412.5,-1170.5 1412.5,-1372.5 1412.5,-1372.5 1412.5,-1378.5 1406.5,-1384.5 1400.5,-1384.5 1400.5,-1384.5 1277.5,-1384.5 1277.5,-1384.5 1271.5,-1384.5 1265.5,-1378.5 1265.5,-1372.5 1265.5,-1372.5 1265.5,-1170.5 1265.5,-1170.5 1265.5,-1164.5 1271.5,-1158.5 1277.5,-1158.5"/>

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 234 KiB

Before After
Before After

View file

@ -175,6 +175,8 @@ namespace :dev do
end end
end end
Setting.registrar_ip_whitelist_enabled = false
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
generate_default_data generate_default_data
generate_random_data if with_random_data generate_random_data if with_random_data

View file

@ -9,7 +9,6 @@ Fabricator(:registrar) do
country_code 'EE' country_code 'EE'
code { sequence(:code) { |i| "REGISTRAR#{i}" } } code { sequence(:code) { |i| "REGISTRAR#{i}" } }
reference_no { sequence(:reference_no) { |i| "RF#{i}" } } reference_no { sequence(:reference_no) { |i| "RF#{i}" } }
white_ips { [Fabricate(:white_ip), Fabricate(:white_ip, interfaces: [WhiteIp::REGISTRAR])] }
end end
Fabricator(:registrar_with_no_account_activities, from: :registrar) do Fabricator(:registrar_with_no_account_activities, from: :registrar) do

View file

@ -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

View file

@ -0,0 +1,5 @@
FactoryGirl.define do
factory :white_ip do
ipv4 '127.0.0.1'
end
end

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,24 +1,8 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe ApiUser do 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 context 'with invalid attribute' do
before :all do before do
@api_user = ApiUser.new @api_user = ApiUser.new
end end
@ -43,7 +27,7 @@ RSpec.describe ApiUser do
end end
context 'with valid attributes' do context 'with valid attributes' do
before :all do before do
@api_user = Fabricate(:api_user) @api_user = Fabricate(:api_user)
end end
@ -74,4 +58,71 @@ RSpec.describe ApiUser do
expect(described_class.min_password_length).to eq(6) expect(described_class.min_password_length).to eq(6)
end end
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 end

View file

@ -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

View file

@ -25,18 +25,7 @@ describe WhiteIp do
context 'with valid attributes' do context 'with valid attributes' do
before :all do before :all do
@white_ip = Fabricate(:white_ip) @white_ip = create(: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([])
end end
it 'should have one version' do it 'should have one version' do
@ -49,4 +38,32 @@ describe WhiteIp do
end end
end 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 end

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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