nuclear_secrets 1.0.1 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57e88636b13f8f0b1e9697a6dc9621f9a3d2a8ba
4
- data.tar.gz: 823b10f98e3078d78fea563e33455ea03ce188b6
3
+ metadata.gz: 175b07894161bdae17411c570da95b2378fb64a8
4
+ data.tar.gz: ed3c759584c3e898ecf93461df2a6705c1d76368
5
5
  SHA512:
6
- metadata.gz: c48b0e1421e051ab3d687acf119ae42e315ee7b9cc83034a6c189a797dca4e94cc6aba3aafa75aedf3631b6194f11154b3f8ffd6f496dd9162b5479e36c097e8
7
- data.tar.gz: 725ad3b2597c8b97e2e3fe0ad231afc8c47a801ef89abe59938e3f25abd4c7e3c9e20d82adc2cb13f3729261440aa18aef0eadbcb10bcb1e6e17bfdc206bfec7
6
+ metadata.gz: 9e57fb6daf72613508d0008fe2a20a3a5f2109856b61a840fa764d5f62c10fb15d2274d153b52d94e90aaf54bff78b3b18e0df1e1a1a42b201ff705155c140ab
7
+ data.tar.gz: 1c71339468af3cc4f234991b9e6a7d4fdf5fa863c67eadb99ae9fc419413c64e784684aefb5e5ed2aaf8c327d4b1e9c87b50501c610cac72948148f7da4b6f4b
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # NuclearSecrets
1
+ # Nuclear Secrets
2
2
  Quell rails secret espionage by verifying what secrets exist and their types in your rails application
3
3
 
4
4
  ## Usage
@@ -30,6 +30,21 @@ end
30
30
  ```
31
31
  Include all secrets that your application utilizes, and their types, in `required_secrets` hash
32
32
 
33
+ ## Advanced Usage
34
+ In addition to being able to supply NuclearSecrets with the type of a secret,
35
+ you can also pass a Proc or a Lambda. If the proc or lamba returns true when
36
+ passed the value of the secret, then the secret will be allowed.
37
+
38
+ ```
39
+ NuclearSecrets.configure do |config|
40
+ config.required_secrets = {
41
+ my_string_secret: String,
42
+ my_numeric_secret: Fixnum,
43
+ my_secret: Proc.new { |secret| secret.is_worthy? }
44
+ }
45
+ end
46
+ ```
47
+
33
48
  ## Contributing
34
49
  Contribution directions go here.
35
50
 
@@ -1,61 +1,78 @@
1
1
  require "nuclear_secrets/engine"
2
+ require "nuclear_secrets/errors"
2
3
 
3
4
  module NuclearSecrets
4
- class NuclearSecretError < StandardError
5
- def initialize(secrets: [])
6
- @secrets = secrets
7
- end
8
-
9
- def get_error_list
10
- @secrets.reduce("") do |message, current|
11
- message << "#{current.first} of type #{current.last} \n"
12
- end
13
- end
14
- end
5
+ class << self
6
+ attr_accessor(:required_secrets)
15
7
 
16
- class RequiredSecretsListMissing < NuclearSecretError
17
- def message
18
- "You must include a required_secrets key in your config/secrets.yml file"
8
+ def configure
9
+ yield self if block_given?
19
10
  end
20
- end
21
11
 
22
- class SecretsMissingError < NuclearSecretError
23
- def initialize(secrets)
24
- super(secrets: secrets)
12
+ def make_type_check(type)
13
+ Proc.new { |item| item.class == type }
25
14
  end
26
15
 
27
- def message
28
- "Missing secrets: \n#{get_error_list}"
16
+ # secrets: hash of given secrets
17
+ # required_values: hash of required secrets
18
+ # key: key to build tuple for
19
+ # returns [key, required_type, given_type]
20
+ def build_secret_tuple(secrets, required_values, key)
21
+ [key, required_values[key], secrets[key]]
29
22
  end
30
- end
31
23
 
32
- class ExtraSecretsError < NuclearSecretError
33
- def initialize(secrets)
34
- super(secrets: secrets)
24
+ def build_pairs(keys, secrets)
25
+ keys.map do |k|
26
+ build_secret_tuple(secrets, required_secrets, k)
27
+ end
35
28
  end
36
29
 
37
- def message
38
- "Secrets not included in required_secrets list: \n#{get_error_list}"
30
+ def build_assertions(secrets, existing_keys)
31
+ existing_keys.map do |key|
32
+ if required_secrets[key].class == Class
33
+ make_type_check(required_secrets[key])
34
+ elsif required_secrets[key].respond_to? :call
35
+ required_secrets[key]
36
+ else
37
+ raise NuclearSecrets::InvalidRequiredSecretValue.new(
38
+ [
39
+ build_secret_tuple(secrets, required_secrets, key),
40
+ ],
41
+ )
42
+ end
43
+ end
39
44
  end
40
- end
41
-
42
- class << self
43
- attr_accessor(:required_secrets)
44
45
 
45
- def configure
46
- yield self if block_given?
46
+ def check_assertions(secrets, assertions)
47
+ secrets.to_a.zip(assertions).select do |pair|
48
+ result = pair.last.call(pair.first[1])
49
+ if !result
50
+ pair.first[0]
51
+ else
52
+ false
53
+ end
54
+ end.map do |pair|
55
+ flat_pair = pair.flatten
56
+ build_secret_tuple(secrets, required_secrets, flat_pair.first)
57
+ end
47
58
  end
48
59
 
49
60
  def check_secrets(secrets)
50
61
  raise NuclearSecrets::RequiredSecretsListMissing if required_secrets.nil?
51
- req_secret_pairs = required_secrets.map { |pair| [pair.first.to_sym, pair.last.to_s] }
52
- types = secrets.map { |pair| [pair.first, pair.last.class.to_s] }
62
+ req_keys = required_secrets.keys
63
+ existing_keys = secrets.keys
64
+
65
+ missing_keys = req_keys - existing_keys
66
+ extra_keys = existing_keys - req_keys
53
67
 
54
- missing_secrets = req_secret_pairs - types
55
- extra_secrets = types - req_secret_pairs
68
+ missing_pairs = build_pairs(missing_keys, secrets)
69
+ extra_pairs = build_pairs(extra_keys, secrets)
70
+ raise SecretsMissingError.new(missing_pairs) unless missing_keys.empty?
71
+ raise ExtraSecretsError.new(extra_pairs) unless extra_keys.empty?
56
72
 
57
- raise SecretsMissingError.new(missing_secrets) unless missing_secrets.empty?
58
- raise ExtraSecretsError.new(extra_secrets) unless extra_secrets.empty?
73
+ assertions = build_assertions(secrets, existing_keys)
74
+ error_pairs = check_assertions(secrets, assertions)
75
+ raise MismatchedSecretType.new(error_pairs) if !error_pairs.empty?
59
76
  end
60
77
  end
61
78
  end
@@ -0,0 +1,84 @@
1
+ module NuclearSecrets
2
+ class NuclearSecretError < StandardError
3
+ def initialize(secrets: [])
4
+ @secrets = secrets
5
+ end
6
+
7
+ def required_type_message(req_type)
8
+ if req_type.nil?
9
+ " of value nil"
10
+ elsif req_type.class == Class
11
+ " of type #{req_type}"
12
+ elsif req_type.class == Proc
13
+ source_pair = req_type.source_location
14
+ " of type Proc (defined in file: #{source_pair.first}, line: #{source_pair.last})"
15
+ else
16
+ " of value #{req_type}"
17
+ end
18
+ end
19
+
20
+ def given_type_message(given_type)
21
+ if given_type.nil?
22
+ "\n"
23
+ elsif given_type.class == String
24
+ " was given \"#{given_type}\"\n"
25
+ else
26
+ " was given #{given_type}\n"
27
+ end
28
+ end
29
+
30
+ def get_error_list
31
+ @secrets.reduce("") do |message, current|
32
+ message << current.first.to_s
33
+ message << required_type_message(current[1])
34
+ message << given_type_message(current.last)
35
+ end
36
+ end
37
+ end
38
+
39
+ class RequiredSecretsListMissing < NuclearSecretError
40
+ def message
41
+ "You must include a NuclearSecrets initializer in your app"
42
+ end
43
+ end
44
+
45
+ class SecretsMissingError < NuclearSecretError
46
+ def initialize(secrets)
47
+ super(secrets: secrets)
48
+ end
49
+
50
+ def message
51
+ "You are not using a secret that is required in the secrets list: \n#{get_error_list}"
52
+ end
53
+ end
54
+
55
+ class ExtraSecretsError < NuclearSecretError
56
+ def initialize(secrets)
57
+ super(secrets: secrets)
58
+ end
59
+
60
+ def message
61
+ "You have used a secret that is not in included in the secrets list: \n#{get_error_list}"
62
+ end
63
+ end
64
+
65
+ class InvalidRequiredSecretValue < NuclearSecretError
66
+ def initialize(secrets)
67
+ super(secrets: secrets)
68
+ end
69
+
70
+ def message
71
+ "You used an invalid secret: \n#{get_error_list}"
72
+ end
73
+ end
74
+
75
+ class MismatchedSecretType < NuclearSecretError
76
+ def initialize(secrets)
77
+ super(secrets: secrets)
78
+ end
79
+
80
+ def message
81
+ "You included a secret of the wrong type: \n#{get_error_list}"
82
+ end
83
+ end
84
+ end
@@ -1,3 +1,3 @@
1
1
  module NuclearSecrets
2
- VERSION = "1.0.1".freeze
2
+ VERSION = "1.0.2".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nuclear_secrets
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Atomic Jolt
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-09-13 00:00:00.000000000 Z
12
+ date: 2017-11-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -52,6 +52,7 @@ files:
52
52
  - config/initializers/nuclear_secrets.rb
53
53
  - lib/nuclear_secrets.rb
54
54
  - lib/nuclear_secrets/engine.rb
55
+ - lib/nuclear_secrets/errors.rb
55
56
  - lib/nuclear_secrets/version.rb
56
57
  homepage: https://github.com/atomicjolt/NuclearSecrets
57
58
  licenses:
@@ -73,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
74
  version: '0'
74
75
  requirements: []
75
76
  rubyforge_project:
76
- rubygems_version: 2.6.13
77
+ rubygems_version: 2.6.11
77
78
  signing_key:
78
79
  specification_version: 4
79
80
  summary: Quell rails secret espionage by verifying what secrets exist and their types