accessing JIRA rest API over ruby - ruby

I was trying to write a ruby script which would use the rest API.
However am stuck at the auth step ( am using basic auth ).
From what I thought I understood i was supposed to base 64 encode my login:password then pass it with header Authorization along with my
request but its getting me nowhere but 403 forbidden errors.
enc = Base64.encode64('username:passs')
my_url = 'http://intenthq.atlassian.net/rest/api/2/application-properties'
my_key = 'Basic '+ enc
puts enc
puts 'Authorization ' + my_key
RestClient::Request.execute(
:method => :get,
:url => my_url,
:headers => {'Authorization' => my_key}
)
what am I doing wrong ?
Am I even using the correct methods ?

managed to sort it out by using github.com/sumoheavy/jira-ruby
thanks Coderhs :)

Related

Ruby Oauth2.0: client_secret_post not working with ory hydra

I am trying to get a Ruby Oauth2.0 client talking with the Ory Hydra docker-compose 5 minute demo. I am stuck on the client app's authentication code exchange for the token. LOG is below. Looks like the main problem is the following "hashedPassword is not the hash of the given password".
DEBUG LOG FROM HYDRA SERVER
time="2019-06-04T21:32:09Z" level=info msg="started handling request" method=POST remote="172.19.0.2:35482" request=/oauth2/token
hydra_1
time="2019-06-04T21:32:09Z" level=error msg="An error occurred" debug="crypto/bcrypt: hashedPassword is not the hash of the given password" description="Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)" error=invalid_client
hydra_1
time="2019-06-04T21:32:09Z" level=info msg="completed handling request" measure#hydra/public: http://127.0.0.1:4444/.latency=92931900 method=POST remote="172.19.0.2:35482" request=/oauth2/token status=401 text_status=Unauthorized took=92.9319ms
I've read up here and it would appear this 'is' possible.
Here is how I register my client 'test-app9' in hydra:
docker-compose -f quickstart.yml exec hydra hydra clients create --endpoint http://127.0.0.1:4445 --id test-app9 --secret secret--skip-tls-verify --grant-types authorization_code,refresh_token,client_credentials,implicit --response-types token,code,id_token --scope profile --callbacks http://127.0.0.1:8088/auth/callback --token-endpoint-auth-method client_secret_post -g client_credentials
I can indeed see the client appearing in the postgres DB from the docker-compose demo. The password 'secret' is hashed in the DB.
Here is my single Sinatra file acting as the Oauth2.0 client:
require 'rubygems'
require 'sinatra'
require 'oauth2'
require 'json'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
# If you add your authentication in the header then use ~Sclient_secret_basic~T
# If you add your authentication details in the post use ~Sclient_secret_post~T
def client
OAuth2::Client.new('test-app9',
'secret',
# 'c2VjcmV0',
:site => "http://127.0.0.1:4445",
:logger => Logger.new('example.log'),
:authorize_url => "http://127.0.0.1:4444/oauth2/auth",
:token_url => "http://hydra:4444/oauth2/token")
end
set :root, File.dirname(__FILE__)
set :views, Proc.new { File.join(root, "views") }
set :run, true
set :port, 80
get "/" do
erb :index
end
get '/auth' do
authorization_url = client.auth_code.authorize_url(:redirect_uri => redirect_uri, :response_type => "code", :scope => "profile", :state => "pqrst1234")
puts "Redirecting to URL: #{authorization_url.inspect}"
redirect authorization_url
end
get '/auth/callback' do
begin
access_token = client.auth_code.get_token(params[:code], :redirect_uri => redirect_uri, :client_id => "test-app9", :client_secret => 'secret', :headers => {'Authorization' => 'basic_auth_header', 'client_id' => 'test-app9', 'client_secret' => 'c2VjcmV0'} )
api_url = "/me.json"
me = JSON.parse(access_token.get(api_url).body)
erb "<p>Your data:\n#{me.inspect}</p>"
rescue OAuth2::Error => e
erb %(<p>Wassup #{$!}</p><p>Retry</p>)
end
end
get '/auth/failure' do
erb "<h1>Authentication Failed:</h1><h3>message:<h3> <pre>#{params}</pre>"
end
def redirect_uri(path = '/auth/callback', query = nil)
uri = URI.parse(request.url)
uri.path = path
uri.query = query
uri.to_s
end
__END__
So some interesting notes:
It apparently does not matter what secret I initiate the OAuth2 client with. I can use 'secret' or the base64 encoded 'c2VjcmV0' string. Either way I get up to the token exchange portion.
I was shotgunning this and ended up putting the client_id and the client_secret in what I believe is the proper way to set in the headers as well as the body.
I have tried many variations of this. Can't seem to get the correct syntax that the author of this apparently succeeded with OR I'm hitting a bug (doubtful).
Anyone able to help here?
UPDATE
Fixed this myself. Problem was syntax issue when creating my client 'app'. This is the corrected version.
docker-compose -f quickstart.yml exec hydra hydra clients create --endpoint http://127.0.0.1:4445 --id test-app10 --secret secret --skip-tls-verify --grant-types authorization_code,refresh_token,client_credentials,implicit --response-types token,code,id_token --scope profile --callbacks http://127.0.0.1:8088/auth/callback --token-endpoint-auth-method client_secret_post -g client_credentials

DELETE method with a payload using Ruby Rest:Client?

While I don't think it is very restful to have to include a payload in a DELETE request. I ran into an instance where I am testing a service that requires a payload for DELETE. Might there be a way using Ruby's Rest Client to accomplish this? Unfortunately, I am having a hard time with this one.
#json_request = '{"user_id": 5, "meta_data": "foo"}'
resource = RestClient::Resource.new "http://www.foo.com/some/process"
#response_update = resource.delete(#json_request, :content_type => :json, :accept => :json)
Output:
ArgumentError:
wrong number of arguments (2 for 0..1)
Try this
RestClient::Request.execute(:method => 'delete', :url => "http://www.foo.com", :payload => json_data)
Currently it's not possible with that gem. You can see a PL addressing that. Maybe you could fork it and pull those changes to your own fork of the rest-client gem.
The pull request https://github.com/rest-client/rest-client/pull/98
As a very modern update, from the ReadMe
RestClient::Request.execute(method: :delete, url: 'http://example.com/resource',
payload: 'foo', headers: {myheader: 'bar'})

Ruby RestClient converts XML to Hash

I need to send a POST request as an XML string but I get odd results. The code:
require 'rest_client'
response = RestClient.post "http://127.0.0.1:2000", "<tag1>text</tag1>", :content_type => "text/xml"
I expect to receive "<tag1>text</tag1>" as the parameter on the request server. Instead, I get "tag1"=>"text". It converts the XML to a hash. Why is that? Any way around this?
Try this:
response = RestClient.post "http://127.0.0.1:2000",
"<tag1>text</tag1>",
{:accept => :xml, :content_type => :xml}
I think you just needed to specify the ":accept" to let it know you wanted to receive it in the XML format. Assuming it's your own server, you can debug on the server and see the request format used is probably html.
Hope that helps.
Instead of using RestClient, use Ruby's built-in Open::URI for GET requests or something like Net::HTTP or the incredibly powerful Typhoeus:
uri = URI('http://www.example.com/search.cgi')
res = Net::HTTP.post_form(uri, 'q' => 'ruby', 'max' => '50')
In Typhoeus, you'd use:
res = Typhoeus::Request.post(
'http://localhost:3000/posts',
:params => {
:title => 'test post',
:content => 'this is my test'
}
)
Your resulting page, if it's in XML will be easy to parse using Nokogiri:
doc = Nokogiri::XML(res.body)
At that point you'll have a fully parsed DOM, ready to be searched, using Nokogiri's search methods, such as search and at, or any of their related methods.

Ruby rest_client and windows LIVE connect OAUTH Wrap

Hi all I am trying to get my rails app to talk to Windows LIVE (through OAuth Wrap) so I can retrieve a list of contacts. I am using the rest_client gem to do this. Here is the action code for it:
def hotmail
app_id = 'some_id'
app_sec = 'some_secret'
app_callback = 'http://my.callback.com/same/as/getting/verification_code'
app_var = params[:wrap_verification_code]
encoded = "wrap_client_id=#{app_id}&wrap_client_secret=#{app_sec}&wrap_verification_code=#{app_var}&wrap_callback=#{app_callback}".encode!('UTF-8')
begin
r = RestClient.post("https://consent.live.com/AccessToken.aspx", encoded.bytes.to_a, {:content_type => 'application/x-www-form-urlencoded', :content_length => encoded.bytesize})
rescue => e
puts e.message
end
render :text => 'hello'
end
I base this on a c# example http://msdn.microsoft.com/en-us/library/ff750952.aspx (note: http://www.goatly.net/2010/12/23/401-unauthorized-when-acquiring-an-access-token-windows-live-sdk.aspx shows the correct payload)
However I keep getting 401 Unauthorized, so I am thinking is the way I am using rest_client incorrectly? During a form post is there somthing else I need to do?
ANy hints will be really helpful :) thanks in advance.
Found the problem. The C# code says it post the byte array but thats not true just post the encoded st direct is enough.

Using Shoes' download() to do basic HTTP authentication

I'm trying to use Shoes' download() method to pass a username and password in the HTTP header to authenticate the HTTP request (talking to a Rails app).
I'm a bit of a newb when it comes to this stuff.
I havn't quite understood whether I should be automatically able to use the below syntax (username:pwd#) or whether the username and password should be created manually inside the HTTP header (which I think I can also access using :headers of the download method).
download "http://username:pwd#127.0.0.1:3000/authenticate", :method => "POST" do |result|
# process result.response.body here
end
Any help would be appreciated
Can I answer my own question?
This seems to do the trick:
require 'base64'
< ... snip ... >
# create the headers
headers = {}
headers['Authorization'] = 'Basic ' + encode64("#{#login.text()}:#{#pword.text()}").chop
# run the download
download "#{$SITE_URL}/do_something", :method => "GET", :headers => headers do |result|
#status.text = "The result is #{result.response.body}"
end

Resources