josebuilder 0.0.5 → 0.0.6

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
  SHA1:
3
- metadata.gz: 4e8502f7a92c455fcf01dd5269f74db124200011
4
- data.tar.gz: b0afffb20bc1c2e647d1cb51d9c9bf062d9d2303
3
+ metadata.gz: 829439b805873f4fc7316f4cb4cff959f0d3a575
4
+ data.tar.gz: e38b3821283ce3f1d46fb318b32b6fbee46f3de6
5
5
  SHA512:
6
- metadata.gz: c4d842b799cdf5e7717272796986cc990c91b5222ad992933870ea01fc666ed74591c631c60a568530c6030186787efb76273b9905569616cf71e75bdbe0b4a1
7
- data.tar.gz: 644cc1935b7dfb29bacd67007f67edb4c9db1826e6badf4667c1098c24505e2283b8ca908e087aae93ecc0903f320b3b6f65114a2f46ef8fb977dd1903ee669a
6
+ metadata.gz: 14c50307fab5e8a189c8ac785453d8eedcba47f07018c6aad24522f0132adfc3c096e322ef2d249b1fbf11f3326cec1901a6f167b8e26d0ad63294f8436c018c
7
+ data.tar.gz: 235e76fcfafc51970b4097409058e0ce1fe9db87f730d6a995569b12fb644b3c126d94170c2b6aea2960f4b60924b9ff1fe3d9ce3e2cce4915f20b3bd6e58fd4
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,19 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'josebuilder'
3
+ s.version = '0.0.6'
4
+ s.authors = ['Nguyen Ngo Dinh']
5
+ s.email = ['nguyenngodinh@outlook.com']
6
+ s.summary = 'Create JSON Signature and encryption structures'
7
+ s.description = "json signature and encryption builder"
8
+ s.homepage = 'https://github.com/nguyenngodinh/josebuilder'
9
+ s.license = 'MIT'
10
+
11
+ s.required_ruby_version = '>= 1.9.3'
12
+
13
+ s.add_dependency 'activesupport', '>= 3.0.0', '< 5'
14
+ s.add_dependency 'multi_json', '~> 1.2'
15
+ s.add_runtime_dependency 'jwt', '~> 1.4', '>= 1.4.1'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ end
19
+
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ rails generate josebuilder Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,63 @@
1
+ require 'rails/generators/resource_helpers'
2
+ require 'rails/generators/named_base'
3
+
4
+ class JosebuilderGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ argument :resource_name, :type => :string, :default => "defaultResourceName"
8
+ argument :secret, :type => :string, :default => "secret"
9
+ argument :algorithm, :type => :string, :default => "HS256"
10
+
11
+ class_option :signature, :type => :boolean, :default => true,
12
+ :description => "include signature"
13
+ class_option :encryption, :type => :boolean, :default => false,
14
+ :description => "include encryption"
15
+ class_option :combination, :type => :boolean, :default => false,
16
+ :description => "combine digital signature and encryption"
17
+
18
+ def generate_json_web_signature_file
19
+ ["index", "show"].each do |view|
20
+ file = filename_with_directory(view)
21
+ template filename_with_extensions(view), file
22
+ end if options.signature?
23
+ end
24
+
25
+
26
+ private
27
+
28
+ def get_secret
29
+ secret
30
+ end
31
+ def file_name
32
+ resource_name.underscore
33
+ end
34
+
35
+ def filename_with_extensions(name)
36
+ [name, :json, :jbuilder] * '.'
37
+ end
38
+
39
+ def pluralize(count, singular, plural = nil)
40
+ word = if (count == 1 || count =~ /^1(\.0+)?$/)
41
+ singular
42
+ else
43
+ plural || singular.pluralize
44
+ end
45
+
46
+ "#{count || 0} #{word}"
47
+ end
48
+
49
+ def filename_with_directory(file_name)
50
+ file_name = filename_with_extensions(file_name)
51
+ File.join('app/views', controller_file_path, file_name)
52
+ end
53
+
54
+ def controller_file_path
55
+ pluralize_without_count(2, resource_name)
56
+ end
57
+ def pluralize_without_count(count, noun, text=nil)
58
+ if count!=0
59
+ count == 1? "#{noun}#{text}": "#{noun.pluralize}#{text}"
60
+ end
61
+ end
62
+
63
+ end
@@ -0,0 +1,7 @@
1
+ json.header = {alg: "<%= algorithm %>", typ: "JWS"}
2
+ json.payload do
3
+ json.array!(@<%= controller_file_path %>) do |<%= file_name %>|
4
+ json.<%= file_name %> = <%= file_name %>.as_json
5
+ end
6
+ end
7
+ json.signature = JWS.encode(@<%= controller_file_path %>.to_a.as_json, "<%= secret %>", "<%= algorithm %>")
@@ -0,0 +1,3 @@
1
+ json.header = {alg: "<%= algorithm %>", typ: "JWT"}
2
+ json.payload = @<%= file_name %>.as_json
3
+ json.signature = JWT.encode(@<%= file_name %>.as_json, "<%= secret %>", "<%= algorithm %>")
data/lib/jose/json.rb ADDED
@@ -0,0 +1,15 @@
1
+ module JWS
2
+ module Json
3
+ require 'json'
4
+
5
+ def decode_json(encoded_json)
6
+ JSON.parse(encoded_json)
7
+ rescue JSON::ParseError
8
+ raise JOSE::DecodeError.new("Invalid encoding")
9
+ end
10
+
11
+ def encode_json(raw)
12
+ JSON.generate(raw)
13
+ end
14
+ end
15
+ end
File without changes
data/lib/jws.rb ADDED
@@ -0,0 +1,127 @@
1
+ require 'base64'
2
+ require 'openssl'
3
+ require 'jose/json'
4
+
5
+ module JWS
6
+ class DecodeError < StandardError; end
7
+ class VerificationError < DecodeError; end
8
+ extend JWS::Json
9
+
10
+ module_function
11
+
12
+ def sign(algorithm, msg, key)
13
+ if ['HS256', 'HS384', 'HS512'].include?(algorithm)
14
+ sign_hmac(algorithm, msg, key)
15
+ else
16
+ raise NotImplementedError.new("Unsupported signing mehtod")
17
+ end
18
+ end
19
+
20
+ def sign_hmac(algorithm, msg, key)
21
+ OpenSSL::HMAC.digest(OpenSSL::Digest.new(algorithm.sub('HS', 'Sha')), key, msg)
22
+ end
23
+
24
+ def base64url_decode(str)
25
+ str += '=' *(4 - str.length.modulo(4))
26
+ Base64.decode64(str.tr('-_', '+/'))
27
+ end
28
+
29
+ def base64url_encode(str)
30
+ Base64.encode64(str).tr('+/', '-_').gsub(/[\n=]/, '')
31
+ end
32
+
33
+ def encoded_header(algorithm='HS256', header_fields={})
34
+ header = {'typ' => 'JWS', 'alg' => algorithm}.merge(header_fields)
35
+ base64url_encode(encode_json(header))
36
+ end
37
+
38
+ def encoded_payload(payload)
39
+ base64url_encode(encode_json(payload))
40
+ end
41
+
42
+ def encoded_signature(signing_input, key, algorithm)
43
+ if algorithm == 'none'
44
+ ''
45
+ else
46
+ signature = sign(algorithm, signing_input, key)
47
+ base64url_encode(signature)
48
+ end
49
+ end
50
+
51
+ def encode(payload, key, algorithm='HS256', header_fields={})
52
+ algorithm ||= 'none'
53
+ segments = []
54
+ segments << encoded_header(algorithm, header_fields)
55
+ segments << encoded_payload(payload)
56
+ segments << encoded_signature(segments.join('.'), key, algorithm)
57
+ segments.join('.')
58
+ end
59
+
60
+ def raw_segments(jws, verify=true)
61
+ segments = jws.split('.')
62
+ required_number_of_segments = verify ? [3] :[2,3]
63
+ raise JWS::DecodeError.new('Not enough or too many segments') unless required_number_of_segments.include? segments.length
64
+ segments
65
+ end
66
+
67
+ def decode_header_and_payload(header_segment, payload_segment)
68
+ header = decode_json(base64url_decode(header_segment))
69
+ payload = decode_json(base64url_decode(payload_segment))
70
+ [header, payload]
71
+ end
72
+
73
+ def decoded_segments(jws, verify=true)
74
+ header_segment, payload_segment, crypto_segment = raw_segments(jws, verify)
75
+ header, payload = decode_header_and_payload(header_segment, payload_segment)
76
+ signature = base64url_decode(crypto_segment.to_s) if verify
77
+ signing_input = [header_segment, payload_segment].join('.')
78
+ [header, payload, signature, signing_input]
79
+ end
80
+
81
+ def decode(jws, key=nil, verify=true, options={}, &keyfinder)
82
+ raise JWS::DecodeError.new('Nil JSON Web Signature') unless jws
83
+ header, payload, signature, signing_input = decoded_segments(jws, verify)
84
+ raise JWS::DecodeError.new('Not enough or too many segments') unless header && payload
85
+
86
+ if verify
87
+ algo, key = signature_algorithm_and_key(header, key, &keyfinder)
88
+ if options[:algorithm] && algo != options[:algorithm]
89
+ raise JWS::IncorrectAlgorithm.new('Expected a different algorithm')
90
+ end
91
+ verify_signature(algo, key, signing_input, signature)
92
+ end
93
+
94
+ return payload, header
95
+ end
96
+
97
+ def signature_algorithm_and_key(header, key, &keyfinder)
98
+ if keyfinder
99
+ key = keyfinder.call(header)
100
+ end
101
+ [header['alg'], key]
102
+ end
103
+
104
+ def verify_signature(algo, key, signing_input, signature)
105
+ begin
106
+ if ['HS256', 'HS384', 'HS512'].include?(algo)
107
+ raise JWS::VerificationError.new('Signature verification failed') unless secure_compare(signature, sign_hmac(algo, signing_input, key))
108
+ else
109
+ raise JWS::VerificationError.new('Algorithm not supported')
110
+ end
111
+ rescue OpenSSL::Pkey::PkeyError
112
+ raise JWS::VerificationError.new('Signature verification failed')
113
+ ensure
114
+ OpenSSL.errors.clear
115
+ end
116
+ end
117
+
118
+ def secure_compare(a, b)
119
+ return false if a.nil? || b.nil? || a.empty? || b.empty? || a.bytesize != b.bytesize
120
+ l = a.unpack "C#{a.bytesize}"
121
+
122
+ res = 0
123
+ b.each_byte { |byte| res |= byte ^ l.shift }
124
+ res == 0
125
+ end
126
+
127
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: josebuilder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nguyen Ngo Dinh
@@ -70,7 +70,20 @@ email:
70
70
  executables: []
71
71
  extensions: []
72
72
  extra_rdoc_files: []
73
- files: []
73
+ files:
74
+ - josebuilder-0.0.0.gem
75
+ - josebuilder-0.0.1.gem
76
+ - josebuilder-0.0.2.gem
77
+ - josebuilder-0.0.3.gem
78
+ - josebuilder-0.0.4.gem
79
+ - josebuilder.gemspec
80
+ - lib/jose/generators/josebuilder/USAGE
81
+ - lib/jose/generators/josebuilder/josebuilder_generator.rb
82
+ - lib/jose/generators/josebuilder/templates/index.json.jbuilder
83
+ - lib/jose/generators/josebuilder/templates/show.json.jbuilder
84
+ - lib/jose/json.rb
85
+ - lib/josebuilder.rb
86
+ - lib/jws.rb
74
87
  homepage: https://github.com/nguyenngodinh/josebuilder
75
88
  licenses:
76
89
  - MIT