authtrail 0.3.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/README.md +68 -9
- data/app/jobs/auth_trail/geocode_job.rb +3 -0
- data/lib/auth_trail/engine.rb +1 -0
- data/lib/auth_trail/version.rb +1 -1
- data/lib/authtrail.rb +1 -2
- data/lib/generators/authtrail/install_generator.rb +50 -1
- data/lib/generators/authtrail/templates/initializer.rb.tt +2 -2
- data/lib/generators/authtrail/templates/login_activities_migration.rb.tt +2 -5
- data/lib/generators/authtrail/templates/model_activerecord.rb.tt +14 -0
- data/lib/generators/authtrail/templates/model_lockbox.rb.tt +14 -0
- data/lib/generators/authtrail/templates/{login_activity_model.rb.tt → model_none.rb.tt} +0 -0
- metadata +6 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff58207c013a0181500aea1886029896cae2af4fe0cf8dbf65bd1545e0637f4a
|
4
|
+
data.tar.gz: f2b530b002daaa2ca52f2dbf471199e9fcfc13c04c9c821df139b9e6e909eecc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94ec2b6986bef058156630c1dccf900c366f1b9c2aaf84703c5372370dbf305af698c554c9e1b5f0ca64d144cd934c065499ac745c711a98d8dfe33c3138ed5b
|
7
|
+
data.tar.gz: ae73465fd479199a31cabed9a87a6afdf6acca838de32c8b329f2da061709229046812584dfce1a9a8fdb4650834a5b2a4f2928ac7ea0d6e0cbf50da98e2c4c2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
## 0.4.2 (2021-12-13)
|
2
|
+
|
3
|
+
- Added experimental support for Active Record encryption
|
4
|
+
- Fixed error with Rails 7 rc1
|
5
|
+
|
6
|
+
## 0.4.1 (2021-08-14)
|
7
|
+
|
8
|
+
- Improved error message when `geocoder` gem not installed
|
9
|
+
|
10
|
+
## 0.4.0 (2021-08-13)
|
11
|
+
|
12
|
+
- Disabled geocoding by default (this was already the case for new installations with 0.3.0+)
|
13
|
+
- Made the `geocoder` gem an optional dependency
|
14
|
+
- Added `country_code` to geocoding
|
15
|
+
|
16
|
+
## 0.3.1 (2021-03-03)
|
17
|
+
|
18
|
+
- Added `--lockbox` option to install generator
|
19
|
+
|
1
20
|
## 0.3.0 (2021-03-01)
|
2
21
|
|
3
22
|
- Disabled geocoding by default for new installations
|
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
Track Devise login activity
|
4
4
|
|
5
|
+
**AuthTrail 0.4.0 was recently released** - see [how to upgrade](#upgrading)
|
6
|
+
|
5
7
|
:tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
|
6
8
|
|
7
9
|
[](https://github.com/ankane/authtrail/actions)
|
@@ -14,13 +16,29 @@ Add this line to your application’s Gemfile:
|
|
14
16
|
gem 'authtrail'
|
15
17
|
```
|
16
18
|
|
17
|
-
|
19
|
+
To encrypt email and IP addresses with Lockbox, install [Lockbox](https://github.com/ankane/lockbox) and [Blind Index](https://github.com/ankane/blind_index) and run:
|
18
20
|
|
19
21
|
```sh
|
20
|
-
rails generate authtrail:install
|
22
|
+
rails generate authtrail:install --encryption=lockbox
|
21
23
|
rails db:migrate
|
22
24
|
```
|
23
25
|
|
26
|
+
To use Active Record encryption (Rails 7+, experimental, unreleased), run:
|
27
|
+
|
28
|
+
```sh
|
29
|
+
rails generate authtrail:install --encryption=activerecord
|
30
|
+
rails db:migrate
|
31
|
+
```
|
32
|
+
|
33
|
+
If you prefer not to encrypt data, run:
|
34
|
+
|
35
|
+
```sh
|
36
|
+
rails generate authtrail:install --encryption=none
|
37
|
+
rails db:migrate
|
38
|
+
```
|
39
|
+
|
40
|
+
To enable geocoding, see the [Geocoding section](#geocoding).
|
41
|
+
|
24
42
|
## How It Works
|
25
43
|
|
26
44
|
A `LoginActivity` record is created every time a user tries to login. You can then use this information to detect suspicious behavior. Data includes:
|
@@ -95,9 +113,15 @@ The `LoginActivity` model uses a [polymorphic association](https://guides.rubyon
|
|
95
113
|
|
96
114
|
## Geocoding
|
97
115
|
|
98
|
-
AuthTrail uses [Geocoder](https://github.com/alexreisner/geocoder) for geocoding. We recommend configuring [local geocoding](#local-geocoding) so IP addresses are not sent to a 3rd party service. If you do use a 3rd party service and adhere to GDPR, be sure to add it to your subprocessor list.
|
116
|
+
AuthTrail uses [Geocoder](https://github.com/alexreisner/geocoder) for geocoding. We recommend configuring [local geocoding](#local-geocoding) or [load balancer geocoding](#load-balancer-geocoding) so IP addresses are not sent to a 3rd party service. If you do use a 3rd party service and adhere to GDPR, be sure to add it to your subprocessor list.
|
117
|
+
|
118
|
+
To enable geocoding, add this line to your application’s Gemfile:
|
99
119
|
|
100
|
-
|
120
|
+
```ruby
|
121
|
+
gem 'geocoder'
|
122
|
+
```
|
123
|
+
|
124
|
+
And update `config/initializers/authtrail.rb`:
|
101
125
|
|
102
126
|
```ruby
|
103
127
|
AuthTrail.geocode = true
|
@@ -146,17 +170,40 @@ Geocoder.configure(
|
|
146
170
|
)
|
147
171
|
```
|
148
172
|
|
149
|
-
|
173
|
+
### Load Balancer Geocoding
|
174
|
+
|
175
|
+
Some load balancers can add geocoding information to request headers.
|
150
176
|
|
151
|
-
|
177
|
+
- [nginx](https://nginx.org/en/docs/http/ngx_http_geoip_module.html)
|
178
|
+
- [Google Cloud](https://cloud.google.com/load-balancing/docs/custom-headers)
|
179
|
+
- [Cloudflare](https://support.cloudflare.com/hc/en-us/articles/200168236-Configuring-Cloudflare-IP-Geolocation)
|
152
180
|
|
153
181
|
```ruby
|
154
|
-
|
155
|
-
|
156
|
-
|
182
|
+
AuthTrail.geocode = false
|
183
|
+
|
184
|
+
AuthTrail.transform_method = lambda do |data, request|
|
185
|
+
data[:country] = request.headers["<country-header>"]
|
186
|
+
data[:region] = request.headers["<region-header>"]
|
187
|
+
data[:city] = request.headers["<city-header>"]
|
157
188
|
end
|
158
189
|
```
|
159
190
|
|
191
|
+
Check out [this example](https://github.com/ankane/authtrail/issues/40)
|
192
|
+
|
193
|
+
## Data Retention
|
194
|
+
|
195
|
+
Delete older data with:
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
LoginActivity.where("created_at < ?", 2.years.ago).in_batches.delete_all
|
199
|
+
```
|
200
|
+
|
201
|
+
Delete data for a specific user with:
|
202
|
+
|
203
|
+
```ruby
|
204
|
+
LoginActivity.where(user_id: 1, user_type: "User").in_batches.delete_all
|
205
|
+
```
|
206
|
+
|
160
207
|
## Other Notes
|
161
208
|
|
162
209
|
We recommend using this in addition to Devise’s `Lockable` module and [Rack::Attack](https://github.com/kickstarter/rack-attack).
|
@@ -165,6 +212,18 @@ Check out [Hardening Devise](https://ankane.org/hardening-devise) and [Secure Ra
|
|
165
212
|
|
166
213
|
## Upgrading
|
167
214
|
|
215
|
+
### 0.4.0
|
216
|
+
|
217
|
+
There are two notable changes to geocoding:
|
218
|
+
|
219
|
+
1. Geocoding is now disabled by default (this was already the case for new installations with 0.3.0+). Check out the instructions for [how to enable it](#geocoding) (you may need to create `config/initializers/authtrail.rb`).
|
220
|
+
|
221
|
+
2. The `geocoder` gem is now an optional dependency. To use geocoding, add it to your Gemfile:
|
222
|
+
|
223
|
+
```ruby
|
224
|
+
gem 'geocoder'
|
225
|
+
```
|
226
|
+
|
168
227
|
### 0.2.0
|
169
228
|
|
170
229
|
To store latitude and longitude, create a migration with:
|
@@ -8,6 +8,8 @@ module AuthTrail
|
|
8
8
|
result =
|
9
9
|
begin
|
10
10
|
Geocoder.search(login_activity.ip).first
|
11
|
+
rescue NameError
|
12
|
+
raise "Add the geocoder gem to your Gemfile to use geocoding"
|
11
13
|
rescue => e
|
12
14
|
Rails.logger.info "Geocode failed: #{e.message}"
|
13
15
|
nil
|
@@ -18,6 +20,7 @@ module AuthTrail
|
|
18
20
|
city: result.try(:city),
|
19
21
|
region: result.try(:state),
|
20
22
|
country: result.try(:country),
|
23
|
+
country_code: result.try(:country_code),
|
21
24
|
latitude: result.try(:latitude),
|
22
25
|
longitude: result.try(:longitude)
|
23
26
|
}
|
data/lib/auth_trail/engine.rb
CHANGED
data/lib/auth_trail/version.rb
CHANGED
data/lib/authtrail.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# dependencies
|
2
|
-
require "geocoder"
|
3
2
|
require "warden"
|
4
3
|
|
5
4
|
# modules
|
@@ -11,7 +10,7 @@ module AuthTrail
|
|
11
10
|
class << self
|
12
11
|
attr_accessor :exclude_method, :geocode, :track_method, :identity_method, :job_queue, :transform_method
|
13
12
|
end
|
14
|
-
self.geocode =
|
13
|
+
self.geocode = false
|
15
14
|
self.identity_method = lambda do |request, opts, user|
|
16
15
|
if user
|
17
16
|
user.try(:email)
|
@@ -6,7 +6,12 @@ module Authtrail
|
|
6
6
|
include ActiveRecord::Generators::Migration
|
7
7
|
source_root File.join(__dir__, "templates")
|
8
8
|
|
9
|
+
class_option :encryption, type: :string
|
10
|
+
# deprecated
|
11
|
+
class_option :lockbox, type: :boolean
|
12
|
+
|
9
13
|
def copy_migration
|
14
|
+
encryption # ensure valid
|
10
15
|
migration_template "login_activities_migration.rb", "db/migrate/create_login_activities.rb", migration_version: migration_version
|
11
16
|
end
|
12
17
|
|
@@ -15,12 +20,56 @@ module Authtrail
|
|
15
20
|
end
|
16
21
|
|
17
22
|
def generate_model
|
18
|
-
|
23
|
+
case encryption
|
24
|
+
when "lockbox"
|
25
|
+
template "model_lockbox.rb", "app/models/login_activity.rb"
|
26
|
+
when "activerecord"
|
27
|
+
template "model_activerecord.rb", "app/models/login_activity.rb"
|
28
|
+
else
|
29
|
+
template "model_none.rb", "app/models/login_activity.rb"
|
30
|
+
end
|
19
31
|
end
|
20
32
|
|
21
33
|
def migration_version
|
22
34
|
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
23
35
|
end
|
36
|
+
|
37
|
+
def identity_column
|
38
|
+
case encryption
|
39
|
+
when "lockbox"
|
40
|
+
"t.text :identity_ciphertext\n t.string :identity_bidx, index: true"
|
41
|
+
else
|
42
|
+
# TODO add limit: 510 for Active Record encryption + MySQL?
|
43
|
+
"t.string :identity, index: true"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def ip_column
|
48
|
+
case encryption
|
49
|
+
when "lockbox"
|
50
|
+
"t.text :ip_ciphertext\n t.string :ip_bidx, index: true"
|
51
|
+
else
|
52
|
+
# TODO add limit: 510 for Active Record encryption + MySQL?
|
53
|
+
"t.string :ip, index: true"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# TODO remove default
|
58
|
+
def encryption
|
59
|
+
case options[:encryption]
|
60
|
+
when "lockbox", "activerecord", "none"
|
61
|
+
options[:encryption]
|
62
|
+
when nil
|
63
|
+
if options[:lockbox]
|
64
|
+
# TODO deprecation warning
|
65
|
+
"lockbox"
|
66
|
+
else
|
67
|
+
"none"
|
68
|
+
end
|
69
|
+
else
|
70
|
+
abort "Error: encryption must be lockbox, activerecord, or none"
|
71
|
+
end
|
72
|
+
end
|
24
73
|
end
|
25
74
|
end
|
26
75
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
# set to true for geocoding
|
2
|
-
# we recommend configuring local geocoding
|
1
|
+
# set to true for geocoding (and add the geocoder gem to your Gemfile)
|
2
|
+
# we recommend configuring local geocoding as well
|
3
3
|
# see https://github.com/ankane/authtrail#geocoding
|
4
4
|
AuthTrail.geocode = false
|
5
5
|
|
@@ -3,12 +3,12 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
|
|
3
3
|
create_table :login_activities do |t|
|
4
4
|
t.string :scope
|
5
5
|
t.string :strategy
|
6
|
-
|
6
|
+
<%= identity_column %>
|
7
7
|
t.boolean :success
|
8
8
|
t.string :failure_reason
|
9
9
|
t.references :user, polymorphic: true
|
10
10
|
t.string :context
|
11
|
-
|
11
|
+
<%= ip_column %>
|
12
12
|
t.text :user_agent
|
13
13
|
t.text :referrer
|
14
14
|
t.string :city
|
@@ -18,8 +18,5 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
|
|
18
18
|
t.float :longitude
|
19
19
|
t.datetime :created_at
|
20
20
|
end
|
21
|
-
|
22
|
-
add_index :login_activities, :identity
|
23
|
-
add_index :login_activities, :ip
|
24
21
|
end
|
25
22
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class LoginActivity < ApplicationRecord
|
2
|
+
belongs_to :user, polymorphic: true, optional: true
|
3
|
+
|
4
|
+
encrypts :identity, deterministic: true
|
5
|
+
encrypts :ip, deterministic: true
|
6
|
+
|
7
|
+
before_save :reduce_precision
|
8
|
+
|
9
|
+
# reduce precision to city level to protect IP
|
10
|
+
def reduce_precision
|
11
|
+
self.latitude = latitude&.round(1) if try(:latitude_changed?)
|
12
|
+
self.longitude = longitude&.round(1) if try(:longitude_changed?)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class LoginActivity < ApplicationRecord
|
2
|
+
belongs_to :user, polymorphic: true, optional: true
|
3
|
+
|
4
|
+
encrypts :identity, :ip
|
5
|
+
blind_index :identity, :ip
|
6
|
+
|
7
|
+
before_save :reduce_precision
|
8
|
+
|
9
|
+
# reduce precision to city level to protect IP
|
10
|
+
def reduce_precision
|
11
|
+
self.latitude = latitude&.round(1) if try(:latitude_changed?)
|
12
|
+
self.longitude = longitude&.round(1) if try(:longitude_changed?)
|
13
|
+
end
|
14
|
+
end
|
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: authtrail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: geocoder
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
55
|
description:
|
70
56
|
email: andrew@ankane.org
|
71
57
|
executables: []
|
@@ -83,7 +69,9 @@ files:
|
|
83
69
|
- lib/generators/authtrail/install_generator.rb
|
84
70
|
- lib/generators/authtrail/templates/initializer.rb.tt
|
85
71
|
- lib/generators/authtrail/templates/login_activities_migration.rb.tt
|
86
|
-
- lib/generators/authtrail/templates/
|
72
|
+
- lib/generators/authtrail/templates/model_activerecord.rb.tt
|
73
|
+
- lib/generators/authtrail/templates/model_lockbox.rb.tt
|
74
|
+
- lib/generators/authtrail/templates/model_none.rb.tt
|
87
75
|
homepage: https://github.com/ankane/authtrail
|
88
76
|
licenses:
|
89
77
|
- MIT
|
@@ -103,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
91
|
- !ruby/object:Gem::Version
|
104
92
|
version: '0'
|
105
93
|
requirements: []
|
106
|
-
rubygems_version: 3.2.
|
94
|
+
rubygems_version: 3.2.32
|
107
95
|
signing_key:
|
108
96
|
specification_version: 4
|
109
97
|
summary: Track Devise login activity
|