
Calling all vimmers!
Mark your calendars, clear your registers, and follow the leader to the first Boston Vim Meetup.
On October 24th at 7pm, passersby of the thoughtbot office (41 Winter St #8, 02108) will wonder aloud at the audible “Om”ing of programmers in vim nirvana. This enlightened evening will feature talks by Mike Burns, Ben Orenstein, and Gabe Berke-Williams. Attendees will see useful vim techniques revealed, emacs users sassed, and food and drink provided.
Come to learn, or bring your own lighting talk (which must adhere to our strict “no slides” rule. Yes, really.) No registration required. Neckbeards optional.
Questions? Hit the comments.
:qa!
Recently, I created thoughtbot Foursquare lists to help out-of-town workshops students find hotels, coffee shops, and bars.
In the process, I noticed Foursquare has an “act as” feature:

It lets you, well, “act as” another user:

It caught my eye because I had recently implemented a similar feature for a client. I named it with slightly more aplomb: “masquerading.”
Here’s what we wanted:
Given a user exists with email "bobby@example.com" and name "Bobby Tables"
And an admin with email "admin@example.com"
When I sign in as "admin@example.com"
Then I should see "Bobby Tables"
When I follow "Masquerade" within the "bobby@example.com" row
And I should see "Now masquerading as Bobby Tables"
And I should see "Hi Bobby" within the navigation
When I follow "Stop Masquerading"
Then I should be on the admin page
The context is that I’m an admin. A user is on the phone with me right now with support questions. I quickly find their account and see the app through their eyes.
In app/views/admin/users/index.html.erb:
<% @users.each do |user| %>
...
<%= link_to 'Masquerade', new_user_masquerade_path(user) %>
<% end %>
In config/routes.rb:
resources :users, only: [:edit, :update] do
resources :masquerades, only: [:new]
end
Nothing crazy so far.
In app/controllers/masquerades_controller.rb:
class MasqueradesController < ApplicationController
before_filter :authorize, :authorize_admin
def new
session[:admin_id] = current_user.id
user = User.find(params[:user_id])
sign_in(user)
redirect_to home_path, notice: "Now masquerading as #{user.name}"
end
def destroy
user = User.find(session[:admin_id])
sign_in :user, user
session[:admin_id] = nil
redirect_to admin_users_path, notice: "Stopped masquerading"
end
end
The masquerading controller actions are restricted to admins by before filters provided by the authentication library and the developer.
The create action switches the user ids and signs in as the user. Put your mask on because we’re masquerading.
When the customer support session is over, we’ll want to return to the admin views. In app/views/shared/_navigation.html.erb:
<% if masquerading? %>
<%= link_to "Stop Masquerading", "#" %>
<% end %>
In application_controller.rb:
def masquerading?
session[:admin_id].present?
end
helper_method :masquerading?
We define that in a controller, then expose it as a helper method to the views, so that we can alter the authorize_admin method that is used as a before_filter:
In application_controller.rb:
def authorize_admin
current_user.admin? || masquerading?
end
That way, the MasqueradesController stays protected, even when you’re signed in as a non-admin user during a masquerade.
We aren’t using this technique on our own products right now. One concern is that on many apps, the customer’s view could reveal sensitive data. Airbrake, for example, would require at minimum asking the person “may I act as your account?”
Heroku’s ZenDesk support form does something similar: “May we access your application code? Check here to allow us to clone and/or inspect your code for debugging purposes.”
However, I like the idea of providing better support by viewing the app as our customers do.
Written by Dan Croak.
Antonio Rodriguez of Matrix Partners has spoken on the advantages of early stage web startups in which everybody codes, including “business people”.
In this context, “coding” might mean activities like:
Antonio graciously agreed to record a 10-minute video on the topic. He’s interviewed by Brendan Schwartz of Wistia, the makers of the famed video heatmap.
Update: Antonio wrote a followup to our post on Business Insider.
Written by Dan Croak.
Design With Boston is a new meetup for web designers in and around the Boston area. It will be held at 7PM on the first Thursday of every month at the thoughtbot offices. We are located at 41 Winter Street, 3rd Floor, 02108. Everyone with an interest in web design is welcome, from beginners to experts.
Doors open at 7. Around 7:30 we’ll have a short 30 minute presentation from a scheduled speaker. The inaugural meetup will be featuring Jay Contonio speaking about the importance of content in a talk titled “Content isn’t lorem ipsum.” If you’re interested in speaking you can message me on twitter, drop me a line, or just catch me in person. Following the talk we’ll have some food delivered and hang out till you feel like leaving. Bring your laptop if you’d like to share any work or even help others work on their projects. If you’re familiar with the boston.rb hackfests our design meetups will be structured the same way, but for us designers.
This meetup was born in order to solve a few different problems I have. First and foremost, I know there are many talented and interesting web designers around Boston but I don’t know enough of them personally. This is something that I’ve always wanted and instead of waiting to run into designers one at a time here and there, I’m organizing this event to facilitate new connections.
Another problem I’ve had as a local, successful, and fully employed web designer is having many companies or individuals seeking my help in finding good web designers to employ. Most of these jobs would appeal to me if I were looking for work so I’m always eager to help other designers in need. Sadly, I often don’t know of any designers looking for work but surely there are plenty of web designers looking for new opportunities. Hopefully some great work can be found through our meetups.
My final reason for putting this event together is to grow and become a better designer by surrounding myself with other good designers. I work with 4 great designers and talk to numerous others online daily. However, I feel that being able to mingle with a multitude of web designers face to face will prove to be invaluable.
If you want to come just checkout the site and click “I’m Coming!” or “RSVP”. It will authenticate with your twitter account and add your twitter handle to a list of people that have also RSVP’d.
Be sure to follow our twitter account for any changes in the schedule, location, or important news about the monthly meetup. Thanks for your interest!
Our event, Developers Developers Developers Developers, is this weekend.
When the amount of registrations reached the capacity of the venue, we removed the registration form from the website.
However, we left the Rails route and controller around and encouraged students to register by reading the source code of the application and coding their way in. We pointed them to the staging app so they could practice before registering via the production app.

So we just need to POST to /registrations with the right params, right? Right. However, “the right params” needs to include Rails’ authenticity_token, which the framework uses to combat CSRF. The payload also needs to include a cookie because the authenticity_token depends on it.

So here’s the cURL solution.
Step 1:
curl http://dddd-staging.heroku.com --cookie-jar cookie | grep csrf
That will store the cookies in a file named “cookie” and print out the authenticity_token you need (it’s the value of the content attribute on the csrf-token meta tag):
<meta name="csrf-param" content="authenticity_token"/>
<meta name="csrf-token" content="sNMk592JV2wwHn6DPJ8C5oy/hHDnjIlZBOHyngtTbpQ="/>
Meanwhile, the contents of the cookies file looks like this:
# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This file was generated by libcurl! Edit at your own risk.
#HttpOnly_dddd-staging.heroku.com FALSE / FALSE 0 _dddd_session BAh7ByIQX2NzcmZfdG9rZW4iMXdNWm5kUWRLWGRWWGlUZSswT0VFRFN6NHl5dkNWL1NuLzZ1alh3c2lndU09Ig9zZXNzaW9uX2lkIiUwNzNmYmI2MTA0MmI5ZTgxNmUxODA0MzJhOTIyNTk2Yw%3D%3D--fb9ee7c9f96cea60d7be43ff87ce1ac9a8e53548
Step 2:
curl http://dddd-staging.heroku.com/registrations --data "registration[name]=Dan Croak®istration[twitter]=croaky®istration[school_name]=Holy Cross®istration[role]=Developer&authenticity_token=sNMk592JV2wwHn6DPJ8C5oy/hHDnjIlZBOHyngtTbpQ=" --cookie cookie
This adds the authenticity_token and also includes the cookie from the first request.
The output will be the original HTML that we fetched and replaced on the page via Ajax when registration was still open:
<div class="student">
<div class="avatar">
<img src="http://avatar.statusok.com/croaky?size=73" />
</div>
<div class="student-details">
<div class="name">Dan Croak</div>
<div class="twitter">@croaky</div>
<div class="role-and-school">
Developer, Holy Cross
</div>
</div>
<h2>Thanks for registering! We can't wait to see you!</>
<h3>Follow @<a href="http://twitter.com/thoughtbot">thoughtbot</a> and @<a href="http://twitter.com/greenhornboston">greenhornboston</a> for updates.</h3>
<h3>We also invite you to join our private <a href="http://groups.google.com/group/developers-developers-developers-developers">mailing list</a> for speakers and attending students.</h3>
</div>
However, we’re living in the future here, folks. It’s 2011, and we’ve got a GUI for everything - no need to get Terminal all over your hands.

So let’s load the site normally in a web browser, view the HTML source to grab that authenticity token, insert a form into the DOM, then submit it.
I’ll be using Chrome and the WebKit Inspector here, but you could also use Firefox and the excellent Firebug plugin.
Step 1: Find the authenticity token
Here I view the HTML source and look for the authenticity token in the element:

Step 2: Insert a form into the HTML
Here’s the registration form that we’ll add back into the page. I made sure to insert the right authenticity token:
<form action="/registrations" method="POST">
<input type="text" name="registration[name]" value="Jason Morrison" />
<input type="text" name="registration[twitter]" value="jayunit" />
<input type="text" name="registration[school_name]" value="RIT" />
<input type="text" name="registration[role]" value="Developer" />
<input type="text" name="authenticity_token" value="iKSXdP4+Ir80ABwsmwvX5LjUKdto3n6p99E/+pgmegI=" />
<input type="submit" />
</form>
You can insert the form anywhere. Let’s overwrite this paragraph:

Paste in the HTML:

Step 3: Submit the form
Click submit, and you’re off to the races.

See you at the event!