redacted_struct 1.0.1 → 2.0.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: 64c02de7881517f0bbb564741a2b999e8066a8de32f7aed539c86da981d5bddf
4
- data.tar.gz: ad4589962d6c3be459ffc88ef3712b3e59177b83cddef3b2526a0dfb11c2a2ad
3
+ metadata.gz: 84097ef8bb895a91b3d17f35daee43dd9e6b4d0a677c25bf4bd9c82962aba823
4
+ data.tar.gz: 3c7c5c3328485f20e92b23e9ae2f221eab868830b6efecab27ddd08221bae014
5
5
  SHA512:
6
- metadata.gz: a4616807a9c76c8f01c63585d02c79a592b1eaed901263bfc1109ff29ceb165e3b860b6e9a5005d6fa772ab585fef04d3469b18a78466b91a10f56af438d0ee1
7
- data.tar.gz: ffe8ffa0f62360f78113cc98c4ee8972d1cb181682b3f10c87d63bc821ab24a25e62662b1e3485ab09f774f47a1e7b0681e04214037f4bbcfe936786f2c8c83a
6
+ metadata.gz: a6bc81b2aa8cf0abcaa1b69b1f748443d60d35778ce08635076f27010a37c897652fd1a154d635d72f076958a74dd3203bd7525d7e3240a432c30d99d26b6c7a
7
+ data.tar.gz: 44c61acc111af1b2ce4310fcf6e44001bbc96ccbd18eedb055f6a9d87e1bbec8ca8ea26673400b30217218531a614bd8bfe7b9b88b9f4815e284387f211b6406
data/.circleci/config.yml CHANGED
@@ -1,18 +1,33 @@
1
1
  version: 2.1
2
2
  orbs:
3
- ruby: circleci/ruby@0.1.2
3
+ ruby: circleci/ruby@1.1
4
4
 
5
5
  jobs:
6
- build:
6
+ test:
7
+ parameters:
8
+ ruby-version:
9
+ type: string
7
10
  docker:
8
- - image: cimg/ruby:2.6.5
9
- executor: ruby/default
11
+ - image: cimg/ruby:<< parameters.ruby-version >>
10
12
  steps:
11
13
  - checkout
12
14
  - run:
13
- name: Which bundler?
14
- command: bundle -v
15
- - ruby/bundle-install
15
+ name: "Add platform for Bundler"
16
+ description: "Normally the platforms lives in Gemfile.lock, but as a gem this repo does not have one, CircleCI fails if there are no platforms"
17
+ command: bundle lock --add-platform x86_64-linux
18
+ - ruby/install-deps:
19
+ bundler-version: '1.17.2'
20
+ with-cache: false
21
+ - ruby/rspec-test
16
22
  - run:
17
- name: Run specs
18
- command: bundle exec rake spec
23
+ name: Rubocop
24
+ command: bundle exec rubocop
25
+
26
+ workflows:
27
+ build_and_test:
28
+ jobs:
29
+ - test:
30
+ matrix:
31
+ parameters:
32
+ # https://github.com/CircleCI-Public/cimg-ruby
33
+ ruby-version: ["2.6", "3.1", "3.2"]
data/.rubocop.yml CHANGED
@@ -23,6 +23,12 @@ Style/TrailingCommaInArguments:
23
23
  Layout/LineLength:
24
24
  Max: 120
25
25
 
26
+ # require "pp" in specs is flagged in Ruby 2.6 but not in other ones
27
+ # and doing a point disable gets a "unused lint" warning, so this is easier
28
+ # to disable here
29
+ Lint/RedundantRequireStatement:
30
+ Enabled: false
31
+
26
32
  Metrics/BlockLength:
27
33
  Exclude:
28
34
  - "spec/**/*.rb"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [2.0.0] - 2024-01-10
4
+
5
+ - Add support to redact `Data` objects
6
+
7
+ ## [1.1.0] - 2021-03-24
8
+
9
+ - Override `Struct#pretty_print` to keep redacted fields redacted when
10
+ pretty-printing via `pp`
11
+
3
12
  ## [1.0.0] - 2021-03-24
4
13
 
5
14
  - Initial release
data/Gemfile CHANGED
@@ -7,4 +7,5 @@ gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
9
  gem "rspec", "~> 3.0"
10
+ gem "rspec_junit_formatter", "~> 0.6"
10
11
  gem "rubocop", "~> 1.7"
data/README.md CHANGED
@@ -8,14 +8,47 @@ Config = RedactedStruct.new(
8
8
  :username,
9
9
  :password,
10
10
  :timeout,
11
+ :url,
11
12
  keyword_init: true,
12
13
  allowed_members: [:username, :timeout]
13
14
  )
14
15
 
15
- Config.new(username: 'example', password: 'secret', timeout: 5)
16
+ config = Config.new(username: 'example', password: 'secret', timeout: 5, url: 'https://example.com')
16
17
  => #<struct Config username="example" password=[REDACTED] timeout=5>
17
18
  ```
18
19
 
20
+ ## Pretty-Printing
21
+
22
+ The struct will automatically redact itself when pretty-printed via `#pp`:
23
+
24
+ ```ruby
25
+ require 'pp'
26
+
27
+ pp config
28
+ #<struct Config
29
+ username="example",
30
+ password=[REDACTED],
31
+ timeout=5,
32
+ url="https://example.com">
33
+ ```
34
+
35
+ ## RedactedData
36
+
37
+ Redaction is also supported for Ruby's built-in Data class:
38
+
39
+ ```ruby
40
+ Config = RedactedData.define(
41
+ :username,
42
+ :password,
43
+ :timeout,
44
+ :url,
45
+ allowed_members: [:username, :timeout]
46
+ )
47
+
48
+ config = Config.new(username: 'example', password: 'secret', timeout: 5, url: 'https://example.com')
49
+ => #<data Config username="example" password=[REDACTED] timeout=5>
50
+ ```
51
+
19
52
  ## Installation
20
53
 
21
54
  Add this line to your application's Gemfile:
data/lib/redactable.rb ADDED
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A module that adds redacted functionality to a class
4
+ module Redactable
5
+ def self.included(mod)
6
+ class << mod
7
+ attr_reader :allowed_members
8
+ end
9
+ end
10
+
11
+ def inspect
12
+ name_or_nil = self.class.name ? " #{self.class.name}" : nil
13
+
14
+ members_h = to_h
15
+ attributes = members.map do |member|
16
+ if allowed_members.include?(member)
17
+ "#{member}=#{members_h[member].inspect}"
18
+ else
19
+ "#{member}=[REDACTED]"
20
+ end
21
+ end.join(" ")
22
+
23
+ "#<#{base_name_for_inspection}#{name_or_nil} #{attributes}>"
24
+ end
25
+
26
+ def allowed_members
27
+ self.class.allowed_members
28
+ end
29
+
30
+ # Overrides for pp
31
+ # See https://github.com/ruby/pp/blob/3d925b5688b8226f653127d990a8dce48bced5fe/lib/pp.rb#L379-L391
32
+ # rubocop:disable all
33
+ def pretty_print(q)
34
+ q.group(1, sprintf("#<%s %s", base_name_for_inspection, PP.mcall(self, Kernel, :class).name), '>') {
35
+ members_h = to_h
36
+ q.seplist(PP.mcall(self, base_type_for_pp, :members), lambda { q.text "," }) {|member|
37
+ q.breakable
38
+ q.text member.to_s
39
+ q.text '='
40
+ q.group(1) {
41
+ q.breakable ''
42
+ if allowed_members.include?(member)
43
+ q.pp members_h[member]
44
+ else
45
+ q.text "[REDACTED]"
46
+ end
47
+ }
48
+ }
49
+ }
50
+ end
51
+ # rubocop:enable all
52
+
53
+ alias_method :to_s, :inspect
54
+
55
+ def base_name_for_inspection
56
+ if is_a? Struct
57
+ "struct"
58
+ else
59
+ "data"
60
+ end
61
+ end
62
+
63
+ def base_type_for_pp
64
+ if is_a? Struct
65
+ Struct
66
+ else
67
+ Data
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Style/Documentation
4
+ # rubocop:disable Style/MultilineIfModifier
5
+ # A subclass of Data that redacts members by default, and can allow some to be printed
6
+ class RedactedData < Data
7
+ include Redactable
8
+
9
+ def self.define(*members, allowed_members: [], &block)
10
+ super(*members, &block).tap do |data_class|
11
+ data_class.class_eval do
12
+ @allowed_members = Array(allowed_members)
13
+ end
14
+ end
15
+ end
16
+ end if defined?(Data) && Data.respond_to?(:define)
17
+ # rubocop:enable Style/MultilineIfModifier
18
+ # rubocop:enable Style/Documentation
@@ -1,8 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "./redactable"
4
+ require_relative "./redacted_data"
5
+
3
6
  # A subclass of Struct that redacts members by default, and can allow some to be printed
4
7
  class RedactedStruct < Struct
5
- VERSION = "1.0.1"
8
+ include Redactable
9
+
10
+ VERSION = "2.0.0"
6
11
 
7
12
  def self.new(*name_and_members, keyword_init: nil, allowed_members: [], &block)
8
13
  super(*name_and_members, keyword_init: keyword_init, &block).tap do |struct_class|
@@ -11,28 +16,4 @@ class RedactedStruct < Struct
11
16
  end
12
17
  end
13
18
  end
14
-
15
- class << self
16
- attr_reader :allowed_members
17
- end
18
-
19
- def allowed_members
20
- self.class.allowed_members
21
- end
22
-
23
- def inspect
24
- name_or_nil = self.class.name ? " #{self.class.name}" : nil
25
-
26
- attributes = members.map do |member|
27
- if allowed_members.include?(member)
28
- "#{member}=#{self[member].inspect}"
29
- else
30
- "#{member}=[REDACTED]"
31
- end
32
- end.join(" ")
33
-
34
- "#<struct#{name_or_nil} #{attributes}>"
35
- end
36
-
37
- alias_method :to_s, :inspect
38
19
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redacted_struct
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Margolis
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-24 00:00:00.000000000 Z
11
+ date: 2024-01-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Help prevent logging sensitive information by accident
14
- email:
14
+ email:
15
15
  executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
@@ -26,6 +26,8 @@ files:
26
26
  - Rakefile
27
27
  - bin/console
28
28
  - bin/setup
29
+ - lib/redactable.rb
30
+ - lib/redacted_data.rb
29
31
  - lib/redacted_struct.rb
30
32
  - redacted_struct.gemspec
31
33
  homepage: https://github.com/zachmargolis/redacted_struct
@@ -34,7 +36,7 @@ metadata:
34
36
  homepage_uri: https://github.com/zachmargolis/redacted_struct
35
37
  source_code_uri: https://github.com/zachmargolis/redacted_struct
36
38
  changelog_uri: https://github.com/zachmargolis/redacted_struct/blob/main/CHANGELOG.md
37
- post_install_message:
39
+ post_install_message:
38
40
  rdoc_options: []
39
41
  require_paths:
40
42
  - lib
@@ -49,8 +51,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
51
  - !ruby/object:Gem::Version
50
52
  version: '0'
51
53
  requirements: []
52
- rubygems_version: 3.1.2
53
- signing_key:
54
+ rubygems_version: 3.4.6
55
+ signing_key:
54
56
  specification_version: 4
55
57
  summary: A Ruby Struct that can be redacted
56
58
  test_files: []