auth-sanitizer 0.1.5 → 0.2.0

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
2
  SHA256:
3
- metadata.gz: c91251e1007c195c50ee201a4c41cd42b618ca427a6be9cbbbf6fbb9e27c9954
4
- data.tar.gz: 07dc8e308d6177992350f763615c9abecb77fc4e807d6b34d332e1a1880b17de
3
+ metadata.gz: ee9c13c8e833242ae444802320b2a44204222f09529c8d7d588bbb7f725e2dff
4
+ data.tar.gz: 7fc39449d814609f58f5c7b6ce432bbb14fb532e5cf84e0a3f296e7e2e770763
5
5
  SHA512:
6
- metadata.gz: 22a80ac4d3a37a9570bb2cc875c5f725b989a6b6e93be87d03c9e0145e598deadf8da4c90114f2a5ad4b28ab253f491d31679c7b459015571069f52aac651750
7
- data.tar.gz: 8a03ebabaebda0de8ea0144e613fe5198d6f03d8b1612e431a272fab6bed71f846f75794932714d0abd7a34c70925ea08b6e582c48a01d61132e4bddcd019e7d
6
+ metadata.gz: 1c3fdbb99b0835a7694818b891daebe08bdc6e1cd95348e214970bf02c3ece6caa41fc9ae9d22a118720c9064baf16c066c0a7718121362b7d7141622ec2ccd9
7
+ data.tar.gz: 9057c5111136395c5418bfbd2acde6206d42a7c4b19d67e7fff8ae5449675019608557d4582ac53bd62f9b1792cdf56a186ffaac10989b5148a180e2cc48efcd
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,24 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [0.2.0] - 2026-06-04
34
+
35
+ - TAG: [v0.2.0][0.2.0t]
36
+ - COVERAGE: 100.00% -- 145/145 lines in 6 files
37
+ - BRANCH COVERAGE: 100.00% -- 28/28 branches in 6 files
38
+ - 84.62% documented
39
+
40
+ ### Changed
41
+
42
+ - Changed `FilteredAttributes#inspect` to redact narrow patterns from
43
+ `super.inspect` instead of rebuilding object inspect output, preserving host
44
+ inspect behavior.
45
+
46
+ ### Fixed
47
+
48
+ - Redacted configured attributes inside standard Ruby hash inspect fragments,
49
+ including nested attribute hashes.
50
+
33
51
  ## [0.1.5] - 2026-06-03
34
52
 
35
53
  - TAG: [v0.1.5][0.1.5t]
@@ -119,7 +137,9 @@ Please file a bug if you notice a violation of semantic versioning.
119
137
 
120
138
  - Initial release
121
139
 
122
- [Unreleased]: https://github.com/ruby-oauth/auth-sanitizer/compare/v0.1.5...HEAD
140
+ [Unreleased]: https://github.com/ruby-oauth/auth-sanitizer/compare/v0.2.0...HEAD
141
+ [0.2.0]: https://github.com/ruby-oauth/auth-sanitizer/compare/v0.1.5...v0.2.0
142
+ [0.2.0t]: https://github.com/ruby-oauth/auth-sanitizer/releases/tag/v0.2.0
123
143
  [0.1.5]: https://github.com/ruby-oauth/auth-sanitizer/compare/v0.1.4...v0.1.5
124
144
  [0.1.5t]: https://github.com/ruby-oauth/auth-sanitizer/releases/tag/v0.1.5
125
145
  [0.1.4]: https://github.com//ruby-oauth/auth-sanitizer/compare/v0.1.3...v0.1.4
data/README.md CHANGED
@@ -27,7 +27,7 @@ inspection and log output.
27
27
  The gem is intentionally narrow in scope. It does not change HTTP requests, token objects, persistence, or application
28
28
  configuration for you. Instead, it gives host gems and applications two reusable redaction surfaces:
29
29
 
30
- - `Auth::Sanitizer::FilteredAttributes` redacts selected instance variables from `#inspect`.
30
+ - `Auth::Sanitizer::FilteredAttributes` redacts selected attributes from standard Ruby `#inspect` output.
31
31
  - `Auth::Sanitizer::SanitizedLogger` wraps an existing logger and redacts sensitive values from string log messages.
32
32
 
33
33
  Out of the box, logger sanitization filters the key names most commonly found in OAuth and OpenID Connect debug output:
@@ -357,8 +357,43 @@ class OAuthCredential
357
357
  end
358
358
  ```
359
359
 
360
- Declared names are matched against instance variable names. For example, `filtered_attributes :access_token` redacts
361
- `@access_token` in `#inspect`.
360
+ `FilteredAttributes#inspect` delegates to `super.inspect` first, then redacts only narrow, standard Ruby inspect
361
+ fragments for configured names. This preserves host object inspect behavior instead of rebuilding the object's output.
362
+
363
+ For example, `filtered_attributes :access_token` redacts `@access_token="..."` in normal object inspect output:
364
+
365
+ ```ruby
366
+ OAuthCredential.new("secret", Time.now).inspect
367
+ # => #<OAuthCredential:0x... @access_token=[FILTERED], @expires_at=2026-06-04 08:00:00 -0600>
368
+ ```
369
+
370
+ Configured names are also redacted when they appear as string-valued keys inside standard Ruby hash inspect fragments,
371
+ which is useful for adapter models that store attributes in an internal hash:
372
+
373
+ ```ruby
374
+ class IdentityRecord
375
+ include Auth::Sanitizer::FilteredAttributes
376
+
377
+ filtered_attributes :password_digest
378
+
379
+ def initialize(identity_data)
380
+ @identity_data = identity_data
381
+ end
382
+ end
383
+
384
+ IdentityRecord.new({id: 1, password_digest: "$2a$secret"}).inspect
385
+ # => #<IdentityRecord:0x... @identity_data={id: 1, password_digest: [FILTERED]}>
386
+ ```
387
+
388
+ The inspect redactor intentionally leaves unsupported or highly customized inspect formats unchanged. It only replaces
389
+ quoted string values in these standard shapes:
390
+
391
+ - `@name="value"`
392
+ - `{name: "value"}`
393
+ - `{:name => "value"}`
394
+ - `{"name" => "value"}`
395
+
396
+ This conservative behavior avoids breaking host models whose `inspect` output has application-specific formatting.
362
397
 
363
398
  Calling `filtered_attributes` again replaces the class-level list:
364
399
 
@@ -427,11 +462,12 @@ response = TokenResponse.new(
427
462
  )
428
463
 
429
464
  response.inspect
430
- # => #<TokenResponse:123456 @access_token=[FILTERED], @refresh_token=[FILTERED], @scope="profile email">
465
+ # => #<TokenResponse:0x... @access_token=[FILTERED], @refresh_token=[FILTERED], @scope="profile email">
431
466
  ```
432
467
 
433
468
  Only the configured attributes are redacted. Other instance variables remain visible so inspected objects are still
434
- useful while debugging.
469
+ useful while debugging. Inspect filtering is conservative: unsupported custom formats are left unchanged rather than
470
+ risking a malformed `inspect` result.
435
471
 
436
472
  ### Redact Logger Output
437
473
 
@@ -875,7 +911,7 @@ Thanks for RTFM. ☺️
875
911
  [📌gitmoji]: https://gitmoji.dev
876
912
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
877
913
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
878
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.138-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
914
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.145-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
879
915
  [🔐security]: https://github.com/ruby-oauth/auth-sanitizer/blob/main/SECURITY.md
880
916
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
881
917
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -93,16 +93,34 @@ module Auth
93
93
  #
94
94
  # @return [String]
95
95
  def inspect
96
- return super if thing_filter.things.empty?
96
+ inspected = super
97
+ return inspected if thing_filter.things.empty?
97
98
 
98
- inspected_vars = instance_variables.map do |var|
99
- if thing_filter.filtered?(var)
100
- "#{var}=#{thing_filter.label}"
101
- else
102
- "#{var}=#{instance_variable_get(var).inspect}"
99
+ redact_inspected_values(inspected.dup)
100
+ end
101
+
102
+ private
103
+
104
+ INSPECTED_STRING_VALUE = /"(?:(?:\\.)|[^"\\])*"/
105
+ INSPECTED_REDACTABLE_VALUE = /
106
+ (?:
107
+ (@([A-Za-z_]\w*[!?=]?)=) |
108
+ ([,{]\s*([A-Za-z_]\w*[!?=]?):\s*) |
109
+ ([,{]\s*:([A-Za-z_]\w*[!?=]?)\s*=>\s*) |
110
+ ([,{]\s*"([A-Za-z_]\w*[!?=]?)"\s*=>\s*)
111
+ )
112
+ #{INSPECTED_STRING_VALUE}
113
+ /x
114
+ private_constant :INSPECTED_STRING_VALUE, :INSPECTED_REDACTABLE_VALUE
115
+
116
+ def redact_inspected_values(inspected)
117
+ inspected.gsub(INSPECTED_REDACTABLE_VALUE) do |match|
118
+ captures = Regexp.last_match.captures
119
+ prefix, = captures.each_slice(2).detect do |(_candidate_prefix, candidate_key)|
120
+ thing_filter.things.include?(candidate_key)
103
121
  end
122
+ prefix ? "#{prefix}#{thing_filter.label}" : match
104
123
  end
105
- "#<#{self.class}:#{object_id} #{inspected_vars.join(", ")}>"
106
124
  end
107
125
  end
108
126
  end
@@ -3,7 +3,7 @@
3
3
  module Auth
4
4
  module Sanitizer
5
5
  module Version
6
- VERSION = "0.1.5"
6
+ VERSION = "0.2.0"
7
7
  end
8
8
  VERSION = Version::VERSION # Traditional Constant Location
9
9
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: auth-sanitizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -279,10 +279,10 @@ licenses:
279
279
  - MIT
280
280
  metadata:
281
281
  homepage_uri: https://auth-sanitizer.galtzo.com
282
- source_code_uri: https://github.com/ruby-oauth/auth-sanitizer/tree/v0.1.5
283
- changelog_uri: https://github.com/ruby-oauth/auth-sanitizer/blob/v0.1.5/CHANGELOG.md
282
+ source_code_uri: https://github.com/ruby-oauth/auth-sanitizer/tree/v0.2.0
283
+ changelog_uri: https://github.com/ruby-oauth/auth-sanitizer/blob/v0.2.0/CHANGELOG.md
284
284
  bug_tracker_uri: https://github.com/ruby-oauth/auth-sanitizer/issues
285
- documentation_uri: https://www.rubydoc.info/gems/auth-sanitizer/0.1.5
285
+ documentation_uri: https://www.rubydoc.info/gems/auth-sanitizer/0.2.0
286
286
  funding_uri: https://github.com/sponsors/pboling
287
287
  wiki_uri: https://github.com/ruby-oauth/auth-sanitizer/wiki
288
288
  news_uri: https://www.railsbling.com/tags/auth-sanitizer
metadata.gz.sig CHANGED
Binary file