Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update biometric comparison language #11296

Merged
merged 13 commits into from
Oct 1, 2024
2 changes: 1 addition & 1 deletion app/controllers/concerns/idv/document_capture_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def stored_result
end

def selfie_requirement_met?
!resolved_authn_context_result.biometric_comparison? ||
!resolved_authn_context_result.facial_match? ||
stored_result.selfie_check_performed?
end

Expand Down
8 changes: 4 additions & 4 deletions app/controllers/concerns/idv_session_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def hybrid_session?
end

def idv_needed?
user_needs_biometric_comparison? ||
user_needs_facial_match? ||
idv_session_user.active_profile.blank? ||
decorated_sp_session.requested_more_recent_verification?
end
Expand Down Expand Up @@ -59,8 +59,8 @@ def idv_session_user
current_user
end

def user_needs_biometric_comparison?
resolved_authn_context_result.biometric_comparison? &&
!idv_session_user.identity_verified_with_biometric_comparison?
def user_needs_facial_match?
resolved_authn_context_result.facial_match? &&
!idv_session_user.identity_verified_with_facial_match?
end
end
2 changes: 1 addition & 1 deletion app/controllers/concerns/idv_step_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def flow_policy

def confirm_step_allowed
# set it everytime, since user may switch SP
idv_session.selfie_check_required = resolved_authn_context_result.biometric_comparison?
idv_session.selfie_check_required = resolved_authn_context_result.facial_match?
return if flow_policy.controller_allowed?(controller: self.class)

redirect_to url_for_latest_step
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/idv/document_capture_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def extra_view_variables
skip_doc_auth_from_how_to_verify: idv_session.skip_doc_auth_from_how_to_verify,
skip_doc_auth_from_handoff: idv_session.skip_doc_auth_from_handoff,
opted_in_to_in_person_proofing: idv_session.opted_in_to_in_person_proofing,
doc_auth_selfie_capture: resolved_authn_context_result.biometric_comparison?,
doc_auth_selfie_capture: resolved_authn_context_result.facial_match?,
}.merge(
acuant_sdk_upgrade_a_b_testing_variables,
)
Expand Down Expand Up @@ -100,8 +100,8 @@ def analytics_arguments
analytics_id: 'Doc Auth',
redo_document_capture: idv_session.redo_document_capture,
skip_hybrid_handoff: idv_session.skip_hybrid_handoff,
liveness_checking_required: resolved_authn_context_result.biometric_comparison?,
selfie_check_required: resolved_authn_context_result.biometric_comparison?,
liveness_checking_required: resolved_authn_context_result.facial_match?,
selfie_check_required: resolved_authn_context_result.facial_match?,
}.merge(ab_test_analytics_buckets)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def analytics_arguments
flow_path: 'hybrid',
step: 'capture_complete',
analytics_id: 'Doc Auth',
liveness_checking_required: resolved_authn_context_result.biometric_comparison?,
liveness_checking_required: resolved_authn_context_result.facial_match?,
}.merge(ab_test_analytics_buckets)
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def extra_view_variables
mock_client: doc_auth_vendor == 'mock',
document_capture_session_uuid: document_capture_session_uuid,
failure_to_proof_url: return_to_sp_failure_to_proof_url(step: 'document_capture'),
doc_auth_selfie_capture: resolved_authn_context_result.biometric_comparison?,
doc_auth_selfie_capture: resolved_authn_context_result.facial_match?,
}.merge(
acuant_sdk_upgrade_a_b_testing_variables,
)
Expand All @@ -58,8 +58,8 @@ def analytics_arguments
flow_path: 'hybrid',
step: 'document_capture',
analytics_id: 'Doc Auth',
liveness_checking_required: resolved_authn_context_result.biometric_comparison?,
selfie_check_required: resolved_authn_context_result.biometric_comparison?,
liveness_checking_required: resolved_authn_context_result.facial_match?,
selfie_check_required: resolved_authn_context_result.facial_match?,
}.merge(
ab_test_analytics_buckets,
)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/idv/image_uploads_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def image_upload_form
service_provider: current_sp,
analytics: analytics,
uuid_prefix: current_sp&.app_id,
liveness_checking_required: resolved_authn_context_result.biometric_comparison?,
liveness_checking_required: resolved_authn_context_result.facial_match?,
)
end
end
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/idv_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ def activated
private

def already_verified?
if resolved_authn_context_result.biometric_comparison?
current_user.identity_verified_with_biometric_comparison?
if resolved_authn_context_result.facial_match?
current_user.identity_verified_with_facial_match?
else
current_user.active_profile.present?
end
Expand Down
8 changes: 4 additions & 4 deletions app/controllers/openid_connect/authorization_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def index
return redirect_to reactivate_account_url if user_needs_to_reactivate_account?
return redirect_to url_for_pending_profile_reason if user_has_pending_profile?
return redirect_to idv_url if identity_needs_verification?
return redirect_to idv_url if biometric_comparison_needed?
return redirect_to idv_url if facial_match_needed?
end
return redirect_to sign_up_completed_url if needs_completion_screen_reason
link_identity_to_service_provider
Expand Down Expand Up @@ -140,9 +140,9 @@ def identity_needs_verification?
decorated_sp_session.requested_more_recent_verification?)
end

def biometric_comparison_needed?
resolved_authn_context_result.biometric_comparison? &&
!current_user.identity_verified_with_biometric_comparison?
def facial_match_needed?
resolved_authn_context_result.facial_match? &&
!current_user.identity_verified_with_facial_match?
end

def build_authorize_form_from_params
Expand Down
8 changes: 4 additions & 4 deletions app/controllers/saml_idp_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def auth
return redirect_to reactivate_account_url if user_needs_to_reactivate_account?
return redirect_to url_for_pending_profile_reason if user_has_pending_profile?
return redirect_to idv_url if identity_needs_verification?
return redirect_to idv_url if biometric_comparison_needed?
return redirect_to idv_url if facial_match_needed?
end
return redirect_to sign_up_completed_url if needs_completion_screen_reason
if auth_count == 1 && first_visit_for_sp?
Expand Down Expand Up @@ -113,9 +113,9 @@ def prompt_for_password_if_ial2_request_and_pii_locked
redirect_to capture_password_url
end

def biometric_comparison_needed?
resolved_authn_context_result.biometric_comparison? &&
!current_user.identity_verified_with_biometric_comparison?
def facial_match_needed?
resolved_authn_context_result.facial_match? &&
!current_user.identity_verified_with_facial_match?
end

def set_devise_failure_redirect_for_concurrent_session_logout
Expand Down
6 changes: 3 additions & 3 deletions app/forms/openid_connect_authorize_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ def scopes
def validate_privileges
if (identity_proofing_requested? && !identity_proofing_service_provider?) ||
(ialmax_requested? && !ialmax_allowed_for_sp?) ||
(biometric_ial_requested? && !service_provider.biometric_ial_allowed?) ||
(facial_match_ial_requested? && !service_provider.facial_match_ial_allowed?) ||
(semantic_authn_contexts_requested? && !service_provider.semantic_authn_contexts_allowed?)
errors.add(
:acr_values, t('openid_connect.authorization.errors.no_auth'),
Expand Down Expand Up @@ -351,8 +351,8 @@ def ialmax_requested?
Saml::Idp::Constants::AUTHN_CONTEXT_CLASSREF_TO_IAL[ial_values.sort.max] == 0
end

def biometric_ial_requested?
ial_values.any? { |ial| Saml::Idp::Constants::BIOMETRIC_IAL_CONTEXTS.include? ial }
def facial_match_ial_requested?
ial_values.any? { |ial| Saml::Idp::Constants::FACIAL_MATCH_IAL_CONTEXTS.include? ial }
end

def highest_level_aal(aal_values)
Expand Down
2 changes: 1 addition & 1 deletion app/models/anonymous_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def locked_out?
second_factor_locked_at.present? && !lockout_period_expired?
end

def identity_verified_with_biometric_comparison?
def identity_verified_with_facial_match?
false
end

Expand Down
10 changes: 5 additions & 5 deletions app/models/profile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def activate(reason_deactivated: nil)
now = Time.zone.now
profile_to_deactivate = Profile.find_by(user_id: user_id, active: true)
is_reproof = profile_to_deactivate.present?
is_biometric_upgrade = is_reproof && biometric? && !profile_to_deactivate.biometric?
is_facial_match_upgrade = is_reproof && facial_match? && !profile_to_deactivate.facial_match?

attrs = {
active: true,
Expand All @@ -107,7 +107,7 @@ def activate(reason_deactivated: nil)
Profile.where(user_id: user_id).update_all(active: false)
update!(attrs)
end
track_biometric_reproof if is_biometric_upgrade
track_facial_match_reproof if is_facial_match_upgrade
send_push_notifications if is_reproof
end
# rubocop:enable Rails/SkipsModelValidations
Expand Down Expand Up @@ -309,8 +309,8 @@ def profile_age_in_seconds
(Time.zone.now - created_at).round
end

def biometric?
::User::BIOMETRIC_COMPARISON_IDV_LEVELS.include?(idv_level)
def facial_match?
::User::FACIAL_MATCH_IDV_LEVELS.include?(idv_level)
end

private
Expand Down Expand Up @@ -341,7 +341,7 @@ def send_push_notifications
PushNotification::HttpPush.deliver(event)
end

def track_biometric_reproof
def track_facial_match_reproof
SpUpgradedBiometricProfile.create(
user: user,
upgraded_at: Time.zone.now,
Expand Down
2 changes: 1 addition & 1 deletion app/models/service_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def ialmax_allowed?
IdentityConfig.store.allowed_ialmax_providers.include?(issuer)
end

def biometric_ial_allowed?
def facial_match_ial_allowed?
IdentityConfig.store.biometric_ial_enabled &&
IdentityConfig.store.allowed_biometric_ial_providers.include?(issuer)
end
Expand Down
6 changes: 3 additions & 3 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class User < ApplicationRecord
MAX_RECENT_EVENTS = 5
MAX_RECENT_DEVICES = 5

BIOMETRIC_COMPARISON_IDV_LEVELS = %w[unsupervised_with_selfie in_person].to_set.freeze
FACIAL_MATCH_IDV_LEVELS = %w[unsupervised_with_selfie in_person].to_set.freeze

enum otp_delivery_preference: { sms: 0, voice: 1 }

Expand Down Expand Up @@ -376,8 +376,8 @@ def identity_verified?
active_profile.present?
end

def identity_verified_with_biometric_comparison?
BIOMETRIC_COMPARISON_IDV_LEVELS.include?(active_profile&.idv_level)
def identity_verified_with_facial_match?
FACIAL_MATCH_IDV_LEVELS.include?(active_profile&.idv_level)
Comment on lines +379 to +380
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just while I'm here, maybe for a future PR, wondering if if we could have moved this constant to the Profile class, and then delegate via something like active_profile&.verified_with_facial_match?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i added it as a task -- will take care of this in a future PR!

end

# This user's most recently activated profile that has also been deactivated
Expand Down
10 changes: 5 additions & 5 deletions app/policies/pending_profile_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def initialize(user:, resolved_authn_context_result:)
def user_has_pending_profile?
return false if user.blank?

if biometric_comparison_requested?
pending_biometric_profile?
if facial_match_requested?
pending_facial_match_profile?
else
pending_legacy_profile? || fraud_review_pending?
end
Expand All @@ -20,12 +20,12 @@ def user_has_pending_profile?

attr_reader :user, :resolved_authn_context_result

def pending_biometric_profile?
def pending_facial_match_profile?
user.pending_profile&.idv_level == 'unsupervised_with_selfie'
end

def biometric_comparison_requested?
resolved_authn_context_result.biometric_comparison?
def facial_match_requested?
resolved_authn_context_result.facial_match?
end

def pending_legacy_profile?
Expand Down
6 changes: 3 additions & 3 deletions app/presenters/account_show_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class AccountShowPresenter
:authn_context,
:sp_name

delegate :identity_verified_with_biometric_comparison?, to: :user
delegate :identity_verified_with_facial_match?, to: :user

def initialize(
decrypted_pii:,
Expand Down Expand Up @@ -54,7 +54,7 @@ def active_profile_for_authn_context?
return @active_profile_for_authn_context if defined?(@active_profile_for_authn_context)

@active_profile_for_authn_context = active_profile? && (
!authn_context.biometric_comparison? || identity_verified_with_biometric_comparison?
!authn_context.facial_match? || identity_verified_with_facial_match?
)
end

Expand All @@ -78,7 +78,7 @@ def formatted_ipp_due_date
I18n.l(user.pending_in_person_enrollment.due_date, format: :event_date)
end

def formatted_nonbiometric_idv_date
def formatted_legacy_idv_date
I18n.l(user.active_profile.created_at, format: :event_date)
end

Expand Down
4 changes: 0 additions & 4 deletions app/presenters/idv/welcome_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ def title
t('doc_auth.headings.welcome', sp_name: sp_name)
end

def selfie_required?
decorated_sp_session.biometric_comparison_required?
end

def explanation_text(help_link)
if first_time_idv?
t(
Expand Down
32 changes: 16 additions & 16 deletions app/services/authn_context_resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def asserted_ial_acr
return resolve_acr(Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF) unless
user&.identity_verified?

if result.biometric_comparison?
if result.facial_match?
resolve_acr(Saml::Idp::Constants::IAL2_BIO_REQUIRED_AUTHN_CONTEXT_CLASSREF)
elsif result.identity_proofing? ||
result.ialmax?
Expand All @@ -35,10 +35,10 @@ def asserted_ial_acr
private

def selected_vtr_parser_result_from_vtr_list
if biometric_proofing_vot.present? && user&.identity_verified_with_biometric_comparison?
biometric_proofing_vot
elsif non_biometric_identity_proofing_vot.present? && user&.identity_verified?
non_biometric_identity_proofing_vot
if facial_match_proofing_vot.present? && user&.identity_verified_with_facial_match?
facial_match_proofing_vot
elsif non_facial_match_identity_proofing_vot.present? && user&.identity_verified?
non_facial_match_identity_proofing_vot
elsif no_identity_proofing_vot.present?
no_identity_proofing_vot
else
Expand All @@ -52,13 +52,13 @@ def parsed_vectors_of_trust
end
end

def biometric_proofing_vot
parsed_vectors_of_trust.find(&:biometric_comparison?)
def facial_match_proofing_vot
parsed_vectors_of_trust.find(&:facial_match?)
end

def non_biometric_identity_proofing_vot
def non_facial_match_identity_proofing_vot
parsed_vectors_of_trust.find do |vot_parser_result|
vot_parser_result.identity_proofing? && !vot_parser_result.biometric_comparison?
vot_parser_result.identity_proofing? && !vot_parser_result.facial_match?
end
end

Expand Down Expand Up @@ -99,15 +99,15 @@ def result_with_sp_aal_defaults(result)
end

def decorate_acr_result_with_user_context(result)
return result unless result.biometric_comparison?
return result unless result.facial_match?

return result if user&.identity_verified_with_biometric_comparison? ||
biometric_is_required?(result)
return result if user&.identity_verified_with_facial_match? ||
facial_match_is_required?(result)

if user&.identity_verified?
result.with(biometric_comparison?: false, two_pieces_of_fair_evidence?: false)
result.with(facial_match?: false, two_pieces_of_fair_evidence?: false)
else
result.with(biometric_comparison?: true)
result.with(facial_match?: true)
end
end

Expand Down Expand Up @@ -139,8 +139,8 @@ def resolve_acr(acr)
Saml::Idp::Constants::LEGACY_ACRS_TO_SEMANTIC_ACRS.fetch(acr, default_value: acr)
end

def biometric_is_required?(result)
Saml::Idp::Constants::BIOMETRIC_REQUIRED_IAL_CONTEXTS.intersect?(result.component_names)
def facial_match_is_required?(result)
Saml::Idp::Constants::FACIAL_MATCH_REQUIRED_IAL_CONTEXTS.intersect?(result.component_names)
end

def use_semantic_authn_contexts?
Expand Down
2 changes: 1 addition & 1 deletion app/services/id_token_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def timestamp_claims
def acr
return nil unless identity.acr_values.present?

if resolved_authn_context_result.biometric_comparison?
if resolved_authn_context_result.facial_match?
Vot::AcrComponentValues::IAL2_BIO_REQUIRED.name
elsif resolved_authn_context_result.ialmax?
determine_ial_max_acr.name
Expand Down
Loading