Module: Reputable::Rails::ControllerHelpers

Extended by:
ActiveSupport::Concern
Defined in:
lib/reputable/rails.rb

Overview

Helper methods for controllers

Instance Method Summary collapse

Instance Method Details

#block_current_ip(reason:, **metadata) ⇒ Object

Block the current IP



84
85
86
87
88
89
90
# File 'lib/reputable/rails.rb', line 84

def block_current_ip(reason:, **)
  Reputable::Reputation.block_ip(
    request.remote_ip,
    reason: reason,
    **
  )
end

#challenge_current_ip(reason:, **metadata) ⇒ Object

Challenge the current IP



75
76
77
78
79
80
81
# File 'lib/reputable/rails.rb', line 75

def challenge_current_ip(reason:, **)
  Reputable::Reputation.challenge_ip(
    request.remote_ip,
    reason: reason,
    **
  )
end

#clear_reputable_verification!(session_key: :reputable_verified_at) ⇒ Object

Clear verification status for the current session

Parameters:

  • session_key (Symbol) (defaults to: :reputable_verified_at)


174
175
176
# File 'lib/reputable/rails.rb', line 174

def clear_reputable_verification!(session_key: :reputable_verified_at)
  session.delete(session_key)
end

#current_ip_blocked?Boolean

Check if current IP is blocked

Returns:

  • (Boolean)


104
105
106
# File 'lib/reputable/rails.rb', line 104

def current_ip_blocked?
  Reputable::Reputation.blocked_ip?(request.remote_ip)
end

#current_ip_challenged?Boolean

Check if current IP should be challenged

Returns:

  • (Boolean)


110
111
112
# File 'lib/reputable/rails.rb', line 110

def current_ip_challenged?
  Reputable::Reputation.challenged_ip?(request.remote_ip)
end

#current_ip_reputationHash?

Get full reputation data for current IP

Returns:

  • (Hash, nil)


116
117
118
# File 'lib/reputable/rails.rb', line 116

def current_ip_reputation
  Reputable::Reputation.lookup(:ip, request.remote_ip)
end

#current_ip_statusString?

Get reputation status for current IP

Returns:

  • (String, nil)


122
123
124
# File 'lib/reputable/rails.rb', line 122

def current_ip_status
  Reputable::Reputation.lookup_ip(request.remote_ip)
end

#current_ip_trusted?Boolean

Check if current IP is trusted

Returns:

  • (Boolean)


98
99
100
# File 'lib/reputable/rails.rb', line 98

def current_ip_trusted?
  Reputable::Reputation.trusted_ip?(request.remote_ip)
end

#render_reputable_blocked_page(status: 403, site_name: nil, support_email: nil, support_url: nil, heading: "Access blocked", message: nil, show_ip: true) ⇒ Object

Render the standard blocked page



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/reputable/rails.rb', line 142

def render_reputable_blocked_page(
  status: 403,
  site_name: nil,
  support_email: nil,
  support_url: nil,
  heading: "Access blocked",
  message: nil,
  show_ip: true
)
  config = Reputable.configuration
  html = Reputable::BlockedPage.html(
    site_name: site_name || config.site_name,
    support_email: support_email || config.support_email,
    support_url: support_url || config.support_url,
    client_ip: request.remote_ip,
    heading: heading,
    message: message,
    show_ip: show_ip
  )

  render html: html.html_safe, status: status, content_type: "text/html"
end

#reputable_ignore_analytics?Boolean

Check if analytics should be ignored for this request Uses middleware-populated flag when available, falls back to lookup.

Returns:

  • (Boolean)


128
129
130
131
132
133
134
135
# File 'lib/reputable/rails.rb', line 128

def reputable_ignore_analytics?
  value = request.env["reputable.ignore_analytics"]
  return value unless value.nil?

  current_ip_status == "untrusted_ignore"
rescue StandardError
  false
end

#reputable_verified?(session_key: :reputable_verified_at) ⇒ Boolean

Check if the current session has already passed verification

Parameters:

  • session_key (Symbol) (defaults to: :reputable_verified_at)

Returns:

  • (Boolean)


168
169
170
# File 'lib/reputable/rails.rb', line 168

def reputable_verified?(session_key: :reputable_verified_at)
  session[session_key].present?
end

#require_reputable_reputation!(return_url: request.original_url, failure_url: nil, session_id: session.id, force_challenge: false, session_key: :reputable_verified_at, blocked_status: 403, blocked_site_name: nil, blocked_support_email: nil, blocked_support_url: nil, blocked_heading: "Access blocked", blocked_message: nil, blocked_show_ip: true) ⇒ Object

Enforce reputation-based access control.

  • If IP is blocked, render a blocked page.
  • If IP is challenged, run verification flow.


234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/reputable/rails.rb', line 234

def require_reputable_reputation!(
  return_url: request.original_url,
  failure_url: nil,
  session_id: session.id,
  force_challenge: false,
  session_key: :reputable_verified_at,
  blocked_status: 403,
  blocked_site_name: nil,
  blocked_support_email: nil,
  blocked_support_url: nil,
  blocked_heading: "Access blocked",
  blocked_message: nil,
  blocked_show_ip: true
)
  # Skip all gating when circuit is open — the Reputable server is likely unreachable
  return unless Reputable.operational?

  if current_ip_blocked?
    render_reputable_blocked_page(
      status: blocked_status,
      site_name: blocked_site_name,
      support_email: blocked_support_email,
      support_url: blocked_support_url,
      heading: blocked_heading,
      message: blocked_message,
      show_ip: blocked_show_ip
    )
    return
  end

  return unless current_ip_challenged?

  require_reputable_verification!(
    return_url: return_url,
    failure_url: failure_url,
    session_id: session_id,
    force_challenge: force_challenge,
    session_key: session_key
  )
end

#require_reputable_verification!(return_url: request.original_url, failure_url: nil, session_id: session.id, force_challenge: false, session_key: :reputable_verified_at) ⇒ Object

Enforce verification redirect flow.

  • If already verified in this session, returns immediately.
  • If returning with signature, validates and marks session.
  • Otherwise redirects to verification URL.

Parameters:

  • return_url (String) (defaults to: request.original_url)

    URL to return to after verification

  • failure_url (String) (defaults to: nil)

    URL to return to on failure/invalid token

  • session_id (String) (defaults to: session.id)

    Optional session id to link

  • force_challenge (Boolean) (defaults to: false)

    Force challenge even if trusted

  • session_key (Symbol) (defaults to: :reputable_verified_at)

    Session key used to store verified state



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/reputable/rails.rb', line 188

def require_reputable_verification!(
  return_url: request.original_url,
  failure_url: nil,
  session_id: session.id,
  force_challenge: false,
  session_key: :reputable_verified_at
)
  return if reputable_verified?(session_key: session_key)

  # Skip redirect when circuit is open — the Reputable server is likely unreachable
  return unless Reputable.operational?

  # Check for new format (reputable_s) or legacy format (reputable_signature)
  if params[:reputable_s] || params[:reputable_signature]
    if Reputable.verify_redirect_return(params)
      # For new format, decode payload to get status
      # For legacy format, use reputable_status directly
      status = if params[:reputable_r]
        decoded = Reputable.decode_reputable_response(params)
        decoded&.dig("status")
      else
        params[:reputable_status]
      end

      if status == "pass"
        session[session_key] = Time.now.to_i
        return
      end

      redirect_to failure_url and return
    else
      render plain: "Verification failed", status: 403 and return
    end
  end

  redirect_to reputable_verification_url(
    return_url: return_url,
    failure_url: failure_url,
    session_id: session_id,
    force_challenge: force_challenge
  ) and return
end

#track_reputable_request(tags: [], **options) ⇒ Object

Track the current request with optional extra tags



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/reputable/rails.rb', line 15

def track_reputable_request(tags: [], **options)
  Reputable::Tracker.track_request(
    ip: request.remote_ip,
    path: request.path,
    query: request.query_string,
    method: request.method,
    user_agent: request.user_agent,
    referer: request.referer,
    tags: tags,
    **options
  )
end

#track_reputable_security_event(event_type:, outcome: nil, reason_code: nil, account_id: nil, user_id: nil, context: {}, resource: nil, metadata: {}, **options) ⇒ Object

Track a trusted backend security event for user/account profiling.



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
# File 'lib/reputable/rails.rb', line 29

def track_reputable_security_event(
  event_type:,
  outcome: nil,
  reason_code: nil,
  account_id: nil,
  user_id: nil,
  context: {},
  resource: nil,
  metadata: {},
  **options
)
  base_context = {
    ip: request.remote_ip
  }.merge(context || {})

  Reputable::Tracker.track_security_event(
    event_type: event_type,
    ip: request.remote_ip,
    path: request.path,
    outcome: outcome,
    reason_code: reason_code,
    account_id: ,
    user_id: user_id,
    session_id: options[:session_id] || session.id,
    request_id: options[:request_id] || request.request_id,
    user_agent: request.user_agent,
    referer: request.referer,
    context: base_context,
    resource: resource,
    metadata: ,
    **options
  )
end

#trust_current_ip(reason:, status: :trusted_behavior, ttl: nil, **metadata) ⇒ Object

Trust the current user's IP (behavioral by default, verified optional)



64
65
66
67
68
69
70
71
72
# File 'lib/reputable/rails.rb', line 64

def trust_current_ip(reason:, status: :trusted_behavior, ttl: nil, **)
  Reputable::Reputation.trust_ip(
    request.remote_ip,
    reason: reason,
    status: status,
    ttl: ttl,
    **
  )
end