giant robots smashing into other giant robots

Written by thoughtbot

codeulate

Boston Vim Meetup

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!

0

dancroak

How to masquerade as another user to see how they use your app

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:

foursquare masquerade

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

foursquare masquerade

It caught my eye because I had recently implemented a similar feature for a client. I named it with slightly more aplomb: “masquerading.”

Ingredients

  • an authentication library
  • aplomb

Recipe

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 .

dancroak

Everybody Codes

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:

  • Adding Javscript snippets for analytics tools to the app.
  • Writing SQL queries on a read-only database.
  • Writing HTML and CSS to change a layout a customer found confusing.
  • Committing to version control.
  • Deploying to staging.

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 .

fyates

Introducing: Design With Boston

Design With Boston

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.

The Format

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.

Why

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.

Want to Come?

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.

Stay up to date

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!

dancroak

cURLing with Rails’ authenticity_token

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.

D8 registration challenge

Rails’ authenticity_token

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.

Curling

cURL

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&registration[twitter]=croaky&registration[school_name]=Holy Cross&registration[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>

Another Approach: Using Web Inspector

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.

This is a web browser, I know this

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:

Auth Token

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:

Edit HTML

Paste in the HTML:

Pasted HTML

Step 3: Submit the form

Click submit, and you’re off to the races.

Form Success

See you at the event!