Class: SignIn::Idme::Service
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from PublicJwks
#jwks_loader, #parse_public_jwks, #public_jwks
#config, configuration, #connection, #delete, #get, #perform, #post, #put, #raise_backend_exception, #raise_not_authenticated, #request, #sanitize_headers!, #service_name
#log_exception_to_sentry, #log_message_to_sentry, #non_nil_hash?, #normalize_level, #rails_logger, #set_sentry_metadata
Instance Attribute Details
#type ⇒ Object
Returns the value of attribute type.
14
15
16
|
# File 'lib/sign_in/idme/service.rb', line 14
def type
@type
end
|
Instance Method Details
#address_defined?(user_info) ⇒ Boolean
147
148
149
|
# File 'lib/sign_in/idme/service.rb', line 147
def address_defined?(user_info)
user_info.street && user_info.zip && user_info.state && user_info.city
end
|
#auth_params(acr, state, operation) ⇒ Object
55
56
57
58
59
60
61
62
63
64
|
# File 'lib/sign_in/idme/service.rb', line 55
def auth_params(acr, state, operation)
{
scope: acr,
state:,
client_id: config.client_id,
redirect_uri: config.redirect_uri,
response_type: config.response_type,
op: convert_operation(operation)
}.compact
end
|
#auth_url ⇒ Object
187
188
189
|
# File 'lib/sign_in/idme/service.rb', line 187
def auth_url
"#{config.base_path}/#{config.auth_path}"
end
|
#convert_operation(operation) ⇒ Object
66
67
68
69
70
71
|
# File 'lib/sign_in/idme/service.rb', line 66
def convert_operation(operation)
case operation
when Constants::Auth::SIGN_UP
config.sign_up_operation
end
end
|
#dslogon_attributes(user_info) ⇒ Object
116
117
118
119
120
121
122
123
124
125
|
# File 'lib/sign_in/idme/service.rb', line 116
def dslogon_attributes(user_info)
{
ssn: user_info.dslogon_idvalue&.tr('-', ''),
birth_date: user_info.dslogon_birth_date,
first_name: user_info.dslogon_fname,
middle_name: user_info.dslogon_mname,
last_name: user_info.dslogon_lname,
edipi: user_info.dslogon_uuid
}
end
|
#get_authn_context(current_ial) ⇒ Object
#idme_attributes(user_info) ⇒ Object
106
107
108
109
110
111
112
113
114
|
# File 'lib/sign_in/idme/service.rb', line 106
def idme_attributes(user_info)
{
ssn: user_info.social&.tr('-', ''),
birth_date: user_info.birth_date,
first_name: user_info.fname,
last_name: user_info.lname,
address: normalize_address(user_info)
}
end
|
#jwe_decrypt(encrypted_jwe) ⇒ Object
155
156
157
158
159
|
# File 'lib/sign_in/idme/service.rb', line 155
def jwe_decrypt(encrypted_jwe)
JWE.decrypt(encrypted_jwe, config.ssl_key)
rescue JWE::DecodeError
raise Errors::JWEDecodeError, '[SignIn][Idme][Service] JWE is malformed'
end
|
#jwt_decode(encoded_jwt) ⇒ Object
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
# File 'lib/sign_in/idme/service.rb', line 161
def jwt_decode(encoded_jwt)
verify_expiration = true
decoded_jwt = JWT.decode(
encoded_jwt,
nil,
verify_expiration,
{ verify_expiration:, algorithm: config.jwt_decode_algorithm, jwks: method(:jwks_loader) }
).first
log_parsed_credential(decoded_jwt) if config.log_credential
OpenStruct.new(decoded_jwt)
rescue JWT::JWKError
raise Errors::PublicJWKError, '[SignIn][Idme][Service] Public JWK is malformed'
rescue JWT::VerificationError
raise Errors::JWTVerificationError, '[SignIn][Idme][Service] JWT body does not match signature'
rescue JWT::ExpiredSignature
raise Errors::JWTExpiredError, '[SignIn][Idme][Service] JWT has expired'
rescue JWT::DecodeError
raise Errors::JWTDecodeError, '[SignIn][Idme][Service] JWT is malformed'
end
|
#log_parsed_credential(decoded_jwt) ⇒ Object
183
184
185
|
# File 'lib/sign_in/idme/service.rb', line 183
def log_parsed_credential(decoded_jwt)
MockedAuthentication::Mockdata::Writer.save_credential(credential: decoded_jwt, credential_type: type)
end
|
#mhv_attributes(user_info) ⇒ Object
127
128
129
130
131
132
133
|
# File 'lib/sign_in/idme/service.rb', line 127
def mhv_attributes(user_info)
{
mhv_correlation_id: user_info.mhv_uuid,
mhv_icn: user_info.mhv_icn,
mhv_assurance: user_info.mhv_assurance
}
end
|
#normalize_address(user_info) ⇒ Object
135
136
137
138
139
140
141
142
143
144
145
|
# File 'lib/sign_in/idme/service.rb', line 135
def normalize_address(user_info)
return unless address_defined?(user_info)
{
street: user_info.street,
postal_code: user_info.zip,
state: user_info.state,
city: user_info.city,
country: united_states_country_code
}
end
|
#normalized_attributes(user_info, credential_level) ⇒ Object
23
24
25
26
27
28
29
30
31
32
33
|
# File 'lib/sign_in/idme/service.rb', line 23
def normalized_attributes(user_info, credential_level)
attributes = case type
when Constants::Auth::IDME
idme_attributes(user_info)
when Constants::Auth::DSLOGON
dslogon_attributes(user_info)
when Constants::Auth::MHV
mhv_attributes(user_info)
end
attributes.merge(standard_attributes(user_info, credential_level))
end
|
#raise_client_error(client_error, function_name) ⇒ Object
73
74
75
76
77
78
|
# File 'lib/sign_in/idme/service.rb', line 73
def raise_client_error(client_error, function_name)
status = client_error.status
description = client_error.body && client_error.body[:error_description]
raise client_error, "[SignIn][Idme][Service] Cannot perform #{function_name} request, " \
"status: #{status}, description: #{description}"
end
|
#render_auth(state: SecureRandom.hex, acr: Constants::Auth::IDME_LOA1, operation: Constants::Auth::AUTHORIZE) ⇒ Object
16
17
18
19
20
21
|
# File 'lib/sign_in/idme/service.rb', line 16
def render_auth(state: SecureRandom.hex, acr: Constants::Auth::IDME_LOA1,
operation: Constants::Auth::AUTHORIZE)
Rails.logger.info('[SignIn][Idme][Service] Rendering auth, ' \
"state: #{state}, acr: #{acr}, operation: #{operation}")
RedirectUrlGenerator.new(redirect_uri: auth_url, params_hash: auth_params(acr, state, operation)).perform
end
|
#standard_attributes(user_info, credential_level) ⇒ Object
80
81
82
83
84
85
86
87
88
89
90
91
|
# File 'lib/sign_in/idme/service.rb', line 80
def standard_attributes(user_info, credential_level)
{
idme_uuid: user_info.sub,
current_ial: credential_level.current_ial,
max_ial: credential_level.max_ial,
service_name: type,
csp_email: user_info.email,
multifactor: user_info.multifactor,
authn_context: get_authn_context(credential_level.current_ial),
auto_uplevel: credential_level.auto_uplevel
}
end
|
#token(code) ⇒ Object
35
36
37
38
39
40
41
42
43
|
# File 'lib/sign_in/idme/service.rb', line 35
def token(code)
response = perform(
:post, config.token_path, token_params(code), { 'Content-Type' => 'application/json' }
)
Rails.logger.info("[SignIn][Idme][Service] Token Success, code: #{code}, scope: #{response.body[:scope]}")
response.body
rescue Common::Client::Errors::ClientError => e
raise_client_error(e, 'Token')
end
|
#token_params(code) ⇒ Object
191
192
193
194
195
196
197
198
199
|
# File 'lib/sign_in/idme/service.rb', line 191
def token_params(code)
{
grant_type: config.grant_type,
code:,
client_id: config.client_id,
client_secret: config.client_secret,
redirect_uri: config.redirect_uri
}.to_json
end
|
#united_states_country_code ⇒ Object
151
152
153
|
# File 'lib/sign_in/idme/service.rb', line 151
def united_states_country_code
'USA'
end
|
#user_info(token) ⇒ Object
45
46
47
48
49
50
51
|
# File 'lib/sign_in/idme/service.rb', line 45
def user_info(token)
response = perform(:get, config.userinfo_path, nil, { 'Authorization' => "Bearer #{token}" })
decrypted_jwe = jwe_decrypt(JSON.parse(response.body))
jwt_decode(decrypted_jwe)
rescue Common::Client::Errors::ClientError => e
raise_client_error(e, 'UserInfo')
end
|