How to Disable the Google Hangouts Menu Bar Icon on OS X

This has been annoying me for weeks now. Google Hangouts would place an menu-bar icon for each instance of Chrome I had running. Repeatedly quitting them didn’t have much effect; they’d keep coming back.

Menu Bar Screenshot

Luckily, there’s an easy way to turn off the menu-bar icons.

  • Open Chrome
  • Menu Bar > Chrome > Preferences
  • Click on Extensions, scroll down to Hangouts, and click on Options
  • Uncheck Show system tray icon
  • Click OK

And that’s it.

Encrypt Your Emails on OS X

Introduction

Now that we know that the American government is probably reading all our email, we should be encrypting all sensitive emails that we send. At the very least, we should be signing all the email that we send, so that it can’t be changed en route.

This guide assumes that you’re using a Mail.app on a Mac, although similar tools exist for Windows and Linux.

First, for those who are unfamiliar with this, here’s an (oversimplified) explanation of how encryption works.

A key is a randomly generated string of characters which is used to encrypt/decrypt your data. Every user has a pair of keys. His public key can be freely shared online. His private key is known only to him, and must be safely stored.

Let’s consider the classic Alice and Bob example.

  • Alice wants to send a message to Bob
  • Alice combines her private key with Bob’s public key to generate a shared secret
  • Alice encrypts her message with the shared secret and sends it to Bob.
  • Now the way this works, the same shared secret can also be generated by combining Bob’s private key and Alice’s public key
  • This means that the message can be decrypted by Bob (assuming he has Alice’s private key)

So, in practice, this means:

  • You need a private/public key pair
  • The person you’re sending email to needs a private/public key pair
  • You need to know the public key of the person you’re sending email to
  • That person needs to know your public key
  • Additionally, your private key is usually encrypted on disk, so you need a password (sometimes called a passphrase) to unlock your private key.

Generating a Key Pair

First, download and install GPG Suite. Then, the GPG Keychain Access application. This should be present in your Applications folder after you install the GPG Suite.

Click on New, and enter your Name and Email address. Upload public key after generation should be checked. You will also need to pick a passphrase to secure your private key on disk.

You should now have a key pair generated for you. To be safe, use GPG Keychain Access to export your key to a file. Make sure that the Allow secret key export option is checked. This makes sure that your private key is exported as well. This will create a file with an asc extension. Keep this file safe!

Remember, if you lose your private key, you cannot read any encrypted mail sent to you, nor can you send any encrypted email. Ditto for your passphrase. I use Arq to backup my private keys and 1Password for my passphrase.

Getting Another Person’s Public Key

You cannot send an encrypted email to someone unless you know their public key.

To do this, open GPG Keychain Access, and press ⌘F to launch the Find dialog. Enter the email address of the person you want to email. Once the search completes, you can import the public key for the email you entered.

You can also do this manually using a key server like http://pgp.mit.edu/

Sending an Encrypted Email

Open/Restart Mail.app. Type ⌘N to compose a new mail. If you set up your keys right, you should see a green OpenPGP on the top right corner of the window.

Once you fill in the To: field with an email address you know the public key for, the little padlock icon on the right should become clickable. Click it.

Padlock Icon

If the padlock is closed, that means that the email you’re about to send is encrypted.

The person you’re sending the email to should be able to view the email as normal (using software like GPG Suite to handle decryption).

If someone else were to try and view the email, this is what they would see:

Un-Decrypted View

Receiving an Encrypted Email

Thankfully, there’s nothing you have to do here, assuming you have the sender’s public key imported into GPG Keychain Access. GPG Suite will automatically decrypt the email and show it to you. It’s seamless!

In fact, here’s what the email from the previous screenshot would look like in Mail.app:

Decrypted Email

Digital Signatures

It might not always be practical/necessary to encrypt all your emails.

However, there is an easy way to avoid MITM attacks (man-in-the-middle attacks, where a third-party could modify the text of the email before it reaches you).

Simply (digitally) sign every email you send. GPG Suite makes this very easy. Just make sure the button next to the padlock is clicked:

Signature Button

Here’s what this does:

  • The text of your message is applied to a one-way function, and a digital fingerprint of your message is obtained.
  • If the text of your message changes even by a single character, this fingerprint ceases to be valid.
  • The fingerprint is signed with your private key, and is attached with the email in a plain-text file called signature.asc
  • The receiver independently calculates the fingerprint of the message, and also decrypts your signature.asc using your public key.
  • If the two match, the email was sent by you, and was not tampered with.

An email client that supports digital signatures (GPG Suite included) will complain if this verification fails.

Pow Over HTTPS

I use Pow to manage web servers on my development machine. It works pretty well. To start my server, I just hit a URL like http://surveyweb.dev, which starts the server (if it isn’t running) and spins it down automatically in 5 minutes.

It doesn’t work over HTTPS by default; here’s how you get that done.

1
$ gem install tunnels

This gem lets you route traffic from one port to another port.

We need to route traffic from port 443, to port 80 (where the Pow server runs).

1
$ sudo tunnels 443 80

While the tunnel is open, I can access https://surveyweb.dev just fine.

Pow also has a feature where I can access my server from another machine on the LAN using a URL like http://surveyweb.192.168.1.10.xip.io/ where 192.168.1.10 is the IP address of my machine. Even with the tunnel open, HTTPS doesn’t work for this URL.

We need to start another tunnel:

1
$ sudo tunnels 192.168.1.10:443 127.0.0.1:80 # Replace 192.168.1.10 with your IP address

And now, both URLs work over HTTPS.

Using RoboGuice to Inject Views Into a POJO

RoboGuice is great. It lets you get rid of code like:

1
2
3
4
5
6
7
8
public class LoginActivity extends Activity {
    private Button mSignInButtonView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mSignInButtonView = (Button) findViewById(R.id.sign_in_button);
    }
}

Instead, with a single line, RoboGuice will take care of injecting that view into your activity:

1
2
3
4
5
6
7
8
public class LoginActivity extends RoboActivity {
    @InjectView(R.id.sign_in_button) Button mSignInButtonView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // I have a reference to mSignInButtonView here.
    }
}

Now we’re rewriting ashoka-survey-mobile as a layered native app). We have a LoginView (POJO) which needs references to views present on-screen. Normally, we would instantiate the POJO in the activity, and pass it all the views it needs.

But can we do this with RoboGuice? We can’t really use @InjectView in a POJO. It needs an Activity context. The next best thing is to inject the activity into the POJO (RoboGuice is smart enough to inject the correct activity), and pick the views manually using findViewById.

So in the activity:

1
2
3
4
5
6
7
8
public class LoginActivity extends RoboActivity {
    @Inject LoginView loginView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        loginView.onCreate(); // Need to manually build up the view references inside LoginView
    }
}

and in LoginView:

1
2
3
4
5
6
7
8
9
10
public class LoginView {
    @Inject Activity activity; // This gets injected with the correct instance of LoginActivity
    private Button buttonView;
    private EditText editText;

    public void onCreate() {
        buttonView = activity.findViewById(R.id.my_button);
        editText = activity.findViewById(R.id.my_edit_text);
    }
}

And then your POJO can manipulate the views that are on-screen as required.

Recursive Postgres Queries

Introduction

At Nilenso, I’m working on an (open-source!) app to design and conduct surveys.

Here’s a simple survey being designed:

Survey Builder Overview

Internally, this is represented as:

Survey Model Overview

A survey is made up of many questions. A number of questions can (optionally) be grouped together in a category. Our actual data model is a bit more complicated than this (sub-questions, especially), but let’s assume that we’re just working with questions and categories.

Here’s how we preserve the ordering of questions and categories in this survey.

Each question and category has an order_number field. It’s an integer that specifies the relative ordering of itself and its siblings.

For example, in this case,

Order Number Overview

the question Bar will have an order_number that is less than the order number of Baz.

This guarantees that the a category can fetch its sub-questions in the right order:

1
2
3
4
5
# In category.rb

def sub_questions_in_order
  questions.order('order_number')
end

In fact, this is how we fetch the entire survey at this point. Each category calls sub_questions_in_order on each of its children, and so on down the entire tree.

This gives us a depth-first ordering of this tree:

Naive Ordering

For large surveys with 5+ levels of nesting, and more than a hundred questions, this is pretty slow.

Turning Your Local Git Repo Into a Remote

Need to pull some changes from a friend’s local Git repo without having to push to origin? This post will show you how to do that.

You can access a local Git repo using SSH, but setting up keys and such will probably take some time. For a quick-and-dirty solution, HTTP is much easier.

On the machine you want to use as the server, navigate to your project and then into the .git directory.

1
2
$ cd /path/to/project
$ cd .git

Stand up a HTTP server using Python’s SimpleHTTPServer module. You can use any port number you like.

1
$ python -m SimpleHTTPServer 5000

You’ll need the IP address of this machine as well. (Use ifconfig)

Make sure you can access the python server from a browser on the client machine. You should be able to see something like this at http://ip.address:5000/

Python Server Browser Screenshot

On the client, you should be now able to access the git repo over HTTP as though it were a normal git remote.

1
2
$ git ls-remote http://ip.address:5000
$ git pull http://ip.address:5000 master

Add it as a remote to avoid typing out the entire IP each time.

1
2
$ git remote add http://ip.address:5000 local-foo
$ git pull local-foo master

Writing Custom RSpec Matchers

RSpec matchers let you abstract away common assertions in your test code.

For example, we recently had a spec file with a bunch of lines that looked like this:

1
worksheet.rows[0].cells.map(&:value).should include "Foo"

Which tests if the excel file we’re generating (using axlsx) includes Foo in the header row.

That isn’t very neat. What if we replace it with this?

1
worksheet.should have_header_cell "Foo"

That looks a lot better. We can implement this kind of abstraction using custom RSpec matchers.

The matcher for this is as simple as:

1
2
3
4
5
RSpec::Matchers.define :have_header_cell do |cell_value|
  match do |worksheet|
    worksheet.rows[0].cells.map(&:value).include? cell_value
  end
end

RSpec passes in the expected and actual values to these blocks, and our code has to return a boolean representing the result of the assertion.

Now what about assertions that look like this?

1
2
3
worksheet.rows[1].cells.map(&:value).should include "Foo"
worksheet.rows[2].cells.map(&:value).should include "Bar"
worksheet.rows[3].cells.map(&:value).should include "Baz"

The row that we’re checking changes for each assertion. Of course, we could create a different matcher for each of these cases, but there’s a better way.

1
2
3
worksheet.should have_cell("Foo").in_row 1
worksheet.should have_cell("Bar").in_row 2
worksheet.should have_cell("Baz").in_row 3

RSpec lets you chain custom matchers.

1
2
3
4
5
6
7
8
9
10
11
12
13
RSpec::Matchers.define :have_cell do |expected|
  match do |worksheet|
    worksheet.rows[@index].cells.map(&:value).include? expected
  end

  chain :in_row do |index|
    @index = index
  end

  failure_message_for_should do |actual|
    "Expected #{actual} to include #{expected} at row #{@index}."
  end
end

We first store the argument passed in to in_row as an instance variable, and then access it in the main have_cell matcher.

The example also includes a custom error message handler, which properly formats an error message if the assertion fails.

YAML Serialization for Delayed Job

When we first moved excel generation off to a delayed job on survey-web, we had code that looked like this:

1
2
responses = Response.where(:foo => bar)
Delayed::Job.enqueue(MyCustomJob.new(responses))

And this would bomb with an error like Can't dump anonymous Module. After some time getting nowhere, we solved it like this:

1
2
response_ids = Response.where(:foo => bar).map(&:id)
Delayed::Job.enqueue(MyCustomJob.new(response_ids))

And in the job:

1
responses = Response.where('id in (?)', response_ids)

While refactoring a lot of that code over the last few days, we ran into the same issue. But with one difference. A controller spec was failing, but a test for the job which also passed a bunch of responses into it passed.

We wondered if maybe it was because we were passing a relation into the job instead of an array.

So we tried:

1
2
responses = Response.where(:foo => bar).all
Delayed::Job.enqueue(MyCustomJob.new(responses))

And that worked great.

(The files in question are here and here).

Changing the Server Timeout on EngineYard

While working on survey-web today, we were stuck for a really long time trying to figure out this problem.

Unless otherwise specified, image uploads while adding a response are capped at 5MB per image. Adding a larger image (like this 20MB image) should result in a validation error showing up.

Validation Error

On production, we’d see this.

Production

After a lot of digging, including looking at Carrierwave (and Backgrounder), delayed_job server logs, and our controller logic pretty closely, we noticed in production.log that Rails was sending down a 200, but the browser was recieving a 502.

unicorn.log showed that a worker process was being killed with a SIGIOP whenever the error page showed up.

Only then did we realise that the worker was being killed around 60s every time. It had to be a timeout issue.

On EngineYard, the unicorn config already had:

1
2
3
4
5
6
7
8
# sets the timeout of worker processes to +seconds+.  Workers
# handling the request/app.call/response cycle taking longer than
# this time period will be forcibly killed (via SIGKILL).  This
# timeout is enforced by the master process itself and not subject
# to the scheduling limitations by the worker process.  Due the
# low-complexity, low-overhead implementation, timeouts of less
# than 3.0 seconds can be considered inaccurate and unsafe.
timeout 180

The server didn’t seem to be following this configuration.

After a fair bit of googling and help from the #engineyard IRC channel, this is what we did to fix it. Add the following lines to /data/nginx/nginx.conf inside the http{} block (replacing 300 with the timeout you need).

1
2
3
client_header_timeout 300;
client_body_timeout 300;
send_timeout 300;

And restart nginx/unicorn with

1
2
$ sudo /etc/init.d/nginx reload
$ /engineyard/bin/app_<app_name> reload

Use Lambdas for Date-based Rails Scopes

A scope allows you to specify an ARel query that can be used as a method call to the model (or association objects).

1
2
3
4
5
6
class Item
  scope :delivered, where(delivered: true)
end

Item.delivered.to_sql                     # SELECT "items".* FROM "items"  WHERE "items"."delivered" = 't'
Item.where(price: 2000).delivered.to_sql  # SELECT "items".* FROM "items"  WHERE "items"."price" = 2000 AND "items"."delivered" = 't'

There’s a problem if we try using a scope for a relative date, though.

1
2
3
class Item
  scope :expired, where("expiry_date < ?", Date.today)
end

This code gets evaluated when the server is started, and the output of Date.today is stored in the scope.

That scope is equivalent to the following:

1
2
3
4
5
class Item
  def self.expired
    where("expiry_date < ?", "2013-04-01")
  end
end

The date is hardcoded in there, and will not be changed until the scope is re-evaluated. This typically happens only when the server is restarted.

To get around this problem, use a lambda when defining date (or time) based scopes. This will force the evaluation of the scope each time it is called.

1
2
3
class Item
  scope :expired, lambda { where("expiry_date < ?", Date.today) }
end