Manuel Neuhauser

Ruby, PHP, JavaScript, SQL, HTML, CSS, Networking, Security

Design Pattern for Structuring Rails Apps

| Comments

I recently worked on the web application Wishgram and its development quickly got more complex when the need for an API arose to support an iOS app.

I’m not a proponent for building controllers that handle both web browser requests and API calls, because it yields a less skinny controller with more complex code when web application and API specific code are mixed.

For example, responses to success and failure actions in web application requests are generally handled with render or redirect_to, while API requests encapsulate the action outcome in a JSON or XML response. In a RESTful controller with 6 actions, we are quickly losing the beach body of a skinny controller.

Usually, the login mechanisms for web application and API users differ, where the former typically uses a username or email with a password and the latter tends to use a certificate or an OAuth implementation for granting authentication. This was the case in my project, and handling two authentication methods in the controller added unnecessary complexity.

Furthermore, the flat structure of controllers — as produced by the Rails generators — became too cumbersome to organize with two or more separate areas of application functionality.

My solution and proposed Rails design pattern is to always group common controllers into modules and to have them inherit from a dedicated group parent controller. Thus, group specific code such as callbacks that would generally reside in the ApplicationController can now be applied in isolation to a group in its dedicated parent controller. Even if, at the time of developing a Rails app, there are only plans for a basic web application this pattern should still be used to account for future growth.



Implementation of Controller Groups

In my example, we are creating a Customers controller for the customer-facing web application, the company-internal back end system and the API.



Generate Controllers

1
2
3
4
5
6
7
8
9
$ rails generate controller FrontEnd
$ rails generate controller FrontEnd/Customers

$ rails generate controller BackEnd
$ rails generate controller BackEnd/Customers

$ rails generate controller API
$ rails generate controller API/V1/Customers
$ rails generate controller API/V2/Customers


Update Controllers

After generating the controllers in the groups, we change the superclass from ApplicationController to <Group>Controller.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# app/controllers/front_end/customers_controller.rb
class FrontEnd::CustomersController < FrontEndController

  def index
    render text: "Welcome to our Website"
  end

end

# app/controllers/back_end/customers_controller.rb
class BackEnd::CustomersController < BackEndController

  def index
    render text: "Admin Panel"
  end

end

# app/controllers/api/v1/customers_controller.rb
class Api::V1::CustomersController < ApiController

  def index
    render json: { customers: [] }
  end

end

# app/controllers/api/v2/customers_controller.rb
class Api::V2::CustomersController < ApiController

  def index
    render json: { customers: [], total_count: 0, request_time: Time.now }
  end
end

Since all API controllers inherit from ApiController, we can easily disable CSRF for API calls to make non-GET valid requests without affecting the behavior in the front and back end controllers. This is a great example to demonstrate the advantage of separate controller groups.


1
2
3
4
# app/controllers/api_controller.api
class ApiController < ApplicationController
  protect_from_forgery with: :null_session
end


Building Routes

Now that we have the controllers separated, we want to separate the 3 different controller groups in individual subdomains thus reflecting a logical separation in the domain name. One bonus with this approach is that cookies won’t be shared between our front and back end.

The constraints option is used to tie controller groups to subdomains, and the scope specifies the Module that denotes a controller group without exposing it in the route path.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#config/routes.rb
require 'api_constraints'

MyApp::Application.routes.draw do

  constraints subdomain: "www" do
    scope module: :front_end do
      resources :customers
    end
  end

  constraints subdomain: "admin" do
    scope module: :back_end do
      resources :customers
    end
  end

  constraints subdomain: "api" do
    scope module: :api do
      scope module: :v1, constraints: ApiConstraints.new(version: 1) do
        resources :customers, controller: "customers"
      end
      scope module: :v2, constraints: ApiConstraints.new(version: 2, default: :true) do
        resources :customers, controller: "customers"
      end
    end
  end


API Versioning

At this point, we also want to future-proof the API and allow for supplemental versions. Ryan Bates’ REST API Versioning Rail Cast #350 provides a perfect solution. We will integrate it by creating a customized constraint for the API version route scope.


1
2
3
4
5
6
7
8
9
10
11
#lib/api_constraints
class ApiConstraints
  def initialize(options)
    @version = options[:version]
    @default = options[:default]
  end

  def matches?(req)
    @default || req.headers['Accept'].include?("application/vnd.myapp.v#{@version}")
  end
end


Final Words

At this time, there is no functionality in the Rails generator to set the inheritance for a controller. I’m currently looking into building a gem to add such a feature to facilitate the use of the proposed Rails design pattern.

The example application code used in this blog post is on Github, so feel free to fork it, and please share your thoughts on the proposed Rails pattern.

Challenge Accepted: Local File Inclusion

| Comments

This morning I woke up to some unfriendly ice rain, and last night’s snow covered sidewalk has turned into an ice-skating rink. Baby steps were necessary to avoid ending up in a horizontal position involuntarily. I made it to the train station safely, and got on the NYC-bound train. On the bright side, Egor Homakov (@homakov) posted a challenge on Twitter for finding the local file inclusion security hole in a piece of path validation code.

1
2
3
4
5
6
7
8
9
10
input = 'sub/dir/ectory'
input = input.strip

raise 'NO WAI' if input[0] == '/'

if input.split('/').any?{|folder| !(folder =~ /\A[a-zA-Z*.]+\z/) or folder == '..' }
puts 'Error'
else
puts `cat #{input}`
end

Looks like my 40 minute train ride has turned into a hacking session and I eagerly played around with the provided code to access the contents of my local etc/passwd file. Eureka! Finally, I figured out that by breaking up .. (parent directory) with the wildcard symbol *, I could trick the validation code into allowing my path string. Also, in bash the folder .*. behaves the same as .., so by prepending etc/passwd with the right number of .*./ strings, I could finally access the coveted password file.

1
2
3
4
5
6
7
8
9
10
11
12
# Note: This path gives me the passwd file contents on my local system
input = '.*./.*./.*./.*./.*./etc/passwd'

input = input.strip

raise 'NO WAI' if input[0] == '/'

if input.split('/').any?{|folder| !(folder =~ /\A[a-zA-Z*.]+\z/) or folder == '..' }
puts 'Error'
else
puts `cat #{input}`
end

OAuth 2.0 - What You Need to Know About It for Building Your Next App

| Comments

OAuth 2.0 is an authorization framework that allows applications to gain access to an HTTP service. It has become the de facto standard for users to share data from one website account with another website. You may have already used OAuth without even realizing it. The popular login options “Login with Facebook” and “Login with Twitter” are both utilizing the OAuth authorization process defined in RFC6749 — namely OAuth 2.0.

When building a web application, OAuth is making it easy for developers to tie in with other websites, though there are some terms that first need to be understood to comprehend exactly how access can be gained and granted.

Authentication is the process in which one user identifies herself based on some shared secret like a username and password or a token. Authorization, on the other hand, dictates the level of access an authenticated user has to any given resource. A token or hash (not to be confused with the Hash data-type) is merely a generated, hard-to-guess string of characters.

Token-based authorization such as OAuth has the advantage of eliminating the need for a user to share her password with a 3rd party app, allowing the user to restrict the level of access, and permitting the user to revoke access to her data.

In order to ensure security without compromising the ease of use, OAuth 2.0 requires that all communication is sent over an SSL connection.

Let’s look at a concrete example of how we can use OAuth to gain access to a users GitHub account within our app.


1. Register the application

First and foremost, we need to establish a trust relationship between our application MyApp and Github. This is done through means of using a shared client ID and client secret which is generated when registering our app with Github. When using these credentials in API requests, Github can properly identify the authenticity of our app.


2. Authorization request & grant

1
2
3
4
5
+-------+                               +------------+
|       |--(1)- Authorization Request ->|   GitHub   |
| MyApp |                               | (Resource  |
|       |<-(2)-- Authorization Grant ---|   Owner)   |
+-------+                               +------------+

In order to initiate a request to gain access to certain data in the user’s Github account, we craft a special link in our application MyApp which, when clicked, will forward the user to GitHub with an authorization request. It looks like this:

1
GET https://github.com/login/oauth/authorize/?client_id=71d3cfc29d&scope=user:email&redirect_uri=https://myapp.com/callback

When looking closer at the link, we see three parameters:

  • client_id – This is the secret shared identifier that Github has previously provided to us when we registered our app.
  • scope – It describes what resources our app wants access to. The available scopes are defined by Github.
  • redirect_uri – Tells Github where to send the authorization grant to.

Github will use these parameters to validate the authenticity of the request and find out what resources is requested. It presents a prompt to the logged in Github user asking whetherMyApp should be allowed to access a certain set of resources in their account. When the user agrees to grant access, Github will send an HTTP GET request to the redirect_uri and appends a code parameter with contains the authorization grant.

1
GET https://www.myapp.com/?code=4dabfce522efeecaac6819

3. Access Token

1
2
3
4
5
+-------+                               +----------------+
|       |--(3)-- Authorization Grant -->|     GitHub     |
| MyApp |                               | (Authorization |
|       |<-(4)------ Access Token ------|     Server)    |
+-------+                               +----------------+

Now that MyApp has the authorization grant, it can contact Github and request an access token, which is used for the actual API calls. To do that MyApp sends a POST request to Github including the client ID, client secret and the authorization grant code.

1
2
3
4
POST https://github.com/login/oauth/access_token
 client_id=71d3cfc29d
 client_secret=c826145889facbca
 code=4dabfce522efeecaac6819

If Github’s authorization server receives valid credentials, it will respond with an access token. This access token allows MyApp to send API requests on behalf of the user for resources belonging to the previously defined scope.

1
{ access_token: c826145889facbcae488411a45339a19 }

4. Making API calls

1
2
3
4
5
+-------+                               +-----------+
|       |--(5)----- Access Token ------>|   Github  |
| MyApp |                               | (Resource |
|       |<-(6)--- Protected Resource ---|   Server) |
+-------+                               +-----------+

At this point, MyApp can make API calls to retrieve information from the Github user account, and it is authorized with the access token. The access token can be put into either the header:

1
Authorization: token c826145889facbcae488411a45339a19

… or alternatively, added as a parameter to the API call URI:

1
https://api.github.com/user?access_token=c826145889facbcae488411a45339a19

Additional information

For a detailed breakdown of OAuth 2.0, I can highly recommend to read RFC6749, especially section 4 and 5.

Ruby’s 7 Best Kept Secrets

| Comments

1. Syntactical Shortcuts for Iterations

When you need to apply a method to all items within an Enumerable, instead of creating a block syntax with a local variable, you can prepend an & before the Symbol that represents the method name and pass it to the iteration method as an argument. This works for all functions that do not take an argument.

1
2
3
4
5
%w(alice bob carl).map {|name| name.capitalize}
 => ["Alice", "Bob", "Carl"]

%w(alice bob carl).map &:capitalize
 => ["Alice", "Bob", "Carl"]

These shortcuts work because calling Symbol#to_proc returns a proc that responds to the symbol’s method. So the :capitalize symbol is first converted to a proc, and then to a block.

Similarly, you can pass the Symbol for a function into #inject and it will sequentially apply the method to items. This method needs to take one argument, which in this case will be num and it gets sent to the collector sum.

1
2
3
4
5
(1..10).inject {|sum,num| sum += num }
 => 55

(1..10).inject :+
 => 55


2. Set Intersection for an Array

There’s an easy way to get the intersection, or set of common elements, of two Arrays. By applying the & operator to one Array and passing the other as an argument.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[1,2,3,4] & [1,3]
 => [1, 3]

%w(Hi, my name is Alice) & %w(My name is Bob)
 => ["name", "is"]   # The comparison is case sensitive

class Dog
  def ==(other_dog)
    self.name == other_dog.name
  end
end

shared_dog = Dog.new('Fido')

[Dog.new('Scooby'), Dog.new('Snoopy'), shared_dog] & [Dog.new('Scooby'), shared_dog]
 => [#<Dog:0x007fd96c0f4658 @name="Fido">]
  # shared_dog is considered a match because the object IDs match. 
  # The Dog#== method is not used


3. Ignoring Arguments and Return Values

In cases where argument variables need to be set in order to receive values, you can end up with verbose code becaues unused arguments are specified. By using the _ (underscore) as an argument, it visually hides some of the received values. Also, when defining _ multiple times it will not raise a SyntaxError unlike any other variable name.

1
2
3
4
5
6
7
[["Alice", 24, "female"], ["Bob", 28, "male"], ["Trudy", 100, "alien"]].map {|ignore,ignore,gender| gender }

SyntaxError: (irb):81: duplicated argument name
... "alien"]].map {|ignore,ignore,gender| gender }

[["Alice", 24, "female"], ["Bob", 28, "male"], ["Trudy", 100, "alien"]].map {|_,_,gender| gender }
 => ["female", "male", "alien"]
1
2
3
4
5
name, _, _, hometown = ["Alice", 24, "female", "New York City"]
name
 => "Alice"
hometown
 => "New York City"


4. Autovivification

Hash.new can take a block that is run when a non-existing key is accessed. The code snipped below ensures that a Hash with infinite sub-Hash nesting gets created when accessing an arbitrary depth of non-existing keys.

1
2
3
4
endless = Hash.new{|hash, key| hash[key] = Hash.new(&hash.default_proc) }

endless[:one][:two][:three][:or][:more][:levels][:deep] = "This is insane!!!"
 => "This is insane!!!"


5. Advanced Text Interpolation

When interpolating variable values into a string, the variables are commonly placed within the delimited text. The % allows us to replace the character string %s within the text with items from an array.

1
2
3
4
5
"Hi, my name is %s, and I live in %s." % ["Alice","New York"]
 => "Hi, my name is Alice, and I live in New York."

phone_template = "I'm %s and my phone number is %s."
phone_template % ["Jenny","867-5309"]


6. Lazy Loading

We all like to be lazy sometimes. Starting in Ruby 2.0, we can now let Enumerable objects be lazy too. All this means is that the result of the enumerable function will not get evaluated until you tell it to.

1
2
3
4
5
6
7
car_names = %w(audi chevrolet dodge)

capitalized_car_names = car_names.lazy.map &:capitalize
 => #<Enumerator::Lazy: #<Enumerator::Lazy: ["audi", "chevrolet", "dodge"]>:map>

capitalized_car_names.to_a
 => ["Audi", "Chevrolet", "Dodge"]

The behavior in this example doesn’t really show the full potential of #lazy. Imagine that you have an operation that you want to apply to a collection, however, the contents of the given collection are dynamically changing. Using #lazy keeps the enumerator updated with the latest state of the collection.

1
2
3
4
5
6
7
8
9
10
11
12
13
car_names << 'volkswagen'

capitalized_car_names
 => #<Enumerator::Lazy: #<Enumerator::Lazy: ["audi", "chevrolet", "dodge", "volkswagen"]>:map> 

capitalized_car_names.to_a
 => ["Audi", "Chevrolet", "Dodge", "Volkswagen"]

car_names.shift
 => "audi"

capitalized_car_names.to_a
 => ["Chevrolet", "Dodge", "Volkswagen"]


7. Counting A Subset

You may use #count on a daily basis, but did you know that you can specify a parameter to the method call? It will return the number of occurrances of that particular value.

1
2
3
fruit = %w(apple orange banana apple kiwi grapes apple)

fruit.count("apple") #=> 3

If you though that was cool, then hold on to your pants. When you add a block that evaluates a condition for each item in the collection, you can add logic regarding which items you want to count. If the block return true the item gets counted.

1
2
fruit = %w(apple orange banana apple kiwi grapes apple)
fruit.count { |item| %w(banana kiwi).include? item } #=> 2

What the Splat?

| Comments

The asterisk operator commonly known as splat can be a powerful ally in writing clean and highly functional code. The splat operator has a variety of behaviors depending on where it is used, and in this post I’ll focus on the use of splat in conjunction with methods in Ruby 1.9 and later.


Arbitrary Argument Length in Method Signature

Occasionally, we would like to define a method that will accept an undefined number of argument. Typically, we use an optional Hash as the last argument, which holds a variety of arguments. However, we can also take advantage of the splat operator by placing it in front of an argument variable name in the method definition. It will cause the argument variable to capture an Array of all arguments passed to the function that have not been matched to other arguments in the method signature. The splat operator can be used at the beginning or at the end of the argument list, though for the latter, the last argument that is passed into the function must be a Hash.

1
2
3
4
5
6
7
8
9
10
11
def add_to(playlist, *songs)
  songs.each do |song|
    playlist << song
  end
end

rock = []
add_to(rock, "Beatles - Yellow Submarine", "Counting Crows - Big Yellow Taxi", "Coldplay - Yellow")

rock.inspect
 #=> "["Beatles - Yellow Submarine", "Counting Crows - Big Yellow Taxi", "Coldplay - Yellow"]" 
1
2
3
4
5
6
7
8
9
10
def display_songs(*songs, formatting)
  songs.each do |song|
    puts "#{formatting[:start]} #{song} #{formatting[:end]}"
  end
end

display_songs("Stairway to Heaven", "Hotel California", "Hold the Line", {:start => ">>>", :end => "<<<"})
 # >>> Stairway to Heaven <<<
 # >>> Hotel California <<<
 # >>> Hold the Line <<<

There is one more —for the lack of a better word— interesting use of the splat operator in the method signature at the end when it’s by itself. It allows for additional arguments to be accepted, but ignored by the method.

1
2
3
4
5
6
def my_favorite_food(first,second,*)
  puts "My favorite food items are #{first} and #{second}."
end

my_favorite_food("pizza","sushi","salad")
 #=> My favorite food items are pizza and sushi.


Calling Methods

The reason for this blog entry is actually this section. I recently worked on a project in which I wanted to use Object#send to dynamically call an instance method. The method #play takes an argument, while #list doesn’t. I quickly ran into a problem with this particular code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def play(song)
  # code to play given song
end

def list
  # code to display all songs
end

def process(input)
  command, args = input.split(" ", 2)
  puts args.inspect
  self.send(command, args)
end

process("play Michael Jackson - Beat It")
 #=> nil 

process("list")
 #ArgumentError: wrong number of arguments (1 for 0)
 # from (irb):32:in `list'
 # from (irb):38:in `process'

When processing the input “list”, args is set to nil, which is still considered an argument and it triggers an ArgumentError because #list does not take any arguments.

Our little friend splat can actually help us resolve this issue. When calling a method and prepending the splat to an array variable, it will cause it to be distributed across the arguments of the method. In my case, the empty args variable was distributed across exactly no arguments. By adding the splat, we can now dynamically send either one or two arguments to the #send function.

1
2
3
4
5
6
7
8
9
10
11
def process(input)
  command, args = input.split(" ", 2)
  puts args.class
  self.send(command, *args)
end

process("play Michael Jackson - Beat It")
 #=> nil 

process("list")
 #=> nil

When using splat to distribute the values to the arguments, the count must match exactly. Also, only a splat in front of an empty Array, Hash or nil will yield no value to argument assignment.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def zero
  puts "Nothing"
end

def one(a)
  puts "#{a}"
end

def two(a,b)
  puts "#{a}, #{b}"
end

def three(a,b,c)
  puts "#{a}, #{b}, #{c}"
end

values = [1, 2]

zero(*values)  # Error
one(*values)   # Error
two(*values)   # Success
three(*values) # Error

zero(*[])      # Success
zero(*{})      # Success
zero(*nil)     # Success

Enumerable’s Best Kept Secrets

| Comments

An Enumerator is defined as a “class which allows both internal and external iteration.” It represent a series of objects, it can be lazily generated and it can be infinite. In contrast, the an Enumerable is a module and it “provides collection classes with several traversal and searching methods, and with the ability to sort.”


In Ruby, enumerators are used quite frequently for their extensive abstraction of iteration functionality. When we call the Array#each method, we can focus on dealing with the individual Array items rather than having to worry about how to retrieve each item one by one. When we need to find a subset of items from a Hash, we can use #select with a code block to decide which item we want in the result, without necessarily knowing how the Hash is traversed.


All this power comes from the Enumerable module, and it is inlucded by many of the common Object types such as Array, Hash, Range, and Set. When first learning Ruby, #each and #collect quickly become an often-used tool we use for iterating over data. Most functionality can be accomplished by their use, however, there are many more advanced iterators available with very specific funtionality, but unless we constantly skim over the Ruby documentation, we may not know about them. I’d like to introduce (or re-introduce for some of you) some of my favorites.


#count

Alright, alright. You may use #count on a daily basis, but did you know that you can specify a parameter to the method call? It will return the number of occurrances of that particular value.

1
2
3
fruit = %w(apple orange banana apple kiwi grapes apple)

fruit.count("apple") #=> 3

If you though that was cool, then hold on to your pants. When you add a block that evaluates a condition for each item in the collection, you can add logic regarding which items you want to count. If the block return true the item gets counted.

1
2
fruit = %w(apple orange banana apple kiwi grapes apple)
fruit.count { |item| %w(banana kiwi).include? item } #=> 2

#lazy

We all like to be lazy sometimes. Starting in Ruby 2.0, we can now let Enumerable objects be lazy too. All this means is that the result of the enumerable function will not get evaluated until you tell it to.

1
2
3
4
5
6
7
car_names = %w(audi chevrolet dodge)

capitalized_car_names = car_names.lazy.map &:capitalize
 => #<Enumerator::Lazy: #<Enumerator::Lazy: ["audi", "chevrolet", "dodge"]>:map>

capitalized_car_names.to_a
 => ["Audi", "Chevrolet", "Dodge"]

The behavior in this example doesn’t really show the full potential of #lazy. Imagine that you have an operation that you want to apply to a collection, however, the contents of the given collection are dynamically changing. Using #lazy keeps the enumerator updated with the latest state of the collection.

1
2
3
4
5
6
7
8
9
10
11
12
13
car_names << 'volkswagen'

capitalized_car_names
 => #<Enumerator::Lazy: #<Enumerator::Lazy: ["audi", "chevrolet", "dodge", "volkswagen"]>:map> 

capitalized_car_names.to_a
 => ["Audi", "Chevrolet", "Dodge", "Volkswagen"]

car_names.shift
 => "audi"

capitalized_car_names.to_a
 => ["Chevrolet", "Dodge", "Volkswagen"]

Nag a Ram

| Comments

An anagram is a type of word play, the result of rearranging the letters of a word or phrase to produce a new word or phrase, using all the original letters exactly once; for example orchestra can be rearranged into carthorse. Someone who creates anagrams may be called an “anagrammatist”. Source: Wikipedia


The core of a recent code challange included finding out whether one string is an anagram of another. Now this task can be accomplished with a couple of iterators and character comparison, but such an answer would yield code that is too complex looking for what I needs to accomplish and it may be difficult to read.

Rather than picking each letter from the first string and finding it in the second, I wanted to compare the two strings in a single step. First, the strings both need to be sorted and in order to do this, they first had to be converted to an array of single letters. With a little String#split and Array#sort magic the resulting arrays can easily be compared.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Anagram

  def initialize(word)
    @word = word
    @word_match_string = generate_match_string(word)
  end

  def match(words)
    words.select do |potential_anagram|
      @word_match_string == generate_match_string(potential_anagram)
    end
  end

  private

  def generate_match_string(word)
    word.downcase.split("").sort
  end

end