oauth 0.5.6 → 1.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +504 -0
  3. data/CODE_OF_CONDUCT.md +84 -0
  4. data/CONTRIBUTING.md +40 -0
  5. data/LICENSE +19 -17
  6. data/README.md +390 -0
  7. data/SECURITY.md +26 -0
  8. data/lib/oauth/client/action_controller_request.rb +23 -21
  9. data/lib/oauth/client/em_http.rb +99 -99
  10. data/lib/oauth/client/helper.rb +83 -82
  11. data/lib/oauth/client/net_http.rb +112 -105
  12. data/lib/oauth/client.rb +2 -0
  13. data/lib/oauth/consumer.rb +147 -133
  14. data/lib/oauth/errors/error.rb +2 -0
  15. data/lib/oauth/errors/problem.rb +3 -0
  16. data/lib/oauth/errors/unauthorized.rb +7 -1
  17. data/lib/oauth/errors.rb +5 -3
  18. data/lib/oauth/helper.rb +26 -18
  19. data/lib/oauth/oauth.rb +6 -4
  20. data/lib/oauth/oauth_test_helper.rb +6 -4
  21. data/lib/oauth/request_proxy/action_controller_request.rb +49 -71
  22. data/lib/oauth/request_proxy/action_dispatch_request.rb +8 -4
  23. data/lib/oauth/request_proxy/base.rb +136 -132
  24. data/lib/oauth/request_proxy/curb_request.rb +49 -43
  25. data/lib/oauth/request_proxy/em_http_request.rb +59 -49
  26. data/lib/oauth/request_proxy/jabber_request.rb +12 -9
  27. data/lib/oauth/request_proxy/mock_request.rb +5 -3
  28. data/lib/oauth/request_proxy/net_http.rb +61 -54
  29. data/lib/oauth/request_proxy/rack_request.rb +35 -31
  30. data/lib/oauth/request_proxy/rest_client_request.rb +54 -50
  31. data/lib/oauth/request_proxy/typhoeus_request.rb +51 -45
  32. data/lib/oauth/request_proxy.rb +7 -4
  33. data/lib/oauth/server.rb +14 -12
  34. data/lib/oauth/signature/base.rb +78 -71
  35. data/lib/oauth/signature/hmac/sha1.rb +16 -10
  36. data/lib/oauth/signature/hmac/sha256.rb +16 -10
  37. data/lib/oauth/signature/plaintext.rb +18 -20
  38. data/lib/oauth/signature/rsa/sha1.rb +46 -38
  39. data/lib/oauth/signature.rb +8 -5
  40. data/lib/oauth/token.rb +7 -5
  41. data/lib/oauth/tokens/access_token.rb +5 -3
  42. data/lib/oauth/tokens/consumer_token.rb +4 -2
  43. data/lib/oauth/tokens/request_token.rb +12 -10
  44. data/lib/oauth/tokens/server_token.rb +2 -1
  45. data/lib/oauth/tokens/token.rb +2 -0
  46. data/lib/oauth/version.rb +5 -1
  47. data/lib/oauth.rb +17 -9
  48. metadata +105 -98
  49. data/README.rdoc +0 -88
  50. data/bin/oauth +0 -11
  51. data/lib/oauth/cli/authorize_command.rb +0 -71
  52. data/lib/oauth/cli/base_command.rb +0 -208
  53. data/lib/oauth/cli/help_command.rb +0 -22
  54. data/lib/oauth/cli/query_command.rb +0 -25
  55. data/lib/oauth/cli/sign_command.rb +0 -81
  56. data/lib/oauth/cli/version_command.rb +0 -7
  57. data/lib/oauth/cli.rb +0 -56
@@ -1,5 +1,7 @@
1
- require 'action_controller'
2
- require 'action_controller/test_process'
1
+ # frozen_string_literal: true
2
+
3
+ require "action_controller"
4
+ require "action_controller/test_process"
3
5
 
4
6
  module OAuth
5
7
  module OAuthTestHelper
@@ -8,7 +10,7 @@ module OAuth
8
10
  incoming.request_uri = request.path
9
11
  incoming.host = request.uri.host
10
12
  incoming.env["SERVER_PORT"] = request.uri.port
11
- incoming.env['REQUEST_METHOD'] = request.http_method
13
+ incoming.env["REQUEST_METHOD"] = request.http_method
12
14
  incoming
13
15
  end
14
16
 
@@ -18,7 +20,7 @@ module OAuth
18
20
  incoming.host = request.uri.host
19
21
  incoming.env["HTTP_AUTHORIZATION"] = request.to_auth_string
20
22
  incoming.env["SERVER_PORT"] = request.uri.port
21
- incoming.env['REQUEST_METHOD'] = request.http_method
23
+ incoming.env["REQUEST_METHOD"] = request.http_method
22
24
  incoming
23
25
  end
24
26
  end
@@ -1,90 +1,68 @@
1
- require 'active_support'
2
- require "active_support/version"
3
- require 'action_controller'
4
- require 'uri'
1
+ # frozen_string_literal: true
5
2
 
6
- if
7
- Gem::Version.new(ActiveSupport::VERSION::STRING) < Gem::Version.new("3")
8
- then # rails 2.x
9
- require 'action_controller/request'
10
- unless ActionController::Request::HTTP_METHODS.include?("patch")
11
- ActionController::Request::HTTP_METHODS << "patch"
12
- ActionController::Request::HTTP_METHOD_LOOKUP["PATCH"] = :patch
13
- ActionController::Request::HTTP_METHOD_LOOKUP["patch"] = :patch
14
- end
3
+ require "active_support"
4
+ require "action_controller"
5
+ require "uri"
15
6
 
16
- elsif
17
- Gem::Version.new(ActiveSupport::VERSION::STRING) < Gem::Version.new("4")
18
- then # rails 3.x
19
- require 'action_dispatch/http/request'
20
- unless ActionDispatch::Request::HTTP_METHODS.include?("patch")
21
- ActionDispatch::Request::HTTP_METHODS << "patch"
22
- ActionDispatch::Request::HTTP_METHOD_LOOKUP["PATCH"] = :patch
23
- ActionDispatch::Request::HTTP_METHOD_LOOKUP["patch"] = :patch
24
- end
7
+ require "action_dispatch/http/request"
25
8
 
26
- else # rails 4.x and later - already has patch
27
- require 'action_dispatch/http/request'
28
- end
9
+ module OAuth
10
+ module RequestProxy
11
+ class ActionControllerRequest < OAuth::RequestProxy::Base
12
+ proxies(::ActionDispatch::Request)
29
13
 
30
- module OAuth::RequestProxy
31
- class ActionControllerRequest < OAuth::RequestProxy::Base
32
- proxies(defined?(ActionDispatch::AbstractRequest) ? ActionDispatch::AbstractRequest : ActionDispatch::Request)
33
-
34
- def method
35
- request.method.to_s.upcase
36
- end
14
+ def method
15
+ request.method.to_s.upcase
16
+ end
37
17
 
38
- def uri
39
- request.url
40
- end
18
+ def uri
19
+ request.url
20
+ end
41
21
 
42
- def parameters
43
- if options[:clobber_request]
44
- options[:parameters] || {}
45
- else
46
- params = request_params.merge(query_params).merge(header_params)
47
- params.stringify_keys! if params.respond_to?(:stringify_keys!)
48
- params.merge(options[:parameters] || {})
22
+ def parameters
23
+ if options[:clobber_request]
24
+ options[:parameters] || {}
25
+ else
26
+ params = request_params.merge(query_params).merge(header_params)
27
+ params.stringify_keys! if params.respond_to?(:stringify_keys!)
28
+ params.merge(options[:parameters] || {})
29
+ end
49
30
  end
50
- end
51
31
 
52
- # Override from OAuth::RequestProxy::Base to avoid roundtrip
53
- # conversion to Hash or Array and thus preserve the original
54
- # parameter names
55
- def parameters_for_signature
56
- params = []
57
- params << options[:parameters].to_query if options[:parameters]
32
+ # Override from OAuth::RequestProxy::Base to avoid round-trip
33
+ # conversion to Hash or Array and thus preserve the original
34
+ # parameter names
35
+ def parameters_for_signature
36
+ params = []
37
+ params << options[:parameters].to_query if options[:parameters]
58
38
 
59
- unless options[:clobber_request]
60
- params << header_params.to_query
61
- params << request.query_string unless query_string_blank?
39
+ unless options[:clobber_request]
40
+ params << header_params.to_query
41
+ params << request.query_string unless query_string_blank?
62
42
 
63
- if raw_post_signature?
64
- params << request.raw_post
43
+ params << request.raw_post if raw_post_signature?
65
44
  end
66
- end
67
45
 
68
- params.
69
- join('&').split('&').
70
- reject { |s| s.match(/\A\s*\z/) }.
71
- map { |p| p.split('=').map{|esc| CGI.unescape(esc)} }.
72
- reject { |kv| kv[0] == 'oauth_signature'}
73
- end
46
+ params.
47
+ join("&").split("&").
48
+ reject { |s| s.match(/\A\s*\z/) }.
49
+ map { |p| p.split("=").map { |esc| CGI.unescape(esc) } }.
50
+ reject { |kv| kv[0] == "oauth_signature" }
51
+ end
74
52
 
75
- def raw_post_signature?
76
- (request.post? || request.put?) && request.content_type.to_s.downcase.start_with?("application/x-www-form-urlencoded")
77
- end
53
+ def raw_post_signature?
54
+ (request.post? || request.put?) && request.content_type.to_s.downcase.start_with?("application/x-www-form-urlencoded")
55
+ end
78
56
 
79
- protected
57
+ protected
80
58
 
81
- def query_params
82
- request.query_parameters
83
- end
59
+ def query_params
60
+ request.query_parameters
61
+ end
84
62
 
85
- def request_params
86
- request.request_parameters
63
+ def request_params
64
+ request.request_parameters
65
+ end
87
66
  end
88
-
89
67
  end
90
68
  end
@@ -1,7 +1,11 @@
1
- require 'oauth/request_proxy/rack_request'
1
+ # frozen_string_literal: true
2
2
 
3
- module OAuth::RequestProxy
4
- class ActionDispatchRequest < OAuth::RequestProxy::RackRequest
5
- proxies ActionDispatch::Request
3
+ require "oauth/request_proxy/rack_request"
4
+
5
+ module OAuth
6
+ module RequestProxy
7
+ class ActionDispatchRequest < OAuth::RequestProxy::RackRequest
8
+ proxies ::ActionDispatch::Request
9
+ end
6
10
  end
7
11
  end
@@ -1,178 +1,182 @@
1
- require 'oauth/request_proxy'
2
- require 'oauth/helper'
1
+ # frozen_string_literal: true
3
2
 
4
- module OAuth::RequestProxy
5
- class Base
6
- include OAuth::Helper
3
+ require "oauth/request_proxy"
4
+ require "oauth/helper"
7
5
 
8
- def self.proxies(klass)
9
- OAuth::RequestProxy.available_proxies[klass] = self
10
- end
6
+ module OAuth
7
+ module RequestProxy
8
+ class Base
9
+ include OAuth::Helper
11
10
 
12
- attr_accessor :request, :options, :unsigned_parameters
11
+ def self.proxies(klass)
12
+ OAuth::RequestProxy.available_proxies[klass] = self
13
+ end
13
14
 
14
- def initialize(request, options = {})
15
- @request = request
16
- @unsigned_parameters = (options[:unsigned_parameters] || []).map {|param| param.to_s}
17
- @options = options
18
- end
15
+ attr_accessor :request, :options, :unsigned_parameters
19
16
 
20
- ## OAuth parameters
17
+ def initialize(request, options = {})
18
+ @request = request
19
+ @unsigned_parameters = (options[:unsigned_parameters] || []).map(&:to_s)
20
+ @options = options
21
+ end
21
22
 
22
- def oauth_callback
23
- parameters['oauth_callback']
24
- end
23
+ ## OAuth parameters
25
24
 
26
- def oauth_consumer_key
27
- parameters['oauth_consumer_key']
28
- end
25
+ def oauth_callback
26
+ parameters["oauth_callback"]
27
+ end
29
28
 
30
- def oauth_nonce
31
- parameters['oauth_nonce']
32
- end
29
+ def oauth_consumer_key
30
+ parameters["oauth_consumer_key"]
31
+ end
33
32
 
34
- def oauth_signature
35
- # TODO can this be nil?
36
- [parameters['oauth_signature']].flatten.first || ""
37
- end
33
+ def oauth_nonce
34
+ parameters["oauth_nonce"]
35
+ end
38
36
 
39
- def oauth_signature_method
40
- case parameters['oauth_signature_method']
41
- when Array
42
- parameters['oauth_signature_method'].first
43
- else
44
- parameters['oauth_signature_method']
37
+ def oauth_signature
38
+ # TODO: can this be nil?
39
+ [parameters["oauth_signature"]].flatten.first || ""
45
40
  end
46
- end
47
41
 
48
- def oauth_timestamp
49
- parameters['oauth_timestamp']
50
- end
42
+ def oauth_signature_method
43
+ case parameters["oauth_signature_method"]
44
+ when Array
45
+ parameters["oauth_signature_method"].first
46
+ else
47
+ parameters["oauth_signature_method"]
48
+ end
49
+ end
51
50
 
52
- def oauth_token
53
- parameters['oauth_token']
54
- end
51
+ def oauth_timestamp
52
+ parameters["oauth_timestamp"]
53
+ end
55
54
 
56
- def oauth_verifier
57
- parameters['oauth_verifier']
58
- end
55
+ def oauth_token
56
+ parameters["oauth_token"]
57
+ end
59
58
 
60
- def oauth_version
61
- parameters["oauth_version"]
62
- end
59
+ def oauth_verifier
60
+ parameters["oauth_verifier"]
61
+ end
63
62
 
64
- # TODO deprecate these
65
- alias_method :consumer_key, :oauth_consumer_key
66
- alias_method :token, :oauth_token
67
- alias_method :nonce, :oauth_nonce
68
- alias_method :timestamp, :oauth_timestamp
69
- alias_method :signature, :oauth_signature
70
- alias_method :signature_method, :oauth_signature_method
63
+ def oauth_version
64
+ parameters["oauth_version"]
65
+ end
71
66
 
72
- ## Parameter accessors
67
+ # TODO: deprecate these
68
+ alias consumer_key oauth_consumer_key
69
+ alias token oauth_token
70
+ alias nonce oauth_nonce
71
+ alias timestamp oauth_timestamp
72
+ alias signature oauth_signature
73
+ alias signature_method oauth_signature_method
73
74
 
74
- def parameters
75
- raise NotImplementedError, "Must be implemented by subclasses"
76
- end
75
+ ## Parameter accessors
77
76
 
78
- def parameters_for_signature
79
- parameters.select { |k,v| not signature_and_unsigned_parameters.include?(k) }
80
- end
77
+ def parameters
78
+ raise NotImplementedError, "Must be implemented by subclasses"
79
+ end
81
80
 
82
- def oauth_parameters
83
- parameters.select { |k,v| OAuth::PARAMETERS.include?(k) }.reject { |k,v| v == "" }
84
- end
81
+ def parameters_for_signature
82
+ parameters.select { |k, _v| !signature_and_unsigned_parameters.include?(k) }
83
+ end
85
84
 
86
- def non_oauth_parameters
87
- parameters.reject { |k,v| OAuth::PARAMETERS.include?(k) }
88
- end
85
+ def oauth_parameters
86
+ parameters.select { |k, v| OAuth::PARAMETERS.include?(k) && !v.nil? && v != "" }
87
+ end
89
88
 
90
- def signature_and_unsigned_parameters
91
- unsigned_parameters+["oauth_signature"]
92
- end
89
+ def non_oauth_parameters
90
+ parameters.select { |k, _v| !OAuth::PARAMETERS.include?(k) }
91
+ end
93
92
 
94
- # See 9.1.2 in specs
95
- def normalized_uri
96
- u = URI.parse(uri)
97
- "#{u.scheme.downcase}://#{u.host.downcase}#{(u.scheme.downcase == 'http' && u.port != 80) || (u.scheme.downcase == 'https' && u.port != 443) ? ":#{u.port}" : ""}#{(u.path && u.path != '') ? u.path : '/'}"
98
- end
93
+ def signature_and_unsigned_parameters
94
+ unsigned_parameters + ["oauth_signature"]
95
+ end
99
96
 
100
- # See 9.1.1. in specs Normalize Request Parameters
101
- def normalized_parameters
102
- normalize(parameters_for_signature)
103
- end
97
+ # See 9.1.2 in specs
98
+ def normalized_uri
99
+ u = URI.parse(uri)
100
+ "#{u.scheme.downcase}://#{u.host.downcase}#{(u.scheme.casecmp("http").zero? && u.port != 80) || (u.scheme.casecmp("https").zero? && u.port != 443) ? ":#{u.port}" : ""}#{u.path && u.path != "" ? u.path : "/"}"
101
+ end
104
102
 
105
- def sign(options = {})
106
- OAuth::Signature.sign(self, options)
107
- end
103
+ # See 9.1.1. in specs Normalize Request Parameters
104
+ def normalized_parameters
105
+ normalize(parameters_for_signature)
106
+ end
108
107
 
109
- def sign!(options = {})
110
- parameters["oauth_signature"] = sign(options)
111
- @signed = true
112
- signature
113
- end
108
+ def sign(options = {})
109
+ OAuth::Signature.sign(self, options)
110
+ end
114
111
 
115
- # See 9.1 in specs
116
- def signature_base_string
117
- base = [method, normalized_uri, normalized_parameters]
118
- base.map { |v| escape(v) }.join("&")
119
- end
112
+ def sign!(options = {})
113
+ parameters["oauth_signature"] = sign(options)
114
+ @signed = true
115
+ signature
116
+ end
120
117
 
121
- # Has this request been signed yet?
122
- def signed?
123
- @signed
124
- end
118
+ # See 9.1 in specs
119
+ def signature_base_string
120
+ base = [method, normalized_uri, normalized_parameters]
121
+ base.map { |v| escape(v) }.join("&")
122
+ end
123
+
124
+ # Has this request been signed yet?
125
+ def signed?
126
+ @signed
127
+ end
128
+
129
+ # URI, including OAuth parameters
130
+ def signed_uri(with_oauth: true)
131
+ if signed?
132
+ params = if with_oauth
133
+ parameters
134
+ else
135
+ non_oauth_parameters
136
+ end
125
137
 
126
- # URI, including OAuth parameters
127
- def signed_uri(with_oauth = true)
128
- if signed?
129
- if with_oauth
130
- params = parameters
138
+ [uri, normalize(params)].join("?")
131
139
  else
132
- params = non_oauth_parameters
140
+ warn "This request has not yet been signed!"
133
141
  end
134
-
135
- [uri, normalize(params)] * "?"
136
- else
137
- STDERR.puts "This request has not yet been signed!"
138
142
  end
139
- end
140
143
 
141
- # Authorization header for OAuth
142
- def oauth_header(options = {})
143
- header_params_str = oauth_parameters.map { |k,v| "#{k}=\"#{escape(v)}\"" }.join(', ')
144
+ # Authorization header for OAuth
145
+ def oauth_header(options = {})
146
+ header_params_str = oauth_parameters.map { |k, v| "#{k}=\"#{escape(v)}\"" }.join(", ")
144
147
 
145
- realm = "realm=\"#{options[:realm]}\", " if options[:realm]
146
- "OAuth #{realm}#{header_params_str}"
147
- end
148
+ realm = "realm=\"#{options[:realm]}\", " if options[:realm]
149
+ "OAuth #{realm}#{header_params_str}"
150
+ end
148
151
 
149
- def query_string_blank?
150
- if uri = request.env['REQUEST_URI']
151
- uri.split('?', 2)[1].nil?
152
- else
153
- request.query_string.match(/\A\s*\z/)
152
+ def query_string_blank?
153
+ if (uri = request.env["REQUEST_URI"])
154
+ uri.split("?", 2)[1].nil?
155
+ else
156
+ request.query_string.match(/\A\s*\z/)
157
+ end
154
158
  end
155
- end
156
159
 
157
- protected
160
+ protected
158
161
 
159
- def header_params
160
- %w( X-HTTP_AUTHORIZATION Authorization HTTP_AUTHORIZATION ).each do |header|
161
- next unless request.env.include?(header)
162
+ def header_params
163
+ %w[X-HTTP_AUTHORIZATION Authorization HTTP_AUTHORIZATION].each do |header|
164
+ next unless request.env.include?(header)
162
165
 
163
- header = request.env[header]
164
- next unless header[0,6] == 'OAuth '
166
+ header = request.env[header]
167
+ next unless header[0, 6] == "OAuth "
165
168
 
166
- # parse the header into a Hash
167
- oauth_params = OAuth::Helper.parse_header(header)
169
+ # parse the header into a Hash
170
+ oauth_params = OAuth::Helper.parse_header(header)
168
171
 
169
- # remove non-OAuth parameters
170
- oauth_params.reject! { |k,v| k !~ /^oauth_/ }
172
+ # remove non-OAuth parameters
173
+ oauth_params.select! { |k, _v| k =~ /^oauth_/ }
171
174
 
172
- return oauth_params
173
- end
175
+ return oauth_params
176
+ end
174
177
 
175
- return {}
178
+ {}
179
+ end
176
180
  end
177
181
  end
178
182
  end
@@ -1,55 +1,61 @@
1
- require 'oauth/request_proxy/base'
2
- require 'curb'
3
- require 'uri'
4
- require 'cgi'
5
-
6
- module OAuth::RequestProxy::Curl
7
- class Easy < OAuth::RequestProxy::Base
8
- # Proxy for signing Curl::Easy requests
9
- # Usage example:
10
- # oauth_params = {:consumer => oauth_consumer, :token => access_token}
11
- # req = Curl::Easy.new(uri)
12
- # oauth_helper = OAuth::Client::Helper.new(req, oauth_params.merge(:request_uri => uri))
13
- # req.headers.merge!({"Authorization" => oauth_helper.header})
14
- # req.http_get
15
- # response = req.body_str
16
- proxies ::Curl::Easy
17
-
18
- def method
19
- nil
20
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "oauth/request_proxy/base"
4
+ require "curb"
5
+ require "uri"
6
+ require "cgi"
7
+
8
+ module OAuth
9
+ module RequestProxy
10
+ module Curl
11
+ class Easy < OAuth::RequestProxy::Base
12
+ # Proxy for signing Curl::Easy requests
13
+ # Usage example:
14
+ # oauth_params = {:consumer => oauth_consumer, :token => access_token}
15
+ # req = Curl::Easy.new(uri)
16
+ # oauth_helper = OAuth::Client::Helper.new(req, oauth_params.merge(:request_uri => uri))
17
+ # req.headers.merge!({"Authorization" => oauth_helper.header})
18
+ # req.http_get
19
+ # response = req.body_str
20
+ proxies ::Curl::Easy
21
+
22
+ def method
23
+ nil
24
+ end
21
25
 
22
- def uri
23
- options[:uri].to_s
24
- end
26
+ def uri
27
+ options[:uri].to_s
28
+ end
25
29
 
26
- def parameters
27
- if options[:clobber_request]
28
- options[:parameters]
29
- else
30
- post_parameters.merge(query_parameters).merge(options[:parameters] || {})
31
- end
32
- end
30
+ def parameters
31
+ if options[:clobber_request]
32
+ options[:parameters]
33
+ else
34
+ post_parameters.merge(query_parameters).merge(options[:parameters] || {})
35
+ end
36
+ end
33
37
 
34
- private
38
+ private
35
39
 
36
- def query_parameters
37
- query = URI.parse(request.url).query
38
- return(query ? CGI.parse(query) : {})
39
- end
40
+ def query_parameters
41
+ query = URI.parse(request.url).query
42
+ (query ? CGI.parse(query) : {})
43
+ end
40
44
 
41
- def post_parameters
42
- post_body = {}
45
+ def post_parameters
46
+ post_body = {}
43
47
 
44
- # Post params are only used if posting form data
45
- if (request.headers['Content-Type'] && request.headers['Content-Type'].to_s.downcase.start_with?("application/x-www-form-urlencoded"))
48
+ # Post params are only used if posting form data
49
+ if request.headers["Content-Type"] && request.headers["Content-Type"].to_s.downcase.start_with?("application/x-www-form-urlencoded")
46
50
 
47
- request.post_body.split("&").each do |str|
48
- param = str.split("=")
49
- post_body[param[0]] = param[1]
51
+ request.post_body.split("&").each do |str|
52
+ param = str.split("=")
53
+ post_body[param[0]] = param[1]
54
+ end
55
+ end
56
+ post_body
50
57
  end
51
58
  end
52
- post_body
53
59
  end
54
60
  end
55
61
  end