ArgumentError (wrong number of arguments (2 for 1)): /usr/lib/ruby/gems/1.8/gems/json-1.1.3/lib/json/pure/generator.rb:251:in `to_json' /usr/lib/ruby/gems/1.8/gems/json-1.1.3/lib/json/pure/generator.rb:251:in `json_transform' /vendor/plugins/juggernaut/lib/juggernaut.rb:105:in `map' /usr/lib/ruby/gems/1.8/gems/json-1.1.3/lib/json/pure/generator.rb:245:in `each' /usr/lib/ruby/gems/1.8/gems/json-1.1.3/lib/json/pure/generator.rb:245:in `map' /usr/lib/ruby/gems/1.8/gems/json-1.1.3/lib/json/pure/generator.rb:245:in `json_transform' /usr/lib/ruby/gems/1.8/gems/json-1.1.3/lib/json/pure/generator.rb:218:in `to_json' /vendor/plugins/juggernaut/lib/juggernaut.rb:114:in `send_data' /vendor/plugins/juggernaut/lib/juggernaut.rb:108:in `each' /vendor/plugins/juggernaut/lib/juggernaut.rb:108:in `send_data' /vendor/plugins/juggernaut/lib/juggernaut.rb:50:in `send_to_client_on_channel'
Adding require "json/add/rails" to vendor/plugins/juggernaut/lib/juggernaut.rb solved the problem. This file has a call to to_json.
Wednesday, August 27, 2008
Tip: ArgumentError when using to_json in Rails.
Posted by
Sonal
at
5:14 PM
0
comments
Links to this post
Labels: ArgumentError, json_pure, juggernaut plugin, Ruby on Rails, to_json
Sunday, August 10, 2008
Google Accounts Authentication using Ruby on Rails and Secure Authsub (Gmail contacts API)
I was able to set up the non-secure authentication after reading Tom Hunter's blog post about Google Contacts API authentication. If you use non-secure authentication Google shows a warning to the user about insecure authentication etc. which may not be a good thing. But getting the secure version to work was a pain in the $%&& to say the least. Anyway, after getting some pointers in Google groups, things got rolling.
- Register your app with Google. For secure authentication, you also need to provide an X.509 certificate to Google, which can be uploaded from the same link.
- To generate this certificate read the instructions given by Google and use the openssl command: # Generate the RSA keys and certificate
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj \
'/C=US/ST=CA/L=Mountain View/CN=www.example.com' -keyout \
myrsakey.pem -out /tmp/myrsacert.pem - The above command will generate 2 files, one in your current directory (myrsaky.pem, which is the private key) and the other in /tmp (myrsacert.pem) which is the certificate to upload. Remember to input your company or website information in the command instead of example.com's. Also remember to upload the 'certificate' and not the 'private_key' file.
- In the code below, callback_url is the link you provide on your Manage Domains form to Google, along with the certificate.
- When someone clicks 'Invite contacts', they get directed to the url of the init action. From there, they are shown the Google login page if they are not logged in to their Google account. After that they are shown the page on which they can choose to authorize you to import their gmail contacts.
- If you place the private key file in config folder of the app, then you can refer to it as shown in the method sign_data.
- Here's the code: (this is my rough draft of the code, so it may not be the most efficient piece of code on earth, but it works for me for now)
class GauthController (greater_than) ApplicationController
require 'uri'
require 'net/http'
require 'net/https'
require 'rexml/document'
def init
callback_url = "http://guitarati.com/gauth/authsub"
next_param = URI.escape(callback_url, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
scope_param = "https%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F"
secure_param = "1"
session_param = "1"
root_url = "https://www.google.com/accounts/AuthSubRequest"
query_string = "?scope=#{scope_param}&session=#{session_param}&secure=#{secure_param}&next=#{next_param}"
redirect_to root_url + query_string
end
def authsub
token = params[:token] # received the single-use authsub token, exchange for authsub session token
url = "https://www.google.com/accounts/AuthSubSessionToken"
headers = set_headers(url, token)
http = Net::HTTP.new('www.google.com', 443)
http.use_ssl = true
path = '/accounts/AuthSubSessionToken'
resp, data = http.get(path, headers)
if resp.code == "200"
token = ''
data.split.each do str
if not (str =~ /Token=/).nil?
token = str.gsub(/Token=/, '')
end
end
redirect_to "http://guitarati.com/gauth/import?token=#{token}"
else
redirect_to "http://guitarati.com/"
end
end
def import
token = params[:token]
#http = Net::HTTP.new('www.google.com', 80)
http = Net::HTTP.new('www.google.com', 443)
http.use_ssl = true
#path = "/m8/feeds/contacts/default/base?max-results=10000"
path = "/m8/feeds/contacts/default/base"
url = "https://www.google.com" + path
headers = set_headers(url, token)
resp, data = http.get(path, headers)
xml = REXML::Document.new(data)
contacts = []
xml.elements.each('//entry') do entry
person = {}
person['name'] = entry.elements['title'].text
gd_email = entry.elements['gd:email']
person['email'] = gd_email.attributes['address'] if gd_email
contacts << text =""> "#{contacts.inspect}"
end
private
require 'base64'
require 'openssl'
include OpenSSL
include PKey
include Digest
def sign_data(data)
private_key = OpenSSL::PKey::RSA.new(File.read("config/myrsaky.pem"))
sig = private_key.sign(OpenSSL::Digest::SHA1.new, data)
return Base64.b64encode(sig).gsub(/\n/, '')
end
def set_headers(url, token)
time = Time.now.to_i.to_s
nonce = OpenSSL::BN.rand_range(2**64)
data = "GET #{url} #{time} #{nonce}"
sig = sign_data(data)
return {'Authorization' => "AuthSub token=\"#{token}\" sigalg=\"rsa-sha1\" data=\"#{data}\" sig=\"#{sig}\""}
end
end
Friday, August 1, 2008
Installing and using Juggernaut on Windows
NOTE: After I wrote this post, I came across an article which seems pretty useful. Please refer to it for installing Juggernaut on Windows. It is different from the post below mainly in that it tells you to use json_pure instead of json. Here is the link: http://wiki.mintworx.com/index.php/How_to_Setup_juggernaut_on_windows
- Juggernaut requires Rails version of 2.0.2. I haven't tried with any lower version, so I've no idea if there might be some problems using it there.
- Start out: gem install eventmachine
- Then: gem install juggernaut --include-dependencies. Adding include-dependencies will try to install json along with juggernaut. The version of json available for Windows at the time of writing this is 1.1.1. Juggernaut gem has a requirement that the version of json must be >= 1.1.2. So installing the gem along with dependencies does not go through as this requirement puts a spanner in the works. Instead, use this: gem install --ignore-dependencies, which should go through fine. Before/after this, install json on your own.
- While installing json (gem install json) it asks you the version you want to install. Select 1.1.1 (ms-win32).
- Install plugin: ruby script/plugin install http://juggernaut.rubyforge.org/svn/trunk/juggernaut
- So by now, eventmachine, json, juggernaut gem and juggernaut plugin are installed.
- Time to configure the gem. Typing juggernaut -g juggernaut.yml to configure the gem fails with the error about your json version not being >= 1.1.2. To get past this, edit this file (thanks Google desktop!) ...\ruby\lib\ruby\gems\1.8\specifications\juggernaut-0.5.4.gemspec and try configuring again.
s.add_dependency(%q eventmachine, [">= 0.10.0"])
s.add_dependency(%q json, [">= 1.1.2"]) # ---- changed this to 1.1.1
s.add_dependency(%q hoe, [">= 1.5.1"]) #--- changed this to 1.3.1 - Then start juggernaut. juggernaut -c juggernaut.yml
- Look at Juggernaut README and cool RoR chat with Juggernaut for tips and code examples.
