authtrail 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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