Error working with Typhoreus and SeoMoz API - ruby

I am working with the SEOMoz API using the Typhoreus gem. To authenticate(Signed Authentication) with the API, I use the following code:
url = "http://lsapi.seomoz.com/linkscape/url-metrics/"+website.url.strip+"?Cols=103079231520"
response = Typhoeus::Request.get(url, :username => "member-xxxxxxx", :password => "abcxyzwhatever")
To which I get the error: Ethon::Errors::InvalidOption: The option: username is invalid.
Please try userpwd instead of username.
If I change the username to userpwd, it asks to change password to userpwd as well.
Where am I going wrong?

The api changed a bit, that should work:
Typhoeus::Request.get(url, :userpwd => "member-xxxxxxx:abcxyzwhatever")

Related

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

Unable to get folder by id when using Boxr JWT get_user_token- Box API

I'm unable to a folder by providing an id to that folder using Boxr gem. Previously I didn't has the enterprise settings as shown in this post which I have now fixed. I'm creating a token using JWT authentication get_user_token method the following way.
token = Boxr::get_user_token("38521XXXX", private_key: ENV.fetch('JWT_PRIVATE_KEY'), private_key_password: ENV.fetch('JWT_PRIVATE_KEY_PASSWORD'), public_key_id: ENV.fetch('JWT_PUBLIC_KEY_ID'), client_id: ENV.fetch('BOX_CLIENT_ID'), client_secret: ENV.fetch('BOX_CLIENT_SECRET'))
I then pass this this token when creating a client.
client = Boxr::Client.new(token)
when I check the current user on client this is what I get:
client.current_user
=> {"type"=>"user",
"id"=>"60853XXXX",
"name"=>"OnlineAppsPoC",
"login"=>"AutomationUser_629741_06JgxiPtPj#boxdevedition.com",
"created_at"=>"2018-10-04T08:41:32-07:00",
"modified_at"=>"2018-10-04T08:41:50-07:00",
"language"=>"en",
"timezone"=>"America/Los_Angeles",
"space_amount"=>10737418240,
"space_used"=>0,
"max_upload_size"=>2147483648,
"status"=>"active",
"job_title"=>"",
"phone"=>"",
"address"=>"",
"avatar_url"=>"https://app.box.com/api/avatar/large/6085300897"}
When I run client.methods I see there is folder_from_id however when I call that method I get the following error:
pry(#<FormsController>)> client.folder_from_id("123456", fields: [])
Boxr::BoxrError: 404: Not Found
from /usr/local/bundle/gems/boxr-1.4.0/lib/boxr/client.rb:239:in `check_response_status'
I have the following settings:
I also authorize the application. Not sure what else to do.
token = Boxr::get_user_token(user_id,
private_key: ENV.fetch('JWT_PRIVATE_KEY'),
private_key_password: ENV.fetch('JWT_PRIVATE_KEY_PASSWORD'),
public_key_id: ENV.fetch('JWT_PUBLIC_KEY_ID'),
client_id: ENV.fetch('BOX_CLIENT_ID'),
client_secret: ENV.fetch('BOX_CLIENT_SECRET'))
client = Boxr::Client.new(token.access_token)
folder = client.folder_from_id(folder_id)
client.upload_file(file_path, folder)
For anybody using C# and BOXJWT.
You just need to have a boxManager set up and will get you with anything you need, say BoxFile, Folder etc.
If you have the folderID, well & good, but if you need to retrieve, this can be done as shown below:
string inputFolderId = _boxManager.GetFolder(RootFolderID).Folders.Where(i => i.Name == boxFolder).FirstOrDefault().Id; //Retrieves FolderId
Folder inputFolder = _boxManager.GetFolder(inputFolderId);

Trouble with Google Apps API and Service Accounts in Ruby

I'm having some trouble getting the sample code for instantiating a Drive Service Account working. I've set up the service account in the API console as directed and included the scope for the 'https://www.googleapis.com/auth/drive', but running this generates the following error: "Authorization failed. Server message: (Signet::AuthorizationError)".
Oddly, if I omit the user_email address it doesn't generate an error.
My objective is to be able to do an audit on all the files stored on the organization's Drive, and it's my understanding that using a service account would be the way to get a listing of all the files stored.
Have I missed some special setting on the server side for this?
require 'google/api_client'
## Email of the Service Account #
SERVICE_ACCOUNT_EMAIL = '<service account email>#developer.gserviceaccount.com'
## Path to the Service Account's Private Key file #
SERVICE_ACCOUNT_PKCS12_FILE_PATH = '<private key file>-privatekey.p12'
def build_client(user_email)
key = Google::APIClient::PKCS12.load_key(SERVICE_ACCOUNT_PKCS12_FILE_PATH, 'notasecret')
asserter = Google::APIClient::JWTAsserter.new(SERVICE_ACCOUNT_EMAIL, 'https://www.googleapis.com/auth/drive', key)
client = Google::APIClient.new
client.authorization = asserter.authorize(user_email)
return client
end
client = build_client("<users email address>")
This looks to me like you are using an older example. I think that's how you used to do it about a year ago. Back in late 2012 that method of setting up the app was deprecated because Signet was updated to handle all aspects of the OAuth2 setup.
Here is the code I generally use to create a service account. You can tweak it to fit into your method.
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/drive",
:issuer => "<service account email>#developer.gserviceaccount.com",
:signing_key => Google::APIClient::KeyUtils.load_from_pkcs12("<private key file>-privatekey.p12", "notasecret"),
:person => "<users email address>")
client.authorization.fetch_access_token!
If you are still having issues let me know and I'll see if I can help.
Using version 0.9.13 of google-api-client, I succeeded in using the following slight adaptation of Woodward's answer (note the absence of the person parameter):
def service_account_authorization(credentials_file, scope)
credentials = JSON.parse(File.open(credentials_file, 'rb').read)
authorization = Signet::OAuth2::Client.new(
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => scope,
:issuer => credentials['client_id'],
:signing_key => OpenSSL::PKey::RSA.new(credentials['private_key'], nil),
)
authorization.fetch_access_token!
authorization
end
This snippet takes a file as it was downloaded from Google Cloud Console for a service account and returns an auth object that can be fed to Google::Apis::*Service.authorization.
Thanks James!
I have worked with service account+Drive+file permissions using Java. In order to use permissions for a particular user, I had to allow certain scope. The only thing I can guess about your issue is that you might have missed the Delegation part

RestClient basic auth with # in username

I have a problem with a daemon accessing a REST api.
The access requires basic authentication. The username and password are fixed and can not be changed.
The problem seems to be, that the username looks like this: #ws+R4nd0mS7r1n
I access the API like this:
resource = RestClient::Resource.new( "#{base_url}/failover/#{failover_ip}", { :user => user_name, :password => user_password})
response = resource.get
This gets me an bad URI error:
bad URI(absolute but no path): https://#ws+R4nd0mS7r1n:RaNdOmPaSsWoRd#robot-ws.your-server.de/failover/11.11.11.11
When I itentionally remove the # from the username it works, but I get a NOT Authenticated error.
Is there a way to pass a username or password containing # to restclient?
Passing the complete URI manually to a .get does not work either.
I don't get the same error. What version of rest-client do you have installed?
You may simply be able to update the version to fix your problem (I tested with version 1.6.7 of the gem)
Alternatively, this works around the URI failure by directly writing to the Authorization header (which is where this data ends up anyway):
require 'base64'
auth = 'Basic ' + Base64.encode64( "#{user_name}:#{user_password}" ).chomp
resource = RestClient::Resource.new( "#{base_url}/failover/#{failover_ip}", { :headers => { 'Authorization' => auth } } )
resource.get

Oauth2 google-api-ruby-client: How to set Approval Prompt to Auto?

Question:
How to set the Approval Prompt to Auto? It defaults to 'approval_prompt=force'
Code:
I am setting up the client like this.
#client = Google::APIClient.new(
:authorization => :oauth_2,
:host => 'www.googleapis.com',
:http_adapter => HTTPAdapter::NetHTTPAdapter.new
)
#client.authorization.client_id = 'xxxx.apps.googleusercontent.com'
#client.authorization.client_secret = 'xxxx'
Context: Google OAuth2
Client Library: google-api-ruby-client
Reference: Same question for the php client :
Google+ OAuth API store and retrieve tokens after first login and authorization
Signet Documentation. I can't find the approval_prompt setter
http://signet.rubyforge.org/api/Signet/OAuth2/Client.html
This is how I solved the problem.
I wrote a separate helper method that will generate the Google OAuth URI
def build_auth_uri
return #client.authorization.authorization_uri(
:approval_prompt => :auto
).to_s
end
Next, instead of referring to Google OAuth URI directly in my view, I called the helper.
That did the trick.
This is how I solved the problem:
In /app/views/devise/shared/_links.haml (it's similar for _links.erb):
- if devise_mapping.omniauthable?
- resource_class.omniauth_providers.each do |provider|
- if provider == :google_oauth2
= link_to "Sign in with Google", omniauth_authorize_path(resource_name, provider, approval_prompt: :auto)
- else
= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider)
%br/
EDIT: Even easier: Add this to your devise.rb or omniauth.rb initializer (in /config/initializers):
provider :google_oauth2, ENV["GOOGLE_KEY"], ENV["GOOGLE_SECRET"], {
approval_prompt: "auto"
}
Check the documentation here for more info.

Resources