m2m_keygen 0.2.1 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -44,6 +44,94 @@
44
44
  <ul id="full_list" class="method">
45
45
 
46
46
 
47
+ <li class="odd ">
48
+ <div class="item">
49
+ <span class='object_link'><a href="M2mKeygen/Signature.html#algorithm-instance_method" title="M2mKeygen::Signature#algorithm (method)">#algorithm</a></span>
50
+ <small>M2mKeygen::Signature</small>
51
+ </div>
52
+ </li>
53
+
54
+
55
+ <li class="even ">
56
+ <div class="item">
57
+ <span class='object_link'><a href="M2mKeygen/ParamsEncoder.html#encode-instance_method" title="M2mKeygen::ParamsEncoder#encode (method)">#encode</a></span>
58
+ <small>M2mKeygen::ParamsEncoder</small>
59
+ </div>
60
+ </li>
61
+
62
+
63
+ <li class="odd ">
64
+ <div class="item">
65
+ <span class='object_link'><a href="M2mKeygen/RackValidator.html#header_name-instance_method" title="M2mKeygen::RackValidator#header_name (method)">#header_name</a></span>
66
+ <small>M2mKeygen::RackValidator</small>
67
+ </div>
68
+ </li>
69
+
70
+
71
+ <li class="even ">
72
+ <div class="item">
73
+ <span class='object_link'><a href="M2mKeygen/Signature.html#initialize-instance_method" title="M2mKeygen::Signature#initialize (method)">#initialize</a></span>
74
+ <small>M2mKeygen::Signature</small>
75
+ </div>
76
+ </li>
77
+
78
+
79
+ <li class="odd ">
80
+ <div class="item">
81
+ <span class='object_link'><a href="M2mKeygen/RackValidator.html#initialize-instance_method" title="M2mKeygen::RackValidator#initialize (method)">#initialize</a></span>
82
+ <small>M2mKeygen::RackValidator</small>
83
+ </div>
84
+ </li>
85
+
86
+
87
+ <li class="even ">
88
+ <div class="item">
89
+ <span class='object_link'><a href="M2mKeygen/ParamsEncoder.html#initialize-instance_method" title="M2mKeygen::ParamsEncoder#initialize (method)">#initialize</a></span>
90
+ <small>M2mKeygen::ParamsEncoder</small>
91
+ </div>
92
+ </li>
93
+
94
+
95
+ <li class="odd ">
96
+ <div class="item">
97
+ <span class='object_link'><a href="M2mKeygen/Signature.html#secret-instance_method" title="M2mKeygen::Signature#secret (method)">#secret</a></span>
98
+ <small>M2mKeygen::Signature</small>
99
+ </div>
100
+ </li>
101
+
102
+
103
+ <li class="even ">
104
+ <div class="item">
105
+ <span class='object_link'><a href="M2mKeygen/Signature.html#sign-instance_method" title="M2mKeygen::Signature#sign (method)">#sign</a></span>
106
+ <small>M2mKeygen::Signature</small>
107
+ </div>
108
+ </li>
109
+
110
+
111
+ <li class="odd ">
112
+ <div class="item">
113
+ <span class='object_link'><a href="M2mKeygen/RackValidator.html#signature-instance_method" title="M2mKeygen::RackValidator#signature (method)">#signature</a></span>
114
+ <small>M2mKeygen::RackValidator</small>
115
+ </div>
116
+ </li>
117
+
118
+
119
+ <li class="even ">
120
+ <div class="item">
121
+ <span class='object_link'><a href="M2mKeygen/Signature.html#validate-instance_method" title="M2mKeygen::Signature#validate (method)">#validate</a></span>
122
+ <small>M2mKeygen::Signature</small>
123
+ </div>
124
+ </li>
125
+
126
+
127
+ <li class="odd ">
128
+ <div class="item">
129
+ <span class='object_link'><a href="M2mKeygen/RackValidator.html#validate-instance_method" title="M2mKeygen::RackValidator#validate (method)">#validate</a></span>
130
+ <small>M2mKeygen::RackValidator</small>
131
+ </div>
132
+ </li>
133
+
134
+
47
135
 
48
136
  </ul>
49
137
  </div>
@@ -100,7 +100,7 @@
100
100
  </div>
101
101
 
102
102
  <div id="footer">
103
- Generated on Mon Aug 29 18:08:40 2022 by
103
+ Generated on Mon Sep 5 14:49:01 2022 by
104
104
  <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
105
  0.9.28 (ruby-3.1.2).
106
106
  </div>
@@ -0,0 +1,56 @@
1
+ # typed: strict
2
+
3
+ module M2mKeygen
4
+ # Encoder for params hash
5
+ class ParamsEncoder
6
+ extend T::Sig
7
+
8
+ sig { params(params: Types::ParamsType).void }
9
+ def initialize(params)
10
+ @params = T.let(params, Types::ParamsType)
11
+ end
12
+
13
+ sig { returns(String) }
14
+ def encode
15
+ return "" if @params.nil? || @params.empty?
16
+ @params
17
+ .sort_by { |k, _| k.to_s }
18
+ .reject { |_, v| (v.is_a?(String) && v == "") || v.nil? }
19
+ .map { |k, v| "#{k}=#{jsonify_value(encode_value(T.must(v)))}" }
20
+ .join("&")
21
+ end
22
+
23
+ private
24
+
25
+ sig do
26
+ params(value: Types::ParamsValueType).returns(
27
+ T.any(String, Symbol, Integer)
28
+ )
29
+ end
30
+ def jsonify_value(value)
31
+ return value unless value.is_a?(Hash) || value.is_a?(Array)
32
+ value.to_json
33
+ end
34
+
35
+ sig do
36
+ params(value: Types::ParamsValueType).returns(Types::ParamsValueType)
37
+ end
38
+ def encode_value(value)
39
+ return encode_hash_value(value) if value.is_a?(Hash)
40
+ value
41
+ end
42
+
43
+ sig do
44
+ params(value: Types::ParamsHashNotNilType).returns(
45
+ T::Hash[String, Types::ParamsValueType]
46
+ )
47
+ end
48
+ def encode_hash_value(value)
49
+ value
50
+ .sort_by { |k, _| k.to_s }
51
+ .reject { |_, v| (v.is_a?(String) && v == "") || v.nil? }
52
+ .map { |k, v| [k.to_s, encode_value(v)] }
53
+ .to_h
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,34 @@
1
+ # typed: strict
2
+
3
+ require "rack"
4
+
5
+ module M2mKeygen
6
+ class RackValidator
7
+ extend T::Sig
8
+
9
+ sig { returns(Signature) }
10
+ attr_reader :signature
11
+
12
+ sig { returns(String) }
13
+ attr_reader :header_name
14
+
15
+ sig { params(secret: String, algorithm: String, header_name: String).void }
16
+ def initialize(secret, algorithm: "sha512", header_name: "X-Signature")
17
+ @header_name = T.let("HTTP_#{header_name.tr("-", "_").upcase}", String)
18
+ @signature = T.let(Signature.new(secret, algorithm: algorithm), Signature)
19
+ end
20
+
21
+ sig { params(req: T.untyped).returns(T::Boolean) }
22
+ def validate(req)
23
+ # This will cover the case when Rails is used.
24
+ req = Rack::Request.new(req.env)
25
+ @signature.validate(
26
+ params: req.params,
27
+ verb: req.request_method,
28
+ path: req.path,
29
+ signature: req.env["HTTP_X_SIGNATURE"]
30
+ ) && req.params["expiry"] && req.params["expiry"].to_i > Time.now.to_i &&
31
+ req.params["expiry"].to_i < Time.now.to_i + 120
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,78 @@
1
+ # typed: strict
2
+
3
+ require "openssl"
4
+ require "json"
5
+
6
+ module M2mKeygen
7
+ class Signature
8
+ extend T::Sig
9
+
10
+ sig { returns(String) }
11
+ attr_reader :secret
12
+
13
+ sig { returns(String) }
14
+ attr_reader :algorithm
15
+
16
+ sig { params(secret: String, algorithm: String).void }
17
+ def initialize(secret, algorithm: "sha512")
18
+ @secret = T.let(secret, String)
19
+ @algorithm = T.let(algorithm, String)
20
+ OpenSSL::HMAC.hexdigest(@algorithm, @secret, "")
21
+ end
22
+
23
+ sig do
24
+ params(
25
+ params: Types::ParamsType,
26
+ verb: T.any(String, Symbol),
27
+ path: String
28
+ ).returns(String)
29
+ end
30
+ def sign(params:, verb:, path:)
31
+ OpenSSL::HMAC.hexdigest(
32
+ @algorithm,
33
+ @secret,
34
+ "#{verb.to_s.upcase}#{path}#{ParamsEncoder.new(params).encode}"
35
+ )
36
+ end
37
+
38
+ sig do
39
+ params(
40
+ params: Types::ParamsType,
41
+ verb: T.any(String, Symbol),
42
+ path: String,
43
+ signature: String
44
+ ).returns(T::Boolean)
45
+ end
46
+ def validate(params:, verb:, path:, signature:)
47
+ if OpenSSL.methods.include?(:fixed_length_secure_compare)
48
+ OpenSSL.fixed_length_secure_compare(
49
+ sign(params: params, verb: verb, path: path),
50
+ signature
51
+ )
52
+ else
53
+ fallback_fixed_length_secure_compare(
54
+ sign(params: params, verb: verb, path: path),
55
+ signature
56
+ )
57
+ end
58
+ rescue StandardError
59
+ false
60
+ end
61
+
62
+ private
63
+
64
+ # Ruby 2.7 openssl lib doesn't have fixed_length_secure_compare method
65
+ # File activesupport/lib/active_support/security_utils.rb, line 11
66
+ # With sorbet fix
67
+ sig { params(str_a: String, str_b: String).returns(T::Boolean) }
68
+ def fallback_fixed_length_secure_compare(str_a, str_b)
69
+ return false unless str_a.bytesize == str_b.bytesize
70
+
71
+ l = str_a.unpack "C#{str_a.bytesize}"
72
+
73
+ res = 0
74
+ str_b.each_byte { |byte| res |= byte ^ l.shift.to_i }
75
+ res == 0
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,25 @@
1
+ # typed: strict
2
+ module M2mKeygen
3
+ module Types
4
+ extend T::Sig
5
+
6
+ ParamsType =
7
+ T.type_alias do
8
+ T.nilable(T::Hash[T.any(String, Symbol), T.nilable(ParamsValueType)])
9
+ end
10
+
11
+ ParamsHashNotNilType =
12
+ T.type_alias { T::Hash[T.any(String, Symbol), ParamsValueType] }
13
+
14
+ ParamsValueType =
15
+ T.type_alias do
16
+ T.any(
17
+ Integer,
18
+ String,
19
+ Symbol,
20
+ T::Array[T.untyped],
21
+ T::Hash[T.untyped, T.untyped]
22
+ )
23
+ end
24
+ end
25
+ end
@@ -3,5 +3,5 @@
3
3
 
4
4
  module M2mKeygen
5
5
  # Gem version
6
- VERSION = "0.2.1"
6
+ VERSION = "0.4.1"
7
7
  end
data/lib/m2m_keygen.rb CHANGED
@@ -1,7 +1,10 @@
1
1
  # typed: strict
2
- # frozen_string_literal: true
3
2
 
4
- require_relative "m2m_keygen/version"
3
+ require "sorbet-runtime"
4
+ require "zeitwerk"
5
+
6
+ loader = Zeitwerk::Loader.for_gem
7
+ loader.setup
5
8
 
6
9
  # Main module
7
10
  module M2mKeygen
data/m2m_keygen.gemspec CHANGED
@@ -41,6 +41,7 @@ Gem::Specification.new do |spec|
41
41
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
42
42
  spec.require_paths = ["lib"]
43
43
 
44
+ spec.add_dependency "rack"
44
45
  spec.add_dependency "sorbet-runtime"
45
46
  spec.add_dependency "zeitwerk", "~> 2.6"
46
47
  end
@@ -1534,6 +1534,30 @@ class ActiveSupport::Cache::Strategy::LocalCache::LocalStore
1534
1534
  def write_entry(key, entry); end
1535
1535
  end
1536
1536
 
1537
+ # --
1538
+ # This class wraps up local storage for middlewares. Only the middleware method should
1539
+ # construct them.
1540
+ #
1541
+ # source://activesupport-7.0.3.1/lib/active_support/cache/strategy/local_cache_middleware.rb:13
1542
+ class ActiveSupport::Cache::Strategy::LocalCache::Middleware
1543
+ # @return [Middleware] a new instance of Middleware
1544
+ #
1545
+ # source://activesupport-7.0.3.1/lib/active_support/cache/strategy/local_cache_middleware.rb:16
1546
+ def initialize(name, local_cache_key); end
1547
+
1548
+ # source://activesupport-7.0.3.1/lib/active_support/cache/strategy/local_cache_middleware.rb:27
1549
+ def call(env); end
1550
+
1551
+ # source://activesupport-7.0.3.1/lib/active_support/cache/strategy/local_cache_middleware.rb:14
1552
+ def local_cache_key; end
1553
+
1554
+ # source://activesupport-7.0.3.1/lib/active_support/cache/strategy/local_cache_middleware.rb:14
1555
+ def name; end
1556
+
1557
+ # source://activesupport-7.0.3.1/lib/active_support/cache/strategy/local_cache_middleware.rb:22
1558
+ def new(app); end
1559
+ end
1560
+
1537
1561
  # These options mean something to all cache implementations. Individual cache
1538
1562
  # implementations may support additional options.
1539
1563
  #