authtrail 0.1.0 → 0.2.1

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
- SHA1:
3
- metadata.gz: d09fb569715557b1fcde80bcab0990674c3950c3
4
- data.tar.gz: 4507a5bfb4536803efcc1a8d29ef04c1dd4c0717
2
+ SHA256:
3
+ metadata.gz: 6ca58a6ac201b761a2cf30bed995135a44690ac7616770f9f1d2e74c45e23080
4
+ data.tar.gz: 3ab3c476d2b75e1697a0a1e08cdc6e0356c07e266b1839c74eea1c1c4d818023
5
5
  SHA512:
6
- metadata.gz: 12879861a9e98af5c5defd08ddf1f10d0aa11e04724ff56dd191a34b3ea778821e8173a4198f1221a92774db49301e8e633f064fdbc7385a7f184df7173de00d
7
- data.tar.gz: 1777a6f8bd28435970616e6dc90937301354edeb89ffb5ada0c85c531e01b07e8f138959f7313dbbd0c7ccb7add148550743425b5f90f200bfad7ca352363ad9
6
+ metadata.gz: b7a769b8963f67a9cc0d37e194dd1e9b936271cfbc7c88ee0f1fe72252926fc6184c01bd9abad0420231507bc99e54fc22b85916c9a0cb3cc1611c402e3436f3
7
+ data.tar.gz: 5cad0685a4773c31ef10f78380c9e64b4ca56828f9ba9eae8b4471a1b7cdd5d827b6f33c27a4963926003b199bbffad3971c98269e87c7cb850db33ad342a352
@@ -1,3 +1,27 @@
1
- ## 0.1.0
1
+ ## 0.2.1 (2020-08-17)
2
+
3
+ - Added `job_queue` option
4
+
5
+ ## 0.2.0 (2019-06-23)
6
+
7
+ - Added latitude and longitude
8
+ - `AuthTrail::GeocodeJob` now inherits from `ActiveJob::Base` instead of `ApplicationJob`
9
+ - Removed support for Rails 4.2
10
+
11
+ ## 0.1.3 (2018-09-27)
12
+
13
+ - Added support for Rails 4.2
14
+
15
+ ## 0.1.2 (2018-07-30)
16
+
17
+ - Added `identity_method` option
18
+ - Fixed geocoding
19
+
20
+ ## 0.1.1 (2018-07-13)
21
+
22
+ - Improved strategy detection for failures
23
+ - Fixed migration for MySQL
24
+
25
+ ## 0.1.0 (2017-11-07)
2
26
 
3
27
  - First release
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017 Andrew Kane
1
+ Copyright (c) 2017-2020 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -4,6 +4,8 @@ Track Devise login activity
4
4
 
5
5
  :tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
6
6
 
7
+ [![Build Status](https://travis-ci.org/ankane/authtrail.svg?branch=master)](https://travis-ci.org/ankane/authtrail)
8
+
7
9
  ## Installation
8
10
 
9
11
  Add this line to your application’s Gemfile:
@@ -16,7 +18,7 @@ And run:
16
18
 
17
19
  ```sh
18
20
  rails generate authtrail:install
19
- rake db:migrate
21
+ rails db:migrate
20
22
  ```
21
23
 
22
24
  ## How It Works
@@ -24,7 +26,7 @@ rake db:migrate
24
26
  A `LoginActivity` record is created every time a user tries to login. You can then use this information to detect suspicious behavior. Data includes:
25
27
 
26
28
  - `scope` - Devise scope
27
- - `strategy` - `database_authenticatable` for password logins, `rememberable` for remember me cookie, or the name of the OmniAuth strategy
29
+ - `strategy` - Devise strategy
28
30
  - `identity` - email address
29
31
  - `success` - whether the login succeeded
30
32
  - `failure_reason` - if the login failed
@@ -32,44 +34,111 @@ A `LoginActivity` record is created every time a user tries to login. You can th
32
34
  - `context` - controller and action
33
35
  - `ip` - IP address
34
36
  - `user_agent` and `referrer` - from browser
35
- - `city`, `region`, and `country` - from IP
37
+ - `city`, `region`, `country`, `latitude`, and `longitude` - from IP
36
38
  - `created_at` - time of event
37
39
 
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
40
  ## Features
45
41
 
46
42
  Exclude certain attempts from tracking - useful if you run acceptance tests
47
43
 
48
44
  ```ruby
49
- AuthTrail.exclude_method = proc do |info|
45
+ AuthTrail.exclude_method = lambda do |info|
50
46
  info[:identity] == "capybara@example.org"
51
47
  end
52
48
  ```
53
49
 
54
- Write data somewhere other than the `login_activities` table.
50
+ Write data somewhere other than the `login_activities` table
55
51
 
56
52
  ```ruby
57
- AuthTrail.track_method = proc do |info|
53
+ AuthTrail.track_method = lambda do |info|
58
54
  # code
59
55
  end
60
56
  ```
61
57
 
58
+ Use a custom identity method
59
+
60
+ ```ruby
61
+ AuthTrail.identity_method = lambda do |request, opts, user|
62
+ if user
63
+ user.email
64
+ else
65
+ request.params.dig(opts[:scope], :email)
66
+ end
67
+ end
68
+ ```
69
+
70
+ Associate login activity with your user model
71
+
72
+ ```ruby
73
+ class User < ApplicationRecord
74
+ has_many :login_activities, as: :user # use :user no matter what your model name
75
+ end
76
+ ```
77
+
78
+ The `LoginActivity` model uses a [polymorphic association](https://guides.rubyonrails.org/association_basics.html#polymorphic-associations) so it can be associated with different user models.
79
+
80
+ ## Geocoding
81
+
82
+ IP geocoding is performed in a background job so it doesn’t slow down web requests. You can disable it entirely with:
83
+
84
+ ```ruby
85
+ AuthTrail.geocode = false
86
+ ```
87
+
62
88
  Set job queue for geocoding
63
89
 
64
90
  ```ruby
65
- AuthTrail::GeocodeJob.queue_as :low
91
+ AuthTrail.job_queue = :low_priority
92
+ ```
93
+
94
+ ### Geocoding Performance
95
+
96
+ 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.
97
+
98
+ Add this line to your application’s Gemfile:
99
+
100
+ ```ruby
101
+ gem 'maxminddb'
102
+ ```
103
+
104
+ And create an initializer at `config/initializers/geocoder.rb` with:
105
+
106
+ ```ruby
107
+ Geocoder.configure(
108
+ ip_lookup: :geoip2,
109
+ geoip2: {
110
+ file: Rails.root.join("lib", "GeoLite2-City.mmdb")
111
+ }
112
+ )
113
+ ```
114
+
115
+ ## Data Protection
116
+
117
+ Protect the privacy of your users by encrypting fields that contain personal data, such as `identity` and `ip`. [Lockbox](https://github.com/ankane/lockbox) is great for this. Use [Blind Index](https://github.com/ankane/blind_index) so you can still query the fields.
118
+
119
+ ```ruby
120
+ class LoginActivity < ApplicationRecord
121
+ encrypts :identity, :ip
122
+ blind_index :identity, :ip
123
+ end
66
124
  ```
67
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
 
72
- Works with Rails 5+
130
+ Check out [Hardening Devise](https://ankane.org/hardening-devise) and [Secure Rails](https://github.com/ankane/secure_rails) for more best practices.
131
+
132
+ ## Upgrading
133
+
134
+ ### 0.2.0
135
+
136
+ To store latitude and longitude, create a migration with:
137
+
138
+ ```ruby
139
+ add_column :login_activities, :latitude, :float
140
+ add_column :login_activities, :longitude, :float
141
+ ```
73
142
 
74
143
  ## History
75
144
 
@@ -83,3 +152,12 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
83
152
  - Fix bugs and [submit pull requests](https://github.com/ankane/authtrail/pulls)
84
153
  - Write, clarify, or fix documentation
85
154
  - Suggest or add new features
155
+
156
+ To get started with development and testing:
157
+
158
+ ```sh
159
+ git clone https://github.com/ankane/authtrail.git
160
+ cd authtrail
161
+ bundle install
162
+ bundle exec rake test
163
+ ```
@@ -1,20 +1,30 @@
1
1
  module AuthTrail
2
- class GeocodeJob < ApplicationJob
2
+ class GeocodeJob < ActiveJob::Base
3
+ # default queue is used if queue_as returns nil
4
+ # Rails has a test for this
5
+ queue_as { AuthTrail.job_queue }
6
+
3
7
  def perform(login_activity)
4
8
  result =
5
9
  begin
6
- Geocoder.search(login_activity.ip).first.try(:data)
10
+ Geocoder.search(login_activity.ip).first
7
11
  rescue => e
8
12
  Rails.logger.info "Geocode failed: #{e.message}"
9
13
  nil
10
14
  end
11
15
 
12
16
  if result
13
- login_activity.update!(
14
- city: result["city"].presence,
15
- region: result["region_name"].presence,
16
- country: result["country_name"].presence
17
- )
17
+ attributes = {
18
+ city: result.try(:city),
19
+ region: result.try(:state),
20
+ country: result.try(:country),
21
+ latitude: result.try(:latitude),
22
+ longitude: result.try(:longitude)
23
+ }
24
+ attributes.each do |k, v|
25
+ login_activity.try("#{k}=", v.presence)
26
+ end
27
+ login_activity.save!
18
28
  end
19
29
  end
20
30
  end
@@ -1,3 +1,5 @@
1
+ require "rails/engine"
2
+
1
3
  module AuthTrail
2
4
  class Engine < Rails::Engine
3
5
  end
@@ -6,15 +6,10 @@ module AuthTrail
6
6
  AuthTrail.safely do
7
7
  request = ActionDispatch::Request.new(auth.env)
8
8
 
9
- strategy = auth.env["omniauth.auth"]["provider"] if auth.env["omniauth.auth"]
10
- strategy ||= auth.winning_strategy.class.name.split("::").last.underscore if auth.winning_strategy
11
- strategy ||= "database_authenticatable"
12
-
13
- identity = user.try(:email)
14
9
  AuthTrail.track(
15
- strategy: strategy,
10
+ strategy: detect_strategy(auth),
16
11
  scope: opts[:scope].to_s,
17
- identity: identity,
12
+ identity: AuthTrail.identity_method.call(request, opts, user),
18
13
  success: true,
19
14
  request: request,
20
15
  user: user
@@ -24,21 +19,27 @@ module AuthTrail
24
19
 
25
20
  def before_failure(env, opts)
26
21
  AuthTrail.safely do
27
- if opts[:message]
28
- request = ActionDispatch::Request.new(env)
29
- identity = request.params[opts[:scope]] && request.params[opts[:scope]][:email] rescue nil
22
+ request = ActionDispatch::Request.new(env)
30
23
 
31
- AuthTrail.track(
32
- strategy: "database_authenticatable",
33
- scope: opts[:scope].to_s,
34
- identity: identity,
35
- success: false,
36
- request: request,
37
- failure_reason: opts[:message].to_s
38
- )
39
- end
24
+ AuthTrail.track(
25
+ strategy: detect_strategy(env["warden"]),
26
+ scope: opts[:scope].to_s,
27
+ identity: AuthTrail.identity_method.call(request, opts, nil),
28
+ success: false,
29
+ request: request,
30
+ failure_reason: opts[:message].to_s
31
+ )
40
32
  end
41
33
  end
34
+
35
+ private
36
+
37
+ def detect_strategy(auth)
38
+ strategy = auth.env["omniauth.auth"]["provider"] if auth.env["omniauth.auth"]
39
+ strategy ||= auth.winning_strategy.class.name.split("::").last.underscore if auth.winning_strategy
40
+ strategy ||= "database_authenticatable"
41
+ strategy
42
+ end
42
43
  end
43
44
  end
44
45
  end
@@ -1,3 +1,3 @@
1
1
  module AuthTrail
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -1,15 +1,25 @@
1
+ # dependencies
1
2
  require "geocoder"
2
- require "rails"
3
3
  require "warden"
4
+
5
+ # modules
4
6
  require "auth_trail/engine"
5
7
  require "auth_trail/manager"
6
8
  require "auth_trail/version"
7
9
 
8
10
  module AuthTrail
9
11
  class << self
10
- attr_accessor :exclude_method, :geocode, :track_method
12
+ attr_accessor :exclude_method, :geocode, :track_method, :identity_method, :job_queue
11
13
  end
12
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
13
23
 
14
24
  def self.track(strategy:, scope:, identity:, success:, request:, user: nil, failure_reason: nil)
15
25
  info = {
@@ -19,12 +29,15 @@ module AuthTrail
19
29
  success: success,
20
30
  failure_reason: failure_reason,
21
31
  user: user,
22
- context: "#{request.params[:controller]}##{request.params[:action]}",
23
32
  ip: request.remote_ip,
24
33
  user_agent: request.user_agent,
25
34
  referrer: request.referrer
26
35
  }
27
36
 
37
+ if request.params[:controller]
38
+ info[:context] = "#{request.params[:controller]}##{request.params[:action]}"
39
+ end
40
+
28
41
  # if exclude_method throws an exception, default to not excluding
29
42
  exclude = AuthTrail.exclude_method && AuthTrail.safely(default: false) { AuthTrail.exclude_method.call(info) }
30
43
 
@@ -32,7 +45,11 @@ module AuthTrail
32
45
  if AuthTrail.track_method
33
46
  AuthTrail.track_method.call(info)
34
47
  else
35
- login_activity = LoginActivity.create!(info)
48
+ login_activity = LoginActivity.new
49
+ info.each do |k, v|
50
+ login_activity.try("#{k}=", v)
51
+ end
52
+ login_activity.save!
36
53
  AuthTrail::GeocodeJob.perform_later(login_activity) if AuthTrail.geocode
37
54
  end
38
55
  end
@@ -53,5 +70,5 @@ Warden::Manager.after_set_user except: :fetch do |user, auth, opts|
53
70
  end
54
71
 
55
72
  Warden::Manager.before_failure do |env, opts|
56
- AuthTrail::Manager.before_failure(env, opts)
73
+ AuthTrail::Manager.before_failure(env, opts) if opts[:message]
57
74
  end
@@ -1,24 +1,10 @@
1
- # taken from https://github.com/collectiveidea/audited/blob/master/lib/generators/audited/install_generator.rb
2
- require "rails/generators"
3
- require "rails/generators/migration"
4
- require "active_record"
5
1
  require "rails/generators/active_record"
6
2
 
7
3
  module Authtrail
8
4
  module Generators
9
5
  class InstallGenerator < Rails::Generators::Base
10
- include Rails::Generators::Migration
11
- source_root File.expand_path("../templates", __FILE__)
12
-
13
- # Implement the required interface for Rails::Generators::Migration.
14
- def self.next_migration_number(dirname) #:nodoc:
15
- next_migration_number = current_migration_number(dirname) + 1
16
- if ::ActiveRecord::Base.timestamped_migrations
17
- [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % next_migration_number].max
18
- else
19
- "%.3d" % next_migration_number
20
- end
21
- end
6
+ include ActiveRecord::Generators::Migration
7
+ source_root File.join(__dir__, "templates")
22
8
 
23
9
  def copy_migration
24
10
  migration_template "login_activities_migration.rb", "db/migrate/create_login_activities.rb", migration_version: migration_version
@@ -1,24 +1,25 @@
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
6
- t.text :identity
4
+ t.string :scope
5
+ t.string :strategy
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
11
- t.text :ip
10
+ t.string :context
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
+ t.float :latitude
18
+ t.float :longitude
17
19
  t.datetime :created_at
18
20
  end
19
21
 
20
22
  add_index :login_activities, :identity
21
23
  add_index :login_activities, :ip
22
- add_index :login_activities, :user_id
23
24
  end
24
25
  end
metadata CHANGED
@@ -1,17 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authtrail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
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: 2017-11-08 00:00:00.000000000 Z
11
+ date: 2020-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - ">="
@@ -82,6 +96,62 @@ dependencies:
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: minitest
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '5'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '5'
111
+ - !ruby/object:Gem::Dependency
112
+ name: combustion
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rails
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: sqlite3
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: devise
85
155
  requirement: !ruby/object:Gem::Requirement
86
156
  requirements:
87
157
  - - ">="
@@ -95,30 +165,25 @@ dependencies:
95
165
  - !ruby/object:Gem::Version
96
166
  version: '0'
97
167
  description:
98
- email:
99
- - andrew@chartkick.com
168
+ email: andrew@chartkick.com
100
169
  executables: []
101
170
  extensions: []
102
171
  extra_rdoc_files: []
103
172
  files:
104
- - ".gitignore"
105
173
  - CHANGELOG.md
106
- - Gemfile
107
- - Gemfile.lock
108
174
  - LICENSE.txt
109
175
  - README.md
110
- - Rakefile
111
176
  - app/jobs/auth_trail/geocode_job.rb
112
- - authtrail.gemspec
113
177
  - lib/auth_trail/engine.rb
114
178
  - lib/auth_trail/manager.rb
115
179
  - lib/auth_trail/version.rb
116
180
  - lib/authtrail.rb
117
181
  - lib/generators/authtrail/install_generator.rb
118
- - lib/generators/authtrail/templates/login_activities_migration.rb
119
- - lib/generators/authtrail/templates/login_activity_model.rb
182
+ - lib/generators/authtrail/templates/login_activities_migration.rb.tt
183
+ - lib/generators/authtrail/templates/login_activity_model.rb.tt
120
184
  homepage: https://github.com/ankane/authtrail
121
- licenses: []
185
+ licenses:
186
+ - MIT
122
187
  metadata: {}
123
188
  post_install_message:
124
189
  rdoc_options: []
@@ -128,15 +193,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
128
193
  requirements:
129
194
  - - ">="
130
195
  - !ruby/object:Gem::Version
131
- version: '0'
196
+ version: '2.4'
132
197
  required_rubygems_version: !ruby/object:Gem::Requirement
133
198
  requirements:
134
199
  - - ">="
135
200
  - !ruby/object:Gem::Version
136
201
  version: '0'
137
202
  requirements: []
138
- rubyforge_project:
139
- rubygems_version: 2.6.13
203
+ rubygems_version: 3.1.2
140
204
  signing_key:
141
205
  specification_version: 4
142
206
  summary: Track Devise login activity
data/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
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
@@ -1,125 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- authtrail (0.1.0)
5
- geocoder
6
- rails (>= 5)
7
- warden
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- actioncable (5.1.4)
13
- actionpack (= 5.1.4)
14
- nio4r (~> 2.0)
15
- websocket-driver (~> 0.6.1)
16
- actionmailer (5.1.4)
17
- actionpack (= 5.1.4)
18
- actionview (= 5.1.4)
19
- activejob (= 5.1.4)
20
- mail (~> 2.5, >= 2.5.4)
21
- rails-dom-testing (~> 2.0)
22
- actionpack (5.1.4)
23
- actionview (= 5.1.4)
24
- activesupport (= 5.1.4)
25
- rack (~> 2.0)
26
- rack-test (>= 0.6.3)
27
- rails-dom-testing (~> 2.0)
28
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
29
- actionview (5.1.4)
30
- activesupport (= 5.1.4)
31
- builder (~> 3.1)
32
- erubi (~> 1.4)
33
- rails-dom-testing (~> 2.0)
34
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
35
- activejob (5.1.4)
36
- activesupport (= 5.1.4)
37
- globalid (>= 0.3.6)
38
- activemodel (5.1.4)
39
- activesupport (= 5.1.4)
40
- activerecord (5.1.4)
41
- activemodel (= 5.1.4)
42
- activesupport (= 5.1.4)
43
- arel (~> 8.0)
44
- activesupport (5.1.4)
45
- concurrent-ruby (~> 1.0, >= 1.0.2)
46
- i18n (~> 0.7)
47
- minitest (~> 5.1)
48
- tzinfo (~> 1.1)
49
- arel (8.0.0)
50
- builder (3.2.3)
51
- concurrent-ruby (1.0.5)
52
- crass (1.0.2)
53
- erubi (1.7.0)
54
- geocoder (1.4.4)
55
- globalid (0.4.1)
56
- activesupport (>= 4.2.0)
57
- i18n (0.9.1)
58
- concurrent-ruby (~> 1.0)
59
- loofah (2.1.1)
60
- crass (~> 1.0.2)
61
- nokogiri (>= 1.5.9)
62
- mail (2.7.0)
63
- mini_mime (>= 0.1.1)
64
- method_source (0.9.0)
65
- mini_mime (0.1.4)
66
- mini_portile2 (2.3.0)
67
- minitest (5.10.3)
68
- nio4r (2.1.0)
69
- nokogiri (1.8.1)
70
- mini_portile2 (~> 2.3.0)
71
- rack (2.0.3)
72
- rack-test (0.7.0)
73
- rack (>= 1.0, < 3)
74
- rails (5.1.4)
75
- actioncable (= 5.1.4)
76
- actionmailer (= 5.1.4)
77
- actionpack (= 5.1.4)
78
- actionview (= 5.1.4)
79
- activejob (= 5.1.4)
80
- activemodel (= 5.1.4)
81
- activerecord (= 5.1.4)
82
- activesupport (= 5.1.4)
83
- bundler (>= 1.3.0)
84
- railties (= 5.1.4)
85
- sprockets-rails (>= 2.0.0)
86
- rails-dom-testing (2.0.3)
87
- activesupport (>= 4.2.0)
88
- nokogiri (>= 1.6)
89
- rails-html-sanitizer (1.0.3)
90
- loofah (~> 2.0)
91
- railties (5.1.4)
92
- actionpack (= 5.1.4)
93
- activesupport (= 5.1.4)
94
- method_source
95
- rake (>= 0.8.7)
96
- thor (>= 0.18.1, < 2.0)
97
- rake (12.2.1)
98
- sprockets (3.7.1)
99
- concurrent-ruby (~> 1.0)
100
- rack (> 1, < 3)
101
- sprockets-rails (3.2.1)
102
- actionpack (>= 4.0)
103
- activesupport (>= 4.0)
104
- sprockets (>= 3.0.0)
105
- thor (0.20.0)
106
- thread_safe (0.3.6)
107
- tzinfo (1.2.4)
108
- thread_safe (~> 0.1)
109
- warden (1.2.7)
110
- rack (>= 1.0)
111
- websocket-driver (0.6.5)
112
- websocket-extensions (>= 0.1.0)
113
- websocket-extensions (0.1.2)
114
-
115
- PLATFORMS
116
- ruby
117
-
118
- DEPENDENCIES
119
- authtrail!
120
- bundler
121
- minitest
122
- rake
123
-
124
- BUNDLED WITH
125
- 1.16.0
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,29 +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 "rails", ">= 5"
23
- spec.add_dependency "warden"
24
- spec.add_dependency "geocoder"
25
-
26
- spec.add_development_dependency "bundler"
27
- spec.add_development_dependency "rake"
28
- spec.add_development_dependency "minitest"
29
- end