-
Notifications
You must be signed in to change notification settings - Fork 7
/
set_gdpr_data.rb
133 lines (118 loc) · 2.95 KB
/
set_gdpr_data.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
require 'net/http'
module SetGdprData
class GdprSessionData
def initialize(session)
@session = session
end
def ip
@session[:gdpr].try(:[],1..-1)
end
def status
raw_value = @session[:gdpr]
return :unknown if raw_value.blank?
case raw_value[0]
when 'i'
return :inside_gdpr
when 'o'
return :outside_gdpr
else
raise "Session GDPR status is improperly formatted"
end
end
def set(ip:, status:)
case status
when :unknown
@session.delete(:gdpr)
when :inside_gdpr
@session[:gdpr] = "i#{ip}"
when :outside_gdpr
@session[:gdpr] = "o#{ip}"
else
raise "Invalid GDPR status: #{status}"
end
end
end
def self.call(user:, session:, ip:)
gdpr_data = GdprSessionData.new(session)
if ip == gdpr_data.ip
# No need to lookup the location, it is already available in the session
status = gdpr_data.status
else
country_code = country_code(ip: ip)
status =
case country_code
when nil
:unknown
when *GDPR_COUNTRY_CODES
:inside_gdpr
else
:outside_gdpr
end
gdpr_data.set(ip: ip, status: status)
end
user.is_not_gdpr_location = :outside_gdpr == status
end
def self.country_code(ip:)
uri = URI("https://pro.ip-api.com/json/#{ip}?key=#{Rails.application.secrets.ip_api_key}")
begin
Net::HTTP.start(uri.host, uri.port, use_ssl: true, read_timeout: LOOKUP_TIMEOUT) do |http|
response = Net::HTTP.get_response uri
body = JSON.parse(response.body)
if body["status"] == "success"
return body["countryCode"]
else
Raven.capture_message("Failed IP address location lookup", extra: body)
return nil
end
end
rescue Net::ReadTimeout => ee
Raven.capture_message("IP address location lookup timed out")
return nil
rescue => ee
# We don't want explosions here to trickle out and impact callers
Raven.capture_exception(ee)
return nil
end
end
LOOKUP_TIMEOUT = 1
GDPR_COUNTRY_CODES = [
'AT', # Austria
'BE', # Belgium
'BG', # Bulgaria
'HR', # Croatia
'CY', # Cyprus
'CZ', # Czech Republic
'DK', # Denmark
'EE', # Estonia
'FI', # Finland
'FR', # France
'GF', # French Guiana
'DE', # Germany
'GR', # Greece
'GP', # Guadeloupe
'HU', # Hungary
'IS', # Iceland
'IE', # Ireland
'IT', # Italy
'LV', # Latvia
'LI', # Liechtenstein
'LT', # Lithuania
'LU', # Luxembourg
'MT', # Malta
'MQ', # Martinique
'YT', # Mayotte
'NL', # Netherlands
'NO', # Norway
'PL', # Poland
'PT', # Portugal
'RE', # Reunion
'RO', # Romania
'MF', # Saint Martin
'SK', # Slovakia
'SI', # Slovenia
'ES', # Spain
'SE', # Sweden
'GB', # United Kingdom
'BR', # Brazil, hack to geofence it
];
end