Class: MobileId::Auth

Inherits:
Object
  • Object
show all
Defined in:
lib/mobile_id/auth.rb

Constant Summary collapse

LIVE_URL =

API documentation github.com/SK-EID/MID

"https://mid.sk.ee/mid-api"
TEST_URL =
"https://tsp.demo.sk.ee/mid-api"
TEST_UUID =
"00000000-0000-0000-0000-000000000000"
TEST_NAME =
"DEMO"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(live:, uuid: nil, name: nil) ⇒ Auth

Returns a new instance of Auth.



14
15
16
17
18
19
20
# File 'lib/mobile_id/auth.rb', line 14

def initialize(live:, uuid: nil, name: nil)
  self.url = live == true ? LIVE_URL : TEST_URL
  self.uuid = live == true ? uuid : TEST_UUID
  self.name = live == true ? name : TEST_NAME
  self.live = live
  init_doc(SecureRandom.hex(40))
end

Instance Attribute Details

#docObject

Returns the value of attribute doc.



12
13
14
# File 'lib/mobile_id/auth.rb', line 12

def doc
  @doc
end

#hashObject

Returns the value of attribute hash.



12
13
14
# File 'lib/mobile_id/auth.rb', line 12

def hash
  @hash
end

#liveObject

Returns the value of attribute live.



12
13
14
# File 'lib/mobile_id/auth.rb', line 12

def live
  @live
end

#nameObject

Returns the value of attribute name.



12
13
14
# File 'lib/mobile_id/auth.rb', line 12

def name
  @name
end

#urlObject

Returns the value of attribute url.



12
13
14
# File 'lib/mobile_id/auth.rb', line 12

def url
  @url
end

#user_certObject

Returns the value of attribute user_cert.



12
13
14
# File 'lib/mobile_id/auth.rb', line 12

def user_cert
  @user_cert
end

#uuidObject

Returns the value of attribute uuid.



12
13
14
# File 'lib/mobile_id/auth.rb', line 12

def uuid
  @uuid
end

Instance Method Details

#authenticate!(phone_calling_code: nil, phone:, personal_code:, language: nil, display_text: nil) ⇒ Object

Raises:



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/mobile_id/auth.rb', line 27

def authenticate!(phone_calling_code: nil, phone:, personal_code:, language: nil, display_text: nil)
  phone_calling_code ||= '+372'
  full_phone = "#{phone_calling_code}#{phone}"
  language ||= 
    case I18n.locale
    when :et
      display_text ||= 'Autentimine' 
      'EST'
    when :ru
      display_text ||= 'Аутентификация' 
      'RUS'
    else
      display_text ||= 'Authentication' 
      'ENG'
    end
  
  options = {
    headers: {
      "Content-Type": "application/json"
    },
    query: {},
    body: {
      relyingPartyUUID: uuid,
      relyingPartyName: name,
      phoneNumber: full_phone.to_s.strip,
      nationalIdentityNumber: personal_code.to_s.strip,
      hash: Base64.strict_encode64(hash),
      hashType: 'SHA256',
      language: language,
      displayText: display_text,
      displayTextFormat: 'GSM-7' # or "UCS-2”
    }.to_json
  }

  response = HTTParty.post(url + '/authentication', options)
  raise Error, "#{I18n.t('mobile_id.some_error')} #{response}" unless response.code == 200

  ActiveSupport::HashWithIndifferentAccess.new(
    session_id: response['sessionID'],
    phone: phone,
    phone_calling_code: phone_calling_code,
    doc: doc
  )
end

#common_nameObject



134
135
136
# File 'lib/mobile_id/auth.rb', line 134

def common_name
  user_cert.common_name
end

#countryObject



130
131
132
# File 'lib/mobile_id/auth.rb', line 130

def country
  user_cert.country
end

#given_nameObject Also known as: first_name



120
121
122
# File 'lib/mobile_id/auth.rb', line 120

def given_name
  user_cert.given_name
end

#init_doc(doc) ⇒ Object



22
23
24
25
# File 'lib/mobile_id/auth.rb', line 22

def init_doc(doc)
  self.doc = doc
  self.hash = Digest::SHA256.digest(doc)
end

#long_poll!(session_id:, doc:) ⇒ Object

Raises:



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/mobile_id/auth.rb', line 85

def long_poll!(session_id:, doc:)
  response = HTTParty.get(url + "/authentication/session/#{session_id}")
  raise Error, "#{I18n.t('mobile_id.some_error')} #{response.code} #{response}" if response.code != 200

  if response['state'] == 'COMPLETE' && response['result'] != 'OK'
    message = 
      case response['result']
      when "TIMEOUT"
        I18n.t('mobile_id.timeout')
      when "NOT_MID_CLIENT"
        I18n.t('mobile_id.user_is_not_mobile_id_client')
      when "USER_CANCELLED"
        I18n.t('mobile_id.user_cancelled')
      when "SIGNATURE_HASH_MISMATCH"
        I18n.t('mobile_id.signature_hash_mismatch')
      when "PHONE_ABSENT"
        I18n.t('mobile_id.phone_absent')
      when "DELIVERY_ERROR"
        I18n.t('mobile_id.delivery_error')
      when "SIM_ERROR"
        I18n.t('mobile_id.sim_error')
      end
    raise Error, message
  end

  @user_cert = MobileId::Cert.new(response['cert'], live: live)
  @user_cert.verify_signature!(response['signature']['value'], doc)
  self.user_cert = @user_cert
end

#organizational_unitObject



138
139
140
# File 'lib/mobile_id/auth.rb', line 138

def organizational_unit
  user_cert.organizational_unit
end

#serial_numberObject Also known as: personal_code



142
143
144
# File 'lib/mobile_id/auth.rb', line 142

def serial_number
  user_cert.serial_number
end

#surnameObject Also known as: last_name



125
126
127
# File 'lib/mobile_id/auth.rb', line 125

def surname
  user_cert.surname
end

#verification_codeObject



115
116
117
118
# File 'lib/mobile_id/auth.rb', line 115

def verification_code
  binary = hash.unpack('B*').first
  "%04d" % (binary[0...6] + binary[-7..-1]).to_i(2)
end

#verify!(auth) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/mobile_id/auth.rb', line 72

def verify!(auth)
  long_poll!(session_id: auth['session_id'], doc: auth['doc'])

  ActiveSupport::HashWithIndifferentAccess.new(
    personal_code: personal_code,
    first_name: first_name,
    last_name: last_name,
    phone: auth['phone'],
    phone_calling_code: auth['phone_calling_code'],
    auth_provider: 'mobileid' # User::MOBILEID
  )
end