mirror of
https://github.com/internetee/registry.git
synced 2025-07-22 18:56:05 +02:00
Merge pull request #1682 from internetee/1680-registrar-tara-integration
Add TARA support
This commit is contained in:
commit
a756b52441
22 changed files with 255 additions and 220 deletions
5
Gemfile
5
Gemfile
|
@ -53,6 +53,11 @@ gem 'digidoc_client',
|
||||||
github: 'tarmotalu/digidoc_client',
|
github: 'tarmotalu/digidoc_client',
|
||||||
ref: '1645e83a5a548addce383f75703b0275c5310c32'
|
ref: '1645e83a5a548addce383f75703b0275c5310c32'
|
||||||
|
|
||||||
|
# TARA
|
||||||
|
gem 'omniauth'
|
||||||
|
gem 'omniauth-rails_csrf_protection'
|
||||||
|
gem 'omniauth-tara', github: 'internetee/omniauth-tara'
|
||||||
|
|
||||||
|
|
||||||
gem 'epp', github: 'internetee/epp', branch: :master
|
gem 'epp', github: 'internetee/epp', branch: :master
|
||||||
gem 'epp-xml', '1.1.0', github: 'internetee/epp-xml'
|
gem 'epp-xml', '1.1.0', github: 'internetee/epp-xml'
|
||||||
|
|
61
Gemfile.lock
61
Gemfile.lock
|
@ -52,6 +52,15 @@ GIT
|
||||||
logger
|
logger
|
||||||
nokogiri
|
nokogiri
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: https://github.com/internetee/omniauth-tara.git
|
||||||
|
revision: cec845ec3794532144c4976104a07e206d759aa6
|
||||||
|
specs:
|
||||||
|
omniauth-tara (0.3.0)
|
||||||
|
addressable (~> 2.5)
|
||||||
|
omniauth (~> 1.3)
|
||||||
|
openid_connect (~> 1.1)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/tarmotalu/digidoc_client.git
|
remote: https://github.com/tarmotalu/digidoc_client.git
|
||||||
revision: 1645e83a5a548addce383f75703b0275c5310c32
|
revision: 1645e83a5a548addce383f75703b0275c5310c32
|
||||||
|
@ -126,6 +135,7 @@ GEM
|
||||||
zeitwerk (~> 2.2, >= 2.2.2)
|
zeitwerk (~> 2.2, >= 2.2.2)
|
||||||
addressable (2.7.0)
|
addressable (2.7.0)
|
||||||
public_suffix (>= 2.0.2, < 5.0)
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
|
aes_key_wrap (1.1.0)
|
||||||
airbrake (11.0.0)
|
airbrake (11.0.0)
|
||||||
airbrake-ruby (~> 5.0)
|
airbrake-ruby (~> 5.0)
|
||||||
airbrake-ruby (5.0.2)
|
airbrake-ruby (5.0.2)
|
||||||
|
@ -133,9 +143,11 @@ GEM
|
||||||
akami (1.3.1)
|
akami (1.3.1)
|
||||||
gyoku (>= 0.4.0)
|
gyoku (>= 0.4.0)
|
||||||
nokogiri
|
nokogiri
|
||||||
|
attr_required (1.0.1)
|
||||||
autoprefixer-rails (10.0.0.2)
|
autoprefixer-rails (10.0.0.2)
|
||||||
execjs
|
execjs
|
||||||
bcrypt (3.1.16)
|
bcrypt (3.1.16)
|
||||||
|
bindata (2.4.8)
|
||||||
bootsnap (1.4.8)
|
bootsnap (1.4.8)
|
||||||
msgpack (~> 1.0)
|
msgpack (~> 1.0)
|
||||||
bootstrap-sass (3.4.1)
|
bootstrap-sass (3.4.1)
|
||||||
|
@ -175,7 +187,7 @@ GEM
|
||||||
data_migrate (6.3.0)
|
data_migrate (6.3.0)
|
||||||
rails (>= 5.0)
|
rails (>= 5.0)
|
||||||
database_cleaner (1.8.5)
|
database_cleaner (1.8.5)
|
||||||
devise (4.7.2)
|
devise (4.7.3)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (>= 4.1.0)
|
railties (>= 4.1.0)
|
||||||
|
@ -227,6 +239,7 @@ GEM
|
||||||
temple (>= 0.8.0)
|
temple (>= 0.8.0)
|
||||||
tilt
|
tilt
|
||||||
hashdiff (1.0.1)
|
hashdiff (1.0.1)
|
||||||
|
hashie (4.1.0)
|
||||||
hpricot (0.8.6)
|
hpricot (0.8.6)
|
||||||
http-accept (1.7.0)
|
http-accept (1.7.0)
|
||||||
http-cookie (1.0.3)
|
http-cookie (1.0.3)
|
||||||
|
@ -247,6 +260,10 @@ GEM
|
||||||
jquery-ui-rails (5.0.5)
|
jquery-ui-rails (5.0.5)
|
||||||
railties (>= 3.2.16)
|
railties (>= 3.2.16)
|
||||||
json (2.3.1)
|
json (2.3.1)
|
||||||
|
json-jwt (1.13.0)
|
||||||
|
activesupport (>= 4.2)
|
||||||
|
aes_key_wrap
|
||||||
|
bindata
|
||||||
kaminari (1.2.1)
|
kaminari (1.2.1)
|
||||||
activesupport (>= 4.1.0)
|
activesupport (>= 4.1.0)
|
||||||
kaminari-actionview (= 1.2.1)
|
kaminari-actionview (= 1.2.1)
|
||||||
|
@ -302,7 +319,23 @@ GEM
|
||||||
nokogiri (1.10.10)
|
nokogiri (1.10.10)
|
||||||
mini_portile2 (~> 2.4.0)
|
mini_portile2 (~> 2.4.0)
|
||||||
nori (2.6.0)
|
nori (2.6.0)
|
||||||
|
omniauth (1.9.1)
|
||||||
|
hashie (>= 3.4.6)
|
||||||
|
rack (>= 1.6.2, < 3)
|
||||||
|
omniauth-rails_csrf_protection (0.1.2)
|
||||||
|
actionpack (>= 4.2)
|
||||||
|
omniauth (>= 1.3.1)
|
||||||
open4 (1.3.4)
|
open4 (1.3.4)
|
||||||
|
openid_connect (1.2.0)
|
||||||
|
activemodel
|
||||||
|
attr_required (>= 1.0.0)
|
||||||
|
json-jwt (>= 1.5.0)
|
||||||
|
rack-oauth2 (>= 1.6.1)
|
||||||
|
swd (>= 1.0.0)
|
||||||
|
tzinfo
|
||||||
|
validate_email
|
||||||
|
validate_url
|
||||||
|
webfinger (>= 1.0.1)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
paper_trail (10.3.1)
|
paper_trail (10.3.1)
|
||||||
activerecord (>= 4.2)
|
activerecord (>= 4.2)
|
||||||
|
@ -326,6 +359,12 @@ GEM
|
||||||
rack (2.2.3)
|
rack (2.2.3)
|
||||||
rack-accept (0.4.5)
|
rack-accept (0.4.5)
|
||||||
rack (>= 0.4)
|
rack (>= 0.4)
|
||||||
|
rack-oauth2 (1.16.0)
|
||||||
|
activesupport
|
||||||
|
attr_required
|
||||||
|
httpclient
|
||||||
|
json-jwt (>= 1.11.0)
|
||||||
|
rack (>= 2.1.0)
|
||||||
rack-protection (2.1.0)
|
rack-protection (2.1.0)
|
||||||
rack
|
rack
|
||||||
rack-test (1.1.0)
|
rack-test (1.1.0)
|
||||||
|
@ -366,7 +405,7 @@ GEM
|
||||||
rb-inotify (0.10.1)
|
rb-inotify (0.10.1)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
rbtree3 (0.6.0)
|
rbtree3 (0.6.0)
|
||||||
regexp_parser (1.7.1)
|
regexp_parser (1.8.0)
|
||||||
request_store (1.5.0)
|
request_store (1.5.0)
|
||||||
rack (>= 1.4)
|
rack (>= 1.4)
|
||||||
responders (3.0.1)
|
responders (3.0.1)
|
||||||
|
@ -425,11 +464,15 @@ GEM
|
||||||
actionpack (>= 4.0)
|
actionpack (>= 4.0)
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
|
swd (1.2.0)
|
||||||
|
activesupport (>= 3)
|
||||||
|
attr_required (>= 0.0.5)
|
||||||
|
httpclient (>= 2.4)
|
||||||
temple (0.8.2)
|
temple (0.8.2)
|
||||||
thor (0.20.3)
|
thor (0.20.3)
|
||||||
thread_safe (0.3.6)
|
thread_safe (0.3.6)
|
||||||
tilt (2.0.10)
|
tilt (2.0.10)
|
||||||
truemail (1.9.0)
|
truemail (1.9.1)
|
||||||
simpleidn (~> 0.1.1)
|
simpleidn (~> 0.1.1)
|
||||||
tzinfo (1.2.7)
|
tzinfo (1.2.7)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
|
@ -439,6 +482,12 @@ GEM
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.7.7)
|
unf_ext (0.0.7.7)
|
||||||
unicode_utils (1.4.0)
|
unicode_utils (1.4.0)
|
||||||
|
validate_email (0.1.6)
|
||||||
|
activemodel (>= 3.0)
|
||||||
|
mail (>= 2.2.5)
|
||||||
|
validate_url (1.0.13)
|
||||||
|
activemodel (>= 3.0.0)
|
||||||
|
public_suffix
|
||||||
validates_email_format_of (1.6.3)
|
validates_email_format_of (1.6.3)
|
||||||
i18n
|
i18n
|
||||||
warden (1.2.9)
|
warden (1.2.9)
|
||||||
|
@ -451,6 +500,9 @@ GEM
|
||||||
nokogiri (~> 1.6)
|
nokogiri (~> 1.6)
|
||||||
rubyzip (>= 1.3.0)
|
rubyzip (>= 1.3.0)
|
||||||
selenium-webdriver (>= 3.0, < 4.0)
|
selenium-webdriver (>= 3.0, < 4.0)
|
||||||
|
webfinger (1.1.0)
|
||||||
|
activesupport
|
||||||
|
httpclient (>= 2.4)
|
||||||
webmock (3.9.1)
|
webmock (3.9.1)
|
||||||
addressable (>= 2.3.6)
|
addressable (>= 2.3.6)
|
||||||
crack (>= 0.3.2)
|
crack (>= 0.3.2)
|
||||||
|
@ -503,6 +555,9 @@ DEPENDENCIES
|
||||||
minitest (~> 5.14)
|
minitest (~> 5.14)
|
||||||
money-rails
|
money-rails
|
||||||
nokogiri
|
nokogiri
|
||||||
|
omniauth
|
||||||
|
omniauth-rails_csrf_protection
|
||||||
|
omniauth-tara!
|
||||||
paper_trail (~> 10.3)
|
paper_trail (~> 10.3)
|
||||||
pdfkit
|
pdfkit
|
||||||
pg (= 1.2.2)
|
pg (= 1.2.2)
|
||||||
|
|
|
@ -49,102 +49,6 @@ class Registrar
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def id_card
|
|
||||||
self.resource = warden.authenticate!(auth_options)
|
|
||||||
|
|
||||||
restricted_ip = Authorization::RestrictedIP.new(request.ip)
|
|
||||||
ip_allowed = restricted_ip.can_access_registrar_area?(resource.registrar)
|
|
||||||
|
|
||||||
unless ip_allowed
|
|
||||||
render plain: t('registrar.authorization.ip_not_allowed', ip: request.ip)
|
|
||||||
warden.logout(:registrar_user)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
set_flash_message!(:notice, :signed_in)
|
|
||||||
sign_in(resource_name, resource)
|
|
||||||
yield resource if block_given?
|
|
||||||
respond_with resource, location: after_sign_in_path_for(resource)
|
|
||||||
end
|
|
||||||
|
|
||||||
def login_mid
|
|
||||||
@user = User.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def mid
|
|
||||||
phone = params[:user][:phone]
|
|
||||||
endpoint = "#{ENV['sk_digi_doc_service_endpoint']}"
|
|
||||||
client = Digidoc::Client.new(endpoint)
|
|
||||||
client.logger = Rails.application.config.logger unless Rails.env.test?
|
|
||||||
|
|
||||||
# country_codes = {'+372' => 'EST'}
|
|
||||||
phone.gsub!('+372', '')
|
|
||||||
response = client.authenticate(
|
|
||||||
phone: "+372#{phone}",
|
|
||||||
message_to_display: 'Authenticating',
|
|
||||||
service_name: ENV['sk_digi_doc_service_name'] || 'Testing'
|
|
||||||
)
|
|
||||||
|
|
||||||
if response.faultcode
|
|
||||||
render json: { message: response.detail.message }, status: :unauthorized
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if Setting.registrar_ip_whitelist_enabled
|
|
||||||
@user = find_user_by_idc_and_allowed(response.user_id_code)
|
|
||||||
else
|
|
||||||
@user = find_user_by_idc(response.user_id_code)
|
|
||||||
end
|
|
||||||
|
|
||||||
if @user.persisted?
|
|
||||||
session[:user_id_code] = response.user_id_code
|
|
||||||
session[:mid_session_code] = client.session_code
|
|
||||||
|
|
||||||
render json: {
|
|
||||||
message: t(:confirmation_sms_was_sent_to_your_phone_verification_code_is, { code: response.challenge_id })
|
|
||||||
}, status: :ok
|
|
||||||
else
|
|
||||||
render json: { message: t(:no_such_user) }, status: :unauthorized
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def mid_status
|
|
||||||
endpoint = "#{ENV['sk_digi_doc_service_endpoint']}"
|
|
||||||
client = Digidoc::Client.new(endpoint)
|
|
||||||
client.logger = Rails.application.config.logger unless Rails.env.test?
|
|
||||||
client.session_code = session[:mid_session_code]
|
|
||||||
auth_status = client.authentication_status
|
|
||||||
|
|
||||||
case auth_status.status
|
|
||||||
when 'OUTSTANDING_TRANSACTION'
|
|
||||||
render json: { message: t(:check_your_phone_for_confirmation_code) }, status: :ok
|
|
||||||
when 'USER_AUTHENTICATED'
|
|
||||||
@user = find_user_by_idc_and_allowed(session[:user_id_code])
|
|
||||||
sign_in(:registrar_user, @user)
|
|
||||||
flash[:notice] = t(:welcome)
|
|
||||||
flash.keep(:notice)
|
|
||||||
render js: "window.location = '#{after_sign_in_path_for(@user)}'"
|
|
||||||
when 'NOT_VALID'
|
|
||||||
render json: { message: t(:user_signature_is_invalid) }, status: :bad_request
|
|
||||||
when 'EXPIRED_TRANSACTION'
|
|
||||||
render json: { message: t(:session_timeout) }, status: :bad_request
|
|
||||||
when 'USER_CANCEL'
|
|
||||||
render json: { message: t(:user_cancelled) }, status: :bad_request
|
|
||||||
when 'MID_NOT_READY'
|
|
||||||
render json: { message: t(:mid_not_ready) }, status: :bad_request
|
|
||||||
when 'PHONE_ABSENT'
|
|
||||||
render json: { message: t(:phone_absent) }, status: :bad_request
|
|
||||||
when 'SENDING_ERROR'
|
|
||||||
render json: { message: t(:sending_error) }, status: :bad_request
|
|
||||||
when 'SIM_ERROR'
|
|
||||||
render json: { message: t(:sim_error) }, status: :bad_request
|
|
||||||
when 'INTERNAL_ERROR'
|
|
||||||
render json: { message: t(:internal_error) }, status: :bad_request
|
|
||||||
else
|
|
||||||
render json: { message: t(:internal_error) }, status: :bad_request
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def depp_controller?
|
def depp_controller?
|
||||||
|
|
33
app/controllers/registrar/tara_controller.rb
Normal file
33
app/controllers/registrar/tara_controller.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
class Registrar
|
||||||
|
class TaraController < ApplicationController
|
||||||
|
skip_authorization_check
|
||||||
|
|
||||||
|
# rubocop:disable Style/AndOr
|
||||||
|
def callback
|
||||||
|
session[:omniauth_hash] = user_hash
|
||||||
|
@api_user = ApiUser.from_omniauth(user_hash)
|
||||||
|
|
||||||
|
if @api_user
|
||||||
|
flash[:notice] = t(:signed_in_successfully)
|
||||||
|
sign_in_and_redirect(:registrar_user, @api_user)
|
||||||
|
else
|
||||||
|
show_error and return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# rubocop:enable Style/AndOr
|
||||||
|
|
||||||
|
def cancel
|
||||||
|
redirect_to root_path, notice: t(:sign_in_cancelled)
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_error
|
||||||
|
redirect_to new_registrar_user_session_url, alert: t(:no_such_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def user_hash
|
||||||
|
request.env['omniauth.auth']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,7 +2,7 @@ require 'open3'
|
||||||
|
|
||||||
class ApiUser < User
|
class ApiUser < User
|
||||||
include EppErrors
|
include EppErrors
|
||||||
devise :database_authenticatable, :trackable, :timeoutable, :id_card_authenticatable,
|
devise :database_authenticatable, :trackable, :timeoutable,
|
||||||
authentication_keys: [:username]
|
authentication_keys: [:username]
|
||||||
|
|
||||||
def epp_code_map
|
def epp_code_map
|
||||||
|
|
|
@ -11,4 +11,11 @@ class User < ApplicationRecord
|
||||||
"#{self.id}-#{self.class}: #{self.username}"
|
"#{self.id}-#{self.class}: #{self.username}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.from_omniauth(omniauth_hash)
|
||||||
|
uid = omniauth_hash['uid']
|
||||||
|
identity_code = uid.slice(2..-1)
|
||||||
|
# country_code = uid.slice(0..1)
|
||||||
|
|
||||||
|
User.find_by(identity_code: identity_code)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,12 +19,10 @@
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<%= link_to '/registrar/login/mid', id: 'login-with-mobile-id-btn' do %>
|
<div id="tara-sign-in" class="login-block ui segment">
|
||||||
<%= image_tag 'mid.gif' %>
|
<h3><%= t('.sign_in_with_identity_document') %></h3>
|
||||||
<% end %>
|
<p><%= t('.identity_document_text')%></p>
|
||||||
|
<%= link_to t(:sign_in), "/auth/tara", method: :post, class: 'btn btn-lg btn-primary btn-block' %>
|
||||||
<%= link_to registrar_id_card_sign_in_path, method: :post do %>
|
</div>
|
||||||
<%= image_tag 'id_card.gif' %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
0
app/views/registrar/tara/callback.html.erb
Normal file
0
app/views/registrar/tara/callback.html.erb
Normal file
|
@ -156,6 +156,13 @@ lhv_dev_mode: 'false'
|
||||||
epp_session_timeout_seconds: '300'
|
epp_session_timeout_seconds: '300'
|
||||||
contact_archivation_log_file_dir:
|
contact_archivation_log_file_dir:
|
||||||
|
|
||||||
|
tara_host: 'tara-test.ria.ee'
|
||||||
|
tara_issuer: 'https://tara-test.ria.ee'
|
||||||
|
tara_identifier: 'identifier'
|
||||||
|
tara_secret: 'secret'
|
||||||
|
tara_redirect_uri: 'redirect_url'
|
||||||
|
tara_keys: "{\"kty\":\"RSA\",\"kid\":\"de6cc4\",\"n\":\"jWwAjT_03ypme9ZWeSe7c-jY26NO50Wo5I1LBnPW2JLc0dPMj8v7y4ehiRpClYNTaSWcLd4DJmlKXDXXudEUWwXa7TtjBFJfzlZ-1u0tDvJ-H9zv9MzO7UhUFytztUEMTrtStdhGbzkzdEZZCgFYeo2i33eXxzIR1nGvI05d9Y-e_LHnNE2ZKTa89BC7ZiCXq5nfAaCgQna_knh4kFAX-KgiPRAtsiDHcAWKcBY3qUVcb-5XAX8p668MlGLukzsh5tFkQCbJVyNtmlbIHdbGvVHPb8C0H3oLYciv1Fjy_tS1lO7OT_cb3GVp6Ql-CG0uED_8pkpVtfsGRviub4_ElQ\",\"e\":\"AQAB\"}"
|
||||||
|
|
||||||
# Since the keys for staging are absent from the repo, we need to supply them separate for testing.
|
# Since the keys for staging are absent from the repo, we need to supply them separate for testing.
|
||||||
test:
|
test:
|
||||||
payments_seb_bank_certificate: 'test/fixtures/files/seb_bank_cert.pem'
|
payments_seb_bank_certificate: 'test/fixtures/files/seb_bank_cert.pem'
|
||||||
|
|
|
@ -43,7 +43,7 @@ Rails.application.configure do
|
||||||
# config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
|
# config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
|
||||||
|
|
||||||
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
||||||
# config.force_ssl = true
|
config.force_ssl = true
|
||||||
|
|
||||||
# Use the lowest log level to ensure availability of diagnostic information
|
# Use the lowest log level to ensure availability of diagnostic information
|
||||||
# when problems arise.
|
# when problems arise.
|
||||||
|
|
|
@ -9,7 +9,7 @@ Devise.setup do |config|
|
||||||
# Devise will use the `secret_key_base` as its `secret_key`
|
# Devise will use the `secret_key_base` as its `secret_key`
|
||||||
# by default. You can change it below and use your own secret key.
|
# by default. You can change it below and use your own secret key.
|
||||||
config.secret_key = ENV['devise_secret']
|
config.secret_key = ENV['devise_secret']
|
||||||
|
|
||||||
# ==> Controller configuration
|
# ==> Controller configuration
|
||||||
# Configure the parent class to the devise controllers.
|
# Configure the parent class to the devise controllers.
|
||||||
# config.parent_controller = 'DeviseController'
|
# config.parent_controller = 'DeviseController'
|
||||||
|
|
46
config/initializers/omniauth.rb
Normal file
46
config/initializers/omniauth.rb
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
OpenIDConnect.logger = Rails.logger
|
||||||
|
OpenIDConnect.debug!
|
||||||
|
|
||||||
|
OmniAuth.config.on_failure = Proc.new { |env|
|
||||||
|
OmniAuth::FailureEndpoint.new(env).redirect_to_failure
|
||||||
|
}
|
||||||
|
|
||||||
|
OmniAuth.config.logger = Rails.logger
|
||||||
|
# Block GET requests to avoid exposing self to CVE-2015-9284
|
||||||
|
OmniAuth.config.allowed_request_methods = [:post]
|
||||||
|
|
||||||
|
signing_keys = ENV['tara_keys']
|
||||||
|
issuer = ENV['tara_issuer']
|
||||||
|
host = ENV['tara_host']
|
||||||
|
identifier = ENV['tara_identifier']
|
||||||
|
secret = ENV['tara_secret']
|
||||||
|
redirect_uri = ENV['tara_redirect_uri']
|
||||||
|
|
||||||
|
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||||
|
provider "tara", {
|
||||||
|
callback_path: '/registrar/open_id/callback',
|
||||||
|
name: 'tara',
|
||||||
|
scope: ['openid'],
|
||||||
|
state: Proc.new{ SecureRandom.hex(10) },
|
||||||
|
client_signing_alg: :RS256,
|
||||||
|
client_jwk_signing_key: signing_keys,
|
||||||
|
send_scope_to_token_endpoint: false,
|
||||||
|
send_nonce: true,
|
||||||
|
issuer: issuer,
|
||||||
|
|
||||||
|
client_options: {
|
||||||
|
scheme: 'https',
|
||||||
|
host: host,
|
||||||
|
|
||||||
|
authorization_endpoint: '/oidc/authorize',
|
||||||
|
token_endpoint: '/oidc/token',
|
||||||
|
userinfo_endpoint: nil, # Not implemented
|
||||||
|
jwks_uri: '/oidc/jwks',
|
||||||
|
|
||||||
|
# Registry
|
||||||
|
identifier: identifier,
|
||||||
|
secret: secret,
|
||||||
|
redirect_uri: redirect_uri,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
|
@ -2,4 +2,4 @@ en:
|
||||||
activerecord:
|
activerecord:
|
||||||
attributes:
|
attributes:
|
||||||
account_activity:
|
account_activity:
|
||||||
created_at: Receipt date
|
created_at: Receipt date
|
||||||
|
|
|
@ -295,6 +295,8 @@ en:
|
||||||
|
|
||||||
authentication_error: 'Authentication error'
|
authentication_error: 'Authentication error'
|
||||||
|
|
||||||
|
sign_in_cancelled: "Sign in cancelled"
|
||||||
|
|
||||||
transfer_requested: 'Transfer requested.'
|
transfer_requested: 'Transfer requested.'
|
||||||
message_was_not_found: 'Message was not found'
|
message_was_not_found: 'Message was not found'
|
||||||
only_one_parameter_allowed: 'Only one parameter allowed: %{param_1} or %{param_2}'
|
only_one_parameter_allowed: 'Only one parameter allowed: %{param_1} or %{param_2}'
|
||||||
|
@ -658,3 +660,5 @@ en:
|
||||||
ipv6: IPv6
|
ipv6: IPv6
|
||||||
reference_no: Reference number
|
reference_no: Reference number
|
||||||
iban: IBAN
|
iban: IBAN
|
||||||
|
sign_in: "Sign in"
|
||||||
|
signed_in_successfully: "Signed in successfully"
|
||||||
|
|
|
@ -4,6 +4,14 @@ en:
|
||||||
new:
|
new:
|
||||||
header_html: Eesti Interneti SA<br>Registrar Portal
|
header_html: Eesti Interneti SA<br>Registrar Portal
|
||||||
submit_btn: Login
|
submit_btn: Login
|
||||||
|
sign_in_with_identity_document: "Sign in with identity document"
|
||||||
|
identity_document_text: |
|
||||||
|
Sign in using Estonian (incl. e-residents) ID card, mobile ID,
|
||||||
|
Bank link or other EU citizen's electronic ID supported by EIDAS.
|
||||||
login_mid:
|
login_mid:
|
||||||
header: Log in with mobile-id
|
header: Log in with mobile-id
|
||||||
submit_btn: Login
|
submit_btn: Login
|
||||||
|
tara:
|
||||||
|
callback:
|
||||||
|
header_html: "Eesti Interneti SA<br>Registrar Portal"
|
||||||
|
submit_btn: Login
|
||||||
|
|
14
config/locales/tara.en.yml
Normal file
14
config/locales/tara.en.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
en:
|
||||||
|
auth:
|
||||||
|
tara:
|
||||||
|
tampering: "Tampering detected. Sign in cancelled."
|
||||||
|
|
||||||
|
callback:
|
||||||
|
title: "Create a user"
|
||||||
|
errors: "prohibited this user from being saved"
|
||||||
|
|
||||||
|
form:
|
||||||
|
contact_data: "Contact Data"
|
||||||
|
data_from_identity_document: "Data from identity document"
|
||||||
|
new_password: "New password"
|
||||||
|
sign_up: "Sign up"
|
14
config/locales/tara.et.yml
Normal file
14
config/locales/tara.et.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
et:
|
||||||
|
auth:
|
||||||
|
tara:
|
||||||
|
tampering: "Avastatud urkimine. Sisselogimine tühistatud."
|
||||||
|
|
||||||
|
callback:
|
||||||
|
title: "Loo kasutaja"
|
||||||
|
errors: "seda kasutajat ei saa salvestada"
|
||||||
|
|
||||||
|
form:
|
||||||
|
contact_data: "Kontaktandmed"
|
||||||
|
data_from_identity_document: "Andmed elektroonselt isikutunnistuselt"
|
||||||
|
new_password: "Uus salasõna"
|
||||||
|
sign_up: "Registreeru"
|
|
@ -77,14 +77,9 @@ Rails.application.routes.draw do
|
||||||
devise_for :users, path: '', class_name: 'ApiUser', skip: %i[sessions]
|
devise_for :users, path: '', class_name: 'ApiUser', skip: %i[sessions]
|
||||||
|
|
||||||
devise_scope :registrar_user do
|
devise_scope :registrar_user do
|
||||||
get 'login/mid' => 'sessions#login_mid'
|
match '/open_id/callback', via: %i[get post], to: 'tara#callback', as: :tara_callback
|
||||||
post 'login/mid' => 'sessions#mid'
|
match '/open_id/cancel', via: %i[get post delete], to: 'tara#cancel',
|
||||||
post 'login/mid_status' => 'sessions#mid_status'
|
as: :tara_cancel
|
||||||
|
|
||||||
# /registrar/id path is hardcoded in Apache config for authentication with Estonian ID-card
|
|
||||||
post 'id' => 'sessions#id_card', as: :id_card_sign_in
|
|
||||||
|
|
||||||
post 'mid' => 'sessions#mid'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :invoices, except: %i[new create edit update destroy] do
|
resources :invoices, except: %i[new create edit update destroy] do
|
||||||
|
|
|
@ -46,4 +46,4 @@ module Devise
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Warden::Strategies.add(:id_card_authenticatable, Devise::Strategies::IdCardAuthenticatable)
|
Warden::Strategies.add(:id_card_authenticatable, Devise::Strategies::IdCardAuthenticatable)
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
require 'test_helper'
|
|
||||||
|
|
||||||
class RegistrarAreaIdCardSignInTest < ApplicationIntegrationTest
|
|
||||||
setup do
|
|
||||||
@user = users(:api_bestnames)
|
|
||||||
@original_registrar_area_ip_whitelist = Setting.registrar_ip_whitelist_enabled
|
|
||||||
end
|
|
||||||
|
|
||||||
teardown do
|
|
||||||
Setting.registrar_ip_whitelist_enabled = @original_registrar_area_ip_whitelist
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_signs_in_a_user_when_id_card_owner_is_found
|
|
||||||
assert_equal '1234', @user.identity_code
|
|
||||||
|
|
||||||
post registrar_id_card_sign_in_path, headers: { 'SSL_CLIENT_S_DN_CN' => 'DOE,JOHN,1234' }
|
|
||||||
follow_redirect!
|
|
||||||
|
|
||||||
assert_response :ok
|
|
||||||
assert_equal registrar_root_path, path
|
|
||||||
assert_not_nil controller.current_registrar_user
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_does_not_sign_in_a_user_when_id_card_owner_is_not_found
|
|
||||||
post registrar_id_card_sign_in_path,
|
|
||||||
headers: { 'SSL_CLIENT_S_DN_CN' => 'DOE,JOHN,unacceptable-personal-code' }
|
|
||||||
|
|
||||||
assert_nil controller.current_registrar_user
|
|
||||||
assert_equal registrar_id_card_sign_in_path, path
|
|
||||||
assert_includes response.body, 'Failed to Login'
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_does_not_sign_in_a_user_when_id_card_owner_is_found_but_ip_is_not_allowed
|
|
||||||
allow_access_to_sign_in_page
|
|
||||||
assert_equal '127.0.0.1', white_ips(:one).ipv4
|
|
||||||
assert_equal '1234', @user.identity_code
|
|
||||||
|
|
||||||
Setting.registrar_ip_whitelist_enabled = true
|
|
||||||
|
|
||||||
post registrar_id_card_sign_in_path, headers: { 'SSL_CLIENT_S_DN_CN' => 'DOE,JOHN,1234',
|
|
||||||
'REMOTE_ADDR' => '127.0.0.2' }
|
|
||||||
|
|
||||||
assert_equal registrar_id_card_sign_in_path, path
|
|
||||||
assert_equal 'Access denied from IP 127.0.0.2', response.body
|
|
||||||
|
|
||||||
get registrar_root_path
|
|
||||||
assert_redirected_to new_registrar_user_session_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_does_not_sign_in_a_user_when_certificate_is_absent
|
|
||||||
post registrar_id_card_sign_in_path, headers: { 'SSL_CLIENT_S_DN_CN' => '' }
|
|
||||||
|
|
||||||
assert_nil controller.current_registrar_user
|
|
||||||
assert_equal registrar_id_card_sign_in_path, path
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def allow_access_to_sign_in_page
|
|
||||||
another_registrar_white_ip = white_ips(:one).dup
|
|
||||||
another_registrar_white_ip.ipv4 = '127.0.0.2'
|
|
||||||
another_registrar_white_ip.registrar = registrars(:goodnames)
|
|
||||||
another_registrar_white_ip.save!
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,35 +0,0 @@
|
||||||
require 'application_system_test_case'
|
|
||||||
|
|
||||||
class RegistrarAreaMobileIDSignInTest < JavaScriptApplicationSystemTestCase
|
|
||||||
def setup
|
|
||||||
super
|
|
||||||
WebMock.allow_net_connect!
|
|
||||||
|
|
||||||
@user = users(:api_bestnames)
|
|
||||||
@user.identity_code = '1234'
|
|
||||||
@user.save
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_valid_phone_number
|
|
||||||
mock_client = Minitest::Mock.new
|
|
||||||
mock_client.expect(:authenticate,
|
|
||||||
OpenStruct.new(user_id_code: '1234', challenge_id: '1234'),
|
|
||||||
[{ phone: "+3721234",
|
|
||||||
message_to_display: "Authenticating",
|
|
||||||
service_name: "Testimine" }])
|
|
||||||
mock_client.expect(:session_code, 1234)
|
|
||||||
|
|
||||||
Digidoc::Client.stub(:new, mock_client) do
|
|
||||||
visit new_registrar_user_session_path
|
|
||||||
|
|
||||||
click_on 'login-with-mobile-id-btn'
|
|
||||||
|
|
||||||
fill_in 'user[phone]', with: '1234'
|
|
||||||
click_button 'Login'
|
|
||||||
|
|
||||||
flash_message = page.find('div.bg-success')
|
|
||||||
assert_equal('Confirmation sms was sent to your phone. Verification code is 1234.',
|
|
||||||
flash_message.text)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
45
test/system/registrar_area/tara/tara_users_test.rb
Normal file
45
test/system/registrar_area/tara/tara_users_test.rb
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
require 'application_system_test_case'
|
||||||
|
|
||||||
|
class TaraUsersTest < ApplicationSystemTestCase
|
||||||
|
def setup
|
||||||
|
super
|
||||||
|
|
||||||
|
OmniAuth.config.test_mode = true
|
||||||
|
@user = users(:api_bestnames)
|
||||||
|
|
||||||
|
@existing_user_hash = {
|
||||||
|
'provider' => 'tara',
|
||||||
|
'uid' => "EE" + @user.identity_code
|
||||||
|
}
|
||||||
|
|
||||||
|
@new_user_hash = {
|
||||||
|
'provider' => 'tara',
|
||||||
|
'uid' => 'EE51007050604'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
super
|
||||||
|
|
||||||
|
OmniAuth.config.test_mode = false
|
||||||
|
OmniAuth.config.mock_auth['tara'] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_existing_user_gets_signed_in
|
||||||
|
OmniAuth.config.mock_auth[:tara] = OmniAuth::AuthHash.new(@existing_user_hash)
|
||||||
|
|
||||||
|
visit new_registrar_user_session_path
|
||||||
|
click_link('Sign in')
|
||||||
|
|
||||||
|
assert_text('Signed in successfully')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_nonexisting_user_gets_error_message
|
||||||
|
OmniAuth.config.mock_auth[:tara] = OmniAuth::AuthHash.new(@new_user_hash)
|
||||||
|
|
||||||
|
visit new_registrar_user_session_path
|
||||||
|
click_link('Sign in')
|
||||||
|
|
||||||
|
assert_text('No such user')
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Add a link
Reference in a new issue