strongmind-platform-sdk 3.27.0 → 3.27.2
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/lib/platform_sdk/logging/pii_formatter.rb +41 -0
- data/lib/platform_sdk/logging.rb +18 -0
- data/lib/platform_sdk/pii.rb +22 -0
- data/lib/platform_sdk/sentry/pii_scrubber.rb +69 -0
- data/lib/platform_sdk/sentry.rb +23 -0
- data/lib/platform_sdk/version.rb +1 -1
- data/lib/platform_sdk.rb +29 -27
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 021a46b4ab2f6bb6309de8a95199bfcbbce20a6f7840d8f019c36b748508e2d4
|
|
4
|
+
data.tar.gz: c70de4fb236c35ebafbe6aa6d46480fb7fcf9e44b81a4c84a66a38c8d15f1a7e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9d29eba2b361d1f35683fc3b3f37bb39829a7c8505a71516d6e3e44f3ceb681cd5db59b3522640ab4682c88551062a75ddfe6985a04df7f475edaaf25773648e
|
|
7
|
+
data.tar.gz: d369c0b967a2e1bbcc0742507f9bd25bf3da167a38694c516d62618998047c0d849c7959601d919e9becdb14998ff305713f4cc665c7fab7763974913b72cbab
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/parameter_filter'
|
|
4
|
+
require_relative '../pii'
|
|
5
|
+
|
|
6
|
+
module PlatformSdk
|
|
7
|
+
module Logging
|
|
8
|
+
# Scrubs PII from stdout
|
|
9
|
+
class PiiFormatter
|
|
10
|
+
attr_reader :original_formatter
|
|
11
|
+
|
|
12
|
+
def initialize(original_formatter:, additional_fields: [])
|
|
13
|
+
@original_formatter = original_formatter
|
|
14
|
+
fields = Pii::DEFAULT_FIELDS + additional_fields
|
|
15
|
+
@param_filter = ActiveSupport::ParameterFilter.new(
|
|
16
|
+
fields, mask: Pii::FILTERED
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def call(severity, timestamp, progname, message)
|
|
21
|
+
scrubbed = scrub_message(message)
|
|
22
|
+
@original_formatter.call(severity, timestamp, progname, scrubbed)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def scrub_message(message)
|
|
28
|
+
case message
|
|
29
|
+
when Hash
|
|
30
|
+
@param_filter.filter(message)
|
|
31
|
+
when String
|
|
32
|
+
Pii::PII_PATTERNS.reduce(message) do |msg, pattern|
|
|
33
|
+
msg.gsub(pattern, Pii::FILTERED)
|
|
34
|
+
end
|
|
35
|
+
else
|
|
36
|
+
message
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'logging/pii_formatter'
|
|
4
|
+
|
|
5
|
+
module PlatformSdk
|
|
6
|
+
# Wraps logging with built-in PII protection
|
|
7
|
+
module Logging
|
|
8
|
+
def self.apply_pii_protection(additional_fields: [])
|
|
9
|
+
logger = Rails.logger
|
|
10
|
+
return if logger.formatter.is_a?(PiiFormatter)
|
|
11
|
+
|
|
12
|
+
logger.formatter = PiiFormatter.new(
|
|
13
|
+
original_formatter: logger.formatter,
|
|
14
|
+
additional_fields:
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PlatformSdk
|
|
4
|
+
module Pii
|
|
5
|
+
DEFAULT_FIELDS = [
|
|
6
|
+
:email, /\Aname\z/i, :first_name, :last_name, :student_name, :username,
|
|
7
|
+
:phone, :phone_number, :address, :street, :city, :zip, :postal_code,
|
|
8
|
+
:ssn, :social_security, :date_of_birth, :dob, :birthday,
|
|
9
|
+
:ip_address, /\Aip\z/i, :remote_ip,
|
|
10
|
+
:password, :password_confirmation, :token, :secret, :api_key,
|
|
11
|
+
:authorization
|
|
12
|
+
].freeze
|
|
13
|
+
|
|
14
|
+
FILTERED = '[FILTERED]'
|
|
15
|
+
|
|
16
|
+
EMAIL_REGEX = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/
|
|
17
|
+
SSN_REGEX = /\b\d{3}-\d{2}-\d{4}\b/
|
|
18
|
+
PHONE_REGEX = /(\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/
|
|
19
|
+
|
|
20
|
+
PII_PATTERNS = [EMAIL_REGEX, SSN_REGEX, PHONE_REGEX].freeze
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/parameter_filter'
|
|
4
|
+
require_relative '../pii'
|
|
5
|
+
|
|
6
|
+
module PlatformSdk
|
|
7
|
+
module Sentry
|
|
8
|
+
# Scrubs PII from Sentry events
|
|
9
|
+
class PiiScrubber
|
|
10
|
+
DEFAULT_PII_FIELDS = Pii::DEFAULT_FIELDS
|
|
11
|
+
FILTERED = Pii::FILTERED
|
|
12
|
+
|
|
13
|
+
attr_reader :filter
|
|
14
|
+
|
|
15
|
+
def initialize(additional_fields: [])
|
|
16
|
+
fields = DEFAULT_PII_FIELDS + additional_fields
|
|
17
|
+
@filter = ActiveSupport::ParameterFilter.new(fields, mask: FILTERED)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def scrub_hash(hash)
|
|
21
|
+
return {} unless hash.is_a?(Hash)
|
|
22
|
+
|
|
23
|
+
filter.filter(hash)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def scrub_event(event)
|
|
27
|
+
scrub_event_data(event)
|
|
28
|
+
scrub_request(event.request) if event.request
|
|
29
|
+
event
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
EMAIL_REGEX = Pii::EMAIL_REGEX
|
|
33
|
+
|
|
34
|
+
def scrub_breadcrumb(breadcrumb)
|
|
35
|
+
breadcrumb.data = scrub_hash(breadcrumb.data) if breadcrumb.data.is_a?(Hash)
|
|
36
|
+
breadcrumb.message = scrub_message(breadcrumb.message) if breadcrumb.message
|
|
37
|
+
|
|
38
|
+
breadcrumb
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def scrub_message(message)
|
|
44
|
+
message.gsub(EMAIL_REGEX, FILTERED)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def scrub_user(user_hash)
|
|
48
|
+
id = user_hash[:id] || user_hash['id']
|
|
49
|
+
scrubbed = scrub_hash(user_hash)
|
|
50
|
+
scrubbed[:id] = id if user_hash.key?(:id)
|
|
51
|
+
scrubbed['id'] = id if user_hash.key?('id')
|
|
52
|
+
scrubbed
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def scrub_request(request)
|
|
56
|
+
request.data = scrub_hash(request.data) if request.data.is_a?(Hash)
|
|
57
|
+
request.headers = scrub_hash(request.headers) if request.headers.is_a?(Hash)
|
|
58
|
+
request.query_string = FILTERED if request.query_string
|
|
59
|
+
request.cookies = FILTERED if request.cookies
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def scrub_event_data(event)
|
|
63
|
+
event.user = scrub_user(event.user) if event.user.is_a?(Hash)
|
|
64
|
+
event.extra = scrub_hash(event.extra) if event.extra.is_a?(Hash)
|
|
65
|
+
event.contexts = scrub_hash(event.contexts) if event.contexts.is_a?(Hash)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
data/lib/platform_sdk/sentry.rb
CHANGED
|
@@ -1,7 +1,30 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'sentry/pii_scrubber'
|
|
4
|
+
|
|
3
5
|
module PlatformSdk
|
|
4
6
|
module Sentry
|
|
7
|
+
def self.apply_pii_protection(config, additional_fields: [])
|
|
8
|
+
config.send_default_pii = false
|
|
9
|
+
config.include_local_variables = false
|
|
10
|
+
|
|
11
|
+
scrubber = PiiScrubber.new(additional_fields: additional_fields)
|
|
12
|
+
|
|
13
|
+
config.before_send = lambda do |event, _hint|
|
|
14
|
+
scrubber.scrub_event(event)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
config.before_breadcrumb = lambda do |breadcrumb, _hint|
|
|
18
|
+
scrubber.scrub_breadcrumb(breadcrumb)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
config.before_send_transaction = lambda do |event, _hint|
|
|
22
|
+
return nil if sentry_ignored(event)
|
|
23
|
+
|
|
24
|
+
scrubber.scrub_event(event)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
5
28
|
def self.sentry_ignored(event, ignored_urls = sentry_ignored_urls)
|
|
6
29
|
return false if event.transaction_info[:source] != :url
|
|
7
30
|
return true if ignored_urls.any? { |url| event.transaction.match?(url) }
|
data/lib/platform_sdk/version.rb
CHANGED
data/lib/platform_sdk.rb
CHANGED
|
@@ -1,32 +1,34 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require
|
|
10
|
-
require
|
|
11
|
-
require
|
|
12
|
-
require
|
|
13
|
-
require
|
|
14
|
-
require
|
|
15
|
-
require
|
|
16
|
-
require
|
|
17
|
-
require
|
|
18
|
-
require
|
|
19
|
-
require
|
|
20
|
-
require
|
|
21
|
-
require
|
|
22
|
-
require
|
|
23
|
-
require
|
|
24
|
-
require
|
|
25
|
-
require
|
|
26
|
-
require
|
|
27
|
-
require
|
|
28
|
-
require
|
|
29
|
-
require
|
|
3
|
+
require_relative 'platform_sdk/version'
|
|
4
|
+
require 'platform_sdk/one_roster'
|
|
5
|
+
require 'platform_sdk/identity'
|
|
6
|
+
require 'platform_sdk/power_school'
|
|
7
|
+
require 'platform_sdk/aws'
|
|
8
|
+
require 'platform_sdk/id_mapper'
|
|
9
|
+
require 'platform_sdk/edkey'
|
|
10
|
+
require 'platform_sdk/data_pipeline'
|
|
11
|
+
require 'platform_sdk/pencil_spaces'
|
|
12
|
+
require 'platform_sdk/edfi'
|
|
13
|
+
require 'platform_sdk/pii'
|
|
14
|
+
require 'platform_sdk/sentry'
|
|
15
|
+
require 'platform_sdk/logging'
|
|
16
|
+
require 'platform_sdk/learnosity_api'
|
|
17
|
+
require 'platform_sdk/canvas_api'
|
|
18
|
+
require 'platform_sdk/bynder'
|
|
19
|
+
require 'platform_sdk/events'
|
|
20
|
+
require 'platform_sdk/central'
|
|
21
|
+
require 'platform_sdk/active_record/data_pipelineable'
|
|
22
|
+
require 'platform_sdk/spec_support'
|
|
23
|
+
require 'asset_sync'
|
|
24
|
+
require 'fog-aws'
|
|
25
|
+
require 'platform_sdk/asset_sync_initializer'
|
|
26
|
+
require 'platform_sdk/sidekiq/ecs_task_protection_middleware'
|
|
27
|
+
require 'platform_sdk/sidekiq'
|
|
28
|
+
require 'platform_sdk/jobs/send_noun_to_pipeline_job'
|
|
29
|
+
require 'platform_sdk/jira'
|
|
30
|
+
require 'platform_sdk/catalog_manager'
|
|
31
|
+
require 'platform_sdk/llm_gateway'
|
|
30
32
|
|
|
31
33
|
module PlatformSdk
|
|
32
34
|
class Error < StandardError; end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: strongmind-platform-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.27.
|
|
4
|
+
version: 3.27.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Platform Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -284,6 +284,8 @@ files:
|
|
|
284
284
|
- lib/platform_sdk/learnosity_api/client.rb
|
|
285
285
|
- lib/platform_sdk/llm_gateway.rb
|
|
286
286
|
- lib/platform_sdk/llm_gateway/client.rb
|
|
287
|
+
- lib/platform_sdk/logging.rb
|
|
288
|
+
- lib/platform_sdk/logging/pii_formatter.rb
|
|
287
289
|
- lib/platform_sdk/one_roster.rb
|
|
288
290
|
- lib/platform_sdk/one_roster/client.rb
|
|
289
291
|
- lib/platform_sdk/ops_genie.rb
|
|
@@ -293,10 +295,12 @@ files:
|
|
|
293
295
|
- lib/platform_sdk/pencil_spaces/constants.rb
|
|
294
296
|
- lib/platform_sdk/pencil_spaces/models.rb
|
|
295
297
|
- lib/platform_sdk/pencil_spaces/models/user_with_role.rb
|
|
298
|
+
- lib/platform_sdk/pii.rb
|
|
296
299
|
- lib/platform_sdk/power_school.rb
|
|
297
300
|
- lib/platform_sdk/power_school/client.rb
|
|
298
301
|
- lib/platform_sdk/power_school/special_program.rb
|
|
299
302
|
- lib/platform_sdk/sentry.rb
|
|
303
|
+
- lib/platform_sdk/sentry/pii_scrubber.rb
|
|
300
304
|
- lib/platform_sdk/sidekiq.rb
|
|
301
305
|
- lib/platform_sdk/sidekiq/ecs_task_protection_middleware.rb
|
|
302
306
|
- lib/platform_sdk/spec_support.rb
|