castle_devise 0.1.0 → 0.2.0

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: c13e653cf7d00df4cdb2436431a031be5c4120d5e667ff2c5feb00effd374011
4
- data.tar.gz: 8c4c4fafd623cda48e9f9c125c81cda8071ae81e7ec62cad74bc0476bd89c4ea
3
+ metadata.gz: 7cc0ef1100f1ceb942fa1be6553b6b7ca862656e3c7a6b9b57459285a69a46a7
4
+ data.tar.gz: 9222268f8c6e22fb367bbc0cc9a0ce52b5dc8854f8eefa0f2f34e2afaa4a92eb
5
5
  SHA512:
6
- metadata.gz: 3066ab56d17f1d3097f4aecaa115162e0e9263016cd4dce602a0491d5071ad5fcb933871d6830147303ca859cd60e5c503cdd30dc23112e0b94c0337e4cabee2
7
- data.tar.gz: b8c18958cc92790e26e4e222c8c7f34f4db8be72c1c55d54225ca23dd427bcad7082c1efe7208655dbe43c3d31840fbc4875797e53d7b074eef88e21d1a7d118
6
+ metadata.gz: b6a11b460114c2133776991e4cde4f11a9030e5b019ea0162712b070a72b9adbd50cfad1f866cf90a92b05f505464ded6d9727a474c22edd5f65a9ed6f4fb0d6
7
+ data.tar.gz: 292fe6b7dff6f11135c8e63b53ee4484cc8c1dd93dab449d58ef765b29935a8f4bbb925896bf4b4d06b21f1e44cc7ce748af8226287c832b9e8409026bc81c23
@@ -1,25 +1,43 @@
1
1
  name: Specs
2
2
 
3
- on: [push,pull_request]
3
+ on: [push]
4
4
 
5
5
  jobs:
6
6
  build:
7
7
  environment: tests
8
8
  runs-on: ubuntu-latest
9
+
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ ruby: ["2.6", "2.7", "3.0"]
14
+ rails: ["5.2", "6.0", "6.1"]
15
+ exclude:
16
+ - ruby: "3.0"
17
+ rails: "5.2"
18
+
9
19
  steps:
10
20
  - uses: actions/checkout@v2
11
- - name: Set up Ruby
21
+ - name: Set up Ruby ${{ matrix.ruby }}
12
22
  uses: ruby/setup-ruby@v1
13
23
  with:
14
- ruby-version: 2.6.5
15
- - name: Run specs
24
+ ruby-version: ${{ matrix.ruby }}
25
+ - name: Install depenencies
26
+ env:
27
+ BUNDLE_GEMFILE: gemfiles/rails_${{ matrix.rails }}.gemfile
16
28
  run: |
17
- gem install bundler -v 2.2.19
29
+ gem update --system
30
+ bundle config path vendor/bundle
18
31
  bundle install
19
- bundle exec rake
32
+ - name: Run specs
20
33
  env:
34
+ BUNDLE_GEMFILE: gemfiles/rails_${{ matrix.rails }}.gemfile
21
35
  CASTLE_API_SECRET: ${{ secrets.CASTLE_API_SECRET }}
36
+ run: |
37
+ bundle exec rake
22
38
  - name: Simplecov Report
39
+ if:
40
+ ${{ matrix.rails == '6.1' && matrix.ruby >= '3.0' }}
23
41
  uses: aki77/simplecov-report-action@v1
24
42
  with:
25
43
  token: ${{ secrets.GITHUB_TOKEN }}
data/.gitignore CHANGED
@@ -13,6 +13,12 @@
13
13
  # IntelliJ
14
14
  .idea/
15
15
 
16
+ .bundle
17
+
18
+ # We do want the CI builds to fail when new dependencies ship breaking changes
19
+ # so don't checkin the lockfiles used for the build.
20
+ gemfiles/*.lock
21
+
16
22
  vendor/
17
23
 
18
24
  spec/dummy_app/log/
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
- --format documentation
1
+ --format progress
2
2
  --color
3
3
  --require spec_helper
data/Appraisals ADDED
@@ -0,0 +1,13 @@
1
+ if RUBY_VERSION < "3.0"
2
+ appraise "rails-5.2" do
3
+ gem "railties", "~> 5.2.6"
4
+ end
5
+ end
6
+
7
+ appraise "rails-6.0" do
8
+ gem "railties", "~> 6.0.4"
9
+ end
10
+
11
+ appraise "rails-6.1" do
12
+ gem "railties", "~> 6.1.4"
13
+ end
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
- ## [Unreleased]
1
+ # Changelog
2
2
 
3
- ## [0.1.0] - 2021-06-11
3
+ ## [Unreleased][main]
4
+
5
+ ## [0.2.0] - 2021-08-12
6
+
7
+ - Add Log action for $profile_update event with $succeeded and $failed statuses during reset password process
8
+ - Add Risk action for $profile_update event with $attempted status and Log action for $profile_update event with $succeeded and $failed statuses
9
+ - Add Log action for $password_reset_request event with $succeeded and $failed statuses
10
+ - Run specs in multiple ruby and rails versions.
11
+
12
+ ## [0.1.0] - 2021-07-08
4
13
 
5
14
  - Initial release
15
+
16
+ [main]: https://github.com/castle/castle_devise/compare/v0.2.0...HEAD
17
+ [0.2.0]: https://github.com/castle/castle_devise/compare/v0.1.0...v0.2.0
18
+ [0.1.0]: https://github.com/castle/castle_devise/releases/tag/v0.1.0
data/Gemfile CHANGED
@@ -5,8 +5,10 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in castle-devise.gemspec
6
6
  gemspec
7
7
 
8
+ gem "actionmailer"
8
9
  gem "activerecord"
9
- gem "railties", "~> 5.2"
10
+ gem "byebug"
11
+ gem "railties", "~> 6.1"
10
12
  gem "rake"
11
13
  gem "rspec"
12
14
  gem "rspec-rails"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- castle_devise (0.1.0)
4
+ castle_devise (0.2.0)
5
5
  activesupport (>= 5.0)
6
6
  castle-rb (>= 7.0, < 8.0)
7
7
  devise (>= 4.3.0, < 5.0)
@@ -9,36 +9,50 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- actionpack (5.2.6)
13
- actionview (= 5.2.6)
14
- activesupport (= 5.2.6)
15
- rack (~> 2.0, >= 2.0.8)
12
+ actionmailer (6.1.4)
13
+ actionpack (= 6.1.4)
14
+ actionview (= 6.1.4)
15
+ activejob (= 6.1.4)
16
+ activesupport (= 6.1.4)
17
+ mail (~> 2.5, >= 2.5.4)
18
+ rails-dom-testing (~> 2.0)
19
+ actionpack (6.1.4)
20
+ actionview (= 6.1.4)
21
+ activesupport (= 6.1.4)
22
+ rack (~> 2.0, >= 2.0.9)
16
23
  rack-test (>= 0.6.3)
17
24
  rails-dom-testing (~> 2.0)
18
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
19
- actionview (5.2.6)
20
- activesupport (= 5.2.6)
25
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
26
+ actionview (6.1.4)
27
+ activesupport (= 6.1.4)
21
28
  builder (~> 3.1)
22
29
  erubi (~> 1.4)
23
30
  rails-dom-testing (~> 2.0)
24
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
25
- activemodel (5.2.6)
26
- activesupport (= 5.2.6)
27
- activerecord (5.2.6)
28
- activemodel (= 5.2.6)
29
- activesupport (= 5.2.6)
30
- arel (>= 9.0)
31
- activesupport (5.2.6)
31
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
32
+ activejob (6.1.4)
33
+ activesupport (= 6.1.4)
34
+ globalid (>= 0.3.6)
35
+ activemodel (6.1.4)
36
+ activesupport (= 6.1.4)
37
+ activerecord (6.1.4)
38
+ activemodel (= 6.1.4)
39
+ activesupport (= 6.1.4)
40
+ activesupport (6.1.4)
32
41
  concurrent-ruby (~> 1.0, >= 1.0.2)
33
- i18n (>= 0.7, < 2)
34
- minitest (~> 5.1)
35
- tzinfo (~> 1.1)
36
- addressable (2.7.0)
42
+ i18n (>= 1.6, < 2)
43
+ minitest (>= 5.1)
44
+ tzinfo (~> 2.0)
45
+ zeitwerk (~> 2.3)
46
+ addressable (2.8.0)
37
47
  public_suffix (>= 2.0.2, < 5.0)
38
- arel (9.0.0)
48
+ appraisal (2.3.0)
49
+ bundler
50
+ rake
51
+ thor (>= 0.14.0)
39
52
  ast (2.4.2)
40
53
  bcrypt (3.1.16)
41
54
  builder (3.2.4)
55
+ byebug (11.1.3)
42
56
  castle-rb (7.1.1)
43
57
  concurrent-ruby (1.1.9)
44
58
  crack (0.4.5)
@@ -53,19 +67,24 @@ GEM
53
67
  diff-lcs (1.4.4)
54
68
  docile (1.4.0)
55
69
  erubi (1.10.0)
70
+ globalid (0.5.1)
71
+ activesupport (>= 5.0)
56
72
  hashdiff (1.0.1)
57
73
  i18n (1.8.10)
58
74
  concurrent-ruby (~> 1.0)
59
75
  loofah (2.10.0)
60
76
  crass (~> 1.0.2)
61
77
  nokogiri (>= 1.5.9)
78
+ mail (2.7.1)
79
+ mini_mime (>= 0.1.1)
62
80
  method_source (1.0.0)
81
+ mini_mime (1.1.0)
63
82
  minitest (5.14.4)
64
83
  nokogiri (1.11.7-x86_64-darwin)
65
84
  racc (~> 1.4)
66
85
  orm_adapter (0.5.0)
67
86
  parallel (1.20.1)
68
- parser (3.0.1.1)
87
+ parser (3.0.2.0)
69
88
  ast (~> 2.4.1)
70
89
  public_suffix (4.0.6)
71
90
  racc (1.5.2)
@@ -77,14 +96,14 @@ GEM
77
96
  nokogiri (>= 1.6)
78
97
  rails-html-sanitizer (1.3.0)
79
98
  loofah (~> 2.3)
80
- railties (5.2.6)
81
- actionpack (= 5.2.6)
82
- activesupport (= 5.2.6)
99
+ railties (6.1.4)
100
+ actionpack (= 6.1.4)
101
+ activesupport (= 6.1.4)
83
102
  method_source
84
- rake (>= 0.8.7)
85
- thor (>= 0.19.0, < 2.0)
103
+ rake (>= 0.13)
104
+ thor (~> 1.0)
86
105
  rainbow (3.0.0)
87
- rake (13.0.3)
106
+ rake (13.0.6)
88
107
  regexp_parser (2.1.1)
89
108
  responders (3.0.1)
90
109
  actionpack (>= 5.0)
@@ -111,18 +130,18 @@ GEM
111
130
  rspec-mocks (~> 3.10)
112
131
  rspec-support (~> 3.10)
113
132
  rspec-support (3.10.2)
114
- rubocop (1.14.0)
133
+ rubocop (1.18.4)
115
134
  parallel (~> 1.10)
116
135
  parser (>= 3.0.0.0)
117
136
  rainbow (>= 2.2.2, < 4.0)
118
137
  regexp_parser (>= 1.8, < 3.0)
119
138
  rexml
120
- rubocop-ast (>= 1.5.0, < 2.0)
139
+ rubocop-ast (>= 1.8.0, < 2.0)
121
140
  ruby-progressbar (~> 1.7)
122
141
  unicode-display_width (>= 1.4.0, < 3.0)
123
- rubocop-ast (1.7.0)
142
+ rubocop-ast (1.8.0)
124
143
  parser (>= 3.0.1.1)
125
- rubocop-performance (1.11.2)
144
+ rubocop-performance (1.11.4)
126
145
  rubocop (>= 1.7.0, < 2.0)
127
146
  rubocop-ast (>= 0.4.0)
128
147
  ruby-progressbar (1.11.0)
@@ -133,13 +152,12 @@ GEM
133
152
  simplecov-html (0.12.3)
134
153
  simplecov_json_formatter (0.1.3)
135
154
  sqlite3 (1.4.2)
136
- standard (1.1.1)
137
- rubocop (= 1.14.0)
138
- rubocop-performance (= 1.11.2)
155
+ standard (1.1.6)
156
+ rubocop (= 1.18.4)
157
+ rubocop-performance (= 1.11.4)
139
158
  thor (1.1.0)
140
- thread_safe (0.3.6)
141
- tzinfo (1.2.9)
142
- thread_safe (~> 0.1)
159
+ tzinfo (2.0.4)
160
+ concurrent-ruby (~> 1.0)
143
161
  unicode-display_width (2.0.0)
144
162
  vcr (6.0.0)
145
163
  warden (1.2.9)
@@ -148,14 +166,19 @@ GEM
148
166
  addressable (>= 2.3.6)
149
167
  crack (>= 0.3.2)
150
168
  hashdiff (>= 0.4.0, < 2.0.0)
169
+ zeitwerk (2.4.2)
151
170
 
152
171
  PLATFORMS
153
172
  x86_64-darwin-18
173
+ x86_64-darwin-19
154
174
 
155
175
  DEPENDENCIES
176
+ actionmailer
156
177
  activerecord
178
+ appraisal (~> 2.3.0)
179
+ byebug
157
180
  castle_devise!
158
- railties (~> 5.2)
181
+ railties (~> 6.1)
159
182
  rake
160
183
  rspec
161
184
  rspec-rails
@@ -166,4 +189,4 @@ DEPENDENCIES
166
189
  webmock
167
190
 
168
191
  BUNDLED WITH
169
- 2.2.15
192
+ 2.2.23
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Gem Version](https://badge.fury.io/rb/castle_devise.svg)](https://badge.fury.io/rb/castle_devise)
2
+
1
3
  **Disclaimer:** CastleDevise is currently in beta. There might be some upcoming breaking changes to the gem before we stabilize the API.
2
4
 
3
5
  ---
@@ -9,6 +11,8 @@ CastleDevise is a [Devise](https://github.com/heartcombo/devise) plugin that int
9
11
  It currently provides the following features:
10
12
  - preventing bots from registration attacks using Castle's [Filter API](https://docs.castle.io/v1/reference/api-reference/#filter)
11
13
  - preventing ATO attacks using Castle's [Risk API](https://docs.castle.io/v1/reference/api-reference/#risk)
14
+ - blocks attempts to update passwords for high-risk logged-in users
15
+ - logs attempts of password reset flows so that you can see them on the Castle dashboard
12
16
 
13
17
  If you want to learn about all capabilities of Castle, please take a look at [our documentation](https://docs.castle.io/).
14
18
 
@@ -83,9 +87,19 @@ You're set! Now verify that everything works by logging in to your application a
83
87
 
84
88
  #### Further steps if you're using Webpacker
85
89
 
86
- Add `castle.js` to your package.json file.
90
+ Add `castle.js` to your package.json file:
91
+
92
+ ```
93
+ yarn add castle.js
94
+ ```
95
+
96
+ Require castle.js in your application pack:
97
+
98
+ ```javascript
99
+ require("castle.js");
87
100
 
88
- TODO: fill this in.
101
+ _castle("setAppId", YOUR_APPLICATION_ID);
102
+ ```
89
103
 
90
104
 
91
105
  ## How-Tos
@@ -161,7 +175,10 @@ class User < ApplicationRecord
161
175
  before_registration: true,
162
176
  # set it to false to prevent CastleDevise from
163
177
  # sending risk($login) and log($login, $failed)
164
- after_login: true
178
+ after_login: true,
179
+ # set it to false to prevent CastleDevise from
180
+ # sending log($password_reset_request)
181
+ after_password_reset_request: true
165
182
  }
166
183
  end
167
184
  ```
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.homepage = "https://github.com/castle/castle_devise"
12
12
  spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
13
13
 
14
- spec.authors = ["Kacper Madej", "Johan Brissmyr"]
14
+ spec.authors = ["Kacper Madej", "Dawid Libiszewski", "Johan Brissmyr"]
15
15
  spec.email = ["kacper@castle.io"]
16
16
 
17
17
  spec.metadata["homepage_uri"] = spec.homepage
@@ -27,9 +27,9 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
- # Uncomment to register a new dependency of your gem
31
- spec.add_dependency "castle-rb", ">= 7.0", "< 8.0"
32
30
  spec.add_dependency "activesupport", ">= 5.0"
31
+ spec.add_dependency "castle-rb", ">= 7.0", "< 8.0"
32
+ spec.add_dependency "devise", ">= 4.3.0", "< 5.0"
33
33
 
34
- spec.add_runtime_dependency "devise", ">= 4.3.0", "< 5.0"
34
+ spec.add_development_dependency "appraisal", "~> 2.3.0"
35
35
  end
@@ -0,0 +1,17 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "actionmailer"
6
+ gem "activerecord"
7
+ gem "railties", "~> 5.2.6"
8
+ gem "rake"
9
+ gem "rspec"
10
+ gem "rspec-rails"
11
+ gem "simplecov"
12
+ gem "standard"
13
+ gem "sqlite3"
14
+ gem "vcr"
15
+ gem "webmock"
16
+
17
+ gemspec path: "../"
@@ -0,0 +1,17 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "actionmailer"
6
+ gem "activerecord"
7
+ gem "railties", "~> 6.0.4"
8
+ gem "rake"
9
+ gem "rspec"
10
+ gem "rspec-rails"
11
+ gem "simplecov"
12
+ gem "standard"
13
+ gem "sqlite3"
14
+ gem "vcr"
15
+ gem "webmock"
16
+
17
+ gemspec path: "../"
@@ -0,0 +1,17 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "actionmailer"
6
+ gem "activerecord"
7
+ gem "railties", "~> 6.1.4"
8
+ gem "rake"
9
+ gem "rspec"
10
+ gem "rspec-rails"
11
+ gem "simplecov"
12
+ gem "standard"
13
+ gem "sqlite3"
14
+ gem "vcr"
15
+ gem "webmock"
16
+
17
+ gemspec path: "../"
data/lib/castle_devise.rb CHANGED
@@ -60,8 +60,8 @@ require_relative "castle_devise/controllers/helpers"
60
60
  require_relative "castle_devise/helpers/castle_helper"
61
61
  require_relative "castle_devise/hooks/castle_protectable"
62
62
  require_relative "castle_devise/models/castle_protectable"
63
+ require_relative "castle_devise/patches/passwords_controller"
63
64
  require_relative "castle_devise/patches/registrations_controller"
64
-
65
65
  require_relative "castle_devise/rails"
66
66
 
67
67
  # Monkey patching Devise module in order to add
@@ -71,7 +71,9 @@ module Devise
71
71
  mattr_accessor :castle_hooks
72
72
  @@castle_hooks = {
73
73
  before_registration: true,
74
- after_login: true
74
+ after_login: true,
75
+ after_password_reset_request: true,
76
+ profile_update: true
75
77
  }
76
78
  end
77
79
 
@@ -10,7 +10,12 @@ module Devise
10
10
  # castle_hooks: configures which events trigger Castle API calls
11
11
  # {
12
12
  # after_login: true, # trigger risk($login) and log($login, $failed),
13
- # before_registration: true # trigger filter($registration)
13
+ # before_registration: true, # trigger filter($registration)
14
+ # after_password_reset_request: true, # trigger log($password_reset_request, $succeeded)
15
+ # # and log($password_reset_request, $failed)
16
+ # profile_update: true # trigger risk($profile_update, $attempted),
17
+ # # log($profile_update, $succeeded)
18
+ # # and log($profile_update, $failed)
14
19
  # }
15
20
  module CastleProtectable
16
21
  extend ActiveSupport::Concern
@@ -6,7 +6,8 @@ module CastleDevise
6
6
  # Applies monkey-patches to Devise controllers
7
7
  # @api private
8
8
  def apply
9
- Devise::RegistrationsController.send(:include, Patches::RegistrationsController)
9
+ Devise::RegistrationsController.send(:prepend, Patches::RegistrationsController)
10
+ Devise::PasswordsController.send(:prepend, Patches::PasswordsController)
10
11
  end
11
12
  end
12
13
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CastleDevise
4
+ module Patches
5
+ # Monkey-patch for
6
+ # {https://github.com/heartcombo/devise/blob/master/app/controllers/devise/passwords_controller.rb Devise::PasswordsController}
7
+ # which includes Castle to the password reset requests flow.
8
+ module PasswordsController
9
+ extend ActiveSupport::Concern
10
+
11
+ # PUT /resource/password
12
+ # @note Notice, this must happen within a block because before calling
13
+ # "reset_password_by_token" method we don't know what resource we operate on.
14
+ def update
15
+ super do |resource|
16
+ next unless resource_class.castle_hooks[:profile_update]
17
+
18
+ begin
19
+ CastleDevise.sdk_facade.log(
20
+ event: "$profile_update",
21
+ status: resource.errors.empty? ? "$succeeded" : "$failed",
22
+ context: CastleDevise::Context.from_rack_env(request.env, scope_name, resource)
23
+ )
24
+ rescue Castle::Error => e
25
+ # log API errors and pass-through it
26
+ CastleDevise.logger.error("[CastleDevise] log($password_reset_request): #{e}")
27
+ end
28
+ end
29
+ end
30
+
31
+ # POST /resource/password
32
+ def create
33
+ super do |resource|
34
+ next unless resource_class.castle_hooks[:after_password_reset_request]
35
+
36
+ begin
37
+ CastleDevise.sdk_facade.log(
38
+ event: "$password_reset_request",
39
+ status: resource.persisted? ? "$succeeded" : "$failed",
40
+ context: CastleDevise::Context.from_rack_env(request.env, scope_name, resource)
41
+ )
42
+ rescue Castle::Error => e
43
+ # log API errors and pass-through it
44
+ CastleDevise.logger.error("[CastleDevise] log($password_reset_request): #{e}")
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -8,8 +8,56 @@ module CastleDevise
8
8
  module RegistrationsController
9
9
  extend ActiveSupport::Concern
10
10
 
11
- included do
12
- before_action :castle_filter, only: :create
11
+ # @param klass [self]
12
+ def self.prepended(klass)
13
+ klass.class_eval do
14
+ before_action :castle_filter, only: :create
15
+ end
16
+ end
17
+
18
+ # PUT /resource
19
+ def update
20
+ context = CastleDevise::Context.from_rack_env(request.env, scope_name, resource)
21
+
22
+ if resource_class.castle_hooks[:profile_update]
23
+ begin
24
+ # TODO: Implement a verification mechanism for this action.
25
+ CastleDevise.sdk_facade.risk(
26
+ event: "$profile_update",
27
+ status: "$attempted",
28
+ context: context
29
+ )
30
+ rescue Castle::InvalidParametersError
31
+ # TODO: We should act differently if the error is about missing/invalid request token
32
+ # compared to any other validation errors. However, we can't do this with the
33
+ # current Castle SDK as it doesn't give us any way to differentiate these two cases.
34
+ CastleDevise.logger.warn(
35
+ "[CastleDevise] /v1/risk request contained invalid parameters." \
36
+ " This might mean that either you didn't configure Castle's Javascript properly," \
37
+ " or a request has been made without Javascript (eg. cURL/bot)." \
38
+ " Such a request is treated as if Castle responded with a 'deny' action in" \
39
+ " non-monitoring mode."
40
+ )
41
+ rescue Castle::Error => e
42
+ # log API errors and allow
43
+ CastleDevise.logger.error("[CastleDevise] risk($profile_update): #{e}")
44
+ end
45
+ end
46
+
47
+ super do |resource|
48
+ next unless resource_class.castle_hooks[:profile_update]
49
+
50
+ begin
51
+ CastleDevise.sdk_facade.log(
52
+ event: "$profile_update",
53
+ status: resource.saved_changes? ? "$succeeded" : "$failed",
54
+ context: context
55
+ )
56
+ rescue Castle::Error => e
57
+ # log API errors and pass-through it
58
+ CastleDevise.logger.error("[CastleDevise] log($password_reset_request): #{e}")
59
+ end
60
+ end
13
61
  end
14
62
 
15
63
  # Sends a /v1/filter request to Castle
@@ -40,7 +88,8 @@ module CastleDevise
40
88
  "[CastleDevise] /v1/filter request contained invalid parameters." \
41
89
  " This might mean that either you didn't configure Castle's Javascript properly, or" \
42
90
  " a request has been made without Javascript (eg. cURL/bot)." \
43
- " Such a request is treated as if Castle responded with a 'deny' action in non-monitoring mode."
91
+ " Such a request is treated as if Castle responded with a 'deny' action in" \
92
+ " non-monitoring mode."
44
93
  )
45
94
 
46
95
  unless CastleDevise.monitoring_mode?
@@ -37,13 +37,14 @@ module CastleDevise
37
37
 
38
38
  # Sends request to the /v1/risk endpoint.
39
39
  # @param event [String]
40
+ # @param status [String]
40
41
  # @param context [CastleDevise::Context]
41
42
  # @return [Hash] Raw API response
42
43
  # @see https://docs.castle.io/v1/reference/api-reference/#v1risk
43
- def risk(event:, context:)
44
+ def risk(event:, context:, status: "$succeeded")
44
45
  payload = {
45
46
  event: event,
46
- status: "$succeeded",
47
+ status: status,
47
48
  user: {
48
49
  id: context.castle_id,
49
50
  email: context.email,
@@ -68,15 +69,25 @@ module CastleDevise
68
69
  # @return [Hash] Raw API response
69
70
  # @see https://docs.castle.io/v1/reference/api-reference/#v1log
70
71
  def log(event:, status:, context:)
71
- payload = {
72
- event: event,
73
- status: status,
74
- user: {
72
+ return if context.castle_id.blank? && context.email.blank?
73
+
74
+ user = if context.castle_id
75
+ {
75
76
  id: context.castle_id,
76
77
  email: context.email,
77
78
  registered_at: format_time(context.registered_at),
78
79
  traits: context.user_traits
79
- }.compact,
80
+ }
81
+ else
82
+ {
83
+ email: context.email
84
+ }
85
+ end
86
+
87
+ payload = {
88
+ event: event,
89
+ status: status,
90
+ user: user,
80
91
  context: payload_context(context.rack_request)
81
92
  }
82
93
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CastleDevise
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,50 +1,51 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: castle_devise
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kacper Madej
8
+ - Dawid Libiszewski
8
9
  - Johan Brissmyr
9
10
  autorequire:
10
11
  bindir: exe
11
12
  cert_chain: []
12
- date: 2021-07-08 00:00:00.000000000 Z
13
+ date: 2021-08-12 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
- name: castle-rb
16
+ name: activesupport
16
17
  requirement: !ruby/object:Gem::Requirement
17
18
  requirements:
18
19
  - - ">="
19
20
  - !ruby/object:Gem::Version
20
- version: '7.0'
21
- - - "<"
22
- - !ruby/object:Gem::Version
23
- version: '8.0'
21
+ version: '5.0'
24
22
  type: :runtime
25
23
  prerelease: false
26
24
  version_requirements: !ruby/object:Gem::Requirement
27
25
  requirements:
28
26
  - - ">="
29
27
  - !ruby/object:Gem::Version
30
- version: '7.0'
31
- - - "<"
32
- - !ruby/object:Gem::Version
33
- version: '8.0'
28
+ version: '5.0'
34
29
  - !ruby/object:Gem::Dependency
35
- name: activesupport
30
+ name: castle-rb
36
31
  requirement: !ruby/object:Gem::Requirement
37
32
  requirements:
38
33
  - - ">="
39
34
  - !ruby/object:Gem::Version
40
- version: '5.0'
35
+ version: '7.0'
36
+ - - "<"
37
+ - !ruby/object:Gem::Version
38
+ version: '8.0'
41
39
  type: :runtime
42
40
  prerelease: false
43
41
  version_requirements: !ruby/object:Gem::Requirement
44
42
  requirements:
45
43
  - - ">="
46
44
  - !ruby/object:Gem::Version
47
- version: '5.0'
45
+ version: '7.0'
46
+ - - "<"
47
+ - !ruby/object:Gem::Version
48
+ version: '8.0'
48
49
  - !ruby/object:Gem::Dependency
49
50
  name: devise
50
51
  requirement: !ruby/object:Gem::Requirement
@@ -65,6 +66,20 @@ dependencies:
65
66
  - - "<"
66
67
  - !ruby/object:Gem::Version
67
68
  version: '5.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: appraisal
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.3.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.3.0
68
83
  description: castle_devise provides out-of-the-box protection against bot registrations
69
84
  and account takeover attacks.
70
85
  email:
@@ -77,6 +92,7 @@ files:
77
92
  - ".github/workflows/specs.yml"
78
93
  - ".gitignore"
79
94
  - ".rspec"
95
+ - Appraisals
80
96
  - CHANGELOG.md
81
97
  - Gemfile
82
98
  - Gemfile.lock
@@ -86,6 +102,9 @@ files:
86
102
  - bin/console
87
103
  - bin/setup
88
104
  - castle_devise.gemspec
105
+ - gemfiles/rails_5.2.gemfile
106
+ - gemfiles/rails_6.0.gemfile
107
+ - gemfiles/rails_6.1.gemfile
89
108
  - lib/castle_devise.rb
90
109
  - lib/castle_devise/configuration.rb
91
110
  - lib/castle_devise/context.rb
@@ -94,6 +113,7 @@ files:
94
113
  - lib/castle_devise/hooks/castle_protectable.rb
95
114
  - lib/castle_devise/models/castle_protectable.rb
96
115
  - lib/castle_devise/patches.rb
116
+ - lib/castle_devise/patches/passwords_controller.rb
97
117
  - lib/castle_devise/patches/registrations_controller.rb
98
118
  - lib/castle_devise/rails.rb
99
119
  - lib/castle_devise/sdk_facade.rb