virgil-jwt 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +37 -0
- data/LICENSE.txt +33 -0
- data/README.md +203 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/virgil-sdk-ruby-jwt +3 -0
- data/lib/virgil/jwt.rb +14 -0
- data/lib/virgil/jwt/access_token.rb +51 -0
- data/lib/virgil/jwt/access_token_provider.rb +46 -0
- data/lib/virgil/jwt/bytes.rb +125 -0
- data/lib/virgil/jwt/caching_jwt_provider.rb +74 -0
- data/lib/virgil/jwt/callback_jwt_provider.rb +60 -0
- data/lib/virgil/jwt/const_access_token_provider.rb +56 -0
- data/lib/virgil/jwt/jwt.rb +132 -0
- data/lib/virgil/jwt/jwt_body_content.rb +110 -0
- data/lib/virgil/jwt/jwt_generator.rb +110 -0
- data/lib/virgil/jwt/jwt_header_content.rb +94 -0
- data/lib/virgil/jwt/jwt_verifier.rb +78 -0
- data/lib/virgil/jwt/token_context.rb +72 -0
- data/lib/virgil/jwt/validation.rb +59 -0
- data/lib/virgil/jwt/version.rb +5 -0
- data/virgil-jwt.gemspec +31 -0
- metadata +161 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
# Copyright (C) 2015-2019 Virgil Security Inc.
|
2
|
+
#
|
3
|
+
# Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are
|
9
|
+
# met:
|
10
|
+
#
|
11
|
+
# (1) Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
#
|
14
|
+
# (2) Redistributions in binary form must reproduce the above copyright
|
15
|
+
# notice, this list of conditions and the following disclaimer in
|
16
|
+
# the documentation and/or other materials provided with the
|
17
|
+
# distribution.
|
18
|
+
#
|
19
|
+
# (3) Neither the name of the copyright holder nor the names of its
|
20
|
+
# contributors may be used to endorse or promote products derived from
|
21
|
+
# this software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
|
24
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
25
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
26
|
+
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
27
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
28
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
# SERVICES; LOSS OF USE, bytes, OR PROFITS; OR BUSINESS INTERRUPTION)
|
30
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
31
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
32
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
|
35
|
+
require 'base64'
|
36
|
+
require 'json'
|
37
|
+
|
38
|
+
module Virgil
|
39
|
+
module Jwt
|
40
|
+
class Bytes < Array
|
41
|
+
# Initializes a new array of bytes from specified string, which encodes binary data.
|
42
|
+
# @param str [String] String to decode.
|
43
|
+
# @param encoding [VirgilStringEncoding] The character encoding of string.
|
44
|
+
# @raise [ArgumentError] if encoding is undefined
|
45
|
+
def self.from_string(str, encoding = VirgilStringEncoding::UTF8)
|
46
|
+
case encoding
|
47
|
+
when VirgilStringEncoding::BASE64
|
48
|
+
from_base64(str)
|
49
|
+
when VirgilStringEncoding::HEX
|
50
|
+
from_hex(str)
|
51
|
+
when VirgilStringEncoding::UTF8
|
52
|
+
from_utf8(str)
|
53
|
+
else
|
54
|
+
raise ArgumentError, 'Encoding is undefined'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Decodes the current bytes to a string according to the specified
|
59
|
+
# character encoding.
|
60
|
+
# @param encoding [VirgilStringEncoding] The character encoding to encode to.
|
61
|
+
# equivalent string representation if raw bytes in selected encoding.
|
62
|
+
# @return [String]
|
63
|
+
# @raise [ArgumentError] if encoding is undefined
|
64
|
+
def to_string(encoding = VirgilStringEncoding::UTF8)
|
65
|
+
case encoding
|
66
|
+
when VirgilStringEncoding::BASE64
|
67
|
+
to_base64
|
68
|
+
when VirgilStringEncoding::HEX
|
69
|
+
to_hex
|
70
|
+
when VirgilStringEncoding::UTF8
|
71
|
+
to_s
|
72
|
+
else
|
73
|
+
raise ArgumentError, 'Encoding is undefined'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Converts all the bytes to its equivalent string representation in utf8.
|
78
|
+
def to_s
|
79
|
+
pack('c*')
|
80
|
+
end
|
81
|
+
|
82
|
+
# Initializes a new array of bytes from specified string,
|
83
|
+
# which encodes binary data as base-64 digits.
|
84
|
+
def self.from_base64(str)
|
85
|
+
new(Base64.decode64(str).bytes)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Initializes a new array of bytes from specified string,
|
89
|
+
# which encodes binary data as utf8.
|
90
|
+
def self.from_utf8(str)
|
91
|
+
new(str.bytes)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Initializes a new array of bytes from specified string,
|
95
|
+
# which encodes binary data as hexadecimal digits.
|
96
|
+
def self.from_hex(str)
|
97
|
+
new(str.scan(/../).map { |x| x.hex })
|
98
|
+
end
|
99
|
+
|
100
|
+
# Converts all the bytes to its equivalent string representation that
|
101
|
+
# is encoded with base-64 digits.
|
102
|
+
def to_base64
|
103
|
+
Base64.strict_encode64(to_s)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Encodes all the bytes into a utf8 string.
|
107
|
+
def to_utf8
|
108
|
+
to_s
|
109
|
+
end
|
110
|
+
|
111
|
+
# Converts the numeric value of each element of a current array of bytes to its
|
112
|
+
# equivalent hexadecimal string representation.
|
113
|
+
def to_hex
|
114
|
+
to_s.each_byte.map { |b| b.to_s(16) }.join
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
module VirgilStringEncoding
|
120
|
+
BASE64 = 1
|
121
|
+
HEX = 2
|
122
|
+
UTF8 = 3
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Copyright (C) 2015-2019 Virgil Security Inc.
|
2
|
+
#
|
3
|
+
# Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are
|
9
|
+
# met:
|
10
|
+
#
|
11
|
+
# (1) Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
#
|
14
|
+
# (2) Redistributions in binary form must reproduce the above copyright
|
15
|
+
# notice, this list of conditions and the following disclaimer in
|
16
|
+
# the documentation and/or other materials provided with the
|
17
|
+
# distribution.
|
18
|
+
#
|
19
|
+
# (3) Neither the name of the copyright holder nor the names of its
|
20
|
+
# contributors may be used to endorse or promote products derived from
|
21
|
+
# this software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
|
24
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
25
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
26
|
+
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
27
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
28
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
# SERVICES; LOSS OF USE, bytes, OR PROFITS; OR BUSINESS INTERRUPTION)
|
30
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
31
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
32
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
require 'thread'
|
35
|
+
|
36
|
+
module Virgil
|
37
|
+
module Jwt
|
38
|
+
|
39
|
+
# Provides an opportunity to
|
40
|
+
# get cached access token or renew it using callback mechanism.
|
41
|
+
class CachingJwtProvider < AccessTokenProvider
|
42
|
+
|
43
|
+
# Callback, that takes an instance of [TokenContext]
|
44
|
+
# and returns string representation of generated instance of [AccessToken]
|
45
|
+
# @return [Proc]
|
46
|
+
attr_reader :renew_access_token_proc
|
47
|
+
|
48
|
+
@@mutex = Mutex.new
|
49
|
+
def initialize(obtain_token_proc)
|
50
|
+
Validation.check_type_argument!(Proc, obtain_token_proc)
|
51
|
+
@renew_access_token_proc = obtain_token_proc
|
52
|
+
end
|
53
|
+
|
54
|
+
# Gets cached or renewed access token.
|
55
|
+
# @param token_context an instance of [TokenContext]
|
56
|
+
# @return The instance of [AccessToken]
|
57
|
+
def get_token(token_context)
|
58
|
+
Validation.check_type_argument!(TokenContext, token_context)
|
59
|
+
|
60
|
+
if !@jwt || (@jwt.body_content.expires_at <= Time.at(Time.now.utc.to_i + 5).utc)
|
61
|
+
@@mutex.synchronize {
|
62
|
+
jwt_str = @renew_access_token_proc.call(token_context)
|
63
|
+
@jwt = Jwt.from(jwt_str)
|
64
|
+
}
|
65
|
+
end
|
66
|
+
@jwt
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
attr_reader :jwt
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright (C) 2015-2019 Virgil Security Inc.
|
2
|
+
#
|
3
|
+
# Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are
|
9
|
+
# met:
|
10
|
+
#
|
11
|
+
# (1) Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
#
|
14
|
+
# (2) Redistributions in binary form must reproduce the above copyright
|
15
|
+
# notice, this list of conditions and the following disclaimer in
|
16
|
+
# the documentation and/or other materials provided with the
|
17
|
+
# distribution.
|
18
|
+
#
|
19
|
+
# (3) Neither the name of the copyright holder nor the names of its
|
20
|
+
# contributors may be used to endorse or promote products derived from
|
21
|
+
# this software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
|
24
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
25
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
26
|
+
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
27
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
28
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
# SERVICES; LOSS OF USE, bytes, OR PROFITS; OR BUSINESS INTERRUPTION)
|
30
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
31
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
32
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
|
35
|
+
module Virgil
|
36
|
+
module Jwt
|
37
|
+
# provides an opportunity to
|
38
|
+
# get access token using callback mechanism.
|
39
|
+
class CallbackJwtProvider < AccessTokenProvider
|
40
|
+
|
41
|
+
# Callback, that takes an instance of [TokenContext]
|
42
|
+
# and returns string representation of generated instance of [AccessToken]
|
43
|
+
attr_reader :obtain_access_token_proc
|
44
|
+
|
45
|
+
def initialize(obtain_token_proc)
|
46
|
+
Validation.check_type_argument!(Proc, obtain_token_proc)
|
47
|
+
@obtain_access_token_proc = obtain_token_proc
|
48
|
+
end
|
49
|
+
|
50
|
+
# Gets access token.
|
51
|
+
# @param token_context [TokenContext]
|
52
|
+
# @return [AccessToken] Access token
|
53
|
+
def get_token(token_context)
|
54
|
+
Validation.check_type_argument!(TokenContext, token_context)
|
55
|
+
jwt_str = @obtain_access_token_proc.call(token_context)
|
56
|
+
Jwt.from(jwt_str)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Copyright (C) 2015-2019 Virgil Security Inc.
|
2
|
+
#
|
3
|
+
# Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are
|
9
|
+
# met:
|
10
|
+
#
|
11
|
+
# (1) Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
#
|
14
|
+
# (2) Redistributions in binary form must reproduce the above copyright
|
15
|
+
# notice, this list of conditions and the following disclaimer in
|
16
|
+
# the documentation and/or other materials provided with the
|
17
|
+
# distribution.
|
18
|
+
#
|
19
|
+
# (3) Neither the name of the copyright holder nor the names of its
|
20
|
+
# contributors may be used to endorse or promote products derived from
|
21
|
+
# this software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
|
24
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
25
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
26
|
+
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
27
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
28
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
# SERVICES; LOSS OF USE, bytes, OR PROFITS; OR BUSINESS INTERRUPTION)
|
30
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
31
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
32
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
|
35
|
+
module Virgil
|
36
|
+
module Jwt
|
37
|
+
# Provides an opportunity to use constant access token.
|
38
|
+
class ConstAccessTokenProvider < AccessTokenProvider
|
39
|
+
def initialize(token)
|
40
|
+
@access_token = token
|
41
|
+
end
|
42
|
+
|
43
|
+
# Gets access token.
|
44
|
+
# @param token_context [TokenContext] can be null as
|
45
|
+
# it does not affect the result.
|
46
|
+
# @return [AccessToken]
|
47
|
+
def get_token(token_context)
|
48
|
+
access_token
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
attr_reader :access_token
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# Copyright (C) 2015-2019 Virgil Security Inc.
|
2
|
+
#
|
3
|
+
# Lead Maintainer: Virgil Security Inc. <support@virgilsecurity.com>
|
4
|
+
#
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are
|
9
|
+
# met:
|
10
|
+
#
|
11
|
+
# (1) Redistributions of source code must retain the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer.
|
13
|
+
#
|
14
|
+
# (2) Redistributions in binary form must reproduce the above copyright
|
15
|
+
# notice, this list of conditions and the following disclaimer in
|
16
|
+
# the documentation and/or other materials provided with the
|
17
|
+
# distribution.
|
18
|
+
#
|
19
|
+
# (3) Neither the name of the copyright holder nor the names of its
|
20
|
+
# contributors may be used to endorse or promote products derived from
|
21
|
+
# this software without specific prior written permission.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
|
24
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
25
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
26
|
+
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
27
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
28
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
29
|
+
# SERVICES; LOSS OF USE, bytes, OR PROFITS; OR BUSINESS INTERRUPTION)
|
30
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
31
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
32
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
|
35
|
+
module Virgil
|
36
|
+
module Jwt
|
37
|
+
# Implements [AccessToken] in terms of Virgil JWT.
|
38
|
+
class Jwt < AccessToken
|
39
|
+
# Gets a jwt body
|
40
|
+
# @return [JwtBodyContent]
|
41
|
+
attr_reader :body_content
|
42
|
+
|
43
|
+
# Gets a jwt header
|
44
|
+
# @return [JwtHeaderContent]
|
45
|
+
attr_reader :header_content
|
46
|
+
|
47
|
+
# Gets a digital signature of jwt
|
48
|
+
# @return [Bytes]
|
49
|
+
attr_reader :signature_data
|
50
|
+
|
51
|
+
# String representation of jwt without signature.
|
52
|
+
# It equals to:
|
53
|
+
# Base64.urlsafe_encode64(JWT Header) + "." + Base64.urlsafe_encode64(JWT Body)
|
54
|
+
# @return [String]
|
55
|
+
attr_reader :unsigned_data
|
56
|
+
|
57
|
+
# Initializes a new instance of the [Jwt] class using specified header,
|
58
|
+
# body and signature.
|
59
|
+
# @param header_content [JwtHeaderContext] jwt header
|
60
|
+
# @param body_content [JwtBodyContent] jwt body
|
61
|
+
# @param signature_data [Bytes] jwt signature data
|
62
|
+
def initialize(header_content:, body_content:, signature_data:)
|
63
|
+
@header_content = header_content
|
64
|
+
@body_content = body_content
|
65
|
+
@signature_data = signature_data
|
66
|
+
@string_representation = "#{header_base64}.#{body_base64}"
|
67
|
+
@unsigned_data = Bytes.from_string(@string_representation)
|
68
|
+
@string_representation += ".#{signature_base64}" unless @signature_data.nil?
|
69
|
+
end
|
70
|
+
|
71
|
+
# Initializes a new instance of the [Jwt] class using
|
72
|
+
# its string representation
|
73
|
+
# @param jwt_str [String] string representation of signed jwt.
|
74
|
+
# It must be equal to:
|
75
|
+
# Base64.urlsafe_encode64(jwt_header.to_base64) + "."
|
76
|
+
# + Base64.urlsafe_encode64(JWT Body) "."
|
77
|
+
# + Base64.urlsafe_encode64(Jwt Signature).
|
78
|
+
# @return [Jwt]
|
79
|
+
def self.from(jwt_str)
|
80
|
+
begin
|
81
|
+
parts = jwt_str.split('.')
|
82
|
+
raise ArgumentError unless parts.size == 3
|
83
|
+
signature_data = Bytes.new(Base64.urlsafe_decode64(parts[2]).bytes)
|
84
|
+
new(header_content: parse_header_content(parts[0]),
|
85
|
+
body_content: parse_body_content(parts[1]),
|
86
|
+
signature_data: signature_data)
|
87
|
+
rescue StandardError
|
88
|
+
raise ArgumentError, 'Wrong JWT format.'
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
# String representation of jwt.
|
94
|
+
# @return [String]
|
95
|
+
def to_s
|
96
|
+
@string_representation
|
97
|
+
end
|
98
|
+
|
99
|
+
# Whether or not token is expired.
|
100
|
+
# @return [TrueClass]
|
101
|
+
def expired?
|
102
|
+
Time.now.utc >= @body_content.expires_at
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
attr_reader :string_representation
|
108
|
+
|
109
|
+
def self.parse_body_content(str)
|
110
|
+
body_json = Base64.urlsafe_decode64(str)
|
111
|
+
JwtBodyContent.restore_from_json(body_json)
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.parse_header_content(str)
|
115
|
+
header_json = Base64.urlsafe_decode64(str)
|
116
|
+
JwtHeaderContent.restore_from_json(header_json)
|
117
|
+
end
|
118
|
+
|
119
|
+
def header_base64
|
120
|
+
Base64.urlsafe_encode64(@header_content.to_json, padding: false)
|
121
|
+
end
|
122
|
+
|
123
|
+
def body_base64
|
124
|
+
Base64.urlsafe_encode64(@body_content.to_json, padding: false)
|
125
|
+
end
|
126
|
+
|
127
|
+
def signature_base64
|
128
|
+
Base64.urlsafe_encode64(@signature_data.to_s, padding: false)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|