Santiago Palladino

Santiago Palladino

Santiago, also known as Palla, is a highly pragmatic dev lead, perfectionist and efficient, motivated mostly by back-end challenges. In Computer Science at UBA, he is known for being a hard TA to his numerical methods students. His preferred topic, and the subject of his master thesis, is linear programming and operations research.

Extracting Subject Alternative Name from Microsoft authentication client certificates

Among the client certificates present in an HSPD-12 smart card, you may find a Windows Smart Card Login certificate used for authentication, which has several particularities, one of them being storing the Subject Alternative Name (this is, the Windows logon and domain of the card’s owner) in an ASN1-encoded UTF8 string in a Microsoft extension (OID 1.3.6.1.4.1.311.20.2.3).

What does this mean? This means that if you attempt to extract the subject alternative name from the certificate using Ruby’s OpenSSL::X509 library in the usual way, you’ll get a string reading simply “unsupported”.

1 2 3 4 5 6 7 8 9
cert = OpenSSL::X509::Certificate.new(certificate_string)
subject_alt_name = cert.extensions.find {|e| e.oid == "subjectAltName"}
return subject_alt_name.value
 
# On a standard certificate...
# 'email:user@example.com'
 
# On a MS certificate...
# 'othername:<unsupported>, othername:<unsupported>'
view raw san.std.rb hosted with ❤ by GitHub

Note that the value returned is a string indeed, not an exception; this is because the underlying unix openssl library, which is wrapped by the Ruby one, returns exactly that value.

In order to properly extract the owner’s identification, you’ll need to parse the certificate using OpenSSL::ASN1 and going through the hierarchy. The element you are looking for has key “msUPN”, this is, Microsoft User Principal Name.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
cert = OpenSSL::X509::Certificate.new(certificate_string)
subject_alt_name = cert.extensions.find {|e| e.oid == "subjectAltName"}
 
# Parse the subject alternate name certificate extension as ASN1, first value should be the key
asn_san = OpenSSL::ASN1.decode(subject_alt_name)
raise "Expected ASN1 Subject Alternate Name extension key to be subjectAltName but was #{asn_san.value[0].value}" if asn_san.value[0].value != 'subjectAltName'
 
# And the second value should be a nested ASN1 sequence
asn_san_sequence = OpenSSL::ASN1.decode(asn_san.value[1].value)
 
# Iterate through the ASN1 sequence looking for the msUPN key
asn_san_sequence.each do |asn_data|
# As before, first value is the key
key = asn_data.value[0].value
next if key != 'msUPN'
# And second value contains the actual data, return it if the key was msUPN
email = asn_data.value[1].value[0].value
return email
end
 
# Raise if we iterated through the sequence and did not find the key
raise "Extension msUPN not found"
view raw san.msupn.rb hosted with ❤ by GitHub

This way, you can set up a solution that works with both Microsoft based certificates and standard X509 authentication certificates.

Please comment if you have found other ways for working with these certificates, I’d love to see other implementations using Ruby’s OpenSSL or any other OpenSSL-based library!

[Many thanks to Ed Magidson for his help in understanding and working with these certificates!]

Organizing coffeescript code in a Rails 3 app

Ever since Rails 3.1 adopted coffeescript within the asset pipeline as a default, coffescript has become an increasingly popular language for easily writing your javascript code.

Despite a lot of tutorials out there on how to write coffee and take advantage of the Rails asset pipeline, there are rather few guidelines on how to properly organize your code using these technologies; so let me outline a few techniques we have been using on some of our projects, such as Verboice and ResourceMap (both of them open source, so feel free to check them out).

Knowing when to execute

One of the key features of the asset pipeline is that all your js code is concatenated, minified and compressed into a single file, with aggresive client-side caching, so that the user only needs to download a single file the first time she visits your site.

However, this will imply that all of your javascript code will execute on every page in your site, unless you do something to prevent it. An easy way to solve this is to simply execute if there is a particular object in your DOM:

1 2 3
if $('#my_div_in_complex_page').length > 0
class Foo
...
view raw blog01.js.coffee hosted with ❤ by GitHub

Eventually, if you find yourself relying too much on a particular object which indicates a complex functionality is required, you can abstract that to a global function, and use it whenever you need it:

1 2 3 4 5 6 7
# on a global functions file
@onComplexFunctionality = (callback) -> $(-> callback() if $('#my_div_in_complex_page').length > 0)
 
# when you need to use it
onComplexFunctionality >
class Foo
...
view raw blog02.js.coffee hosted with ❤ by GitHub

A more comprehensive approach is the one explained here, which allows you to specify particular code to execute for each controller and each action without needing to rely on a particular DOM object or defining an “onFunctionality” function.

Basically, it works by defining functions in a global object with names that match controllers and their actions, such as:

1 2
Site.users.index = () ->
# your code for users/index here...
view raw blog03.js.coffee hosted with ❤ by GitHub

Modify your application’s template so it renders as data attributes of the HTML body which are the controller and action executed:

1
<body data-controller="<%= controller_name %>" data-action="<%= action_name %>">
view raw blog04.html.erb hosted with ❤ by GitHub

And load that information from an executor function that runs on page load, executing the function that matches the current controller and action.

This approach, although it requires a larger setup, works very well for large applications, in which you have clearly separated behaviours in different pages of your app. Otherwise, relying on a simple check for a certain DOM element is a clean solution.

One class per file

One of the goodnesses of coffeescript is that it isolates each unit of code in a separate context, and makes each function local to that particular context, to avoid those pesky global functions so ubiquitous in traditional javascript. If you want to split the behaviour for a particular page in multiple files, if you are using any of the techniques described above, you will run into the problem that whatever classes you defined in file A.js.coffee within a callback at onCondition, will not be visible within the code you write in B.js.coffee in a similar callback.

If you want a class to be usable outside the context in which it is defined, the key is to define it as an attribute of the global window object, as described here:

1 2
class window.Foo
# your code for the class...
view raw blog05.js.coffee hosted with ❤ by GitHub

Even more succint, you can use the “@” syntax, as it will always refer to ‘this’, which, when defining the class, will be the global object:

1 2
class @Foo
# your code for the class...
view raw blog06.js.coffee hosted with ❤ by GitHub

This will allow you to refer to class Foo from any other file in your application easily. But what happens when you need to refer to class Foo before it has been defined, such as when you need to inherit from it? Consider the following case:

1 2 3 4 5 6 7
# in file A.js.coffee
class @A extends B
# fails because B has not been defined yet
 
# in file B.js.coffee
class @B
# is defined after A as this file is processed after A.js.coffee
view raw blog07.js.coffee hosted with ❤ by GitHub

What you need to do is to instruct sprockets that file B.js.coffee needs to be included before file A. Considering your sprockets application.js file is probably simply doing a require_tree of the entire assets/javascripts folder, you want to keep this file as simple as possible, keeping the directive of including B before A within A or B.

As the require directive in sprockets will include the file only if it has not been included yet, you can simply add a require directive for file B at the beginning of A:

1 2 3 4 5 6 7 8
# in file A.js.coffee
#= require B
class @A extends B
...
 
# in file B.js.coffee
class @B
...
view raw blog08.js.coffee hosted with ❤ by GitHub

This way, sprockets will execute the following flow:

  1. Starts from application.js, reads the require_tree directive and starts processing all files in the tree
  2. First file in the tree is A.js.coffee, but begins with a directive to include B first
  3. Includes file B.js.coffee, as specified by the directive in A
  4. Proceeds to include the contents A.js.coffee
  5. Continues processing the remaining files in the tree, skipping B.js.coffee as it has already included it

Also, in the case you want to have a file containing certain global functions or classes, which will be used by other files in your app, you can take advantage of sprockets loading order.

Although you can use a require global directive at the beginning of each of your files, if you keep yout ‘global’ code in the root of your javascripts directory and all page-specific files organised in folders, sprockets’ require_tree directive will first load the files in the root of the directory, and then proceed with the sub-folders.

Another simple alternative is to add a require path/to/globals instruction before the require_tree in application.js, but you will have to follow this procedure for each global or shared file you add.

Wrapping up

There are lots of different techniques you can use to split your coffeescript code in different files and keep it organised. The key concepts to keep in mind when doing so are:

  • You have to prepend @ to a class name if you want to use it from a different context
  • Be careful when writing code that depends on something defined in a different file, make sure to require it or ensure that sprockets will load it before
  • All your javascript code will always execute unless you execute it conditionally based on the HTML being rendered

Hope it helps!

How to check if object can be destroyed if it has dependent: restrict associations

Rails provides several handy options for specifying how to deal with associated models upon deletion, for example:

class Blog
  has_many :posts, :dependent => :destroy
end

The destroy value for the dependent option will call the destroy method for every post in the blog when the blog itself is destroyed. Other options are delete or nullify, but the one we are interested in is restrict.

By specifying a relation as dependent restrict, Rails will prevent us from destroying a particular object if it has any associated objects. In the example, we would not be able to destroy a Blog if it has any Posts. It is implemented simply, by raising an ActiveRecord::DeleteRestrictionError if there is any associated object.

Now, this works perfectly for preventing us from accidentally destroying an object, but we will usually want to check if we can destroy it beforehand, this is, when rendering a page to the client with a big bad delete button. Showing a delete button only to show an alert box with a “Could not delete” annoying message is certainly not a good practice, we should simply not draw the delete button in the first place.

How do we check this? We could manually check if each and every one of the associations we have marked with dependent restrict in the object are empty, but taking Rails DRY principle into account, we would like to automatically get that information from the object.

Luckily, ActiveRecord provides reflection methods for obtaining info on the associations. Therefore, given an object, we can iterate its associations, and check if the restricted ones are empty or not.

This all boils down to this small method, which can be placed as an initializer in the Rails app:

class ActiveRecord::Base
  def can_destroy?
    self.class.reflect_on_all_associations.all? do |assoc|
      assoc.options[:dependent] != :restrict || 
        (assoc.macro == :has_one && self.send(assoc.name).nil?) || 
        (assoc.macro == :has_many && self.send(assoc.name).empty?)
    end
  end
end

That’s it! Now you can simply make a small helper method that renders a destroy link if can_destroy?, or a plain span notifying the user why she cannot destroy the object.

Default request parameters in Rails functional tests

I was looking for an easy way to force every request in a functional test in Rails to use a set of parameters by default, regardless of being specified explicitly. This is, every time I write:

it "should get index" do
  get :index
end

Rails should actually do:

it "should get index" do
  get :index, :foo => 'value'
end

Lacking any option in the testing framework, I opted for simply monkeypatching the process method in ActionController::TestCase::Behaviour. This method is invoked whenever methods get, post, put, delete or head are called, so it is the easiest single point to modify.

This gist has the necessary code to perform the patch. If you are using rspec, simply copy the file in the spec/support folder.