faraday_csrf 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9e3c3f8f9e0e8bce5cf6e116ec115c2741ee1e44
4
+ data.tar.gz: fd5624762051970efca4212b3e6022b3332af389
5
+ SHA512:
6
+ metadata.gz: 9aa73632ba3154af1acb07d4788de366b69df48af51894d494ce9cf35015daaa84244b85833e740b8e1980c34e702ff4d52a5819c6958ecb14386829ebd1f681
7
+ data.tar.gz: 04ab1e08705cf52287375721f8a9207a27d05fcfc467f9f890f7dea5658822c8c4088668965eb748263fc769f0a10bea7e40643c8007c460f09dcddc9db50b31
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /vcr_cassettes
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --order rand
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ Style/MethodDefParentheses:
2
+ Enabled: false
3
+
4
+ Style/Documentation:
5
+ Enabled: false
6
+
7
+ Style/SignalException:
8
+ Enabled: false
9
+
10
+ Style/MultilineOperationIndentation:
11
+ Enabled: false
12
+
13
+ Style/RaiseArgs:
14
+ EnforcedStyle: compact
15
+
16
+ Style/IfUnlessModifier:
17
+ Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.2.2
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ before_install: gem install bundler -v 1.10.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in faraday_csrf.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ [![Build Status](https://travis-ci.org/unmanbearpig/faraday_csrf.svg?branch=master)](https://travis-ci.org/unmanbearpig/faraday_csrf)
2
+ [![Code Climate](https://codeclimate.com/github/unmanbearpig/faraday_csrf/badges/gpa.svg)](https://codeclimate.com/github/unmanbearpig/faraday_csrf)
3
+
4
+ # Faraday CSRF middleware
5
+
6
+ Transparently handles Rails (and maybe not only Rails) CSRF protection, in case you need to send requests to an app that doesn't provide an API.
7
+ It tries to extract a CSRF token from each request and later inserts it into (POST, PUT, DELETE, etc.) requests that probably require it.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'faraday_csrf'
15
+ ```
16
+ You need to add it to your stack, you would also need a cookie_jar
17
+ (gem 'faraday-cookie_jar').
18
+
19
+
20
+ ## Usage
21
+
22
+ Create a Faraday connection like this:
23
+
24
+ ```ruby
25
+ conn = Faraday.new url: 'https://a-rails-app.example.com/' do |conn|
26
+ conn.use :csrf
27
+ conn.request :url_encoded
28
+ conn.use :cookie_jar
29
+ conn.adapter Faraday.default_adapter
30
+ end
31
+ ```
32
+
33
+ When you would make a get request, the CSRF thingy would try to
34
+ parse the page and extract the token from it.
35
+ When you make a POST request after that, it would add the token to it.
36
+
37
+ You have to use faraday-cookie_jar gem for handling cookies, and use :url_encoded middleware or something of that nature to allow this middleware to insert tokens.
38
+
39
+ You can get the token it extracted by accessing response_env[:csrf_token].
40
+
41
+ ## Contributing
42
+
43
+ Bug reports and pull requests are welcome on GitHub at https://github.com/unmanbearpig/faraday_csrf.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
8
+ rescue LoadError
9
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "faraday_csrf"
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
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'faraday_csrf/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "faraday_csrf"
8
+ spec.version = FaradayCsrf::VERSION
9
+ spec.authors = ["unmanbearpig"]
10
+ spec.email = ["unmanbearpig@gmail.com"]
11
+
12
+ spec.summary = %q{Faraday middleware that automatically adds CSRF tokens to requests}
13
+ spec.homepage = 'https://github.com/unmanbearpig/faraday_csrf'
14
+
15
+ spec.description = "Transparently handles Rails (and maybe not only Rails) CSRF protection, in case you need to send requests to an app that doesn't provide an API"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+ spec.add_dependency "faraday"
22
+ spec.add_dependency "nokogiri"
23
+
24
+
25
+ spec.add_development_dependency "bundler", "> 1.9"
26
+ spec.add_development_dependency "rake", "~> 10.4.2"
27
+ spec.add_development_dependency "rspec", "~> 3.3"
28
+ spec.add_development_dependency "rspec-expectations", "~> 3.3"
29
+ spec.add_development_dependency "webmock", "~> 1.21"
30
+ spec.add_development_dependency "vcr", "~> 2.9"
31
+ spec.add_development_dependency "faraday-cookie_jar", "~> 0.0.6"
32
+ end
@@ -0,0 +1,46 @@
1
+ require 'faraday_csrf/token_handler'
2
+ require 'faraday_csrf/token_extractors/first_successful_extractor'
3
+ require 'faraday_csrf/token_extractors/meta_tag_regex_extractor'
4
+ require 'faraday_csrf/token_extractors/meta_tag_nokogiri_extractor'
5
+
6
+ module Faraday
7
+ class CSRF
8
+ class CreatesTokenHandler
9
+ def initialize(app:, fetch_token_from_url: nil)
10
+ @app = app
11
+ @fetch_token_from_url = fetch_token_from_url
12
+ end
13
+
14
+ def self.create *args
15
+ new(*args).token_handler
16
+ end
17
+
18
+ def token_handler
19
+ TokenHandler.new extractor: extractor,
20
+ injector: injector,
21
+ fetcher: fetcher
22
+ end
23
+
24
+ def extractors_to_try
25
+ [MetaTagRegexExtractor,
26
+ MetaTagNokogiriExtractor]
27
+ end
28
+
29
+ def extractor
30
+ FirstSuccessfulExtractor.new(extractors_to_try)
31
+ end
32
+
33
+ def injector
34
+ InjectsTokenIntoBody.new
35
+ end
36
+
37
+ def fetcher
38
+ if @fetch_token_from_url
39
+ TokenFetcher.new app: @app, url: @fetch_token_from_url
40
+ else
41
+ Proc.new {}
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,37 @@
1
+ require 'faraday_csrf/token'
2
+
3
+ module Faraday
4
+ class CSRF
5
+ class InjectsTokenIntoBody
6
+ class MissingToken < Exception
7
+ end
8
+
9
+ DEFAULT_IGNORE_METHODS = [:get, :head]
10
+
11
+ attr_reader :ignore_methods
12
+
13
+ def initialize(ignore_methods: DEFAULT_IGNORE_METHODS)
14
+ @ignore_methods = ignore_methods
15
+ end
16
+
17
+ def inject(token, into:)
18
+ return unless should_inject?(into)
19
+
20
+ raise MissingToken unless token
21
+
22
+ inject!(token, env: into)
23
+ end
24
+
25
+ def inject!(token, env:)
26
+ env.body.merge! token.to_h
27
+ token.expire!
28
+ end
29
+
30
+ def should_inject? env
31
+ return false if ignore_methods.include?(env.method)
32
+ return false unless env.body.respond_to? :merge!
33
+ true
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,55 @@
1
+ require 'faraday'
2
+
3
+ module Faraday
4
+ class CSRF
5
+ class Token
6
+ class NotFound < RuntimeError; end
7
+
8
+ attr_reader :name, :value
9
+ protected :name, :value
10
+
11
+ def initialize(name: nil, value:)
12
+ unless value
13
+ raise ArgumentError.new 'Token must have a value'
14
+ end
15
+
16
+ @name = name || self.class.default_name
17
+ @value = value
18
+ @expired = false
19
+ end
20
+
21
+ def self.default_name
22
+ 'authenticity_token'
23
+ end
24
+
25
+ def expire!
26
+ @name = nil
27
+ @value = nil
28
+ @expired = true
29
+ self
30
+ end
31
+
32
+ def expired?
33
+ @expired
34
+ end
35
+
36
+ def ==(other)
37
+ name == other.name &&
38
+ value == other.value &&
39
+ expired? == other.expired?
40
+ end
41
+
42
+ alias_method :to_s, :value
43
+
44
+ def inspect
45
+ return "CSRF::Token(~expired~)" if expired?
46
+ "CSRF::Token('#{name}' => '#{value}')"
47
+ end
48
+
49
+ def to_h
50
+ return {} if expired?
51
+ { name => value }
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,36 @@
1
+ require 'faraday_csrf/token'
2
+
3
+ module Faraday
4
+ class CSRF
5
+ class FirstSuccessfulExtractor
6
+ attr_reader :extractors
7
+
8
+ def initialize(extractors_to_try)
9
+ @extractors = extractors_to_try
10
+ unless extractors.any?
11
+ raise ArgumentError.new "Pass at least one extractor into FirstSuccessfulExtractor"
12
+ end
13
+ end
14
+
15
+ def extract_from input_data
16
+ results = extractors.lazy
17
+ .map { |x| call_it x, input_data }
18
+ .reject(&:nil?)
19
+
20
+ if results.any?
21
+ results.first
22
+ else
23
+ raise Token::NotFound.new "None of the extractors #{extractors} could find a token"
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def call_it extractor, input_data
30
+ extractor.extract_from(input_data)
31
+ rescue Token::NotFound
32
+ # just skip it
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+ require 'faraday_csrf/token_extractors/nokogiri_extractor'
2
+
3
+ module Faraday
4
+ class CSRF
5
+ class MetaTagNokogiriExtractor < NokogiriExtractor
6
+ protected
7
+
8
+ def name
9
+ find('meta[name=csrf-param]').attr('content').text
10
+ rescue Token::NotFound
11
+ nil
12
+ end
13
+
14
+ def value
15
+ find('meta[name=csrf-token]').attr('content').text
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,58 @@
1
+ require 'faraday_csrf/token'
2
+
3
+ module Faraday
4
+ class CSRF
5
+ # Much faster than using Nokogiri
6
+ # use it in combination with Nokogiri extractor,
7
+ # since it might be not as robust
8
+ class MetaTagRegexExtractor
9
+ attr_reader :html
10
+
11
+ class ExtractionError < RuntimeError; end
12
+
13
+ def initialize(html)
14
+ @html = html
15
+ end
16
+
17
+ def value
18
+ content_from_meta_tag('csrf-token')
19
+ end
20
+
21
+ def name
22
+ content_from_meta_tag('csrf-param')
23
+ rescue ExtractionError
24
+ nil
25
+ end
26
+
27
+ def token
28
+ Token.new value: value, name: name
29
+ rescue RuntimeError
30
+ raise Token::NotFound.new 'Could not find CSRF token'
31
+ end
32
+
33
+ private
34
+
35
+ def content_from_meta_tag tag_name
36
+ content_from_tag(find_meta_tag(tag_name))
37
+ end
38
+
39
+ def find_meta_tag(name)
40
+ html.match(/<meta [^>]*name="#{name}"[^>]+>/)[0]
41
+ rescue NoMethodError
42
+ raise ExtractionError.new "Could not find meta tag with name '#{name}'"
43
+ end
44
+
45
+ def content_from_tag token_string
46
+ token_string.match(/ content="([^"]+)"/)[1]
47
+ rescue NoMethodError
48
+ raise ExtractionError.new "Could not find content inside the html tag '#{token_string}'"
49
+ end
50
+
51
+ class << self
52
+ def extract_from html
53
+ new(html).token
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,44 @@
1
+ require 'nokogiri'
2
+
3
+ module Faraday
4
+ class CSRF
5
+ class NokogiriExtractor
6
+ attr_reader :document
7
+ protected :document
8
+
9
+ def initialize(document)
10
+ @document = document
11
+ end
12
+
13
+ def self.extract_from html
14
+ new(Nokogiri::HTML(html)).token
15
+ end
16
+
17
+ def token
18
+ Token.new name: name,
19
+ value: value
20
+ end
21
+
22
+ protected
23
+
24
+ def name
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def value
29
+ raise NotImplementedError
30
+ end
31
+
32
+ def find(css)
33
+ search_result = document.css(css)
34
+
35
+ unless search_result.any?
36
+ raise Token::NotFound.new(
37
+ "Could not find element with selector '#{css}'")
38
+ end
39
+
40
+ search_result
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ module Faraday
2
+ class CSRF
3
+ class TokenFetcher
4
+ def initialize(app:, url:)
5
+ @app = app
6
+ @url = url
7
+ end
8
+
9
+ def call request_env
10
+ new_env = request_env.dup
11
+ new_env.url = request_env.url.dup
12
+ new_env.url.path = @url
13
+
14
+ new_env.method = :get
15
+
16
+ @app.call(new_env)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ require "faraday_csrf/token_fetcher"
2
+ require "faraday_csrf/injects_token_into_body"
3
+
4
+ module Faraday
5
+ class CSRF
6
+ class TokenHandler
7
+ attr_accessor :token
8
+
9
+ def initialize(extractor:, injector:, fetcher:)
10
+ @extractor = extractor
11
+ @injector = injector
12
+ @fetcher = fetcher
13
+ end
14
+
15
+ def handle_request request_env
16
+ @injector.inject(@token, into: request_env)
17
+ rescue InjectsTokenIntoBody::MissingToken
18
+ @fetcher.call request_env
19
+ retry
20
+ end
21
+
22
+ def handle_response response_env
23
+ @token = @extractor.extract_from(response_env.body)
24
+ rescue Token::NotFound
25
+ nil
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module FaradayCsrf
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,27 @@
1
+ require "faraday_csrf/version"
2
+ require 'faraday_csrf/creates_token_handler'
3
+
4
+ module Faraday
5
+ class CSRF
6
+ attr_reader :app
7
+
8
+ def initialize(app, options = {})
9
+ @app = app
10
+ @handler = options.fetch(:token_handler) do
11
+ CreatesTokenHandler.create(options.merge(app: self))
12
+ end
13
+ end
14
+
15
+ def call request_env
16
+ @handler.handle_request request_env
17
+
18
+ app.call(request_env).on_complete do |response_env|
19
+ @handler.handle_response response_env
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ if Faraday::Middleware.respond_to? :register_middleware
26
+ Faraday::Middleware.register_middleware :csrf => Faraday::CSRF
27
+ end
metadata ADDED
@@ -0,0 +1,193 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: faraday_csrf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - unmanbearpig
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
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: nokogiri
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
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 10.4.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 10.4.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-expectations
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.21'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.21'
111
+ - !ruby/object:Gem::Dependency
112
+ name: vcr
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.9'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.9'
125
+ - !ruby/object:Gem::Dependency
126
+ name: faraday-cookie_jar
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.0.6
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.0.6
139
+ description: Transparently handles Rails (and maybe not only Rails) CSRF protection,
140
+ in case you need to send requests to an app that doesn't provide an API
141
+ email:
142
+ - unmanbearpig@gmail.com
143
+ executables: []
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - ".gitignore"
148
+ - ".rspec"
149
+ - ".rubocop.yml"
150
+ - ".ruby-version"
151
+ - ".travis.yml"
152
+ - Gemfile
153
+ - README.md
154
+ - Rakefile
155
+ - bin/console
156
+ - bin/setup
157
+ - faraday_csrf.gemspec
158
+ - lib/faraday_csrf.rb
159
+ - lib/faraday_csrf/creates_token_handler.rb
160
+ - lib/faraday_csrf/injects_token_into_body.rb
161
+ - lib/faraday_csrf/token.rb
162
+ - lib/faraday_csrf/token_extractors/first_successful_extractor.rb
163
+ - lib/faraday_csrf/token_extractors/meta_tag_nokogiri_extractor.rb
164
+ - lib/faraday_csrf/token_extractors/meta_tag_regex_extractor.rb
165
+ - lib/faraday_csrf/token_extractors/nokogiri_extractor.rb
166
+ - lib/faraday_csrf/token_fetcher.rb
167
+ - lib/faraday_csrf/token_handler.rb
168
+ - lib/faraday_csrf/version.rb
169
+ homepage: https://github.com/unmanbearpig/faraday_csrf
170
+ licenses: []
171
+ metadata: {}
172
+ post_install_message:
173
+ rdoc_options: []
174
+ require_paths:
175
+ - lib
176
+ required_ruby_version: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ required_rubygems_version: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ requirements: []
187
+ rubyforge_project:
188
+ rubygems_version: 2.4.8
189
+ signing_key:
190
+ specification_version: 4
191
+ summary: Faraday middleware that automatically adds CSRF tokens to requests
192
+ test_files: []
193
+ has_rdoc: