RUBY: Get the Steam Username from OmniAuth - ruby-on-rails

I have been using Omniauth to retrieve an environment that contains the steam username.
The output looks like this:
<OmniAuth::AuthHash::InfoHash image="https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d4/d45a66fee7932d270ec32d4457d865b485245cf1_medium.jpg" location="YT, CA" name="Daiki" nickname="Corybantic Walrus" urls=#<OmniAuth::AuthHash FriendList=#<URI::HTTP:0x0000000614f590 URL:http://api.steampowered.com/ISteamUser/GetFriendList/v0001/?key=4A8837BF7A6C439681B57F4962D8B011&steamid=76561198128055024&relationship=friend> Profile="http://steamcommunity.com/id/hatterkiller/">> provider="steam" uid="76561198128055024">
I don't really know how to format this inside Stack Overflow, so here is a cleaner Pastebin.
The information I need is inside the <Omniauth::AuthHash::Infohash thing of the code. Is there a way to use Ruby to retrieve the username (nickname) and to put it inside an array?
Sort of like this, but this only worked for the previous output format:
auth = request.env['omniauth.auth']
session[:current_user] = { :nickname => auth.info['nickname'],
:image => auth.info['image'],
:uid => auth.uid }

Something like this:
session[:current_user] = {
nickname: auth[:info][:nickname],
image: auth[:info][:image],
uid: auth[:uid]
}

Related

Ruby: How to initialize an active merchant gateway instance with credentials?

From this http://www.rubydoc.info/github/Shopify/active_merchant/ActiveMerchant%2FBilling%2FBase.gateway
I should just initialize an instance of active_merchant using this
gateway = ActiveMerchant::Billing::Base.gateway( gateway_name ).new(
:username => :some_credential
:password => :some_other_credential
)
But I don't know :username or :password in advance, however they are in the fixtures file https://github.com/activemerchant/active_merchant/blob/master/test/fixtures.yml here. So how to do this properly?
For an example, in the fixtures.yml file we can see this..
adyen:
username: ''
password: ''
merchant_account: ''
Accordingly we can initialize with this..
gateway = ActiveMerchant::Billing::Base.gateway( 'adien' ).new(
username: => :some_credential
password: => :some_other_credential
merchant_account: => some_more_credential
)
I need to be able to initialize the gateway instance without hard-coding the username:, password: and merchant_account: parameters in the above example.
Thanks in advance!
You should take a look at environment variables. They let you define variables in a safe palce and refer to them when needed.
Somewhere you would define PASSWORD=mysecretpassword and then in the Rails code you refer to it as ENV["PASSWORD"]
There are many ways of doing this. Take a look here:
http://railsapps.github.io/rails-environment-variables.html
The username, password, and merchant_account are instance variables so you need to change them with instance_variable_set
gateway.instance_variable_set(:#username, :some_username)
gateway.instance_variable_set(:#password, :some_password)
gateway.instance_variable_set(:#merchant_account, :some_merchant_account)
I think i can answer my own question. One should pass every different initialization with its own hash..
require 'active_merchant'
settings = {name: 'braintree_blue', merchant_id: 'x', public_key: 'y', private_key: 'z'}
another_settings = {name: 'trust_commerce', login: 'TestMerchant', password: 'password'}
Gateway = ActiveMerchant::Billing::Base::gateway(settings[:name]).new(settings)
Another_Gateway = ActiveMerchant::Billing::Base::gateway(another_settings[:name]).new(another_settings)
puts Gateway.options
puts Another_Gateway.options
Note that I could pass different options without the need to hardcode any keys, which is what i desired.

how to properly authenticate user with devise_token_auth rails gem?

I am trying to write a simple test for a URL which should be visible only to logged in user (I use before_action :authenticate_user! to achieve this).
Even though I (think) that I properly assign all the headers I always get JSON response {"errors":["Authorized users only."]}
My test looks like this (Login (to get header info) then visit protected URL with all the headers needed)
post "/api/v1/auth/sign_in", {:email => user.email, password: 'password'}
header_hash = {
'access-token' => response.headers['access-token'],
'uid' => response.headers['uid'],
'client' => response.headers['client'],
'expiry' => response.headers['expiry']
}
get "/api/v1/subscription_status", nil , header_hash
What am I doing wrong?
I didn't know that authentication token is changing on each request by default.
conf/device_token_auth.rb
config.change_headers_on_each_request = false
I set this setting to false and afterwards I got responses which I expected.

Rails, Devise, OmniAuth: request additional fields and store them in the db

I'm a newbie in Rails.
So...in my Rails app, where I have OmniAuth Facebook integration, I want to add some fields, e.g., first name, last name and location, to my database.
I followed this wiki, and I have a simple login, but without the extra fields (firstname, lastname, location).
So, I added this in my config/initializers/devise.rb:
require 'omniauth-facebook'
config.omniauth :facebook, '123456...', '123456...',
scope: 'first_name, last_name, location',
stategy_class: OmniAuth::Strategies::Facebook
So, if I'm correct, the above will ask for these additional fields.
Now, in my model user.rb, I want to add 3 lines where it will pass the requested values to the database.
def self.find_for_facebook_omniauth(omniauth, signed_in_resource=nil)
basic = {
provider: omniauth.provider,
uid: omniauth.uid,
}
User.where(basic).first || User.create(basic.merge(
firstname: omniauth.info.firstname, # these are the
lastname: omniauth.info.lastname, # lines I'm not
location: omniauth.info.location, # sure of
email: omniauth.info.email,
password: Devise.friendly_token[0,20],
))
end
Assuming your omniauth is request.env["omniauth.auth"], then you may find additional fields are not include in the .info hash.
In this case it's safer to use .extra.raw_info, which will contain the fields for the additional scopes.
Here I requested the additional scope user_hometown, we can see it is missing in the info hash:
>> auth.info
=> #<OmniAuth::AuthHash::InfoHash email="dukedave#gmail.com" first_name="Dave" image="http://graph.facebook.com/508528599/picture?type=square" last_name="Tapley" name="Dave Tapley" nickname="dave.tapley" urls=#<OmniAuth::AuthHash Facebook="https://www.facebook.com/dave.tapley"> verified=true>
But present in extra.raw_info (after gender):
>> auth.extra.raw_info
=> #<OmniAuth::AuthHash email="dukedave#gmail.com" first_name="Dave" gender="male" hometown=#<OmniAuth::AuthHash id="105540216147364" name="Phoenix, Arizona"> id="508528599" last_name="Tapley" link="https://www.facebook.com/dave.tapley" locale="en_US" name="Dave Tapley" timezone=-7 updated_time="2013-11-22T22:10:26+0000" username="dave.tapley" verified=true>

Find user using email + password in Devise

My Rails app uses data from legacy database. Imported users from this DB contain duplicate emails. Authentication doing with email+password (and it's a unique combination in DB).
Devise uses method find_for_database_authentication to find user. However params don't contain password (just login name).
What can I do?
try this :
find_user = User.where("email = ?", params["user"]["email"]).first
find_user.valid_password?(params["user"]["password"])
You can search this way
in the User model override the find method:
def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
email = conditions.delete(:email)
pwd = conditions.delete(:password)
encrypted_pwd = User.new(password: pwd).encrypted_password
where(conditions).where(["lower(email) = :email AND encrypted_password = :pwd", { :email => email.strip.downcase, :pwd => encrypted_pwd }]).first
end
And probably config/initializers/devise.rb will require smth like:
config.authentication_keys = [ :email, :password ]

Rails 3 respond_with json question

Having trouble with generating some json. I am trying to render an
single active record result to json like this:
#data = User.find(1)
respond_with(#data, :include => :status)
The json result is:
{
-user: {
address: null
email: "test#email.com"
first_name: "Test"
last_name: "Man"
status_id: 1
username: "testguy"
status: { }
}
}
So whats the problem? The problem is that the :include=>:status seems
to not bring over the relation. In my User model I have a
belongs_to :status. How do i get this to work on a single result set?
When I do this:
#data = User.where("id = 1")
respond_with(#data, :include => :status)
The relation shows in the json result set fine this way. But its
within an array of objects, which i do not want.
Any ideas?
I assume that the status you want to include is not one of the http status codes (200, 201, etc.) nor an object associated with the User object in any way and is your own variable.
Using Rails 3.0.10 and Ruby 1.9.2 you may have find one of these two solutions suitable for you. Instead of respond_with use render as follows.
Solution 1
render :json => {:data => #data, :status => "whatever"}
The json result is:
{
data:
{
user:
{
address: null
email: "test#email.com"
first_name: "Test"
last_name: "Man"
status_id: 1
username: "testguy"
}
}
status: "whatever"
}
Solution 2
render :json => {:user => {:address => #data.address, :email => #data.email, ..., :status => "whatever"}}
The json result is:
{
user:
{
address: null
email: "test#email.com"
...
status: "whatever"
}
}
I hope this is what you were looking for.
It sounds like you're having some of the same suffering I experienced with using the built in rails serialization. I ended up using RABL templates which made my life a lot easier. If you need a guide on getting up and running with RABL quickly, I've put one together:
http://blog.dcxn.com/2011/06/22/rails-json-templates-through-rabl/
where returns an array, so your results make sense. You'd need where().first, or since it's just an ID lookup, simply use find.
This was a long time ago, but still, this is the most concise answer:
#data = User.find(1)
respond_with(#data, :include => :status)
You might've solved it by now mate, but if you're still running into probs you can do it this way if you want?
#data = User.find(1, :include => :status)
respond_to do |format|
format.json do
render #data.to_json(:include => :status)
end
end
If that doesn't work there may be something wrong with your associations. There's a really good section in the api on 'Eager loading of associations' here:
http://apidock.com/rails/ActiveRecord/Associations/ClassMethods
As nixterrimus pointed out RABL is really the way to go. It's simple, clean and elegant. I'm relatively new to rails and have not used these techniques (to_json, etc) but having done some research and actually using RABL, I cannot help but wonder why it's not a native feature of Rails.

Resources