jira-ruby 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +51 -7
- data/http-basic-example.rb +106 -0
- data/lib/jira.rb +3 -0
- data/lib/jira/client.rb +41 -74
- data/lib/jira/http_client.rb +41 -0
- data/lib/jira/oauth_client.rb +84 -0
- data/lib/jira/request_client.rb +18 -0
- data/lib/jira/version.rb +1 -1
- data/spec/integration/attachment_spec.rb +14 -17
- data/spec/integration/comment_spec.rb +40 -41
- data/spec/integration/component_spec.rb +32 -33
- data/spec/integration/issue_spec.rb +60 -57
- data/spec/integration/issuetype_spec.rb +16 -17
- data/spec/integration/priority_spec.rb +17 -17
- data/spec/integration/project_spec.rb +36 -36
- data/spec/integration/status_spec.rb +17 -17
- data/spec/integration/user_spec.rb +15 -15
- data/spec/integration/version_spec.rb +32 -32
- data/spec/integration/worklog_spec.rb +41 -41
- data/spec/jira/client_spec.rb +125 -95
- data/spec/jira/http_client_spec.rb +79 -0
- data/spec/jira/oauth_client_spec.rb +111 -0
- data/spec/jira/request_client_spec.rb +14 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/clients_helper.rb +16 -0
- data/spec/support/shared_examples/integration.rb +11 -11
- metadata +30 -18
data/README.rdoc
CHANGED
@@ -5,7 +5,7 @@ API version 2).
|
|
5
5
|
|
6
6
|
== Example usage
|
7
7
|
|
8
|
-
client = JIRA::Client.new(CONSUMER_KEY, CONSUMER_SECRET)
|
8
|
+
client = JIRA::Client.new({:consumer_key => CONSUMER_KEY, :consumer_secret => CONSUMER_SECRET})
|
9
9
|
|
10
10
|
project = client.Project.find('SAMPLEPROJECT')
|
11
11
|
|
@@ -70,9 +70,47 @@ key.
|
|
70
70
|
After you have entered all the information click OK and ensure OAuth authentication is
|
71
71
|
enabled.
|
72
72
|
|
73
|
+
== Configuring JIRA to use HTTP Basic Auth
|
74
|
+
|
75
|
+
Follow the same steps described above to set up a new Application Link in JIRA,
|
76
|
+
however there is no need to set up any "incoming authentication" as this
|
77
|
+
defaults to HTTP Basic Auth.
|
78
|
+
|
79
|
+
== Using the API Gem in a command line application
|
80
|
+
|
81
|
+
Using HTTP Basic Authentication, configure and connect a client to your instance
|
82
|
+
of JIRA.
|
83
|
+
|
84
|
+
require 'rubygems'
|
85
|
+
require 'pp'
|
86
|
+
require 'jira'
|
87
|
+
|
88
|
+
# Consider the use of :use_ssl and :ssl_verify_mode options if running locally
|
89
|
+
# for tests.
|
90
|
+
|
91
|
+
username = "myremoteuser"
|
92
|
+
password = "myuserspassword"
|
93
|
+
|
94
|
+
options = {
|
95
|
+
:username => username,
|
96
|
+
:password => password,
|
97
|
+
:site => 'http://localhost:8080/',
|
98
|
+
:context_path => '/myjira',
|
99
|
+
:auth_type => :basic
|
100
|
+
}
|
101
|
+
|
102
|
+
client = JIRA::Client.new(options)
|
103
|
+
|
104
|
+
# Show all projects
|
105
|
+
projects = client.Project.all
|
106
|
+
|
107
|
+
projects.each do |project|
|
108
|
+
puts "Project -> key: #{project.key}, name: #{project.name}"
|
109
|
+
end
|
110
|
+
|
73
111
|
== Using the API Gem in your Rails application
|
74
112
|
|
75
|
-
|
113
|
+
Using oauth, the gem requires the consumer key and public certificate file (which
|
76
114
|
are generated in their respective rake tasks) to initialize an access token for
|
77
115
|
using the JIRA API.
|
78
116
|
|
@@ -95,17 +133,22 @@ errors are handled gracefully
|
|
95
133
|
class ApplicationController < ActionController::Base
|
96
134
|
protect_from_forgery
|
97
135
|
|
98
|
-
rescue_from JIRA::
|
136
|
+
rescue_from JIRA::OauthClient::UninitializedAccessTokenError do
|
99
137
|
redirect_to new_jira_session_url
|
100
138
|
end
|
101
139
|
|
102
140
|
private
|
103
141
|
|
104
142
|
def get_jira_client
|
143
|
+
|
144
|
+
# add any extra configuration options for your instance of JIRA,
|
145
|
+
# e.g. :use_ssl, :ssl_verify_mode, :context_path, :site
|
105
146
|
options = {
|
106
|
-
:private_key_file => "rsakey.pem"
|
147
|
+
:private_key_file => "rsakey.pem",
|
148
|
+
:consumer_key => 'test'
|
107
149
|
}
|
108
|
-
|
150
|
+
|
151
|
+
@jira_client = JIRA::Client.new(options)
|
109
152
|
|
110
153
|
# Add AccessToken if authorised previously.
|
111
154
|
if session[:jira_auth]
|
@@ -190,10 +233,11 @@ Here's the same example as a Sinatra application:
|
|
190
233
|
:authorize_path => "/plugins/servlet/oauth/authorize",
|
191
234
|
:access_token_path => "/plugins/servlet/oauth/access-token",
|
192
235
|
:private_key_file => "rsakey.pem",
|
193
|
-
:rest_base_path => "/rest/api/2"
|
236
|
+
:rest_base_path => "/rest/api/2",
|
237
|
+
:consumer_key => "jira-ruby-example"
|
194
238
|
}
|
195
239
|
|
196
|
-
@jira_client = JIRA::Client.new(
|
240
|
+
@jira_client = JIRA::Client.new(options)
|
197
241
|
@jira_client.consumer.http.set_debug_output($stderr)
|
198
242
|
|
199
243
|
# Add AccessToken if authorised previously.
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'pp'
|
3
|
+
require 'jira'
|
4
|
+
|
5
|
+
if ARGV.length == 0
|
6
|
+
# If not passed any command line arguments, prompt the
|
7
|
+
# user for the username and password.
|
8
|
+
puts "Enter the username: "
|
9
|
+
username = gets.strip
|
10
|
+
|
11
|
+
puts "Enter the password: "
|
12
|
+
password = gets.strip
|
13
|
+
elsif ARGV.length == 2
|
14
|
+
username, password = ARGV[0], ARGV[1]
|
15
|
+
else
|
16
|
+
# Script must be passed 0 or 2 arguments
|
17
|
+
raise "Usage: #{$0} [ username password ]"
|
18
|
+
end
|
19
|
+
|
20
|
+
options = {
|
21
|
+
:username => username,
|
22
|
+
:password => password,
|
23
|
+
:site => 'http://localhost:8080/',
|
24
|
+
:context_path => '',
|
25
|
+
:auth_type => :basic,
|
26
|
+
:use_ssl => false
|
27
|
+
}
|
28
|
+
|
29
|
+
client = JIRA::Client.new(options)
|
30
|
+
|
31
|
+
# Show all projects
|
32
|
+
projects = client.Project.all
|
33
|
+
|
34
|
+
projects.each do |project|
|
35
|
+
puts "Project -> key: #{project.key}, name: #{project.name}"
|
36
|
+
end
|
37
|
+
|
38
|
+
# # Find a specific project by key
|
39
|
+
# # ------------------------------
|
40
|
+
# project = client.Project.find('SAMPLEPROJECT')
|
41
|
+
# pp project
|
42
|
+
# project.issues.each do |issue|
|
43
|
+
# puts "#{issue.id} - #{issue.fields['summary']}"
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# # List all Issues
|
47
|
+
# # ---------------
|
48
|
+
# client.Issue.all.each do |issue|
|
49
|
+
# puts "#{issue.id} - #{issue.fields['summary']}"
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# # Delete an issue
|
53
|
+
# # ---------------
|
54
|
+
# issue = client.Issue.find('SAMPLEPROJECT-2')
|
55
|
+
# if issue.delete
|
56
|
+
# puts "Delete of issue SAMPLEPROJECT-2 sucessful"
|
57
|
+
# else
|
58
|
+
# puts "Delete of issue SAMPLEPROJECT-2 failed"
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# # Create an issue
|
62
|
+
# # ---------------
|
63
|
+
# issue = client.Issue.build
|
64
|
+
# issue.save({"fields"=>{"summary"=>"blarg from in example.rb","project"=>{"id"=>"10001"},"issuetype"=>{"id"=>"3"}}})
|
65
|
+
# issue.fetch
|
66
|
+
# pp issue
|
67
|
+
#
|
68
|
+
# # Update an issue
|
69
|
+
# # ---------------
|
70
|
+
# issue = client.Issue.find("10002")
|
71
|
+
# issue.save({"fields"=>{"summary"=>"EVEN MOOOOOOARRR NINJAAAA!"}})
|
72
|
+
# pp issue
|
73
|
+
#
|
74
|
+
# # Find a user
|
75
|
+
# # -----------
|
76
|
+
# user = client.User.find('admin')
|
77
|
+
# pp user
|
78
|
+
#
|
79
|
+
# # Get all issue types
|
80
|
+
# # -------------------
|
81
|
+
# issuetypes = client.Issuetype.all
|
82
|
+
# pp issuetypes
|
83
|
+
#
|
84
|
+
# # Get a single issue type
|
85
|
+
# # -----------------------
|
86
|
+
# issuetype = client.Issuetype.find('5')
|
87
|
+
# pp issuetype
|
88
|
+
#
|
89
|
+
# # Get all comments for an issue
|
90
|
+
# # -----------------------------
|
91
|
+
# issue.comments.each do |comment|
|
92
|
+
# pp comment
|
93
|
+
# end
|
94
|
+
#
|
95
|
+
# # Build and Save a comment
|
96
|
+
# # ------------------------
|
97
|
+
# comment = issue.comments.build
|
98
|
+
# comment.save!(:body => "New comment from example script")
|
99
|
+
#
|
100
|
+
# # Delete a comment from the collection
|
101
|
+
# # ------------------------------------
|
102
|
+
# issue.comments.last.delete
|
103
|
+
#
|
104
|
+
# # Update an existing comment
|
105
|
+
# # --------------------------
|
106
|
+
# issue.comments.first.save({"body" => "an updated comment frome example.rb"})
|
data/lib/jira.rb
CHANGED
@@ -22,6 +22,9 @@ require 'jira/resource/comment'
|
|
22
22
|
require 'jira/resource/worklog'
|
23
23
|
require 'jira/resource/issue'
|
24
24
|
|
25
|
+
require 'jira/request_client'
|
26
|
+
require 'jira/oauth_client'
|
27
|
+
require 'jira/http_client'
|
25
28
|
require 'jira/client'
|
26
29
|
|
27
30
|
require 'jira/railtie' if defined?(Rails)
|
data/lib/jira/client.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'oauth'
|
2
1
|
require 'json'
|
3
2
|
require 'forwardable'
|
4
3
|
|
@@ -6,9 +5,8 @@ module JIRA
|
|
6
5
|
|
7
6
|
# This class is the main access point for all JIRA::Resource instances.
|
8
7
|
#
|
9
|
-
# The client must be initialized with
|
10
|
-
#
|
11
|
-
# are:
|
8
|
+
# The client must be initialized with an options hash containing
|
9
|
+
# configuration options. The available options are:
|
12
10
|
#
|
13
11
|
# :site => 'http://localhost:2990',
|
14
12
|
# :context_path => '/jira',
|
@@ -17,55 +15,56 @@ module JIRA
|
|
17
15
|
# :authorize_path => "/plugins/servlet/oauth/authorize",
|
18
16
|
# :access_token_path => "/plugins/servlet/oauth/access-token",
|
19
17
|
# :private_key_file => "rsakey.pem",
|
20
|
-
# :rest_base_path => "/rest/api/2"
|
21
|
-
#
|
18
|
+
# :rest_base_path => "/rest/api/2",
|
19
|
+
# :consumer_key => nil,
|
20
|
+
# :consumer_secret => nil,
|
21
|
+
# :ssl_verify_mode => OpenSSL::SSL::VERIFY_PEER,
|
22
|
+
# :use_ssl => true,
|
23
|
+
# :username => nil,
|
24
|
+
# :password => nil,
|
25
|
+
# :auth_type => :oauth
|
22
26
|
#
|
23
27
|
# See the JIRA::Base class methods for all of the available methods on these accessor
|
24
28
|
# objects.
|
25
|
-
|
29
|
+
|
26
30
|
class Client
|
27
31
|
|
28
32
|
extend Forwardable
|
29
33
|
|
30
|
-
#
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# The OAuth::Consumer instance used by this client
|
39
|
-
attr_accessor :consumer
|
34
|
+
# The OAuth::Consumer instance returned by the OauthClient
|
35
|
+
#
|
36
|
+
# The authenticated client instance returned by the respective client type
|
37
|
+
# (Oauth, Basic)
|
38
|
+
attr_accessor :consumer, :request_client
|
40
39
|
|
41
40
|
# The configuration options for this client instance
|
42
41
|
attr_reader :options
|
43
42
|
|
44
|
-
|
43
|
+
def_delegators :@request_client, :init_access_token, :set_access_token, :set_request_token, :request_token, :access_token
|
45
44
|
|
46
45
|
DEFAULT_OPTIONS = {
|
47
46
|
:site => 'http://localhost:2990',
|
48
47
|
:context_path => '/jira',
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:private_key_file => "rsakey.pem",
|
54
|
-
:rest_base_path => "/rest/api/2"
|
48
|
+
:rest_base_path => "/rest/api/2",
|
49
|
+
:ssl_verify_mode => OpenSSL::SSL::VERIFY_PEER,
|
50
|
+
:use_ssl => true,
|
51
|
+
:auth_type => :oauth
|
55
52
|
}
|
56
53
|
|
57
|
-
def initialize(
|
54
|
+
def initialize(options={})
|
58
55
|
options = DEFAULT_OPTIONS.merge(options)
|
59
|
-
|
60
|
-
# prepend the context path to all authorization and rest paths
|
61
|
-
options[:request_token_path] = options[:context_path] + options[:request_token_path]
|
62
|
-
options[:authorize_path] = options[:context_path] + options[:authorize_path]
|
63
|
-
options[:access_token_path] = options[:context_path] + options[:access_token_path]
|
64
|
-
options[:rest_base_path] = options[:context_path] + options[:rest_base_path]
|
65
|
-
|
66
56
|
@options = options
|
57
|
+
@options[:rest_base_path] = @options[:context_path] + @options[:rest_base_path]
|
58
|
+
|
59
|
+
case options[:auth_type]
|
60
|
+
when :oauth
|
61
|
+
@request_client = OauthClient.new(@options)
|
62
|
+
@consumer = @request_client.consumer
|
63
|
+
when :basic
|
64
|
+
@request_client = HttpClient.new(@options)
|
65
|
+
end
|
66
|
+
|
67
67
|
@options.freeze
|
68
|
-
@consumer = OAuth::Consumer.new(consumer_key,consumer_secret,options)
|
69
68
|
end
|
70
69
|
|
71
70
|
def Project # :nodoc:
|
@@ -112,44 +111,17 @@ module JIRA
|
|
112
111
|
JIRA::Resource::VersionFactory.new(self)
|
113
112
|
end
|
114
113
|
|
115
|
-
# Returns the current request token if it is set, else it creates
|
116
|
-
# and sets a new token.
|
117
|
-
def request_token
|
118
|
-
@request_token ||= get_request_token
|
119
|
-
end
|
120
|
-
|
121
|
-
# Sets the request token from a given token and secret.
|
122
|
-
def set_request_token(token, secret)
|
123
|
-
@request_token = OAuth::RequestToken.new(@consumer, token, secret)
|
124
|
-
end
|
125
|
-
|
126
|
-
# Initialises and returns a new access token from the params hash
|
127
|
-
# returned by the OAuth transaction.
|
128
|
-
def init_access_token(params)
|
129
|
-
@access_token = request_token.get_access_token(params)
|
130
|
-
end
|
131
|
-
|
132
|
-
# Sets the access token from a preexisting token and secret.
|
133
|
-
def set_access_token(token, secret)
|
134
|
-
@access_token = OAuth::AccessToken.new(@consumer, token, secret)
|
135
|
-
end
|
136
|
-
|
137
|
-
# Returns the current access token. Raises an
|
138
|
-
# JIRA::Client::UninitializedAccessTokenError exception if it is not set.
|
139
|
-
def access_token
|
140
|
-
raise UninitializedAccessTokenError.new unless @access_token
|
141
|
-
@access_token
|
142
|
-
end
|
143
|
-
|
144
114
|
# HTTP methods without a body
|
145
115
|
def delete(path, headers = {})
|
146
|
-
request(:delete, path,
|
116
|
+
request(:delete, path, nil, merge_default_headers(headers))
|
147
117
|
end
|
118
|
+
|
148
119
|
def get(path, headers = {})
|
149
|
-
request(:get, path, merge_default_headers(headers))
|
120
|
+
request(:get, path, nil, merge_default_headers(headers))
|
150
121
|
end
|
122
|
+
|
151
123
|
def head(path, headers = {})
|
152
|
-
request(:head, path, merge_default_headers(headers))
|
124
|
+
request(:head, path, nil, merge_default_headers(headers))
|
153
125
|
end
|
154
126
|
|
155
127
|
# HTTP methods with a body
|
@@ -157,21 +129,16 @@ module JIRA
|
|
157
129
|
headers = {'Content-Type' => 'application/json'}.merge(headers)
|
158
130
|
request(:post, path, body, merge_default_headers(headers))
|
159
131
|
end
|
132
|
+
|
160
133
|
def put(path, body = '', headers = {})
|
161
134
|
headers = {'Content-Type' => 'application/json'}.merge(headers)
|
162
135
|
request(:put, path, body, merge_default_headers(headers))
|
163
136
|
end
|
164
137
|
|
165
138
|
# Sends the specified HTTP request to the REST API through the
|
166
|
-
#
|
167
|
-
|
168
|
-
|
169
|
-
# raises a JIRA::HTTPError if it was not successful, with the response
|
170
|
-
# attached.
|
171
|
-
def request(http_method, path, *arguments)
|
172
|
-
response = access_token.request(http_method, path, *arguments)
|
173
|
-
raise HTTPError.new(response) unless response.kind_of?(Net::HTTPSuccess)
|
174
|
-
response
|
139
|
+
# appropriate method (oauth, basic).
|
140
|
+
def request(http_method, path, body = '', headers)
|
141
|
+
@request_client.request(http_method, path, body, headers)
|
175
142
|
end
|
176
143
|
|
177
144
|
protected
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/https'
|
3
|
+
|
4
|
+
module JIRA
|
5
|
+
class HttpClient < RequestClient
|
6
|
+
|
7
|
+
DEFAULT_OPTIONS = {
|
8
|
+
:username => '',
|
9
|
+
:password => ''
|
10
|
+
}
|
11
|
+
|
12
|
+
attr_reader :options
|
13
|
+
|
14
|
+
def initialize(options)
|
15
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def make_request(http_method, path, body='', headers)
|
19
|
+
request = Net::HTTP.const_get(http_method.capitalize).new(path, headers)
|
20
|
+
request.body = body unless body.nil?
|
21
|
+
request.basic_auth(@options[:username], @options[:password])
|
22
|
+
response = basic_auth_http_conn.request(request)
|
23
|
+
response
|
24
|
+
end
|
25
|
+
|
26
|
+
def basic_auth_http_conn
|
27
|
+
http_conn(uri)
|
28
|
+
end
|
29
|
+
|
30
|
+
def http_conn(uri)
|
31
|
+
http_conn = Net::HTTP.new(uri.host, uri.port)
|
32
|
+
http_conn.use_ssl = @options[:use_ssl]
|
33
|
+
http_conn.verify_mode = @options[:ssl_verify_mode]
|
34
|
+
http_conn
|
35
|
+
end
|
36
|
+
|
37
|
+
def uri
|
38
|
+
uri = URI.parse(@options[:site])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
require 'json'
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module JIRA
|
6
|
+
class OauthClient < RequestClient
|
7
|
+
|
8
|
+
DEFAULT_OPTIONS = {
|
9
|
+
:signature_method => 'RSA-SHA1',
|
10
|
+
:request_token_path => "/plugins/servlet/oauth/request-token",
|
11
|
+
:authorize_path => "/plugins/servlet/oauth/authorize",
|
12
|
+
:access_token_path => "/plugins/servlet/oauth/access-token",
|
13
|
+
:private_key_file => "rsakey.pem",
|
14
|
+
:consumer_key => nil,
|
15
|
+
:consumer_secret => nil
|
16
|
+
}
|
17
|
+
|
18
|
+
# This exception is thrown when the client is used before the OAuth access token
|
19
|
+
# has been initialized.
|
20
|
+
class UninitializedAccessTokenError < StandardError
|
21
|
+
def message
|
22
|
+
"init_access_token must be called before using the client"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
extend Forwardable
|
27
|
+
|
28
|
+
attr_accessor :consumer
|
29
|
+
attr_reader :options
|
30
|
+
|
31
|
+
def_instance_delegators :@consumer, :key, :secret, :get_request_token
|
32
|
+
|
33
|
+
def initialize(options)
|
34
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
35
|
+
@consumer = init_oauth_consumer(@options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def init_oauth_consumer(options)
|
39
|
+
@options[:request_token_path] = @options[:context_path] + @options[:request_token_path]
|
40
|
+
@options[:authorize_path] = @options[:context_path] + @options[:authorize_path]
|
41
|
+
@options[:access_token_path] = @options[:context_path] + @options[:access_token_path]
|
42
|
+
OAuth::Consumer.new(@options[:consumer_key],@options[:consumer_secret],@options)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the current request token if it is set, else it creates
|
46
|
+
# and sets a new token.
|
47
|
+
def request_token
|
48
|
+
@request_token ||= get_request_token
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sets the request token from a given token and secret.
|
52
|
+
def set_request_token(token, secret)
|
53
|
+
@request_token = OAuth::RequestToken.new(@consumer, token, secret)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Initialises and returns a new access token from the params hash
|
57
|
+
# returned by the OAuth transaction.
|
58
|
+
def init_access_token(params)
|
59
|
+
@access_token = request_token.get_access_token(params)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Sets the access token from a preexisting token and secret.
|
63
|
+
def set_access_token(token, secret)
|
64
|
+
@access_token = OAuth::AccessToken.new(@consumer, token, secret)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the current access token. Raises an
|
68
|
+
# JIRA::Client::UninitializedAccessTokenError exception if it is not set.
|
69
|
+
def access_token
|
70
|
+
raise UninitializedAccessTokenError.new unless @access_token
|
71
|
+
@access_token
|
72
|
+
end
|
73
|
+
|
74
|
+
def make_request(http_method, path, body='', headers)
|
75
|
+
case http_method
|
76
|
+
when :delete, :get, :head
|
77
|
+
response = access_token.send http_method, path, headers
|
78
|
+
when :post, :put
|
79
|
+
response = access_token.send http_method, path, body, headers
|
80
|
+
end
|
81
|
+
response
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|