securenative 0.1.5 → 0.1.16

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +57 -0
  3. data/.github/workflows/publish.yml +60 -0
  4. data/.github/workflows/test.yml +45 -0
  5. data/.rakeTasks +7 -0
  6. data/.rspec +3 -0
  7. data/.travis.yml +6 -0
  8. data/Gemfile +4 -1
  9. data/Gemfile.lock +28 -2
  10. data/README.md +134 -66
  11. data/Rakefile +5 -1
  12. data/VERSION +1 -0
  13. data/lib/securenative/api_manager.rb +30 -0
  14. data/lib/securenative/config/configuration_builder.rb +26 -0
  15. data/lib/securenative/config/configuration_manager.rb +53 -0
  16. data/lib/securenative/config/securenative_options.rb +18 -0
  17. data/lib/securenative/context/context_builder.rb +59 -0
  18. data/lib/securenative/context/securenative_context.rb +14 -0
  19. data/lib/securenative/enums/api_route.rb +4 -0
  20. data/lib/securenative/enums/event_types.rb +21 -0
  21. data/lib/securenative/enums/failover_strategy.rb +4 -0
  22. data/lib/securenative/enums/risk_level.rb +5 -0
  23. data/lib/securenative/event_manager.rb +122 -61
  24. data/lib/securenative/event_options_builder.rb +21 -0
  25. data/lib/securenative/exceptions/securenative_config_exception.rb +2 -0
  26. data/lib/securenative/exceptions/securenative_http_exception.rb +2 -0
  27. data/lib/securenative/exceptions/securenative_invalid_options_exception.rb +2 -0
  28. data/lib/securenative/exceptions/securenative_invalid_uri_exception.rb +2 -0
  29. data/lib/securenative/exceptions/securenative_parse_exception.rb +2 -0
  30. data/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb +2 -0
  31. data/lib/securenative/exceptions/securenative_sdk_exception.rb +2 -0
  32. data/lib/securenative/http/http_response.rb +10 -0
  33. data/lib/securenative/http/securenative_http_client.rb +30 -0
  34. data/lib/securenative/logger.rb +42 -0
  35. data/lib/securenative/models/client_token.rb +10 -0
  36. data/lib/securenative/models/device.rb +8 -0
  37. data/lib/securenative/models/event_options.rb +13 -0
  38. data/lib/securenative/models/request_context.rb +15 -0
  39. data/lib/securenative/models/request_options.rb +10 -0
  40. data/lib/securenative/models/sdk_event.rb +25 -0
  41. data/lib/securenative/models/user_traits.rb +10 -0
  42. data/lib/securenative/models/verify_result.rb +10 -0
  43. data/lib/securenative/securenative.iml +9 -0
  44. data/lib/securenative/securenative.rb +82 -0
  45. data/lib/securenative/utils/date_utils.rb +7 -0
  46. data/lib/securenative/utils/encryption_utils.rb +38 -0
  47. data/lib/securenative/utils/ip_utils.rb +22 -0
  48. data/lib/securenative/utils/request_utils.rb +21 -0
  49. data/lib/securenative/utils/signature_utils.rb +14 -0
  50. data/lib/securenative/utils/utils.rb +9 -0
  51. data/lib/securenative/utils/version_utils.rb +10 -0
  52. data/securenative.gemspec +4 -4
  53. metadata +51 -15
  54. data/lib/securenative.rb +0 -39
  55. data/lib/securenative/config.rb +0 -9
  56. data/lib/securenative/event_options.rb +0 -86
  57. data/lib/securenative/event_type.rb +0 -21
  58. data/lib/securenative/http_client.rb +0 -20
  59. data/lib/securenative/secure_native_sdk.rb +0 -62
  60. data/lib/securenative/securenative_options.rb +0 -17
  61. data/lib/securenative/sn_exception.rb +0 -5
  62. data/lib/securenative/utils.rb +0 -41
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b39e9c3c819d0191bcf78f5813681f6679b82c5a864eb04f7bdd05d754b01643
4
- data.tar.gz: a21bcbf70729dace6553c7853154f6a76d341d894a9398cce5c298e9201e8ed7
3
+ metadata.gz: 9b47b308123b4c5c01e92666737a18cdc3bed2757b8486c982fbe6b3f4d3a137
4
+ data.tar.gz: 9b7d71c86d11319bac529cd21e7c7e9647f8d1ffadc8a870000adf53308c1ee6
5
5
  SHA512:
6
- metadata.gz: e4e85d1e8119c75f2e31dfdf74231a20bfc0b5af77b30cca2886a2860a0f7354d28956fcb8aa9a155b3a68c4fe383de9789d9d751ee11111f34646e9aa01db70
7
- data.tar.gz: fc5a540361c33c0570d7be6769418cc2b58ed484e22ca59697508c5f67aca673674c7dd505f53d23ddf0022335a26dc04c95bc93cc1507e174f0af423b1c791e
6
+ metadata.gz: 3c3a1914b13f3fc2faf39f2cdaa48be431f4258d267748318174d2ee30877f1f72f2a2d2f5b93321603f2ad115414b7e3378f360d10c5a9fc9b35cabe4532772
7
+ data.tar.gz: de8e3e0ec647d8a03904aa8e0e0940cab416476b4354df598d4c0aeee221a82b4d4a60c65187a4c3f5de87631622064daa3a69bd4e89926ba29c4282cba89ef3
@@ -0,0 +1,57 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - master
7
+ - dev
8
+ - dev-*
9
+
10
+ jobs:
11
+ ci:
12
+ runs-on: ubuntu-latest
13
+ name: CI
14
+ steps:
15
+ - name: Notify slack success
16
+ if: success()
17
+ id: slack # IMPORTANT: reference this step ID value in future Slack steps
18
+ env:
19
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
20
+ uses: voxmedia/github-action-slack-notify-build@v1.1.1
21
+ with:
22
+ channel: github-actions
23
+ status: STARTING
24
+ color: warning
25
+
26
+ - uses: actions/checkout@v1
27
+ - uses: actions/setup-ruby@v1
28
+ with:
29
+ ruby-version: 2.6.x
30
+ - name: Install dependencies
31
+ run: |
32
+ gem install bundler
33
+ bundler install
34
+ - name: Run tests
35
+ run: bundler exec rspec
36
+
37
+ - name: Notify slack success
38
+ if: success()
39
+ env:
40
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
41
+ uses: voxmedia/github-action-slack-notify-build@v1.1.1
42
+ with:
43
+ message_id: ${{ steps.slack.outputs.message_id }}
44
+ channel: github-actions
45
+ status: SUCCESS
46
+ color: good
47
+
48
+ - name: Notify slack fail
49
+ if: failure()
50
+ env:
51
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
52
+ uses: voxmedia/github-action-slack-notify-build@v1.1.1
53
+ with:
54
+ message_id: ${{ steps.slack.outputs.message_id }}
55
+ channel: github-actions
56
+ status: FAILED
57
+ color: danger
@@ -0,0 +1,60 @@
1
+ name: Upload Python Package
2
+
3
+ on:
4
+ release:
5
+ types: [created]
6
+
7
+ jobs:
8
+ deploy:
9
+ name: Publish
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: Notify slack success
13
+ if: success()
14
+ id: slack # IMPORTANT: reference this step ID value in future Slack steps
15
+ env:
16
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
17
+ uses: voxmedia/github-action-slack-notify-build@v1.1.1
18
+ with:
19
+ channel: github-actions
20
+ status: STARTING
21
+ color: warning
22
+
23
+ - uses: actions/checkout@v2
24
+ - name: Set up Ruby 2.6
25
+ uses: actions/setup-ruby@v1
26
+ with:
27
+ version: 2.6.x
28
+
29
+ - name: Publish to RubyGems
30
+ run: |
31
+ mkdir -p $HOME/.gem
32
+ touch $HOME/.gem/credentials
33
+ chmod 0600 $HOME/.gem/credentials
34
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
35
+ gem build *.gemspec
36
+ gem push *.gem
37
+ env:
38
+ GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
39
+
40
+ - name: Notify slack success
41
+ if: success()
42
+ env:
43
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
44
+ uses: voxmedia/github-action-slack-notify-build@v1.1.1
45
+ with:
46
+ message_id: ${{ steps.slack.outputs.message_id }}
47
+ channel: github-actions
48
+ status: SUCCESS
49
+ color: good
50
+
51
+ - name: Notify slack fail
52
+ if: failure()
53
+ env:
54
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
55
+ uses: voxmedia/github-action-slack-notify-build@v1.1.1
56
+ with:
57
+ message_id: ${{ steps.slack.outputs.message_id }}
58
+ channel: github-actions
59
+ status: FAILED
60
+ color: danger
@@ -0,0 +1,45 @@
1
+ name: Testing
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - '*'
7
+ - '!master'
8
+
9
+ jobs:
10
+ test:
11
+ name: Testing
12
+ runs-on: ubuntu-18.04
13
+ steps:
14
+ - uses: actions/checkout@v1
15
+ - uses: actions/setup-ruby@v1
16
+ with:
17
+ ruby-version: 2.6.x
18
+ - name: Install dependencies
19
+ run: |
20
+ gem install bundler
21
+ bundler install
22
+ - name: Run tests
23
+ run: bundler exec rspec
24
+
25
+ - name: Notify slack success
26
+ if: success()
27
+ env:
28
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
29
+ uses: voxmedia/github-action-slack-notify-build@v1.1.1
30
+ with:
31
+ message_id: ${{ steps.slack.outputs.message_id }}
32
+ channel: github-actions
33
+ status: SUCCESS
34
+ color: good
35
+
36
+ - name: Notify slack fail
37
+ if: failure()
38
+ env:
39
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
40
+ uses: voxmedia/github-action-slack-notify-build@v1.1.1
41
+ with:
42
+ message_id: ${{ steps.slack.outputs.message_id }}
43
+ channel: github-actions
44
+ status: FAILED
45
+ color: danger
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Settings><!--This file was automatically generated by Ruby plugin.
3
+ You are allowed to:
4
+ 1. Remove rake task
5
+ 2. Add existing rake tasks
6
+ To add existing rake tasks automatically delete this file and reload the project.
7
+ --><RakeGroup description="" fullCmd="" taksId="rake" /></Settings>
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.1
6
+ before_install: gem install bundler -v 2.1.2
data/Gemfile CHANGED
@@ -3,4 +3,7 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
  gem "rspec"
5
5
  gem "rake"
6
- gem "httpclient"
6
+ gem "httpclient"
7
+ gem "parseconfig"
8
+ gem "webmock"
9
+ gem "codecov", :require => false, :group => :test
@@ -1,13 +1,26 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- securenative (0.1.5)
4
+ securenative (0.1.16)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ addressable (2.7.0)
10
+ public_suffix (>= 2.0.2, < 5.0)
11
+ codecov (0.1.17)
12
+ json
13
+ simplecov
14
+ url
15
+ crack (0.4.3)
16
+ safe_yaml (~> 1.0.0)
9
17
  diff-lcs (1.3)
18
+ docile (1.3.2)
19
+ hashdiff (1.0.1)
10
20
  httpclient (2.8.3)
21
+ json (2.3.0)
22
+ parseconfig (1.0.8)
23
+ public_suffix (4.0.5)
11
24
  rake (12.3.3)
12
25
  rspec (3.8.0)
13
26
  rspec-core (~> 3.8.0)
@@ -22,16 +35,29 @@ GEM
22
35
  diff-lcs (>= 1.2.0, < 2.0)
23
36
  rspec-support (~> 3.8.0)
24
37
  rspec-support (3.8.2)
38
+ safe_yaml (1.0.5)
39
+ simplecov (0.18.5)
40
+ docile (~> 1.1)
41
+ simplecov-html (~> 0.11)
42
+ simplecov-html (0.12.2)
43
+ url (0.3.2)
44
+ webmock (3.8.3)
45
+ addressable (>= 2.3.6)
46
+ crack (>= 0.3.2)
47
+ hashdiff (>= 0.4.0, < 2.0.0)
25
48
 
26
49
  PLATFORMS
27
50
  ruby
28
51
 
29
52
  DEPENDENCIES
30
53
  bundler (~> 2.0)
54
+ codecov
31
55
  httpclient
56
+ parseconfig
32
57
  rake
33
58
  rspec
34
59
  securenative!
60
+ webmock
35
61
 
36
62
  BUNDLED WITH
37
- 2.1.0.pre.1
63
+ 2.1.4
data/README.md CHANGED
@@ -1,7 +1,32 @@
1
- # SecureNative
2
- **[SecureNative](https://www.securenative.com/) is rethinking-security-as-a-service, disrupting the cyber security space and the way enterprises consume and implement security solutions.**
3
-
4
- ## Installation
1
+ <p align="center">
2
+ <a href="https://www.securenative.com"><img src="https://user-images.githubusercontent.com/45174009/77826512-f023ed80-7120-11ea-80e0-58aacde0a84e.png" alt="SecureNative Logo"/></a>
3
+ </p>
4
+
5
+ <p align="center">
6
+ <b>A Cloud-Native Security Monitoring and Protection for Modern Applications</b>
7
+ </p>
8
+ <p align="center">
9
+ <a href="https://github.com/securenative/securenative-ruby">
10
+ <img alt="Github Actions" src="https://github.com/securenative/securenative-ruby/workflows/CI/badge.svg">
11
+ </a>
12
+ <a href="https://codecov.io/gh/securenative/securenative-ruby">
13
+ <img src="https://codecov.io/gh/securenative/securenative-ruby/branch/master/graph/badge.svg" />
14
+ </a>
15
+ <a href="https://badge.fury.io/rb/securenative"><img src="https://badge.fury.io/rb/securenative.svg" alt="Gem Version" height="18"></a>
16
+ </p>
17
+ <p align="center">
18
+ <a href="https://docs.securenative.com">Documentation</a> |
19
+ <a href="https://docs.securenative.com/quick-start">Quick Start</a> |
20
+ <a href="https://blog.securenative.com">Blog</a> |
21
+ <a href="">Chat with us on Slack!</a>
22
+ </p>
23
+ <hr/>
24
+
25
+
26
+ [SecureNative](https://www.securenative.com/) performs user monitoring by analyzing user interactions with your application and various factors such as network, devices, locations and access patterns to stop and prevent account takeover attacks.
27
+
28
+
29
+ ## Install the SDK
5
30
 
6
31
  Add this line to your application's Gemfile:
7
32
 
@@ -9,7 +34,7 @@ Add this line to your application's Gemfile:
9
34
  gem 'securenative'
10
35
  ```
11
36
 
12
- And then execute:
37
+ Then execute:
13
38
 
14
39
  $ bundle
15
40
 
@@ -18,85 +43,128 @@ Or install it yourself as:
18
43
  $ gem install securenative
19
44
 
20
45
  ## Initialize the SDK
21
- Retrieve your API key from settings page of your SecureNative account and use the following in your code to initialize and use the sdk.
46
+
47
+ To get your *API KEY*, login to your SecureNative account and go to project settings page:
48
+
49
+ ### Option 1: Initialize via Config file
50
+ SecureNative can automatically load your config from *securenative.cfg* file or from the file that is specified in your *SECURENATIVE_CONFIG_FILE* env variable:
51
+
22
52
  ```ruby
23
53
  require 'securenative'
24
54
 
25
- # Do some cool stuff here
26
- # ...
27
- # ...
28
-
29
- begin
30
- SecureNative.init('YOUR_API_KEY') # Should be called before any other call to securenative
31
- rescue SecureNativeSDKException => e
32
- # Do some error handling
33
- end
55
+
56
+ secureative = SecureNative.init
57
+ ```
58
+ ### Option 2: Initialize via API Key
59
+
60
+ ```ruby
61
+ require 'securenative'
62
+
63
+
64
+ securenative = SecureNative.init_with_api_key('YOUR_API_KEY')
65
+ ```
66
+
67
+ ### Option 3: Initialize via ConfigurationBuilder
68
+ ```ruby
69
+ require 'securenative'
70
+
71
+
72
+ securenative = SecureNative.init_with_options(SecureNative.config_builder(api_key = 'API_KEY', max_event = 10, log_level = 'ERROR'))
73
+ ```
74
+
75
+ ## Getting SecureNative instance
76
+ Once initialized, sdk will create a singleton instance which you can get:
77
+ ```ruby
78
+ require 'securenative'
79
+
80
+
81
+ secureNative = SecureNative.instance
34
82
  ```
35
83
 
36
84
  ## Tracking events
37
- Once the SDK has been initialized, you can start sending new events with the `track` function:
85
+
86
+ Once the SDK has been initialized, tracking requests sent through the SDK
87
+ instance. Make sure you build event with the EventBuilder:
88
+
89
+ ```ruby
90
+ require 'securenative'
91
+ require 'securenative/enums/event_types'
92
+ require 'securenative/event_options_builder'
93
+ require 'securenative/models/user_traits'
94
+ require 'securenative/context/context_builder'
95
+
96
+
97
+ securenative = SecureNative.instance
98
+
99
+ context = securenative.context_builder(ip = '127.0.0.1', client_token = 'SECURED_CLIENT_TOKEN',
100
+ headers = { 'user-agent' => 'Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405' })
101
+
102
+ event_options = EventOptionsBuilder(event_type = EventTypes::LOG_IN,
103
+ user_id = 'USER_ID', user_traits = UserTraits('USER_NAME', 'USER_EMAIL'),
104
+ context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build
105
+
106
+ securenative.track(event_options)
107
+ ```
108
+
109
+ You can also create request context from requests:
110
+
38
111
  ```ruby
39
112
  require 'securenative'
40
- require 'securenative/event_type'
41
-
42
-
43
- def login
44
- # Do some cool stuff here
45
- # ...
46
- # ...
47
-
48
- SecureNative.track(Event.new(
49
- event_type = EventTypes::LOG_IN,
50
- user: User.new("1", "Jon Snow", "jon@snow.com"),
51
- ip: "1.2.3.4",
52
- remote_ip: "5.6.7.8",
53
- user_agent: "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; GT-I9500 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.0 QQ-URL-Manager Mobile Safari/537.36",
54
- sn_cookie: "cookie"))
113
+ require 'securenative/enums/event_types'
114
+ require 'securenative/event_options_builder'
115
+ require 'securenative/models/user_traits'
116
+
117
+
118
+ def track(request)
119
+ securenative = SecureNative.instance
120
+ context = SecureNative.context_builder.from_http_request(request).build
121
+
122
+ event_options = EventOptionsBuilder(event_type = EventTypes::LOG_IN,
123
+ user_id = 'USER_ID', user_traits = UserTraits('USER_NAME', 'USER_EMAIL'),
124
+ context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build
125
+
126
+ securenative.track(event_options)
55
127
  end
56
128
  ```
57
129
 
58
- ## Verification events
59
- Once the SDK has been initialized, you can start sending new events with the `verify` function:
130
+ ## Verify events
131
+
132
+ **Example**
133
+
60
134
  ```ruby
61
135
  require 'securenative'
62
- require 'securenative/event_type'
63
-
64
-
65
- def reset_password
66
- res = SecureNative.verify(Event.new(
67
- event_type = EventTypes::PASSWORD_RESET,
68
- user: User.new("1", "Jon Snow", "jon@snow.com"),
69
- ip: "1.2.3.4",
70
- remote_ip: "5.6.7.8",
71
- user_agent: "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; GT-I9500 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.0 QQ-URL-Manager Mobile Safari/537.36",
72
- sn_cookie: "cookie"))
73
-
74
- if res['riskLevel'] == 'high'
75
- return 'Cannot change password'
76
- else res['riskLevel'] == 'medium'
77
- return 'MFA'
78
- end
136
+ require 'securenative/enums/event_types'
137
+ require 'securenative/event_options_builder'
138
+ require 'securenative/models/user_traits'
139
+
140
+
141
+ def track(request)
142
+ securenative = SecureNative.instance
143
+ context = SecureNative.context_builder.from_http_request(request).build
144
+
145
+ event_options = EventOptionsBuilder(event_type = EventTypes::LOG_IN,
146
+ user_id = 'USER_ID', user_traits = UserTraits('USER_NAME', 'USER_EMAIL'),
147
+ context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build
148
+
149
+ verify_result = securenative.verify(event_options)
150
+ verify_result.risk_level # Low, Medium, High
151
+ verify_result.score # Risk score: 0 -1 (0 - Very Low, 1 - Very High)
152
+ verify_result.triggers # ["TOR", "New IP", "New City"]
79
153
  end
80
154
  ```
81
155
 
82
- ## Using webhooks
83
- You can use the SDK to verify incoming webhooks from SecureNative, just call the `veriy_webhook` function which return a boolean which indicates if the webhook came from Secure Native servers.
156
+ ## Webhook signature verification
157
+
158
+ Apply our filter to verify the request is from us, for example:
159
+
84
160
  ```ruby
85
161
  require 'securenative'
86
162
 
87
- begin
88
- SecureNative.init('YOUR_API_KEY') # Should be called before any other call to securenative
89
- rescue SecureNativeSDKException => e
90
- # Do some error handling
91
- end
92
163
 
93
- def handle_some_code(headers, body)
94
- sig_header = headers["X-SecureNative"]
95
- if SecureNative.verify_webhook(sig_header, body)
96
- # Handle the webhook
97
- level = body['riskLevel']
98
- else
99
- # This request wasn't sent from Secure Native servers, you can dismiss/investigate it
100
- end
164
+ def webhook_endpoint(request)
165
+ securenative = SecureNative.instance
166
+
167
+ # Checks if request is verified
168
+ is_verified = securenative.verify_request_payload(request)
101
169
  end
102
- ```
170
+ ```