authenticated_client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2c5c250c311c848b186bfe9b78e1c93a5219c915
4
+ data.tar.gz: 170c59a4a401d24d98aa11cc3b266f9ff1286610
5
+ SHA512:
6
+ metadata.gz: 576c4971cf46dd0f89a11e995b267a279026ad5e9e3f258f20514528bd702d1ea821b16e3fc8aa039a7dc5baf1c9093383fb833d9b4d673c43ad4806a44d2d3e
7
+ data.tar.gz: d030084628102e78ffd1ef61ed6a6ce9821f5874e4626a2c64b4cb802c5c8d5de9c632b8426285a1c7e0141293ad527806883cadab77b93a450d4be9bb890dd2
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ *.gem
3
+ .byebug_history
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1 @@
1
+ authenticated_client
@@ -0,0 +1 @@
1
+ ruby-2.3.0
@@ -0,0 +1,10 @@
1
+ FROM ruby:2.3.0
2
+
3
+ WORKDIR /usr/local/src/
4
+
5
+ ADD . /usr/local/src/
6
+ RUN cd /usr/local/src/
7
+ RUN gem install bundler
8
+ RUN bundle install
9
+
10
+ CMD bundle exec rspec -cfd spec/*
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # A sample Gemfile
2
+ source "https://rubygems.org"
3
+ source 'http://gems.hetzner.co.za'
4
+
5
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Barney de Villiers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,81 @@
1
+ # SoarAuditingProvider
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/authenticated_client.png)](https://badge.fury.io/rb/authenticated_client)
4
+
5
+ This gem provides authentication token generation and validation capability for the SOAR architecture.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'authenticated_client'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install authenticated_client
22
+
23
+ ## Configuration
24
+
25
+ There are three modes of operation.
26
+ ### Local
27
+ In local mode the tokens are decoded, verified and meta extracted locally using configured key material.
28
+
29
+ ### Remote
30
+ In remote mode the tokens are passed to a validation service for dynamic validation. The key material are therefore managed on the validation service. In this mode you only have to provide the url of the validation service.
31
+
32
+ ### Static
33
+ In this mode the validator are configured with a list of preconfigured static tokens. Incoming tokens are simply checked against this list. No extraction of meta is performed on the tokens but retrieved from the configuration. This mode is to be used in only two scenarios:
34
+ * Between the various authentication token services that requires authentication between themselves. These services do not have such a service to rely on. Circular dependency.
35
+ * In test scenarios where you do not want to pull in the authentication services to perform testing of your services.
36
+
37
+
38
+ ## Testing
39
+
40
+ Run the rspec test tests using docker compose:
41
+
42
+ $ docker-compose build
43
+ $ docker-compose run --rm soar-authentication-token
44
+
45
+ Properly clean up containers afterwards:
46
+
47
+ $ docker-compose down
48
+
49
+ Locally run a subset:
50
+
51
+ $ bundle exec rspec -cfd spec/rack_middleware_spec.rb
52
+
53
+
54
+ ## Updating
55
+
56
+ In order to pull the latest from the referenced projects, simply the following command:
57
+
58
+ ```bash
59
+ git pull && git submodule foreach 'git fetch origin --tags; git checkout master; git pull'
60
+ docker-compose build
61
+ ```
62
+
63
+ ## Usage
64
+
65
+
66
+
67
+ ## Detailed example
68
+
69
+
70
+
71
+ ## Contributing
72
+
73
+ Bug reports and feature requests are welcome by email to barney dot de dot villiers at hetzner dot co dot za. This gem is sponsored by Hetzner (Pty) Ltd (http://hetzner.co.za)
74
+
75
+ ## Notes
76
+
77
+
78
+
79
+ ## License
80
+
81
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ task :default => :spec
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'authenticated_client/version'
5
+
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "authenticated_client"
9
+ spec.version = AuthenticatedClient::VERSION
10
+ spec.authors = ["Barney de Villiers"]
11
+ spec.email = ["barney.de.villiers@hetzner.co.za"]
12
+ spec.description = %q{Client livrary for accessing authenticated resources}
13
+ spec.summary = %q{Client livrary for accessing authenticated resources such as token based systems}
14
+ spec.homepage = "https://gitlab.host-h.net/hetznerZA/authenticated-client"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency 'pry', '~> 0'
23
+ spec.add_development_dependency 'bundler', '~> 1.3'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rspec', '~> 2.13'
26
+ spec.add_development_dependency "capybara", '~> 2.1', '>= 2.1.0'
27
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "authenticated_client"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+ require "pathname"
3
+ bin_file = Pathname.new(__FILE__).realpath
4
+ $:.unshift File.expand_path("../../lib", bin_file)
5
+
6
+ require 'authenticated_client'
7
+ require 'yaml'
8
+ require 'json'
9
+
10
+ class Main
11
+
12
+ def generate_keypair
13
+ #create and configure auditing instance
14
+ keypair_generator = AuthenticatedClient::KeypairGenerator.new
15
+ private_key, public_key = keypair_generator.generate
16
+ configuration = {
17
+ 'private_key' => private_key,
18
+ 'public_key' => public_key
19
+ }
20
+ puts "------------"
21
+ puts "YAML Format:"
22
+ puts "------------"
23
+ print configuration.to_yaml
24
+ puts ""
25
+ puts "------------"
26
+ puts "JSON Format:"
27
+ puts "------------"
28
+ print configuration.to_json
29
+ puts ""
30
+ puts ""
31
+ puts "------------"
32
+
33
+ end
34
+ end
35
+
36
+ main = Main.new
37
+ main.generate_keypair
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,9 @@
1
+ module AuthenticatedClient
2
+ end
3
+
4
+ require 'authenticated_client/keypair_generator'
5
+ require 'authenticated_client/auth_client'
6
+ require 'authenticated_client/token_generator'
7
+ require 'authenticated_client/token_validator'
8
+ require 'authenticated_client/rack_middleware'
9
+ require 'authenticated_client/version'
@@ -0,0 +1,52 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+
4
+ module AuthenticatedClient
5
+ class Client
6
+ attr_accessor :url
7
+ attr_accessor :token
8
+ attr_accessor :verb
9
+ attr_accessor :parameters
10
+ attr_accessor :body
11
+ attr_accessor :auditing
12
+
13
+ def initialize
14
+ @url = nil
15
+ @token = nil
16
+ @verb = :post
17
+ @parameters = {}
18
+ @body = {}
19
+ @auditing = nil
20
+ end
21
+
22
+ def request
23
+ validate_elements_before_performing_request
24
+ perform_http_request
25
+ end
26
+
27
+ private
28
+
29
+ def perform_http_request
30
+ uri = URI.parse(@url)
31
+ uri.query = URI.encode_www_form( @parameters )
32
+ http = Net::HTTP.new(uri.host, uri.port)
33
+ http.use_ssl = true if uri.is_a?(URI::HTTPS)
34
+ request = Net::HTTP::Post.new(uri.request_uri) if :post == @verb
35
+ request = Net::HTTP::Get.new(uri.request_uri) if :get == @verb
36
+ request.add_field("AUTHORIZATION", @token) if @token
37
+ request.body = body.to_json
38
+ http.request(request)
39
+ end
40
+
41
+ def validate_elements_before_performing_request
42
+ raise 'only verbs post and get are supported' unless [:post, :get].include?(@verb)
43
+ raise "invalid url #{@url}" unless @url =~ URI::regexp
44
+ raise "parameters must be a hash" unless @parameters.is_a?(Hash)
45
+ raise "body must be a hash" unless @body.is_a?(Hash)
46
+ end
47
+
48
+ def audit_failure
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ module AuthenticatedClient
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .byebug_history
11
+ *.gem
@@ -0,0 +1 @@
1
+ sanity
@@ -0,0 +1 @@
1
+ ruby-2.3.0
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'authenticated_client', :path => "../"
@@ -0,0 +1,55 @@
1
+ require 'authenticated_client'
2
+ require 'yaml'
3
+
4
+ class Main
5
+
6
+ def generate_keypair
7
+ #create and configure auditing instance
8
+ keypair_generator = AuthenticatedClient::KeypairGenerator.new
9
+ private_key, public_key = keypair_generator.generate
10
+ configuration = {
11
+ 'private_key' => private_key,
12
+ 'public_key' => public_key
13
+ }
14
+ print configuration.to_yaml
15
+ end
16
+
17
+ def round_trip_simple_code
18
+ $stderr.puts "Generating Keypair..."
19
+ $ecdsa_key = OpenSSL::PKey::EC.new 'secp521r1'
20
+ $ecdsa_key.generate_key
21
+ $ecdsa_public = OpenSSL::PKey::EC.new $ecdsa_key
22
+ $ecdsa_public.private_key = nil
23
+ $stderr.puts "Generation Complete"
24
+
25
+ $stderr.puts 'DIRECT'
26
+ json_stuff = { 'stuff' => 'bla' }
27
+ token = encode(json_stuff)
28
+ result = decode(token)
29
+ $stderr.puts result
30
+
31
+ extracted_private_key = $ecdsa_key.to_pem
32
+ extracted_public_key = $ecdsa_public.to_pem
33
+ $ecdsa_key = nil
34
+ $ecdsa_public = nil
35
+
36
+ $stderr.puts 'INDIRECT'
37
+ $ecdsa_key = OpenSSL::PKey::EC.new extracted_private_key
38
+ $ecdsa_public = OpenSSL::PKey::EC.new ''#extracted_public_key
39
+ token = encode(json_stuff)
40
+ result = decode(token)
41
+ $stderr.puts result
42
+ end
43
+
44
+ def encode(payload)
45
+ JWT.encode(payload, $ecdsa_key, 'ES512')
46
+ end
47
+
48
+ def decode(authentication_token)
49
+ JWT.decode(authentication_token, $ecdsa_public, true, { :algorithm => 'ES512' })
50
+ end
51
+ end
52
+
53
+ main = Main.new
54
+ main.generate_keypair
55
+ main.round_trip_simple_code
@@ -0,0 +1,83 @@
1
+ require 'soar_auditing_provider'
2
+ require 'log4r_auditor'
3
+ require 'soar_flow'
4
+ require 'benchmark'
5
+ require 'byebug'
6
+
7
+ class Main
8
+
9
+ AUDITING_CONFIGURATION = {
10
+ 'auditing' => {
11
+ 'level' => 'debug',
12
+ 'install_exit_handler' => 'false',
13
+ 'add_caller_source_location' => 'false',
14
+ 'queue_worker' => {
15
+ 'queue_size' => 1000000,
16
+ 'initial_back_off_in_seconds' => 1,
17
+ 'back_off_multiplier' => 2,
18
+ 'back_off_attempts' => 5
19
+ },
20
+ 'default_nfrs' => {
21
+ 'accessibility' => 'local',
22
+ 'privacy' => 'not encrypted',
23
+ 'reliability' => 'instance',
24
+ 'performance' => 'high'
25
+ },
26
+ 'auditors' => {
27
+ 'log4r' => {
28
+ 'adaptor' => 'Log4rAuditor::Log4rAuditor',
29
+ 'file_name' => 'soar_sc.log',
30
+ 'standard_stream' => 'none',
31
+ 'nfrs' => {
32
+ 'accessibility' => 'local',
33
+ 'privacy' => 'not encrypted',
34
+ 'reliability' => 'instance',
35
+ 'performance' => 'high'
36
+ }
37
+ }
38
+ }
39
+ }
40
+ }
41
+
42
+ def test_sanity
43
+ iterations = 1000000
44
+
45
+ #create and configure auditing instance
46
+ myauditing = SoarAuditingProvider::AuditingProvider.new( AUDITING_CONFIGURATION['auditing'] )
47
+ myauditing.startup_flow_id = SoarFlow::ID::generate_flow_id
48
+ myauditing.service_identifier = 'my-test-service.com'
49
+
50
+ #associate a set of auditing entries with a flow by generating a flow identifiers
51
+ flow_id = SoarFlow::ID::generate_flow_id
52
+
53
+ Benchmark.bm do |x|
54
+ myauditing = SoarAuditingProvider::AuditingProvider.new( AUDITING_CONFIGURATION['auditing'].dup.merge("level" => "warn") )
55
+ myauditing.startup_flow_id = SoarFlow::ID::generate_flow_id
56
+ myauditing.service_identifier = 'my-test-service.com'
57
+ x.report ("audit_call_below_audit_threshold:") {
58
+ iterations.times {
59
+ myauditing.info("Benchmarking test",flow_id)
60
+ }
61
+ }
62
+ myauditing = SoarAuditingProvider::AuditingProvider.new( AUDITING_CONFIGURATION['auditing'].dup.merge("add_caller_source_location" => "false") )
63
+ myauditing.startup_flow_id = SoarFlow::ID::generate_flow_id
64
+ myauditing.service_identifier = 'my-test-service.com'
65
+ x.report ("audit_call_without_caller_info :") {
66
+ iterations.times {
67
+ myauditing.info("Benchmarking test",flow_id)
68
+ }
69
+ }
70
+ myauditing = SoarAuditingProvider::AuditingProvider.new( AUDITING_CONFIGURATION['auditing'].dup.merge("add_caller_source_location" => "true") )
71
+ myauditing.startup_flow_id = SoarFlow::ID::generate_flow_id
72
+ myauditing.service_identifier = 'my-test-service.com'
73
+ x.report ("audit_call_with_caller_info :") {
74
+ iterations.times {
75
+ myauditing.info("Benchmarking test",flow_id)
76
+ }
77
+ }
78
+ end
79
+ end
80
+ end
81
+
82
+ main = Main.new
83
+ main.test_sanity
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe AuthenticatedClient::AuthenticatedClient do
4
+ before :each do
5
+ end
6
+
7
+ it 'has a version number' do
8
+ expect(AuthenticatedClient::VERSION).not_to be nil
9
+ end
10
+
11
+ context "when performing an authenticated request" do
12
+ context "with a valid token" do
13
+ it 'respond with a successful request' do
14
+ @iut = AuthenticatedClient::AuthenticatedClient.new
15
+ @iut.url = 'http://authentication-token-generator-service:9393/generate'
16
+ @iut.token = 'test_ecosystem_token_for_auth_token_aaapi_authenticator_service'
17
+ @iut.verb = :post
18
+ @iut.parameters = {}
19
+ @iut.body = {}
20
+ @iut.auditing = nil
21
+
22
+ response = @iut.request
23
+ expect(response.code).to eq '200'
24
+ end
25
+ end
26
+ context "with an invalid token" do
27
+ it 'respond unauthorized' do
28
+ @iut = AuthenticatedClient::AuthenticatedClient.new
29
+ @iut.url = 'http://authentication-token-generator-service:9393/generate'
30
+ @iut.token = 'invalid'
31
+ @iut.verb = :post
32
+ @iut.parameters = {}
33
+ @iut.body = {}
34
+ @iut.auditing = nil
35
+
36
+ response = @iut.request
37
+ expect(response.code).to eq '401'
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,5 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ $LOAD_PATH.unshift File.expand_path('../../spec/support', __FILE__)
3
+
4
+ require 'authenticated_client'
5
+ require 'pry'
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: authenticated_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Barney de Villiers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.13'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.13'
69
+ - !ruby/object:Gem::Dependency
70
+ name: capybara
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.1'
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 2.1.0
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '2.1'
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 2.1.0
89
+ description: Client livrary for accessing authenticated resources
90
+ email:
91
+ - barney.de.villiers@hetzner.co.za
92
+ executables:
93
+ - console
94
+ - keypair-generator
95
+ - setup
96
+ extensions: []
97
+ extra_rdoc_files: []
98
+ files:
99
+ - ".gitignore"
100
+ - ".rspec"
101
+ - ".ruby-gemset"
102
+ - ".ruby-version"
103
+ - Dockerfile
104
+ - Gemfile
105
+ - LICENSE.txt
106
+ - README.md
107
+ - Rakefile
108
+ - authenticated_client.gemspec
109
+ - bin/console
110
+ - bin/keypair-generator
111
+ - bin/setup
112
+ - lib/authenticated_client.rb
113
+ - lib/authenticated_client/auth_client.rb
114
+ - lib/authenticated_client/version.rb
115
+ - sanity/.gitignore
116
+ - sanity/.ruby-gemset
117
+ - sanity/.ruby-version
118
+ - sanity/Gemfile
119
+ - sanity/sanity.rb
120
+ - sanity/sanity_benchmark.rb
121
+ - spec/auth_client_spec.rb
122
+ - spec/spec_helper.rb
123
+ homepage: https://gitlab.host-h.net/hetznerZA/authenticated-client
124
+ licenses:
125
+ - MIT
126
+ metadata: {}
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 2.5.1
144
+ signing_key:
145
+ specification_version: 4
146
+ summary: Client livrary for accessing authenticated resources such as token based
147
+ systems
148
+ test_files:
149
+ - spec/auth_client_spec.rb
150
+ - spec/spec_helper.rb