Helps
Soap4R and Ruby 1.9.2
"Soap4R and Ruby 1.9.2 don't work, what's the best alternative?"
Several people recommended the Savon gem. It was strongly suggested to not try and replicate any of the Soap protocol because it is pretty painful to implement.
Interestings
Constants versus Immutable Objects
Someone apparently had confusion around what it means to be constant in Ruby, and what it means to be immutable.
A constant prevents modifications to references to variables.
SOME_CONST = 3
SOME_CONST = 4
warning: already initialized constant SOME_CONST
Immutability means that the variables themselves cannot be modified.
an_array = [1,2,3]
an_array.freeze
an_array[3] = 4
RuntimeError: can't modify frozen array
You should note, though, that freezing an object only makes the variables that object contains immutable. For instance,
an_array = [1,2,3,{}]
an_array.freeze
an_array[3]["foo"] = "bar"
will not throw any errors or warnings.
Helps
- "How do you change the address and port that Solr is running on?"
Somewhere in the server.xml file was suggested, however that didn't seem to work. The workaround was using IP Tables.
Interestings
as_json (with options) seems to always be called with an explicit nil argument from to_json under Rails 3. Some people just use as_json explicitly, or pass an explicit empty hash as the arg to get around this oddity.
Jenkins now supports Ruby plugins.
Support Movember! Pivotal has raised quite a bit of money and you can too.
Helps
- "How do you change the address and port that Solr is running on?"
Somewhere in the server.xml file was suggested, however that didn't seem to work. The workaround was using IP Tables.
Interestings
as_json (with options) seems to always be called with an explicit nil argument from to_json under Rails 3. Some people just use as_json explicitly, or pass an explicit empty hash as the arg to get around this oddity.
Jenkins now supports Ruby plugins.
Support Movember! Pivotal has raised quite a bit of money and you can too.
Interesting
rspec
stub != stub!.stub!is an alias method forstub. There is however also a methodstubthat is an alias fordouble. If you try to stub a method on the test class (to stub it on the context), you should probably use the magic subject/helper/controller methods. If you don't, usingself.stub(:name => 'result')will create a double, whileself.stub!(:name => 'result')will stub the method as you would expect.Asynchronous file creation and downloading: if an asynchronous process writes a file using
File.openandf.write, an other process checking the presence of the file to determine whether it is already available for download, will deliver the empty file, if the file has been opened, but not yet written.- Workarounds:
- if you have one write to the file only: check filesize.
- update an ActiveRecord attribute after the file writing is completed and check against that.
- Workarounds:
== on DelegateClass: newing up an instance
delegate_xof DelegateClass from objectx,x == delegate_x, while of coursex.class != delegate_x.class.
Keystroke of the day
- Rubymine KOTD: The search+replace mode you reach via
Cmd+rallows you to see recent searches by hitting the down arrow. If that doesn't work for you in Lion, hitCtrl+h.
James' post from a couple of weeks ago inspired me to write up my own experiences of my first couple of weeks at Pivotal. However, instead of telling you how it felt, I will tell you about stuff I learned.
OAuth providers like LinkedIn often pop-up in a new browser window rather than in Javascript so that the user entering their credentials can see the location bar to be sure they are not being phished by the website requesting their credentials. This is great for security, but not so great for Cucumber testing.
features/signup.feature
Scenario: Sign Up with LinkedIn
When I go to the home page
And I follow "Sign Up"
And I grant LinkedIn access
Then I should be on the new user page
My application has a hyperlink that opens the OAuth login on the OAuth provider's website in a new window. Let's presume the simple matter of wiring this up is already coded in my view.
Testing this with Cucumber requires telling the Selenium web driver to interact with the new popup window. We can do this using page.driver.browser.window_handles to find the newest window handle and scoping out actions to that window.
features/support/signup_steps.rb
When /^I grant LinkedIn access$/ do
begin
main, popup = page.driver.browser.window_handles
within_window(popup) do
fill_in("Email", :with => "newlee@pivotallabs.com")
fill_in("Password", :with => "password")
click_on("Ok, I'll Allow It")
end
rescue
end
end
And that's it!
Keep in mind that if you use this test as-is, you will be hitting LinkedIn on the real Internet. This is great if you want a test that will always verify the real API, but not so good for CI, since it is Internet connection-dependent and slow. Consider using something like VCR or Artifice to stub out your service calls.
A client recently expressed concern with a number of gems added to his project. A quick explanation and a little documentation cleared up what each gem was doing/why we needed it.
This satisfied the client, but it got me wondering: what's the worst thing that could happen from a gem if it was malicious? The worst case I could imagine would be the client's customer's data getting stolen, the customers completely loosing faith in the site, and the client's project failing because of it.
How likely is this to happen? I don't really know.
How hard would it be for someone to do this?
I decided to see what it would take to harvest usernames and passwords from a typical Rails app using Devise for authentication. In less than 5 minutes, I had written an initializer which modified the behavior of the Devise controller to write out usernames and passwords to an HTML file in the public directory of the app.
The code wasn't clever at all. I copied/pasted the create action, and added three extra lines to write out the data to the file.
class Devise::SessionsController < ApplicationController
prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
include Devise::Controllers::InternalHelpers
# POST /resource/sign_in
def create
File.open("#{Rails.root}/public/passwords.html", 'a+') do |f|
f.write("#{params[:user][:email]} #{params[:user][:password]}<br />")
end
...
So the answer to my question, how hard would it be for someone to write a malicious gem that would compromise customer data: dead easy.
I packaged up the code as a gem. Anyone can easily pwn their own Devise Rails app by adding the following line to their Gemfile:
gem 'devise_hack'
Of course, who would install a gem that would pwn their own app? No one, but what about a "long con" approach?
Say I wrote a useful gem, pushed updates occasionally, and got a decent level adoption. At this point I could push a new version of the gem which contained a little hack, and wait for the usernames and passwords to roll in. Maybe like this little guy…
gem 'awesome_rails_flash_messages'
This little gem takes all of your Rails flash messages and makes them more awesome. Simple as that. Ohh, it also logs and requests containing a password to a file AND posts it to an external web service, but that's nothing to worry about.
So how do you avoid these malicious gems? For this dead simple hack, it is dead simple to identify. All you have to do is look at the source code. If you see code that is writing credentials to a file, maybe posting to an external web service, or sending emails when it really shouldn't be... you might want to reconsider using that gem.
Ask for Help
Interesting Things
- Looking for performance patches from ruby 1.9.3 that improve the performance of require? They have been back ported to ruby1.9.2p180.
- A new version of iScroll has been released (v4.1.3). It has performance fixes and better compatibility support. If you need position:fixed or overflow:scroll on a mobile device today you need to check it out.
So I didn't go to whatever was going on in Baltimore this week, but I did do a whole bunch of open source coding over the past week or two:
- TestFirst has a totally revamped design, including the downloadable (or cloneable) student exercises, and Learn JavaScript is now a first-class citizen
- Wrong's
expectalias now plays nicer with RSpec'sexpect - Rerun got a few new command-line options, including
--clearand--exitso you can now easily rerun regular scripts (likererun -cx rake test) when their files change - I submitted a patch to RubyGems to make the warningitis less ZOMG and more KTHXBY
- Fonzie is a bookmarklet that tells you what font you're looking at
- Twitter RSS is a bookmarklet that brings back the RSS link to the New Twitter UI
- Showoff works better with nested bullets and missing
showoff.jsonfiles -- so go nag Scott if you want him to accept my patches;-) - I also finally got my git pre-commit hook correctly stripping whitespace, and
A lot of these projects, especially TestFirst, are aching for improvement, so if you feel like contributing code or courseware, or even just feature requests, please get in touch!
Have you upgraded RubyGems lately? Is your console suddenly filled with warnings like this?
NOTE: Gem::Specification#default_executable= is deprecated with no replacement. It will be removed on or after 2011-10-01.
Gem::Specification#default_executable= called from /Users/chaffee/.rvm/gems/ruby-1.9.2-p0/specifications/thin-1.2.7.gemspec:10.
You may be showing signs of a new malady known as Warningitis! So far there is no cure, but doing the following will temporarily cure your symptoms:
gem update --system 1.7.2
Several experimental treatments are being hastily developed as well, but these have not yet been approved by the FDA. Check the "scary warnings are scary" bug thread for more details.
This has been a public health alert. Please do not panic. SARS masks and iodine pills are not recommended at this time.
