http-token-auth 0.0.1 → 0.1.0

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: c0e4b07956136703ffbbaa110ee01175dd85eefb
4
- data.tar.gz: f2a78c070b0d34a32da75a729343e035845e2f22
3
+ metadata.gz: cd2be20131fcf205b737d8b3e39b564b6e56447b
4
+ data.tar.gz: af2a0ac666a211d7db09279521e9a778b48eca38
5
5
  SHA512:
6
- metadata.gz: c5aab0c83f14dab2776ccff79945d34320a425373e4102985b69e0b308cde93e7ef6abeb2dd88bff265a92e157f1ea5bdcf69bc049ccab5e92f0a08ddf363d10
7
- data.tar.gz: aecf139625ed96dc4fd3a13f1e0fb7caea1ec367e553b84bb0ca0a14c5ad9ea43b9195cce8d3c1b1de3e141ea71d03217fbabf1452c4b38c28ecaf55ea5237cf
6
+ metadata.gz: bc9b3e2db21a82004f0a219103791a50d4c91e1cc28d08703be1d590e7f324d6759ad83c44f49e13d5a4041db3d0d53a2e6381e1dc7ff5d4e0f413e2b9b8fb90
7
+ data.tar.gz: 7048ecff80de8c6f70ccfcb87eafccee714a39663afeea4fce1eaf4be17a1d65ebf77c82c618e4d1930fe5009259923c3841afd7f83d66d581d69e471d8cc08b
@@ -1,3 +1,6 @@
1
+ require 'http/token_auth/version'
1
2
  require 'http/token_auth/credentials'
3
+ require 'http/token_auth/challenge'
4
+ require 'http/token_auth/scheme_parser'
2
5
  require 'http/token_auth/authorization_header_parser'
3
- require 'http/token_auth/version'
6
+ require 'http/token_auth/www_authenticate_header_parser'
@@ -6,31 +6,15 @@ module HTTP
6
6
  end
7
7
 
8
8
  class AuthorizationHeaderParsingError < StandardError
9
- def initialize(submessage)
10
- super(%(Error parsing "Authorization" HTTP header with token scheme: #{submessage}))
11
- end
12
9
  end
13
10
 
14
11
  class AuthorizationHeaderParser
15
- def parse(header)
16
- scheme, attributes = split(header)
17
- raise AuthorizationHeaderParsingError,
18
- 'Header has no attributes' if attributes.nil?
19
- raise AuthorizationHeaderParsingError,
20
- %(Invalid scheme "#{scheme}") unless scheme == 'Token'
21
- build_credentials parse_attributes(attributes)
22
- end
23
-
24
- def split(header)
25
- header.split(' ', 2)
12
+ def initialize
13
+ @scheme_parser = SchemeParser.new
26
14
  end
27
15
 
28
- def parse_attributes(string)
29
- attributes = {}
30
- string.scan(/(\w+)="([^"]*)"/).each do |group|
31
- attributes[group[0].to_sym] = group[1]
32
- end
33
- attributes
16
+ def parse(header)
17
+ build_credentials @scheme_parser.parse(header)
34
18
  end
35
19
 
36
20
  def build_credentials(attributes)
@@ -39,22 +23,23 @@ module HTTP
39
23
  nonce: attributes[:nonce],
40
24
  auth: attributes[:auth],
41
25
  timestamp: parse_timestamp(attributes[:timestamp])
42
- rescue MissingCredentialsArgumentError => e
26
+ rescue CredentialsArgumentError => e
43
27
  raise AuthorizationHeaderParsingError, e.message
44
28
  end
45
29
 
46
- def parse_coverage(coverage)
47
- return nil if coverage.nil? || coverage.empty?
48
- case coverage
49
- when 'none' then nil
30
+ def parse_coverage(string)
31
+ case string
32
+ when nil
33
+ when ''
34
+ when 'none' then :none
50
35
  when 'base' then :base
51
36
  when 'base+body-sha-256' then :base_body_sha_256
52
- else raise AuthorizationHeaderParsingError, %(Invalid coverage "#{coverage}")
37
+ else raise AuthorizationHeaderParsingError, %(Unsupported coverage "#{string}")
53
38
  end
54
39
  end
55
40
 
56
- def parse_timestamp(timestamp)
57
- timestamp.nil? ? nil : timestamp.to_i
41
+ def parse_timestamp(string)
42
+ string.nil? ? nil : string.to_i
58
43
  end
59
44
  end
60
45
  end
@@ -0,0 +1,69 @@
1
+ module HTTP
2
+ module TokenAuth
3
+ class ChallengeArgumentError < StandardError
4
+ end
5
+
6
+ class Challenge
7
+ attr_reader :realm, :supported_coverages, :timestamp
8
+
9
+ def initialize(realm:, supported_coverages: nil, timestamp: nil)
10
+ @realm = realm
11
+ @supported_coverages = supported_coverages_or_default(supported_coverages)
12
+ @timestamp = timestamp
13
+ validate_itself
14
+ end
15
+
16
+ def to_header
17
+ attributes = []
18
+ attributes << %(realm="#{@realm}")
19
+ attributes << %(coverage="#{coverage_string}")
20
+ unless supported_coverages.include?(:none)
21
+ attributes << %(timestamp="#{@timestamp}")
22
+ end
23
+ "Token #{attributes.join(', ')}"
24
+ end
25
+
26
+ private
27
+
28
+ def supported_coverages_or_default(list)
29
+ return [:base] if list.nil? || list.empty?
30
+ list
31
+ end
32
+
33
+ def validate_itself
34
+ must_have_realm
35
+ supported_coverages_must_be_consistent
36
+ must_have_timestamp unless supported_coverages.include?(:none)
37
+ end
38
+
39
+ def must_have_realm
40
+ raise ChallengeArgumentError, '"realm" is missing' if @realm.nil? || @realm.empty?
41
+ end
42
+
43
+ def must_have_timestamp
44
+ raise ChallengeArgumentError, '"timestamp" is missing' if @timestamp.nil?
45
+ end
46
+
47
+ def supported_coverages_must_be_consistent
48
+ if supported_coverages.include?(:none) && supported_coverages.size > 1
49
+ raise ChallengeArgumentError,
50
+ 'coverage "none" cannot be combined with other coverages'
51
+ end
52
+ end
53
+
54
+ def coverage_string
55
+ @supported_coverages.map do |coverage|
56
+ coverage_name(coverage)
57
+ end.join(' ')
58
+ end
59
+
60
+ def coverage_name(coverage)
61
+ case coverage
62
+ when :none then 'none'
63
+ when :base then 'base'
64
+ when :base_body_sha_256 then 'base+body-sha-256'
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,9 +1,6 @@
1
1
  module HTTP
2
2
  module TokenAuth
3
- class MissingCredentialsArgumentError < StandardError
4
- def initialize(argument_name)
5
- super(%(Invalid token credentials: "#{argument_name}" is missing))
6
- end
3
+ class CredentialsArgumentError < StandardError
7
4
  end
8
5
 
9
6
  class Credentials
@@ -11,7 +8,7 @@ module HTTP
11
8
 
12
9
  def initialize(token:, coverage: nil, nonce: nil, auth: nil, timestamp: nil)
13
10
  @token = token
14
- @coverage = coverage
11
+ @coverage = coverage.nil? ? :none : coverage
15
12
  @nonce = nonce
16
13
  @auth = auth
17
14
  @timestamp = timestamp
@@ -21,7 +18,7 @@ module HTTP
21
18
  def to_header
22
19
  attributes = []
23
20
  attributes << %(token="#{@token}")
24
- unless coverage.nil?
21
+ unless coverage == :none
25
22
  attributes << %(coverage="#{coverage_name}")
26
23
  attributes << %(nonce="#{@nonce}")
27
24
  attributes << %(auth="#{@auth}")
@@ -34,26 +31,39 @@ module HTTP
34
31
 
35
32
  def validate_itself
36
33
  must_have_token
37
- return if @coverage.nil?
38
- must_have_nonce
39
- must_have_auth
40
- must_have_timestamp
34
+ must_have_valid_coverage
35
+ unless @coverage == :none
36
+ must_have_nonce
37
+ must_have_auth
38
+ must_have_timestamp
39
+ end
40
+ end
41
+
42
+ def must_have_valid_coverage
43
+ case @coverage
44
+ when :none
45
+ when :base
46
+ when :base_body_sha_256
47
+ return
48
+ else
49
+ raise CredentialsArgumentError, %(unsupported "#{@coverage}" coverage)
50
+ end
41
51
  end
42
52
 
43
53
  def must_have_token
44
- raise MissingCredentialsArgumentError, 'token' if @token.nil? || @token.empty?
54
+ raise CredentialsArgumentError, '"token" is missing' if @token.nil? || @token.empty?
45
55
  end
46
56
 
47
57
  def must_have_nonce
48
- raise MissingCredentialsArgumentError, 'nonce' if @nonce.nil? || @nonce.empty?
58
+ raise CredentialsArgumentError, '"nonce" is missing' if @nonce.nil? || @nonce.empty?
49
59
  end
50
60
 
51
61
  def must_have_auth
52
- raise MissingCredentialsArgumentError, 'auth' if @auth.nil? || @auth.empty?
62
+ raise CredentialsArgumentError, '"auth" is missing' if @auth.nil? || @auth.empty?
53
63
  end
54
64
 
55
65
  def must_have_timestamp
56
- raise MissingCredentialsArgumentError, 'timestamp' if @timestamp.nil?
66
+ raise CredentialsArgumentError, '"timestamp" is missing' if @timestamp.nil?
57
67
  end
58
68
 
59
69
  def coverage_name
@@ -0,0 +1,29 @@
1
+ module HTTP
2
+ module TokenAuth
3
+ class SchemeParsingError < StandardError
4
+ end
5
+
6
+ class SchemeParser
7
+ def parse(string)
8
+ scheme, attributes_string = split(string)
9
+ raise SchemeParsingError,
10
+ 'No attributes provided' if attributes_string.nil?
11
+ raise SchemeParsingError,
12
+ %(Unsupported scheme "#{scheme}") unless scheme == 'Token'
13
+ parse_attributes(attributes_string)
14
+ end
15
+
16
+ def split(string)
17
+ string.split(' ', 2)
18
+ end
19
+
20
+ def parse_attributes(string)
21
+ attributes = {}
22
+ string.scan(/(\w+)="([^"]*)"/).each do |group|
23
+ attributes[group[0].to_sym] = group[1]
24
+ end
25
+ attributes
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,5 @@
1
1
  module HTTP
2
2
  module TokenAuth
3
- VERSION = '0.0.1'.freeze
3
+ VERSION = '0.1.0'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,47 @@
1
+ module HTTP
2
+ module TokenAuth
3
+ def self.parse_www_authenticate_header(header)
4
+ parser = WWWAuthenticateHeaderParser.new
5
+ parser.parse(header)
6
+ end
7
+
8
+ class WWWAuthenticateHeaderParsingError < StandardError
9
+ end
10
+
11
+ class WWWAuthenticateHeaderParser
12
+ def initialize
13
+ @schema_parser = SchemeParser.new
14
+ end
15
+
16
+ def parse(header)
17
+ build_challenge @schema_parser.parse(header)
18
+ end
19
+
20
+ private
21
+
22
+ def build_challenge(attributes)
23
+ Challenge.new realm: attributes[:realm],
24
+ supported_coverages: parse_coverage(attributes[:coverage]),
25
+ timestamp: parse_timestamp(attributes[:timestamp])
26
+ rescue ChallengeArgumentError => e
27
+ raise WWWAuthenticateHeaderParsingError, e.message
28
+ end
29
+
30
+ def parse_coverage(string)
31
+ return [:base] if string.nil?
32
+ string.split.map do |token|
33
+ case token
34
+ when 'none' then :none
35
+ when 'base' then :base
36
+ when 'base+body-sha-256' then :base_body_sha_256
37
+ else raise WWWAuthenticateHeaderParsingError, %(Unsupported coverage "#{token}")
38
+ end
39
+ end
40
+ end
41
+
42
+ def parse_timestamp(string)
43
+ string.nil? ? nil : string.to_i
44
+ end
45
+ end
46
+ end
47
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http-token-auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felipe Dornelas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-27 00:00:00.000000000 Z
11
+ date: 2016-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -49,8 +49,11 @@ files:
49
49
  - http-token-auth.gemspec
50
50
  - lib/http/token_auth.rb
51
51
  - lib/http/token_auth/authorization_header_parser.rb
52
+ - lib/http/token_auth/challenge.rb
52
53
  - lib/http/token_auth/credentials.rb
54
+ - lib/http/token_auth/scheme_parser.rb
53
55
  - lib/http/token_auth/version.rb
56
+ - lib/http/token_auth/www_authenticate_header_parser.rb
54
57
  homepage: https://github.com/felipead/http-token-auth
55
58
  licenses:
56
59
  - MIT
@@ -71,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
74
  version: '0'
72
75
  requirements: []
73
76
  rubyforge_project:
74
- rubygems_version: 2.4.5
77
+ rubygems_version: 2.4.5.1
75
78
  signing_key:
76
79
  specification_version: 4
77
80
  summary: Ruby gem to handle the HTTP Token Access Authentication.