Class: Otto::Privacy::Config

Inherits:
Object
  • Object
show all
Includes:
Core::Freezable
Defined in:
lib/otto/privacy/config.rb

Overview

Configuration for IP privacy features

Privacy is ENABLED by default for public IPs. Private/localhost IPs are not masked.

Examples:

Default configuration (privacy enabled)

config = Otto::Privacy::Config.new
config.enabled? # => true

Configure masking level

config = Otto::Privacy::Config.new
config.octet_precision = 2  # Mask 2 octets instead of 1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Core::Freezable

#deep_freeze!

Constructor Details

#initialize(options = {}) ⇒ Config

Initialize privacy configuration

Parameters:

  • options (Hash) (defaults to: {})

    Configuration options

Options Hash (options):

  • :octet_precision (Integer)

    Number of trailing octets to mask (1 or 2, default: 1)

  • :hash_rotation_period (Integer)

    Seconds between key rotation (default: 86400)

  • :geo_enabled (Boolean)

    Enable geo-location resolution (default: true)

  • :disabled (Boolean)

    Disable privacy entirely (default: false)

  • :mask_private_ips (Boolean)

    Mask private/localhost IPs (default: false)

  • :redis (Redis)

    Optional Redis connection for multi-server environments



55
56
57
58
59
60
61
62
# File 'lib/otto/privacy/config.rb', line 55

def initialize(options = {})
  @octet_precision = options.fetch(:octet_precision, 1)
  @hash_rotation_period = options.fetch(:hash_rotation_period, 86_400) # 24 hours
  @geo_enabled = options.fetch(:geo_enabled, true)
  @disabled = options.fetch(:disabled, false) # Enabled by default (privacy-by-default)
  @mask_private_ips = options.fetch(:mask_private_ips, false) # Don't mask private/localhost by default
  @redis = options[:redis] # Optional Redis connection for multi-server environments
end

Instance Attribute Details

#disabledObject (readonly)

Returns the value of attribute disabled.



31
32
33
# File 'lib/otto/privacy/config.rb', line 31

def disabled
  @disabled
end

#geo_enabledObject

Returns the value of attribute geo_enabled.



30
31
32
# File 'lib/otto/privacy/config.rb', line 30

def geo_enabled
  @geo_enabled
end

#hash_rotation_periodObject

Returns the value of attribute hash_rotation_period.



30
31
32
# File 'lib/otto/privacy/config.rb', line 30

def hash_rotation_period
  @hash_rotation_period
end

#mask_private_ipsObject

Returns the value of attribute mask_private_ips.



30
31
32
# File 'lib/otto/privacy/config.rb', line 30

def mask_private_ips
  @mask_private_ips
end

#octet_precisionObject

Returns the value of attribute octet_precision.



30
31
32
# File 'lib/otto/privacy/config.rb', line 30

def octet_precision
  @octet_precision
end

Class Method Details

.rotation_keys_storeConcurrent::Map

Get the class-level rotation keys store

Returns:

  • (Concurrent::Map)

    Thread-safe map for rotation keys



40
41
42
43
# File 'lib/otto/privacy/config.rb', line 40

def rotation_keys_store
  @rotation_keys_store = Concurrent::Map.new unless defined?(@rotation_keys_store) && @rotation_keys_store
  @rotation_keys_store
end

Instance Method Details

#disable!self

Disable privacy (allows access to original IPs)

IMPORTANT: This should only be used when you have a specific requirement to access original IP addresses. By default, Otto provides privacy-safe masked IPs.

Returns:

  • (self)


85
86
87
88
# File 'lib/otto/privacy/config.rb', line 85

def disable!
  @disabled = true
  self
end

#disabled?Boolean

Check if privacy is disabled

Returns:

  • (Boolean)

    true if privacy was explicitly disabled



74
75
76
# File 'lib/otto/privacy/config.rb', line 74

def disabled?
  @disabled
end

#enable!self

Enable privacy (default state)

Returns:

  • (self)


93
94
95
96
# File 'lib/otto/privacy/config.rb', line 93

def enable!
  @disabled = false
  self
end

#enabled?Boolean

Check if privacy is enabled

Returns:

  • (Boolean)

    true if privacy is enabled (default)



67
68
69
# File 'lib/otto/privacy/config.rb', line 67

def enabled?
  !@disabled
end

#rotation_keyString

Get the current rotation key for IP hashing

Keys rotate at fixed intervals based on hash_rotation_period (default: 24 hours). Each rotation period gets a unique key, ensuring IP addresses hash differently across periods while remaining consistent within.

Multi-server support:

  • With Redis: Uses SET NX GET EX for atomic key generation across all servers

  • Without Redis: Falls back to in-memory Concurrent::Hash (single-server only)

Redis keys:

- rotation_key:{timestamp} - Stores the rotation key with TTL

Returns:

  • (String)

    Current rotation key for hashing



112
113
114
115
116
117
118
# File 'lib/otto/privacy/config.rb', line 112

def rotation_key
  if @redis
    rotation_key_redis
  else
    rotation_key_memory
  end
end

#validate!Object

Validate configuration settings

Raises:

  • (ArgumentError)

    if configuration is invalid



123
124
125
126
127
128
129
130
# File 'lib/otto/privacy/config.rb', line 123

def validate!
  raise ArgumentError, "octet_precision must be 1 or 2, got: #{@octet_precision}" unless [1,
                                                                                          2].include?(@octet_precision)

  return unless @hash_rotation_period < 60

  raise ArgumentError, 'hash_rotation_period must be at least 60 seconds'
end