Ahmed's profileAhmed Live !PhotosBlogListsMore Tools Help
    July 24

    HTTP Basic Authentication for functional tests !

    While I was trying to cover a controller with some tests I faced a problem. The controller actions where protected by a filter that prompted the users for login via basic http authentication.

    I found a solution in rails code here http://github.com/rails/rails/tree/master/actionpack/lib/action_controller/http_authentication.rb where it said you should do your get as follows get("/notes", nil, :authorization => ActionController::HttpAuthentication::Basic.encode_credentials(users(:x).name, users(:x).password))

    This didn't work for me where basic http authentication required sending the encoded credentials in the request headers while the previous get request sent the authorization credentials in the session.

    I found the following code snippet in http://snippets.dzone.com/posts/show/3785 which allowed me to set request headers class ActionController::TestRequest def set_header(name, value) @env[name] = value end end

    In my tests, I now write the following @request.set_header "HTTP_AUTHORIZATION", ActionController::HttpAuthentication::Basic.encode_credentials(users(:x).email, '0000') get :show, {:user_id => users(:x).id, :format => "rss"}

    And it works like a charm !

    July 20

    reCAPTCHA your rails application !

    CAPTCHA stands for "Completely Automated Public Turing test to tell Computers and Humans Apart". As the acronym suggests, the main reason of using CAPTCHA is to tell computers and human apart. It is a challenge-response test used to ensure that the response is not machine generated. CAPTCHA comes in many forms, some are more popular than the others
    1. Text based captchas in which the user sees an image displaying letters or numbers and is asked to type what he sees
    2. Image recognition captchas which display some images and asks questions about their content. Microsoft Assira is an example
    3. 3D captchas which display come complex computer generated 3D graphics scene and asks about the 3D details and contents
    Image recoginition and 3D recognition try to impose more difficulty on computer programs that try to break CAPTCHAs.

    reCAPTCHA is one of the CAPTCHA efforts. It also tries to solve another problem in addition to fighting spam. It tries to improve the process of digitizing books by sending words that cannot be read by computers to the Web in the form of CAPTCHAs for humans to decipher. The question that popped immediately in my mind was how does that reCAPTCHA verify the answers if it's using images of words that the computer couldn't really figure out what they were while scanning them. The answer is simple: it display two words at a time, one word can be easily verified and for the other word, your solution is taken to be a suggestion for that word. That word is used many times in different CAPTCHAs and eventually many people will suggest the same thing.

    Currently, reCAPTCHA is recommended as the official CAPTCHA implementation by the original CAPTCHA creators.

    This way reCAPTCHA not only helps you to fight spam but also gets you to participate into a good cause like digitizing the world's books.

    Using reCAPTCHA in your Rails application is so easy thanks to the recaptcha plugin. This plugin gives you 2 main methods that you can use in your application
    1. recaptcha_tags which should be used in the view in your form.
    2. verify_recaptcha which should be used in the controllers to verify the user's answer
    You should register at reCAPTCHA to get your public and private keys which are required by the plugin. The plugin requires that you define them as Environment variables.
    recaptcha_tags accepts an options hash which can define the public key with :public_key so that it doesn't look in your environment variables.
    verify_recaptcha - which uses the private key - doesn't provide a way for you to pass the private_key.

    I've forked the plugin here and modified verify_recaptcha such that it now accepts an options hash - like recaptcha_tags - which allows you to define :private_key which will be used instead of looking into the environment variables.

    Fight spam, help in digitizing books, use reCAPTCHA !

    update: I sent a pull request to the guys over at http://github.com/ambethia/recaptcha to include my changes. Peter Abrahamsen replied and after a couple of messages we modified the plugin such that we no longer need to set the public and private key in any environment variables.  We also added a toggle to enable/disable the plugin. We can use the plugin as follows now
      Ambethia::ReCaptcha.enabled = true
    Ambethia::ReCaptcha.public_key = '0123456789ABCDEF'
    Ambethia::ReCaptcha.private_key = '0123456789ABCDEF'
    If the toggle is set to false the recaptcha_tags will return nothing and the verify_recaptcha will always return true meaning that the recaptcha code does nothing which is what we want in case of disabling it.
    July 07

    version_cache: 1, 2, 3, It's all in the numbers !

    Building on my previous post about caching where the method_cache plugin was introduced, today I'd like to introduce another Rails plugin that also deals with the caching problem. This time, it's about caching views. It uses a technique called version caching. Version caching frees you from having to worry about writing code that expires your cache. For more info about version caching check Yasser Wahba's blog post explaining version caching and how we used it. I've used version caching in my last 2 projects and found it quite useful and quite easy. The problem is that we used to repeat a lot of code violating DRY. It was so clear we had to do something about it. I've taken that code, refactored it and made it available as a Rails (v2.1.0) plugin available at GitHub. Check it here.

    The plugin assumes using a cache store that uses LRU (least recently used) to handle when the cache becomes full and that also supports time caching. Cutting it short, it assumes we're using memcached.

    The plugin makes a couple of methods available in all controllers. These methods are

    • version_cache
    • time_cache
    • version_cache_key_part

    The first 2 are the most important. time_cache as the name implies allows for time caching for a page. it can be used as follows

    class WelcomeController < ApplicationController 
      time_cache :index => {:expiry => 5, :browser_cache_enabled => true}
      .
      .
      def index
        .
        .
      end
      .
      .
    end

    What we've just done is that we declared our intention of caching the index page of the welcome controller for 5 minutes in our cache store. In addition to the cache store, we declared our intention that we also want the page to be cached in the browser for the same period.

    version_cache
    is the one responsible for tying the caching of a page to a model's version. we can use it as follows

    class ItemsController < ApplicationController
     
      version_cache Item, :associates => ["user"], :expiry => 5

    end

    By default, version_cache caches the show action unless an :action is provided. In the previous example we're saying that we want to cache the show action of the items controller.

    Item: the model whose objects versions are used.
    :associates: an array of members on the model whose versions need to be updated as well when the the main model's version is updated. i.e when an item is changed, its version is incremented and the item's user's version is also incremented. This is useful if we also cache users#show based on User model and changing an item reflects on the user's page. :associates is optional
    :expiry => an optional maximum time for the page to expire. if not specified, expiry will happen on the normal LRU
    basis.

    Models' versions are maintained by the means of an observer. The observer has to observer the models we use and to be also declared in the environment.rb

    version_cache_key_part is another method that allows a page to have multiple cached versions. We can use it as follows


    class PostsController < ApplicationController
      .
      .
      version_cache Post, :associates => ["user"], :expiry => 5
      .
      .
      def show
      .
      end
     
      def version_cache_key_part
        if logged_in_user
          "logged_in"
        else
          "guest"
        end
      end

    end

    What just happened here is that based on some conditions we return a string that will be part of the cache key. Now we have 2 versions cached for the show page; one for logged in users and one for guests. You can have as many versions as you want based on whatever conditions as long as they return distinct strings.

    To get the plugin

    ruby script/plugin install git://github.com/humanzz/version_cache.git

    Then use the plugin’s generator to generate the cache observer

    ruby script/generate version_cache_observer Cache Model1 Model2

    The first argument “Cache” is taken to be the observer’s name. Any arguments after that are taken to be the models that the observer will observe.


    Version caching is a great caching technique and hopefully with the introduction of the plugin many developers will find it appealing and easy to use.

     

    Technorati Tags: - - - -