decode_this 0.1.6 → 0.1.7
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/decode_this.gemspec +0 -1
- data/lib/decode_this/safe_decoding.rb +2 -1
- data/lib/decode_this/version.rb +1 -1
- data/lib/decode_this.rb +68 -1
- data/spec/{decode_this/decoder_spec.rb → decode_this_spec.rb} +24 -6
- data/spec/fixtures/nonexistent_config.yml +1 -1
- data/spec/spec_helper.rb +6 -4
- metadata +4 -19
- data/lib/decode_this/decoder.rb +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 606c55fdd8065f0c7684da605cb50dd56ca355eb
|
4
|
+
data.tar.gz: e2474db9de8ae7b5966d9825fd5a111d8fdbc27f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e04f30fa5f0c83a13de6dc2b03fc701ff06d60fd50ccda9dfdcd7cd2b8d5a8a5d834bcf460fe881e460a72d95be37545bef0fbcf3be0b14cff9ac0278741c84f
|
7
|
+
data.tar.gz: b2a607e6a4d02b70bc1280671eaf7649993e649df01916ecd8db16c99bde960d30874528933ceb7a6449b122e5f8bb46b4548e846cbbc2156d5e18a33160fbd8
|
data/decode_this.gemspec
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module DecodeThis
|
3
3
|
BaseError = Class.new(RuntimeError)
|
4
|
+
ConfigFileNotFoundError = Class.new(BaseError)
|
4
5
|
KeyFileNotFoundError = Class.new(BaseError)
|
5
6
|
DecodeError = Class.new(BaseError)
|
6
7
|
|
7
8
|
class SafeDecoding
|
8
|
-
def self.call(logger
|
9
|
+
def self.call(logger, &block)
|
9
10
|
block.call
|
10
11
|
|
11
12
|
rescue JWT::ExpiredSignature => err
|
data/lib/decode_this/version.rb
CHANGED
data/lib/decode_this.rb
CHANGED
@@ -1,3 +1,70 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'decode_this/version'
|
3
|
-
require 'decode_this/
|
3
|
+
require 'decode_this/safe_decoding'
|
4
|
+
require 'yaml'
|
5
|
+
require 'jwt'
|
6
|
+
|
7
|
+
module DecodeThis
|
8
|
+
def self.decode(header_value)
|
9
|
+
token = token_from_header(header_value)
|
10
|
+
|
11
|
+
safe_decode { JWT.decode(token, public_key, true, algorithm: config['algorithm']).first }
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.config
|
15
|
+
raise ConfigFileNotFoundError.new("Cannot found configuration file in #{@config_path}") unless @config_path
|
16
|
+
|
17
|
+
@config ||= YAML.load(File.open(@config_path))[@env]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.config_path=(config_path)
|
21
|
+
@config_path = File.expand_path(config_path)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.config_path
|
25
|
+
@config_path
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.logger
|
29
|
+
@logger
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.logger=(logger)
|
33
|
+
@logger = logger
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.env=(env)
|
37
|
+
@env = env.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.env
|
41
|
+
@env
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def self.safe_decode(&block)
|
47
|
+
SafeDecoding.call(logger, &block)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.token_from_header(header_value)
|
51
|
+
return unless header_value
|
52
|
+
|
53
|
+
token = header_value.match(/^#{config['authorization_scheme']} (.+)/)
|
54
|
+
token[1] if token
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.public_key
|
58
|
+
OpenSSL::PKey::RSA.new(pem).public_key
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.pem
|
62
|
+
keys_absolute_path = File.expand_path(config['key_path'])
|
63
|
+
|
64
|
+
if !File.readable?(keys_absolute_path)
|
65
|
+
raise DecodeThis::KeyFileNotFoundError.new("Cannot found file in #{config['key_path']}")
|
66
|
+
end
|
67
|
+
|
68
|
+
File.read(config['key_path'])
|
69
|
+
end
|
70
|
+
end
|
@@ -1,14 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
RSpec.describe DecodeThis
|
5
|
-
let(:config_path) {
|
4
|
+
RSpec.describe DecodeThis do
|
5
|
+
let(:config_path) { 'spec/fixtures/config.yml' }
|
6
6
|
let(:payload) { { field: 'foobar' } }
|
7
|
-
let(:header_value) { encode(payload) }
|
7
|
+
let(:header_value) { encode(payload, config_path) }
|
8
8
|
let(:logger) { Logger.new(STDOUT) }
|
9
9
|
|
10
|
+
before do
|
11
|
+
DecodeThis.logger = logger
|
12
|
+
DecodeThis.config_path = config_path
|
13
|
+
end
|
14
|
+
|
10
15
|
subject(:decoded_token) do
|
11
|
-
described_class.
|
16
|
+
described_class.decode(header_value)
|
12
17
|
end
|
13
18
|
|
14
19
|
it 'decodes given token correctly' do
|
@@ -18,10 +23,20 @@ RSpec.describe DecodeThis::Decoder do
|
|
18
23
|
end
|
19
24
|
|
20
25
|
context 'when check correct error raising' do
|
21
|
-
context 'when raise error when
|
22
|
-
let(:config_path) { 'spec/fixtures/
|
26
|
+
context 'when raise error when key file not present' do
|
27
|
+
let(:config_path) { 'spec/fixtures/another_nonexistent_config.yml' }
|
28
|
+
let(:header_value) { 'foobar' }
|
23
29
|
|
24
30
|
it 'raises ConfigFileNotFoundError' do
|
31
|
+
expect { decoded_token }.to raise_error { DecodeThis::ConfigFileNotFoundError }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when raise error when key file not present' do
|
36
|
+
let(:config_path) { 'spec/fixtures/nonexistent_config.yml' }
|
37
|
+
let(:header_value) { 'foobar' }
|
38
|
+
|
39
|
+
it 'raises KeyFileNotFoundError' do
|
25
40
|
expect(logger).to receive(:warn).and_call_original
|
26
41
|
expect { decoded_token }.to raise_error { DecodeThis::KeyFileNotFoundError }
|
27
42
|
end
|
@@ -38,6 +53,9 @@ RSpec.describe DecodeThis::Decoder do
|
|
38
53
|
|
39
54
|
context 'when raise error when try to decode by another key' do
|
40
55
|
let(:config_path) { File.expand_path('spec/fixtures/another_config.yml') }
|
56
|
+
let(:header) { encode(payload, config_path) }
|
57
|
+
|
58
|
+
before { DecodeThis.config_path = 'spec/fixtures/config.yml' }
|
41
59
|
|
42
60
|
it 'raises DecodeError' do
|
43
61
|
expect(logger).to receive(:warn).and_call_original
|
data/spec/spec_helper.rb
CHANGED
@@ -4,8 +4,10 @@ require 'bundler/setup'
|
|
4
4
|
require 'logger'
|
5
5
|
require 'decode_this'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
DecodeThis.env = :test
|
8
|
+
|
9
|
+
def encode(payload, config_path = nil)
|
10
|
+
config = YAML.load(File.open(config_path))[DecodeThis.env] || DecodeThis.config
|
11
|
+
private_key = OpenSSL::PKey::RSA.new(File.read(config['key_path']))
|
12
|
+
"#{config['authorization_scheme']} " + JWT.encode(payload, private_key, config['algorithm'])
|
11
13
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: decode_this
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sasha Kotov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jwt
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: huyettings
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: bundler
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,10 +80,9 @@ files:
|
|
94
80
|
- Readme.md
|
95
81
|
- decode_this.gemspec
|
96
82
|
- lib/decode_this.rb
|
97
|
-
- lib/decode_this/decoder.rb
|
98
83
|
- lib/decode_this/safe_decoding.rb
|
99
84
|
- lib/decode_this/version.rb
|
100
|
-
- spec/
|
85
|
+
- spec/decode_this_spec.rb
|
101
86
|
- spec/fixtures/another_config.yml
|
102
87
|
- spec/fixtures/another_unsecured.pem
|
103
88
|
- spec/fixtures/config.yml
|
@@ -129,7 +114,7 @@ signing_key:
|
|
129
114
|
specification_version: 4
|
130
115
|
summary: Decode token. This token
|
131
116
|
test_files:
|
132
|
-
- spec/
|
117
|
+
- spec/decode_this_spec.rb
|
133
118
|
- spec/fixtures/another_config.yml
|
134
119
|
- spec/fixtures/another_unsecured.pem
|
135
120
|
- spec/fixtures/config.yml
|
data/lib/decode_this/decoder.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'decode_this/safe_decoding'
|
3
|
-
require 'openssl'
|
4
|
-
require 'jwt'
|
5
|
-
require 'huyettings'
|
6
|
-
|
7
|
-
module DecodeThis
|
8
|
-
class Decoder
|
9
|
-
attr_reader :header_value, :config_file, :env, :logger
|
10
|
-
|
11
|
-
def initialize(header_value, config_file:, env:, logger: nil)
|
12
|
-
@header_value = header_value
|
13
|
-
@config_file = config_file
|
14
|
-
@env = env
|
15
|
-
@logger = logger
|
16
|
-
end
|
17
|
-
|
18
|
-
def call
|
19
|
-
safe_decode { JWT.decode(token, public_key, true, algorithm: algorithm).first }
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def config
|
25
|
-
@config ||= Huyettings.new(config_file, env)
|
26
|
-
end
|
27
|
-
|
28
|
-
def algorithm
|
29
|
-
config.algorithm
|
30
|
-
end
|
31
|
-
|
32
|
-
def token
|
33
|
-
return unless header_value
|
34
|
-
|
35
|
-
token = header_value.match(/^#{config.authorization_scheme} (.+)/)
|
36
|
-
token[1] if token
|
37
|
-
end
|
38
|
-
|
39
|
-
def public_key
|
40
|
-
private_key.public_key
|
41
|
-
end
|
42
|
-
|
43
|
-
def safe_decode(&block)
|
44
|
-
DecodeThis::SafeDecoding.call(logger, &block)
|
45
|
-
end
|
46
|
-
|
47
|
-
def private_key
|
48
|
-
OpenSSL::PKey::RSA.new(pem)
|
49
|
-
end
|
50
|
-
|
51
|
-
def pem
|
52
|
-
keys_absolute_path = File.expand_path(config.key_path)
|
53
|
-
|
54
|
-
if !File.readable?(keys_absolute_path)
|
55
|
-
raise DecodeThis::KeyFileNotFoundError.new("Cannot found file in #{config.key_path}")
|
56
|
-
end
|
57
|
-
|
58
|
-
File.read(config.key_path)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|