Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/controllers/concerns/idv/phone_otp_rate_limitable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,19 @@ def reset_attempt_count_if_user_no_longer_locked_out

def handle_too_many_otp_sends
analytics.idv_phone_confirmation_otp_rate_limit_sends
# TODO: Attempts API PII phone_number: current_user.phone
attempts_api_tracker.idv_rate_limited(
limiter_type: :phone_otp,
)
handle_max_attempts('otp_requests')
end

def handle_too_many_otp_attempts
analytics.idv_phone_confirmation_otp_rate_limit_attempts
# TODO: Attempts API PII phone_number: current_user.phone
attempts_api_tracker.idv_rate_limited(
limiter_type: :phone_otp,
)
handle_max_attempts('otp_login_attempts')
end

Expand Down
20 changes: 2 additions & 18 deletions app/controllers/concerns/idv/verify_info_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,9 @@ def idv_failure(result)
)

if ssn_rate_limiter.limited?
idv_failure_log_rate_limited(:proof_ssn)
redirect_to idv_session_errors_ssn_failure_url
rate_limit_redirect!(:proof_ssn, step_name: STEP_NAME)
elsif resolution_rate_limiter.limited?
idv_failure_log_rate_limited(:idv_resolution)
redirect_to rate_limited_url
rate_limit_redirect!(:idv_resolution, step_name: STEP_NAME)
elsif has_exception && is_mva_exception
idv_failure_log_warning
redirect_to state_id_warning_url
Expand All @@ -147,20 +145,6 @@ def idv_failure(result)
end
end

def idv_failure_log_rate_limited(rate_limit_type)
if rate_limit_type == :proof_ssn
analytics.rate_limit_reached(
limiter_type: :proof_ssn,
step_name: STEP_NAME,
)
elsif rate_limit_type == :idv_resolution
analytics.rate_limit_reached(
limiter_type: :idv_resolution,
step_name: STEP_NAME,
)
end
end

def idv_failure_log_error
analytics.idv_doc_auth_exception_visited(
step_name: STEP_NAME,
Expand Down
8 changes: 6 additions & 2 deletions app/controllers/concerns/rate_limit_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def confirm_not_rate_limited_after_doc_auth
end

def confirm_not_rate_limited_for_phone_address_verification
# TODO: Attempts API PII add phone number
if idv_attempter_rate_limited?(:proof_address)
rate_limit_redirect!(:proof_address)
return true
Expand All @@ -44,12 +45,15 @@ def confirm_not_rate_limited_for_phone_and_letter_address_verification
if idv_attempter_rate_limited?(:proof_address) && gpo_verify_by_mail_policy.rate_limited?
rate_limit_redirect!(:proof_address)
return true
elsif idv_attempter_rate_limited?(:proof_address) || gpo_verify_by_mail_policy.rate_limited?
attempts_api_tracker.idv_rate_limited(limiter_type: :proof_address)
end
end

def rate_limit_redirect!(rate_limit_type)
def rate_limit_redirect!(rate_limit_type, step_name: nil)
if idv_attempter_rate_limited?(rate_limit_type)
analytics.rate_limit_reached(limiter_type: rate_limit_type)
analytics.rate_limit_reached(limiter_type: rate_limit_type, step_name:)
attempts_api_tracker.idv_rate_limited(limiter_type: rate_limit_type)
rate_limited_redirect(rate_limit_type)
return true
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ def index
analytics.rate_limit_reached(
limiter_type: :verify_gpo_key,
)
attempts_api_tracker.idv_rate_limited(
limiter_type: :verify_gpo_key,
)

@expires_at = rate_limiter.expires_at
end
Expand Down
4 changes: 4 additions & 0 deletions app/controllers/idv/hybrid_handoff_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ def rate_limited_failure
analytics.rate_limit_reached(
limiter_type: :idv_send_link,
)
# TODO: Attempts API PII Add phone_number: formatted_destination_phone,
attempts_api_tracker.idv_rate_limited(
limiter_type: :idv_send_link,
)
message = I18n.t(
'doc_auth.errors.send_link_limited',
timeout: distance_of_time_in_words(
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/idv/image_uploads_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ def image_upload_form
@image_upload_form ||= Idv::ApiImageUploadForm.new(
params,
acuant_sdk_upgrade_ab_test_bucket: ab_test_bucket(:ACUANT_SDK),
analytics:,
attempts_api_tracker:,
service_provider: current_sp,
analytics: analytics,
uuid_prefix: current_sp&.app_id,
liveness_checking_required: resolved_authn_context_result.facial_match?,
)
Expand Down
5 changes: 3 additions & 2 deletions app/controllers/idv/phone_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,10 @@ def handle_proofing_failure

def step
@step ||= Idv::PhoneStep.new(
idv_session: idv_session,
idv_session:,
trace_id: amzn_trace_id,
analytics: analytics,
analytics:,
attempts_api_tracker:,
)
end

Expand Down
13 changes: 11 additions & 2 deletions app/forms/idv/api_image_upload_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ def initialize(
service_provider:,
acuant_sdk_upgrade_ab_test_bucket:,
analytics: nil,
attempts_api_tracker: nil,
uuid_prefix: nil,
liveness_checking_required: false
)
@params = params
@service_provider = service_provider
@acuant_sdk_upgrade_ab_test_bucket = acuant_sdk_upgrade_ab_test_bucket
@analytics = analytics
@attempts_api_tracker = attempts_api_tracker
@readable = {}
@uuid_prefix = uuid_prefix
@liveness_checking_required = liveness_checking_required
Expand Down Expand Up @@ -70,8 +72,14 @@ def submit

private

attr_reader :params, :analytics, :service_provider, :form_response, :uuid_prefix,
:liveness_checking_required, :acuant_sdk_upgrade_ab_test_bucket
attr_reader :acuant_sdk_upgrade_ab_test_bucket,
:analytics,
:attempts_api_tracker,
:form_response,
:liveness_checking_required,
:params,
:service_provider,
:uuid_prefix

def abandon_any_ipp_progress
user_id && User.find(user_id).establishing_in_person_enrollment&.cancel
Expand Down Expand Up @@ -358,6 +366,7 @@ def limit_if_rate_limited

def track_rate_limited
analytics.rate_limit_reached(limiter_type: :idv_doc_auth)
attempts_api_tracker.idv_rate_limited(limiter_type: :idv_doc_auth)
end

def document_capture_session_uuid
Expand Down
11 changes: 11 additions & 0 deletions app/services/attempts_api/tracker_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ def idv_reproof
track_event('idv-reproof')
end

# The user has exceeded the rate limit during idv document upload
# @param limiter_type [String<'idv_doc_auth', 'idv_resolution', 'proof_ssn', 'proof_address',
# 'confirmation', 'idv_send_link']
# Type of rate limit
def idv_rate_limited(limiter_type:)
track_event(
'idv-rate-limited',
limiter_type:,
)
end

# @param [Boolean] success True if account successfully deleted
# A User deletes their Login.gov account
def logged_in_account_purged(success:)
Expand Down
6 changes: 5 additions & 1 deletion app/services/idv/phone_step.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

module Idv
class PhoneStep
def initialize(idv_session:, trace_id:, analytics:)
def initialize(idv_session:, trace_id:, analytics:, attempts_api_tracker:)
self.idv_session = idv_session
@trace_id = trace_id
@analytics = analytics
@attempts_api_tracker = attempts_api_tracker
end

def submit(step_params)
Expand Down Expand Up @@ -122,6 +123,9 @@ def rate_limiter

def rate_limited_result
@analytics.rate_limit_reached(limiter_type: :proof_address, step_name: :phone)
@attempts_api_tracker.idv_rate_limited(
limiter_type: :proof_address,
)
FormResponse.new(success: false)
end

Expand Down
12 changes: 2 additions & 10 deletions docs/attempts-api/schemas/events/IdentityProofingEvents.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ properties:
$ref: './identity-proofing/IdvDocumentUploaded.yml'
idv-document-upload-submitted:
$ref: './identity-proofing/IdvDocumentUploadSubmitted.yml'
idv-document-upload-rate-limited:
$ref: './identity-proofing/IdvDocumentUploadRateLimited.yml'
idv-enrollment-complete:
$ref: './identity-proofing/IdvEnrollmentComplete.yml'
idv-ipp-ready-to-verify-visit:
Expand All @@ -15,14 +13,10 @@ properties:
$ref: './identity-proofing/IdvPhoneOtpSent.yml'
idv-phone-otp-submitted:
$ref: './identity-proofing/IdvPhoneOtpSubmitted.yml'
idv-phone-otp-submitted-rate-limited:
$ref: './identity-proofing/IdvPhoneOtpSubmittedRateLimited.yml'
idv-phone-otp-sent-rate-limited:
$ref: './identity-proofing/IdvPhoneOtpSentRateLimited.yml'
idv-phone-send-link-rate-limited:
$ref: './identity-proofing/IdvPhoneSendLinkRateLimited.yml'
idv-phone-submitted:
$ref: './identity-proofing/IdvPhoneSubmitted.yml'
idv-rate-limited:
$ref: './identity-proofing/IdvRateLimited.yml'
idv-reproof:
$ref: './identity-proofing/IdvReproof.yml'
idv-ssn-submitted:
Expand All @@ -31,8 +25,6 @@ properties:
$ref: './identity-proofing/IdvTmxFraudCheck.yml'
idv-verification-submitted:
$ref: './identity-proofing/IdvVerificationSubmitted.yml'
idv-verification-rate-limited:
$ref: './identity-proofing/IdvVerificationRateLimited.yml'
idv-verify-by-mail-letter-requested:
$ref: './identity-proofing/IdvVerifyByMailLetterRequested.yml'
idv-verify-by-mail-enter-code-submitted:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,39 @@ allOf:
- type: object
properties:
address:
type: string
type: string
address_edited:
type: boolean
description: |
True if updated address does not match document address
failure_reason:
type: object
description: |
An OPTIONAL object. An associative array of attributes and errors if success is false
properties:
state:
type: string
description: An OPTIONAL key if the code does not match
enum:
- blank
zipcode:
type: string
enum:
- pattern_mismatch
city:
type: string
enum:
- blank
address1:
type: string
enum:
- blank
- too_long
address2:
type: string
enum:
- too_long
success:
type: boolean
description: |
Indicates whether the entered code matched the code that was sent confirming the address

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
description: |
The user reaches verification submission rate limits when identity proofing.
allOf:
- $ref: '../shared/EventProperties.yml'
- type: object
properties:
rate_limit_type:
type: string
description: |
Reason for the rate limiting
enum:
- idv_doc_auth
- idv_resolution
- proof_ssn
- proof_address
- phone_confirmation
- idv_send_link
phone:
type: string
description: |
OPTIONAL, the provided phone number (in the event of a phone-related rate limiting)

This file was deleted.

20 changes: 20 additions & 0 deletions spec/controllers/concerns/idv/phone_otp_rate_limitable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,32 @@ def handle_max_attempts(_arg = nil)
describe '#handle_too_many_otp_sends' do
before do
stub_analytics
stub_attempts_tracker
end

it 'calls analytics tracking event' do
expect(@attempts_api_tracker).to receive(:idv_rate_limited).with(
limiter_type: :phone_otp,
)
subject.handle_too_many_otp_sends

expect(@analytics).to have_logged_event('Idv: Phone OTP sends rate limited')
end
end

describe '#handle_too_many_otp_attempts' do
before do
stub_analytics
stub_attempts_tracker
end

it 'calls analytics tracking event' do
expect(@attempts_api_tracker).to receive(:idv_rate_limited).with(
limiter_type: :phone_otp,
)
subject.handle_too_many_otp_attempts

expect(@analytics).to have_logged_event('Idv: Phone OTP attempts rate limited')
end
end
end
Loading