qodex-rails 0.1.13 → 0.1.15
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 +4 -4
- data/README.md +4 -3
- data/lib/qodex/rails/version.rb +1 -1
- data/lib/qodex-rails/configuration.rb +3 -1
- data/lib/qodex-rails/masking_util.rb +44 -0
- data/lib/qodex-rails/middleware.rb +33 -4
- data/lib/qodex-rails/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba87db4007efe72ee98d47d2a52d72614fce543aca0a7e7ba3dd086828da806d
|
4
|
+
data.tar.gz: a7fa6d9cddbdd3485395431a81863990c56c86f7468ec17188ca9a9e515fbfb3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b45cf81b94e23c1186e0bc7b155078ac75a09f858387cdb300b0f9f28bb8be51013e6a81ef51f32d97efab5599cb4676afed41fa09136e76dd8a7ef2f055c071
|
7
|
+
data.tar.gz: 7f452b6f2d952f9d32c1d45962622ae1b6e6b3345ce787a3ba342d158f075f2d7439dfb3a3e4a41d8880ed844d1f71e3ea9a628e07db7a567985b9aa21ee183d
|
data/README.md
CHANGED
@@ -17,7 +17,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
17
17
|
## Configuration
|
18
18
|
# config/initializers/qodex_rails.rb
|
19
19
|
|
20
|
-
|
20
|
+
|
21
21
|
QodexRails.configure do |config|
|
22
22
|
# Your configuration settings for qodex-rails in the staging environment
|
23
23
|
project_name = Rails.application.class.module_parent_name rescue 'qodex'
|
@@ -25,8 +25,9 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
25
25
|
config.allowed_environments = ['staging', 'production'] # Default value is staging if not set. Add production to enable in production
|
26
26
|
config.frequency = 'high' #default value is medium. to control the speed of the logs processing
|
27
27
|
config.api_key = 'Your API Key'
|
28
|
-
|
29
|
-
|
28
|
+
config.pii_masking = ['api-key', 'access-token'] # add keys to skip sending actual value to qodex server
|
29
|
+
end
|
30
|
+
|
30
31
|
## Contributing
|
31
32
|
|
32
33
|
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/qodex-rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/qodex-rails/blob/main/CODE_OF_CONDUCT.md).
|
data/lib/qodex/rails/version.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module QodexRails
|
2
2
|
class Configuration
|
3
|
-
attr_accessor :collection_name, :api_key, :allowed_environments,
|
3
|
+
attr_accessor :collection_name, :api_key, :allowed_environments,
|
4
|
+
:frequency, :api_host, :pii_masking
|
4
5
|
|
5
6
|
def initialize
|
6
7
|
@collection_name = nil
|
@@ -8,6 +9,7 @@ module QodexRails
|
|
8
9
|
@allowed_environments = ['staging']
|
9
10
|
@frequency = 'medium'
|
10
11
|
@api_host = nil
|
12
|
+
@pii_masking = nil
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module MaskingUtil
|
2
|
+
extend self
|
3
|
+
|
4
|
+
def mask_data(data, pii_masking)
|
5
|
+
return data if pii_masking.blank?
|
6
|
+
|
7
|
+
# Base case: If data is not a hash or array, return it as is
|
8
|
+
return data unless data.is_a?(Hash) || data.is_a?(Array)
|
9
|
+
|
10
|
+
# If the data is an array, apply the function recursively to each element
|
11
|
+
if data.is_a?(Array)
|
12
|
+
return data.map { |value| MaskingUtil.mask_data(value, pii_masking) }
|
13
|
+
end
|
14
|
+
|
15
|
+
# If the data is a hash, transform each value
|
16
|
+
data.transform_keys! { |k| k.to_s.downcase } # Convert keys to downcase for case-insensitive comparison
|
17
|
+
data.each do |key, value|
|
18
|
+
if pii_masking.include?(key.downcase) # Check if the key matches PII fields (case-insensitive)
|
19
|
+
data[key] = 'MASKED_' + '{{' + key + '}}' # Mask the value
|
20
|
+
elsif value.is_a?(Hash) || value.is_a?(Array)
|
21
|
+
data[key] = MaskingUtil.mask_data(value, pii_masking) # Recurse for nested hashes or arrays
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def mask_query_params(url, pii_masking)
|
27
|
+
return url if pii_masking.blank?
|
28
|
+
uri = URI.parse(url)
|
29
|
+
query_params = CGI.parse(uri.query || '') # Parse query params into a hash
|
30
|
+
|
31
|
+
# Mask sensitive query params
|
32
|
+
query_params.each do |key, values|
|
33
|
+
if pii_masking.include?(key.downcase) # Check if key matches PII fields (case-insensitive)
|
34
|
+
query_params[key] = ['{{' + 'MASKED_' + key + '}}'] # Replace value with 'XXXX'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Reconstruct the query string with masked values
|
39
|
+
uri.query = URI.encode_www_form(query_params)
|
40
|
+
|
41
|
+
uri.to_s # Return the new URL with masked query params
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -11,6 +11,10 @@ module QodexRails
|
|
11
11
|
@frequency = QodexRails.configuration.frequency || 'low'
|
12
12
|
end
|
13
13
|
|
14
|
+
def pii_masking
|
15
|
+
@pii_masking ||= QodexRails.configuration.pii_masking
|
16
|
+
end
|
17
|
+
|
14
18
|
def call(env)
|
15
19
|
|
16
20
|
# Check if the current environment is allowed
|
@@ -42,28 +46,53 @@ module QodexRails
|
|
42
46
|
request.body.rewind
|
43
47
|
|
44
48
|
status, headers, response = @app.call(env)
|
49
|
+
response_content_type = response.instance_eval('@response').headers['content-type']
|
50
|
+
if response_content_type.present? && !(response_content_type.include?('application/json'))
|
51
|
+
return [status, headers, response]
|
52
|
+
end
|
45
53
|
|
46
54
|
end_time = Time.now
|
47
55
|
|
48
56
|
# Capture the response details
|
49
57
|
response_body = extract_body(response)
|
50
58
|
|
59
|
+
routes = Rails.application.routes
|
60
|
+
parsed_route_info = routes.recognize_path(request.url, {method: request.request_method}) rescue nil
|
61
|
+
return [status, headers, response] if parsed_route_info.blank?
|
62
|
+
|
63
|
+
controller_name = parsed_route_info[:controller]
|
64
|
+
action_name = parsed_route_info[:action]
|
65
|
+
additional_info = parsed_route_info.except(:controller, :action)
|
66
|
+
|
67
|
+
request_headers = extract_request_headers(env)
|
68
|
+
response_headers = extract_headers(headers)
|
69
|
+
request_params = request.params.merge(additional_info)
|
70
|
+
|
71
|
+
request_headers = MaskingUtil.mask_data(request_headers, pii_masking)
|
72
|
+
response_headers = MaskingUtil.mask_data(response_headers, pii_masking)
|
73
|
+
request_params = MaskingUtil.mask_data(request_params, pii_masking)
|
74
|
+
response_body = MaskingUtil.mask_data(response_body, pii_masking)
|
75
|
+
request_body = MaskingUtil.mask_data(request_body, pii_masking)
|
76
|
+
request_url = MaskingUtil.mask_query_params(request.url, pii_masking)
|
77
|
+
|
51
78
|
# Construct the logs
|
52
79
|
logs = {
|
53
80
|
collection_name: QodexRails.configuration.collection_name,
|
54
81
|
api_key: QodexRails.configuration.api_key,
|
55
82
|
api: {
|
83
|
+
controller_name: controller_name,
|
84
|
+
action_name: action_name,
|
56
85
|
time_spent: (end_time - start_time).to_i,
|
57
86
|
body: request_body,
|
58
87
|
response_body: response_body,
|
59
88
|
body_type: 'none-type',
|
60
89
|
request_type: request.request_method,
|
61
90
|
timestamp: Time.now.to_i,
|
62
|
-
url:
|
91
|
+
url: request_url,
|
63
92
|
status: status,
|
64
|
-
headers:
|
65
|
-
response_headers:
|
66
|
-
params:
|
93
|
+
headers: request_headers,
|
94
|
+
response_headers: response_headers,
|
95
|
+
params: request_params # Using Rails' parameter filtering
|
67
96
|
}
|
68
97
|
}
|
69
98
|
|
data/lib/qodex-rails/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qodex-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sid
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Intercept your rails application to power Qodex.ai AI copilot.
|
14
14
|
email:
|
@@ -26,6 +26,7 @@ files:
|
|
26
26
|
- Rakefile
|
27
27
|
- lib/qodex-rails.rb
|
28
28
|
- lib/qodex-rails/configuration.rb
|
29
|
+
- lib/qodex-rails/masking_util.rb
|
29
30
|
- lib/qodex-rails/middleware.rb
|
30
31
|
- lib/qodex-rails/version.rb
|
31
32
|
- lib/qodex/rails.rb
|