authtrail 0.1.1 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d0affe4e892e8dac1a1ddc212ebb6834ef1de340f782de0f4a19dcc230e0a51
4
- data.tar.gz: 72b45a58e89181f07ea0c58e3875e67948287a2b1b0fc9aa627eac6be8aee5f8
3
+ metadata.gz: 686cc3a7c96d52e4cf5ac79c4268bdb0cd9b670978ac23668af4e8e0d4f11b08
4
+ data.tar.gz: 073fd3fefbe1cee4eca8daa2ee3fe13ea2aefd1c3f3d1d868daafa1fe40b7511
5
5
  SHA512:
6
- metadata.gz: 25b90ec6e2059c37c405e3e647cc39c12d3ece6a12697ac0403f0ca4b07c7b288ff73194c6fe07af1fed558bd94feb1e870e267dfba5fd6abd8adf5e3a6e18a2
7
- data.tar.gz: 18428f49536b942f47d260e6d4251eaaae57c7cc6fddcb3d35fba1a3a6bb8adc8492453530569ab0c21b84181ffd2e92672ea8762ccb1c59dcb8c167c6037127
6
+ metadata.gz: 5b2afdc6ab493f2d8c3759d9d0d145b518f3447250889ce5013f737629d3bd89248ddb7413d8f75c2452a221ed950404355a9763814bdcfffe158bb89a7a2da7
7
+ data.tar.gz: ac21a072dd8328cb749a65aedd12188de9cc93501d5ad54bb4ada4b0a56e24bc1cc1116f8d32dfeb3c8a3d28a066258ffc05bbec655c94ec08a30c3ff7e1fee0
@@ -1,3 +1,8 @@
1
+ ## 0.1.2
2
+
3
+ - Added `identity_method` option
4
+ - Fixed geocoding
5
+
1
6
  ## 0.1.1
2
7
 
3
8
  - Improved strategy detection for failures
data/README.md CHANGED
@@ -16,7 +16,7 @@ And run:
16
16
 
17
17
  ```sh
18
18
  rails generate authtrail:install
19
- rake db:migrate
19
+ rails db:migrate
20
20
  ```
21
21
 
22
22
  ## How It Works
@@ -35,40 +35,100 @@ A `LoginActivity` record is created every time a user tries to login. You can th
35
35
  - `city`, `region`, and `country` - from IP
36
36
  - `created_at` - time of event
37
37
 
38
- IP geocoding is performed in a background job so it doesn’t slow down web requests. You can disable it entirely with:
39
-
40
- ```ruby
41
- AuthTrail.geocode = false
42
- ```
43
-
44
38
  ## Features
45
39
 
46
40
  Exclude certain attempts from tracking - useful if you run acceptance tests
47
41
 
48
42
  ```ruby
49
- AuthTrail.exclude_method = proc do |info|
43
+ AuthTrail.exclude_method = lambda do |info|
50
44
  info[:identity] == "capybara@example.org"
51
45
  end
52
46
  ```
53
47
 
54
- Write data somewhere other than the `login_activities` table.
48
+ Write data somewhere other than the `login_activities` table
55
49
 
56
50
  ```ruby
57
- AuthTrail.track_method = proc do |info|
51
+ AuthTrail.track_method = lambda do |info|
58
52
  # code
59
53
  end
60
54
  ```
61
55
 
56
+ Use a custom identity method [master]
57
+
58
+ ```ruby
59
+ AuthTrail.identity_method = lambda do |request, opts, user|
60
+ if user
61
+ user.email
62
+ else
63
+ request.params.dig(opts[:scope], :email)
64
+ end
65
+ end
66
+ ```
67
+
68
+ Associate login activity with your user model
69
+
70
+ ```ruby
71
+ class User < ApplicationRecord
72
+ has_many :login_activities, as: :user # use :user no matter what your model name
73
+ end
74
+ ```
75
+
76
+ The `LoginActivity` model uses a [polymorphic association](http://guides.rubyonrails.org/association_basics.html#polymorphic-associations) so it can be associated with different user models.
77
+
78
+ ## Geocoding
79
+
80
+ IP geocoding is performed in a background job so it doesn’t slow down web requests. You can disable it entirely with:
81
+
82
+ ```ruby
83
+ AuthTrail.geocode = false
84
+ ```
85
+
62
86
  Set job queue for geocoding
63
87
 
64
88
  ```ruby
65
89
  AuthTrail::GeocodeJob.queue_as :low
66
90
  ```
67
91
 
92
+ ### Geocoding Performance
93
+
94
+ To avoid calls to a remote API, download the [GeoLite2 City database](https://dev.maxmind.com/geoip/geoip2/geolite2/) and configure Geocoder to use it.
95
+
96
+ Add this line to your application’s Gemfile:
97
+
98
+ ```ruby
99
+ gem 'maxminddb'
100
+ ```
101
+
102
+ And create an initializer at `config/initializers/geocoder.rb` with:
103
+
104
+ ```ruby
105
+ Geocoder.configure(
106
+ ip_lookup: :geoip2,
107
+ geoip2: {
108
+ file: Rails.root.join("lib", "GeoLite2-City.mmdb")
109
+ }
110
+ )
111
+ ```
112
+
113
+ ## Data Protection
114
+
115
+ Protect the privacy of your users by encrypting fields that contain personal information, such as `identity` and `ip`. [attr_encrypted](https://github.com/attr-encrypted/attr_encrypted) is great for this.
116
+
117
+ ```ruby
118
+ class LoginActivity < ApplicationRecord
119
+ attr_encrypted :identity, ...
120
+ attr_encrypted :ip, ...
121
+ end
122
+ ```
123
+
124
+ You should also make it clear that you collect this information in your privacy policy.
125
+
68
126
  ## Other Notes
69
127
 
70
128
  We recommend using this in addition to Devise’s `Lockable` module and [Rack::Attack](https://github.com/kickstarter/rack-attack).
71
129
 
130
+ Check out [Hardening Devise](https://github.com/ankane/shorts/blob/master/Hardening-Devise.md) and [Secure Rails](https://github.com/ankane/secure_rails) for more best practices.
131
+
72
132
  Works with Rails 5+
73
133
 
74
134
  ## History
@@ -3,7 +3,7 @@ module AuthTrail
3
3
  def perform(login_activity)
4
4
  result =
5
5
  begin
6
- Geocoder.search(login_activity.ip).first.try(:data)
6
+ Geocoder.search(login_activity.ip).first
7
7
  rescue => e
8
8
  Rails.logger.info "Geocode failed: #{e.message}"
9
9
  nil
@@ -11,9 +11,9 @@ module AuthTrail
11
11
 
12
12
  if result
13
13
  login_activity.update!(
14
- city: result["city"].presence,
15
- region: result["region_name"].presence,
16
- country: result["country_name"].presence
14
+ city: result.try(:city).presence,
15
+ region: result.try(:state).presence,
16
+ country: result.try(:country).presence
17
17
  )
18
18
  end
19
19
  end
@@ -6,12 +6,10 @@ module AuthTrail
6
6
  AuthTrail.safely do
7
7
  request = ActionDispatch::Request.new(auth.env)
8
8
 
9
- identity = user.try(:email)
10
-
11
9
  AuthTrail.track(
12
10
  strategy: detect_strategy(auth),
13
11
  scope: opts[:scope].to_s,
14
- identity: identity,
12
+ identity: AuthTrail.identity_method.call(request, opts, user),
15
13
  success: true,
16
14
  request: request,
17
15
  user: user
@@ -24,13 +22,10 @@ module AuthTrail
24
22
  if opts[:message]
25
23
  request = ActionDispatch::Request.new(env)
26
24
 
27
- scope = opts[:scope]
28
- identity = request.params[scope] && request.params[scope][:email] rescue nil
29
-
30
25
  AuthTrail.track(
31
26
  strategy: detect_strategy(env["warden"]),
32
- scope: scope.to_s,
33
- identity: identity,
27
+ scope: opts[:scope].to_s,
28
+ identity: AuthTrail.identity_method.call(request, opts, nil),
34
29
  success: false,
35
30
  request: request,
36
31
  failure_reason: opts[:message].to_s
@@ -1,3 +1,3 @@
1
1
  module AuthTrail
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -9,9 +9,17 @@ require "auth_trail/version"
9
9
 
10
10
  module AuthTrail
11
11
  class << self
12
- attr_accessor :exclude_method, :geocode, :track_method
12
+ attr_accessor :exclude_method, :geocode, :track_method, :identity_method
13
13
  end
14
14
  self.geocode = true
15
+ self.identity_method = lambda do |request, opts, user|
16
+ if user
17
+ user.try(:email)
18
+ else
19
+ scope = opts[:scope]
20
+ request.params[scope] && request.params[scope][:email] rescue nil
21
+ end
22
+ end
15
23
 
16
24
  def self.track(strategy:, scope:, identity:, success:, request:, user: nil, failure_reason: nil)
17
25
  info = {
@@ -21,12 +29,15 @@ module AuthTrail
21
29
  success: success,
22
30
  failure_reason: failure_reason,
23
31
  user: user,
24
- context: "#{request.params[:controller]}##{request.params[:action]}",
25
32
  ip: request.remote_ip,
26
33
  user_agent: request.user_agent,
27
34
  referrer: request.referrer
28
35
  }
29
36
 
37
+ if request.params[:controller]
38
+ info[:context] = "#{request.params[:controller]}##{request.params[:action]}"
39
+ end
40
+
30
41
  # if exclude_method throws an exception, default to not excluding
31
42
  exclude = AuthTrail.exclude_method && AuthTrail.safely(default: false) { AuthTrail.exclude_method.call(info) }
32
43
 
@@ -1,19 +1,19 @@
1
1
  class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
3
  create_table :login_activities do |t|
4
- t.text :scope
5
- t.text :strategy
4
+ t.string :scope
5
+ t.string :strategy
6
6
  t.string :identity
7
7
  t.boolean :success
8
- t.text :failure_reason
8
+ t.string :failure_reason
9
9
  t.references :user, polymorphic: true
10
- t.text :context
10
+ t.string :context
11
11
  t.string :ip
12
12
  t.text :user_agent
13
13
  t.text :referrer
14
- t.text :city
15
- t.text :region
16
- t.text :country
14
+ t.string :city
15
+ t.string :region
16
+ t.string :country
17
17
  t.datetime :created_at
18
18
  end
19
19
 
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.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-13 00:00:00.000000000 Z
11
+ date: 2018-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -109,20 +109,15 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  description:
112
- email:
113
- - andrew@chartkick.com
112
+ email: andrew@chartkick.com
114
113
  executables: []
115
114
  extensions: []
116
115
  extra_rdoc_files: []
117
116
  files:
118
- - ".gitignore"
119
117
  - CHANGELOG.md
120
- - Gemfile
121
118
  - LICENSE.txt
122
119
  - README.md
123
- - Rakefile
124
120
  - app/jobs/auth_trail/geocode_job.rb
125
- - authtrail.gemspec
126
121
  - lib/auth_trail/engine.rb
127
122
  - lib/auth_trail/manager.rb
128
123
  - lib/auth_trail/version.rb
@@ -131,7 +126,8 @@ files:
131
126
  - lib/generators/authtrail/templates/login_activities_migration.rb
132
127
  - lib/generators/authtrail/templates/login_activity_model.rb
133
128
  homepage: https://github.com/ankane/authtrail
134
- licenses: []
129
+ licenses:
130
+ - MIT
135
131
  metadata: {}
136
132
  post_install_message:
137
133
  rdoc_options: []
@@ -141,7 +137,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
137
  requirements:
142
138
  - - ">="
143
139
  - !ruby/object:Gem::Version
144
- version: '0'
140
+ version: '2.2'
145
141
  required_rubygems_version: !ruby/object:Gem::Requirement
146
142
  requirements:
147
143
  - - ">="
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- Gemfile.lock
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
-
5
- # Specify your gem's dependencies in authtrail.gemspec
6
- gemspec
data/Rakefile DELETED
@@ -1,10 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
8
- end
9
-
10
- task default: :test
@@ -1,30 +0,0 @@
1
-
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "auth_trail/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "authtrail"
8
- spec.version = AuthTrail::VERSION
9
- spec.authors = ["Andrew Kane"]
10
- spec.email = ["andrew@chartkick.com"]
11
-
12
- spec.summary = "Track Devise login activity"
13
- spec.homepage = "https://github.com/ankane/authtrail"
14
-
15
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
- f.match(%r{^(test|spec|features)/})
17
- end
18
- spec.bindir = "exe"
19
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ["lib"]
21
-
22
- spec.add_dependency "railties", ">= 5"
23
- spec.add_dependency "activerecord", ">= 5"
24
- spec.add_dependency "warden"
25
- spec.add_dependency "geocoder"
26
-
27
- spec.add_development_dependency "bundler"
28
- spec.add_development_dependency "rake"
29
- spec.add_development_dependency "minitest"
30
- end