How to authenticate oauth, Magento 2.0 SOAP in Ruby - ruby

Having a problem authenticating to Magento 2 SOAP with oauth credentials.
For a magento 1.9 version this is very straightforward:
client = Savon.client(
wsdl: "https://example.com/api/soap/?wsdl=1",
log: true,
pretty_print_xml: true
)
session_id = client.call(:login, message: { username: "username", apiKey: "key" })body[:login_response][:login_return]
client.call(:call, message:{resource_path: 'catalog_product.list', session_id: session_id}).body
Works as expected. With oauth it gets bit more complicated.
I tried all kind of different things, like:
client = Savon.client(
wsdl: "http://example.com/index.php/soap/default?wsdl_list=1",
soap_header: { 'Authorization:' => "Basic xxxx"},
pretty_print_xml: true
)
client.call(:call, message:{resource_path: 'catalogProductAttributeGroupRepositoryV1'}).body
Hope somebody already made an oauth-magento 2 soap integration and give me some pointers.

You need to create a new integration from admin to get authentication keys. These links will be useful resource:
https://devdocs.magento.com/guides/v2.0/get-started/authentication/gs-authentication-oauth.html
https://gist.github.com/rafaelstz/ecab668b80fece4d9acdb9c5358b3173

Related

How to set SameSite to none in Rails 6 API with CreateReactApp?

I have a Rails 6 app acting as an API for a frontend app originally created with create-react-app. I am trying to store a session token to preserve login on page refresh.
When running locally, Chrome shows that SameSite=Lax but the session token is stored anyway. On the live site, SameSite is still Lax, but Chrome gives a little warning saying that the Set-Cookie header was blocked because it came from cross-site response. Both the frontend and api are deployed on Heroku in separate repos.
I've tried a number of things:
secure_headers gem, with the following in app/config/initializers/secure_headers.rb:
SecureHeaders::Configuration.default do |config|
config.cookies = {
secure: true, # mark all cookies as "Secure"
httponly: true, # mark all cookies as "HttpOnly"
samesite: {
lax: false
}
}
end
I have the following in app/config/initializers/session_store.rb:
Rails.application.config.session_store :cookie_store, :key => '_session_id',
:domain => :all,
:same_site => :none,
:secure => :true,
:tld_length => 3
I've tried cookie_serializer, although I commented everything out of that file.
I have the rack-cors gem, with the following in the cors.rb initializer:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'http://localhost:8080', 'http://localhost:5000', 'https://frontend-auth-frontend.herokuapp.com'
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head],
credentials: true,
exposedHeaders: ["Set-Cookie"]
end
end
I've tried a few other gems I saw recommended on SO but I don't remember all of them.
So... yea, how do I set SameSite so that my heroku frontend (react) can store cookies from the heroku api (rails 6)?
I can provide other info about the project, specific versions, etc., just not sure what else would be helpful.
Thanks!
the following code should set sameSite to none (the key is in the last line)
//config/application.rb
config.api_only = true
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore,
key: '_cookie_name', path: '/', same_site: :None, secure: true

OctoKit Ruby Authentication

I'm sure that this is a simple error, but I'm interested in writing a program that collects information on all of my github repositories. While this seems simple enough to do with Octokit, I've run into issues associated with authenticating my session.
client = Octokit::Client.new \
:login => 'MY_USER_NAME',
:password => 'MY_PASSWORD'
puts client
user = client.user("MY_USER_NAME", :headers => { "PERSONAL_ACCESS_TOKEN_NAME" => "TOKEN" })
puts user
Unfortunately this results in the following:
GET https://api.github.com/users/mccoleman75225: 401 - Must specify two-factor authentication OTP code. // See: https://developer.github.com/v3/auth#working-with-two-factor-authentication (Octokit::OneTimePasswordRequired)
How does someone go about authenticating their session?
As of January 2022, you can create a PAT (Personal Access Token) in your GitHub Developer Settings and use that to connect through the Octokit client like so:
client = Octokit::Client.new(:access_token => "<Your Personal Access Token>")
user = client.user
user.login
# => "monacat"
Here's a step-by-step guide on how to create a PAT. Try to select the correct permissions when creating your token or you'll get back a 403 error with a message explaining the missing scope. You can always go back and edit your scopes later though.
Sources:
Octokit.rb — Authentication
GitHub API Authentication - Personal Access Tokens
Looks like you have 2 Factor Authentication enabled on your account so you'll need to add your 2FA token:
client = Octokit::Client.new \
:login => 'defunkt',
:password => 'c0d3b4ssssss!'
client.create_authorization(:scopes => ["user"], :note => "Name of token",
:headers => { "X-GitHub-OTP" => "<your 2FA token>" })
# => <your new oauth token>
See documentation

404 Resource Not Found: domain with Google Directory API

I followed the quick start and am attempting to create a user using the google-api-ruby-client.
I've set up access in the google api console. And I can get this to work using the API explorer.
But when I try using the ruby client, I'm getting a resource not found: domain error.
Here's the code:
def self.create_user
# Initialize the client.
client = Google::APIClient.new(
:application_name => 'MYAPP',
:application_version => '0.0.1'
)
# Authorization
# Load our credentials for the service account
key = Google::APIClient::KeyUtils.load_from_pkcs12(KEY_FILE, KEY_SECRET)
client.authorization = Signet::OAuth2::Client.new(
token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
audience: 'https://accounts.google.com/o/oauth2/token',
scope: 'https://www.googleapis.com/auth/admin.directory.user',
issuer: ACCOUNT_ID,
signing_key: key)
# Request a token for our service account
client.authorization.fetch_access_token!
# Load API Methods
admin = client.discovered_api('admin', 'directory_v1')
# Make an API call.
result = client.execute(
admin.users.update,
name: { familyName: 'testy', givenName: 'testerson' },
password: '!password12345!',
primaryEmail: 'ttesterson#my-actual-domain.com'
)
result.data
end
Here's the response:
"error"=>{"errors"=>[{"domain"=>"global", "reason"=>"notFound", "message"=>"Resource Not Found: domain"}], "code"=>404, "message"=>"Resource Not Found: domain"}
Why?
After a bit of documentation reading, there were two things that I needed to fix.
I hadn't set up the proper authorization for my test service account.
You have to go to the Apps Console > Security > Advanced > Manage API client access and add the client url for your service account as well as any specific permissions that you want to add
As seen in this question, it seems that you need to create a user object rather than just passing in parameters.
Here's my updated code:
# Authorization happens here ....
api = client.discovered_api('admin', 'directory_v1')
new_user = api.users.insert.request_schema.new(
name: { familyName: 'Testy', givenName: 'Testerson' },
primaryEmail: 'ttttesterson#<domain-redacted>.com',
password: 'password123'
)
result = client.execute(
api_method: api.users.insert,
body_object: new_user
)

Authenticate with http headers with savon 2.3.0

I had this code in Savon v1:
client = Savon.client("http://www.server.com:9191/soapserver?wsdl")
service = client.request :get_authentication do
client.http.headers["username"] = "myuser"
client.http.headers["password"] = "mypass"
end
After the update to savon v2.3.0, I don't manage to retranslate. It should be something like
client = Savon.client do
wsdl "http://www.shab.ch:9191/soapserver?wsdl
end
service = client.call(:get_authentication, {username: "myuser", password: "mypass"})`
but the line service = client.call(..." does not work. Any idea?
I think what you want to do is:
gem "savon"
require "savon", "~>2.0"
...
client = Savon.client(headers: { username: "user", password: "password"},
wsdl: "http://www.example.com/?wsdl",
log: true,
log_level: :debug,
pretty_print_xml: true
#, and more options here if necessary)
That will inject the key/values pairs into the http headers.
That last code block of yours is missing a " on line #2 and has a ``` too much in the end. It should look like:
client = Savon.client do
wsdl "http://www.shab.ch:9191/soapserver?wsdl"
end
service = client.call(:get_authentication, {username: "myuser", password: "mypass"})
to not trigger any syntax errors.
This works for me after a lot of trial and error:
client = Savon.client( wsdl: "http://www.server.com:9191/soapserver?wsdl", <\br>
headers: {'username' => 'myuser', 'password' => 'mypass'} )
service = client.call(:get_authentication)
So the header injection I do before calling the :get_authentication function.

omniauth oauth tokens for gmail are invalid

I'm trying to get an oauth token I can use with gmail_xauth (ruby gem)
to look at a user's mail. I first registered my app with google and
then set up devise to request access to mail:
config.omniauth :google, 'key', 'secret', :scope => 'https://mail.google.com/mail/feed/atom/'
I then go through the outh/openid flow and google prompts me to
approve access to gmail, redirecting me back to the app with a a token
and secret in the omniuth credentials & my Google account lists my app
as authorized to access my data. So far so good.
Now, when I take those credentials and try to use them with
gmail_xoauth like so:
require 'gmail_xoauth'
imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs =
nil, verify = false)
imap.authenticate('XOAUTH', '...#gmail.com',
:consumer_key => 'key,
:consumer_secret => 'secret',
:token => 'omniauth_returned_token',
:token_secret => 'omniauth_returned_secret'
)
I get an error "Net::IMAP::NoResponseError: Invalid credentials
(Failure)".
Interestingly, following the gmail_xoauth README to generate a token
with an same consumer using a python script it does work.
This works for me:
config.omniauth :google, 'anonymous', 'anonymous', :scope => 'https://mail.google.com/'
I'm using the gmail gem, so to connect it looks like this:
gmail = Gmail.connect(:xoauth, auth.uid,
:token => auth.token,
:secret => auth.secret,
:consumer_key => 'anonymous',
:consumer_secret => 'anonymous'
)
I'm passing an authentication object in, but you'll be getting it from the env variable env["omniauth.auth"]. I'm using anonymous/anonymous for the key/secret since I haven't registered my domain with google, but I believe you can here. It'll still work with anonymous/anonymous, but Google will just warn the user.
Google's OAuth1 protocol is now deprecated and many gems have not yet updated to use their OAuth2 protocol. Here is a working example of fetching email from Google using their OAuth2 protocol. This example uses the mail, gmail_xoauth, omniauth, and omniauth-google-oauth2 gems.
You will also need to register your app in Google's API console in order to get your API tokens.
# in an initializer:
ENV['GOOGLE_KEY'] = 'yourkey'
ENV['GOOGLE_SECRET'] = 'yoursecret'
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'], {
scope: 'https://mail.google.com/,https://www.googleapis.com/auth/userinfo.email'
}
end
# ...after handling login with OmniAuth...
# in your script
email = auth_hash[:info][:email]
access_token = auth_hash[:credentials][:token]
imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
imap.authenticate('XOAUTH2', email, access_token)
imap.select('INBOX')
imap.search(['ALL']).each do |message_id|
msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
mail = Mail.read_from_string msg
puts mail.subject
puts mail.text_part.body.to_s
puts mail.html_part.body.to_s
end

Resources