Friday, August 19, 2016

Getting started with Netzke_part1


Netzke is a set of Ruby gems that helps you build client-server components, represented in the browser with the help of Sencha Ext JS, and on the server are powered by Ruby on Rails. It's most useful for creating complex data-rich applications that have to provide the UI to a lot of different data - think about banking, logistics, call centers, and other ERP systems.

In this walk-through I'll show you how little time it takes to set up a simple application with 2 interacting grids that provide the UI to 2 associated (one-to-many) Rails models. As both grids will be powered by the Netzke::Basepack::Grid component, you may be surprised with all the features like sorting, pagination, search, multi-line editing, etc that this app will provide out of the box.
So, let's get started.

Setting things up

Create a new Rails application:
  1. $ rails new netzke_bookshelf && cd netzke_bookshelf
Add Netzke gem to your Gemfile:
  1. gem 'netzke'
Install the gems:
  1. $ bundle
Symlink or copy the Ext JS files (direct download link) and, optionally, the FamFamFam silk icons, into public/extjs and public/images/icons respectively. For example:
  1. $ echo MOST PROBABLY NO COPY-PASTING HERE
  2. $ ln -s ~/code/extjs/ext-5.1.0 public/extjs
  3. $ mkdir public/images
  4. $ ln -s ~/assets/famfamfam-silk public/images/icons
Declare Netzke routes:
  1. # config/routes.rb
  2. NetzkeTaskManager::Application.routes.draw do
  3.   netzke
  4. end
The netzke method sets up routes needed for communication between client and server side of every Netzke component.

Creating Rails models

We'll build a little personal bookshelf app, let's start with generating the 2 models for it:
  1. $ rails g model author name
  2. $ rails g model book author:references title exemplars:integer completed:boolean
Run the migrations:
  1. $ rake db:migrate
Let's set the 1-to-many relations between the models, and add basic validations:
  1. # app/models/author.rb
  2. class Author < ActiveRecord::Base
  3.   validates :name, presence: true
  4.   has_many :books, dependent: :delete_all
  5. end

  6. # app/models/book.rb
  7. class Book < ActiveRecord::Base
  8.   validates :title, presence: true
  9.   belongs_to :author
  10. end
Now let's get to the fun part.

Creating the grids

Netzke components are Ruby classes, so, let's create one in the app/components/authors.rb (you'll need to add the app/components directory first):
  1. # app/components/authors.rb
  2. class Authors < Netzke::Basepack::Grid
  3.   def configure(c)
  4.     super
  5.     c.model = "Author"
  6.   end
  7. end
The minimum configuration that Netzke::Basepack::Grid requires is the name of the model, and that's what we provided. Now let's see what this code is capable of.
The netzke-testing gem, which is a part of the Netzke bundle, provides convenient routes for testing components in isolation, so, we'll make use of it. Fire up your Rails app:
  1. $ rails s
... and point your browser to http://localhost:3000/netzke/components/Authors
Here's what you should see:


It's a full-featured grid view: try adding, editing, deleting, sorting and searching records in it, or rearranging the columns:

However, a more interesting example to play with would be our books grid, as it will have more columns of different types:
  1. # app/components/books.rb
  2. class Books < Netzke::Basepack::Grid
  3.   def configure(c)
  4.     super
  5.     c.model = "Book"
  6.   end
  7. end
Navigate to http://localhost:3000/netzke/components/Books in order to see it. I've added a couple of books before sharing the screenshot with you:


Note that the grid has picked up the Author association without any configuration (yes, it honors some conventions).

As you may expect, our grids are highly configurable, and many configuration options can be found in the documentation. Let us, for instance, make a few changes into the Books grid, customizing the columns and the button bar:
  1. class Books < Netzke::Basepack::Grid
  2.   def configure(c)
  3.     c.columns = [
  4.       # you may configure columns inline like this:
  5.       { name: :author__name, text: "Author" },

  6.       :title,
  7.       :exemplars,
  8.       :completed
  9.     ]

  10.     c.model = "Book"

  11.     # which buttons to show in the bottom toolbar
  12.     c.bbar = [:add, :edit, :del, '->', :apply]

  13.     super
  14.   end

  15.   # you may also use DSL to configure columns individually
  16.   column :completed do |c|
  17.     c.width = 100
  18.   end
  19. end
Here's how it'll look like:


Written by Max Gorin
If you found this post interesting, follow and support us.
Suggest for you:

The Complete Ruby on Rails Developer Course

Rails 5: Learning Web Development the Ruby Way

Learn Ruby on Rails from Scratch

Ruby Scripting for Software Testers

Python, Ruby, Shell - Scripting for Beginner


Tuesday, August 16, 2016

Using Braintree's v.zero SDK to accept payments


Tired of Ruby's modules not allowing you to mix in class methods easily? Tired of writing complex self.included(base) code or using over-engineered solutions like ActiveSupport::Concern to accomplish that goal?

Well, worry no more! SuperModule comes to the rescue!

SuperModule allows defining class methods and method invocations the same way a super class does without using self.included(base).

This succeeds ActiveSupport::Concern by offering lighter syntax and simpler module dependency support.

Introductory Comparison

To introduce SuperModule, here is a comparison of three different approaches for writing a UserIdentifiable module.

1) self.included(base)
  1. module UserIdentifiable
  2.   include ActiveModel::Model

  3.   def self.included(base_klass)
  4.     base_klass.extend(ClassMethods)
  5.     base.class_eval do
  6.       belongs_to :user
  7.       validates :user_id, presence: true
  8.     end
  9.   end

  10.   module ClassMethods
  11.     def most_active_user
  12.       User.find_by_id(select('count(id) as head_count, user_id').group('user_id').order('count(id) desc').first.user_id)
  13.     end
  14.   end

  15.   def slug
  16.     "#{self.class.name}_#{user_id}"
  17.   end
  18. end
This is a lot to think about and process for simply wanting inclusion of class method definitions (like most_active_user) and class method invocations (like belongs_to and validates). The unnecessary complexity gets in the way of problem-solving; slows down productivity with repetitive boiler-plate code; and breaks expectations set in other similar object-oriented languages, discouraging companies from including Ruby in a polyglot stack, such as Groupon's Rails/JVM/Node.js stack and SoundCloud's JRuby/Scala/Clojure stack.

2) ActiveSupport::Concern
  1.  module UserIdentifiable
  2.   extend ActiveSupport::Concern
  3.   include ActiveModel::Model

  4.   included do
  5.     belongs_to :user
  6.     validates :user_id, presence: true
  7.   end

  8.   module ClassMethods
  9.     def most_active_user
  10.       User.find_by_id(select('count(id) as head_count, user_id').group('user_id').order('count(id) desc').first.user_id)
  11.     end
  12.   end

  13.   def slug
  14.     "#{self.class.name}_#{user_id}"
  15.   end
  16. end
A step forward that addresses the boiler-plate repetitive code concern, but is otherwise really just lipstick on a pig. To explain more, developer problem solving and creativity flow is still disrupted by having to think about the lower-level mechanism of running code on inclusion (using included) and structuring class methods in an extra sub-module (ClassMethods) instead of simply declaring class methods like they normally would in Ruby and staying focused on the task at hand.

3) SuperModule
  1. module UserIdentifiable
  2.   include SuperModule
  3.   include ActiveModel::Model

  4.   belongs_to :user
  5.   validates :user_id, presence: true

  6.   def self.most_active_user
  7.     User.find_by_id(select('count(id) as head_count, user_id').group('user_id').order('count(id) desc').first.user_id)
  8.   end

  9.   def slug
  10.     "#{self.class.name}_#{user_id}"
  11.   end
  12. end
With include SuperModule declared on top, developers can directly add class method invocations and definitions inside the module's body, and SuperModule takes care of automatically mixing them into classes that include the module.

As a result, SuperModule collapses the difference between extending a super class and including a super module, thus encouraging developers to write simpler code while making better Object-Oriented Design decisions.

In other words, SuperModule furthers Ruby's goal of making programmers happy.

Instructions

1) Install and require gem

Using Bundler

Add the following to Gemfile:
  1. gem 'super_module', '1.0.0'
And run the following command:
  1. bundle
Afterwards, SuperModule will automatically get required in the application (e.g. a Rails application) and be ready for use.

Using RubyGem Directly

Run the following command:
  1. gem install super_module
(add --no-ri --no-rdoc if you wish to skip downloading documentation for a faster install)

Add the following at the top of your Ruby file:
  1. require 'super_module'
2) Include SuperModule at the top of the module
  1. module UserIdentifiable
  2.   include SuperModule
  3.   include ActiveModel::Model

  4.   belongs_to :user
  5.   validates :user_id, presence: true

  6.   def self.most_active_user
  7.     User.find_by_id(select('count(id) as head_count, user_id').group('user_id').order('count(id) desc').first.user_id)
  8.   end

  9.   def slug
  10.     "#{self.class.name}_#{user_id}"
  11.   end
  12. end
3) Mix newly defined module into a class or another super module
  1. class ClubParticipation < ActiveRecord::Base
  2.   include UserIdentifiable
  3. end
  4. class CourseEnrollment < ActiveRecord::Base
  5.   include UserIdentifiable
  6. end
  7. module Accountable
  8.   include SuperModule
  9.   include UserIdentifiable
  10. end
  11. class Activity < ActiveRecord::Base
  12.   include Accountable
  13. end
4) Start using by invoking class methods or instance methods
  1. CourseEnrollment.most_active_user
  2. ClubParticipation.most_active_user
  3. Activity.last.slug
  4. ClubParticipation.create(club_id: club.id, user_id: user.id).slug
  5. CourseEnrollment.new(course_id: course.id).valid?
Glossary and Definitions
  • SuperModule: name of the library and Ruby module that provides functionality via mixin
  • Super module: any Ruby module that mixes in SuperModule
  • Class method definition: Ruby class or module method declared with self.method_name or class << self
  • Class method invocation: Inherited Ruby class or module method invoked in the body of a class or module (e.g. validates :username, presence: true)
  • Code-time: Time of writing code in a Ruby file as opposed to Run-time
  • Run-time: Time of executing Ruby code
Usage Details
  • SuperModule must always be included at the top of a module's body at code-time
  • SuperModule inclusion can be optionally followed by other basic or super module inclusions
  • A super module can only be included in a class or another super module
  • SuperModule adds zero cost to instantiation of including classes and invocation of included methods (both class and instance)
How Does It Work?

Here is the general algorithm from the implementation:
  1. def included(base)
  2.   __invoke_super_module_class_method_calls(base)
  3.   __define_super_module_class_methods(base)
  4. end
  1. 1) Invoke super module class method calls on the including base class.
For example, suppose we have a super module called Locatable:
  1. module Locatable
  2.   include SuperModule

  3.   validates :x_coordinate, numericality: true
  4.   validates :y_coordinate, numericality: true

  5.   def move(x, y)
  6.     self.x_coordinate += x
  7.     self.y_coordinate += y
  8.   end
  9. end

  10. class Vehicle < ActiveRecord::Base
  11.   include Locatable
  12. # … more code follows
  13. end
This first step guarantees invocation of the two Locatable validates method calls on the Vehicle object class.
It does so by relying on method_missing(method_name, *args, &block) to record every class method call that happens in the super module class body, and later replaying those calls on the including base class during self.included(base) by using Ruby's send(method_name, *args, &block) method introspection.

2) Defines super module class methods on the including base class

For example, suppose we have a super module called Addressable:
  1. module Addressable
  2.   include SuperModule

  3.   include Locatable
  4.   validates :city, presence: true, length: { maximum: 255 }
  5.   validates :state, presence: true, length: { is: 2 }

  6.   def self.merge_duplicates
  7.     # 1. Look through all Addressable instances in the database
  8.     # 2. Identify duplicates
  9.     # 3. Merge duplicate addressables
  10.   end
  11. end

  12. class Contact < ActiveRecord::Base
  13.   include Addressable
  14. # … more code follows
  15. end
The second step ensures that merge_duplicates is included in Contact as a class method, allowing the call Contact.merge_duplicates

It does so by recording every class method defined using the self.singleton_method_added(method_name) added hook, and then later replaying these class definitions on the including base class during invocation of self.included(base).

In order to avoid interference with existing class method definitions, there is an exception list for what not to record, such as includedmethod_missingsingleton_method_added, and any other "__" prefixed class method defined in SuperModule (e.g. __super_module_class_method_calls).

Limitations and Caveats
  • SuperModule has been designed to be used only in the code definition of a module, not to be mixed in at run-time.
  • Initial Ruby runtime load of a class or module mixing in SuperModule will incur a very marginal performance hit (in the order of nano-to-milliseconds). However, class usage (instantiation and method invocation) will not incur any performance hit, running as fast as any other Ruby class.
  • Given SuperModule relies on self.included(base) in its implementation, if an including super module (or a super module including another super module) must hook into self.included(base)for meta-programming cases that require it, such as conditional include statements or method definitions, it would have to alias self.included(base) and then invoke the aliased version in every super module that needs it like in this example:
  1. module AdminIdentifiable
  2.  include SuperModule
  3.  include UserIdentifiable

  4.  class << self
  5.      alias included_super_module included
  6.      def included(base)
  7.          included_super_module(base)
  8.          # do some extra work 
  9.          # like conditional inclusion of other modules
  10.          # or conditional definition of methods
  11.      end
  12.  end
In the future, SuperModule could perhaps provide robust built-in facilities for allowing super modules to easily hook into self.included(base) without interfering with SuperModule behavior.
Given SuperModule relies on method_missing(method_name, args, &block) inside class << self, a super module including it that needs to do some additional method_missing (method_missing(method_name, args, &block) meta-programming must not only alias it, but also be mindful of implications on SuperModule behavior.

Feedback and Contribution

SuperModule is written in a very clean and maintainable test-first approach, so you are welcome to read through the code on GitHub for more in-depth details: 
https://github.com/AndyObtiva/super_module

The library is quite new and can use all the feedback and help it can get. So, please do not hesitate to add comments if you have any, and please fork the project on GitHub in order to make contributions via Pull Requests.
Written by Andy Maleh 

If you found this post interesting, follow and support us.
Suggest for you:

Saturday, August 13, 2016

A week with a Rails Security Strategy: More security, new habits


You’re a busy person. Security is not a very visible feature in most applications, and so sometimes it’s not a priority. Of course you know it’s important, but how can you fit it into your busy schedule?
The answer may be in the power of habits, especially mini habits. These are good for busy people or those who want to make a (big) improvement, but get distracted or feel demotivated after a few days. In a minute I’ll show you what this has to do with security.


The key to mini habits is that you minimize your daily goals to an absolute minimum, to something small that requires only willpower to complete, not necessarily motivation. As we all know, starting is the hardest. But once the ball is rolling it’s easy. Even if you only achieve your small goal, you’re one step further. You can do more, of course, but your goal is already reached. As described in the Mini Habits book, although it’s easy to use willpower, we only have a limited amount of it. Motivation tries to push us out of our comfort zone, while willpower just takes a few steps out and then falls back into our comfort zone.

Creating habits should be part of your workday routine. Once the actions you want to turn into a habit are transformed into something that you do automatically, you will feel that the tasks are much easier.

So, what does this have to do with security?” you ask. Here’s the strategy: Set a few minutes aside every day for security. Use reminders to remember your daily goal. Use a pen and paper or software, the tools don’t matter really. The consistency and effort to achieve every day is what matters. To keep the ball rolling, think about the next day today so that you can start right away tomorrow. If you know it will be a very busy day, find an easy task to do first.

If you’re in a team, other people can be responsible for parts of this. But it’s best if you use a system to track responsibilities, otherwise your good intentions will fall through the cracks on busy days.

The Week

So here’s an outline for a week with mini habits that form a Rails security strategy. (Well, actually it’ll also work similarly for other programming languages.)
And if you’d like, I’ve prepared a free 5-page guide for each day for you to follow. Click the link in the pinned tweet in my Twitter profile or here to get it.

Monday

Well, it’s Monday, so start your week with something easy! For example, some manual work: Check your software and components. Your software should be up to date. Chances are you already have a standardized process to update your server or it’s managed by the provider. But what about the Ruby gems? Get on the mailing lists if they have one, subscribe to their blog feed or just keep links to their changelog and check for updates today in these places.
Take a look at the gem bundler-audit to automate this process. It will check your gems for known vulnerabilities and also recommend some improvements regarding the update process in general. However, the database is a community effort and does not include all the gems you might use, so you should also keep some manual checks.

You probably know these two mailing lists already, but do subscribe to these to stay on top of security updates: Rails security updates, Ruby security announcements including updates for some important gems.

Also, the National Vulnerability Database provides an RSS feed about recent vulnerabilities in all kinds of software and libraries. Subscribe to it to hear about updates for your web server, database software or other software in your ecosystem. It only shows the vulnerabilities of the last eight days, so that’s why you should do this every week.


Tuesday

Well, you’re still busy with keeping up, so let’s do something manual again. Chances are your web application uses TLS/SSL and you probably heard a lot about the recent vulnerabilities in that area. So head over to https://www.ssllabs.com/ssltest and perform a free test of your TLS/SSL web server configuration today. This is also a good day to check the expiry date of the SSL certificate because it expires without warning. This could also be the day to start learning something new about this whole complex area. For example, every Tuesday you could read two pages of the book “Bulletproof SSL and TLS”. It’s a complete guide to using SSL/TLS and OpenSSL. It also covers weaknesses at every level and the latest attacks, such as BEAST, Heartbleed et al. Or start with the free short guide “SSL/TLS Deployment Best Practices” in the Preview section on the book’s website.


Wednesday: The bigger picture

Great, we’ve hit the middle of the week and the todo items from the weekend are done, so let’s review something now! Give some thought to the changes or the new features from the past week. What are the security implications? Let’s say somebody added a feature to change a user’s email address. That sounds like a normal feature. And it’s secure by itself, because only the user can change her own email address. But today it’s about the big picture and you’re thinking: What if somebody somehow gained access to an account? That means she could simply take over the entire account by just changing the email address. And from there she could use the “Forgotten password” feature to create a new password which will be sent to the new email address. So you can effectively change the password without knowing the old password, that’s the inconsistency here.

It’s easy to overlook these problems in a busy daily schedule. So what will you do if you have a security strategy here? Ask for the user’s password to change the email address or verify the change with a confirmation email to the former address.

So today, you go through the changes and ask:

  • What if this new field had a special value from somewhere else in the app (an ID from somebody else), or was empty or nil?
  • What will happen to this feature if you copy and paste cookies, tokens, links, IDs from elsewhere?
  • If something bad happened, would this feature make it even worse? As in the example from above. Or if someone gained access to an admin account, would all client data be gone then?
  • What would happen if the user first clicked this new link and then clicked another unexpected link somewhere else in the app?

If this is the first time you do this reflection, look at the critical areas first: Cookies, sessions, authentication, authorization, user accounts, API, and configuration. And limit the time you spend on this. Otherwise you won’t want to do it next week, because it took too long last time.


Thursday

This is another day for reflection because the weekend is still miles away. How about thinking about the “what if” today? What if somebody is trying to brute-force the app, will you notice or be able do something against it? What if someone managed to inject Cross-Site Scripting (XSS) code into the whole application? What if you suddenly have to revoke 300 compromised API keys? Many things can go wrong in a public web application. I think it’s important to be ready for the unexpected. With a security strategy, you’re ready for at least some incidents because you’ve prepared little command line tools and checklists. You can quickly revoke access of some users. You see who is affected by a security breach. You can see what happened. You can quickly develop, test, and deploy a fix. You have a way to notify affected users and ask them to change their password. You have a manual step-by-step script ready to react quickly and not forget important steps. That’s what will set you apart from other applications.

Friday

Well, it’s Friday (hurrah!), so, let’s do something automatic. Today you can run static code security analysis tools like brakeman. Or you can verify that all code follows a style guide, for example with Rubocop. Start with a weekly run because it might be quite some work to do all the fixes that these tools recommend. Only then you could run them more often, or even on a continuous integration (CI) server.

Also, keep a SECURITY.md file in your repository and note when it was last run, who’s responsible for it and what the result was.

Some of it might sound like boring assembly-line work, but the boring things ensure steady quality and security. Ask franchise businesses. Don’t spend too much time every day if you’re usually busy, otherwise it will be like a New Year’s Resolution: The first week of January we’re motivated… but then we go back to our old habits. So instead of doing too much in the first week, move some tasks to the next week.

Bonus

And here’s another habit that is “on-demand”. If you’re the only developer in the “team”: Check your code again before you commit. I use gitk (I’m sure there are better tools) to read through all the changes before each commit and think about the implications for security (and quality) again. It’s amazing how much you can spot by yourself with a little reflection before handing changes in. Over time you’ll develop a way of thinking when doing this. You’ll ask yourself what would happen if this variable was empty, nil, or something unexpected.

And if you’re in a team, reviewing the changes of your colleagues is an effective way to ensure quality and security. Some teams also use pull-request cycles with great success.


One more thing, you like learning, right? Maybe you want to keep a list of topics or Rails methods to look up one day (how about today?). Let’s say that in your code review you come across the sanitize method and think, “How secure is it really?”. And indeed, there’s a huge difference between the newest version and the older implementation that “does it’s best”.

Right, there’s the week.

Tl;dr: In summary, it’s a set of mini habits for every workday to achieve a little progress in all the different aspects of security. Of course you can swap the days and do a different habit on Monday. Or you can add your own procedure to it.
Written  by Heiko Webers

If you found this post interesting, follow and support us.
Suggest for you:

The Complete Ruby on Rails Developer Course

Learn Ruby on Rails from Scratch

Ruby Scripting for Software Testers

Python, Ruby, Shell - Scripting for Beginner

Professional Rails Code Along

Friday, August 12, 2016

Building a RESTful API in a Rails Application_part 2 (end)


4.2.2 ProjectsController
  1. class ApiProjectsController < BaseApiController
  2.   before_filter :find_project, only: [:show, :update]
  3.   before_filter only: :create do
  4.     unless @json.has_key?('project') && @json['project'].responds_to?(:[]) && @json['project']['name']
  5.       render nothing: true, status: :bad_request
  6.     end
  7.   end
  8.   before_filter only: :update do
  9.     unless @json.has_key?('project')
  10.       render nothing: true, status: :bad_request
  11.     end
  12.   end
  13.   before_filter only: :create do
  14.     @project = Project.find_by_name(@json['project']['name'])
  15.   end
  16.   def index
  17.     render json: Project.where('owner_id = ?', @user.id)
  18.   end
  19.   def show
  20.     render json: @project
  21.   end
  22.   def create
  23.     if @project.present?
  24.       render nothing: true, status: :conflict
  25.     else
  26.       @project = Project.new
  27.       @project.assign_attributes(@json['project']
  28.       if @project.save
  29.         render json: @project
  30.       else
  31.          render nothing: true, status: :bad_request
  32.       end
  33.     end
  34.   end
  35.   def update
  36.     @project.assign_attributes(@json['project'])
  37.     if @project.save
  38.         render json: @project
  39.     else
  40.         render nothing: true, status: :bad_request
  41.     end
  42.   end
  43.  private
  44.    def find_project
  45.      @project = Project.find_by_name(params[:name])
  46.      render nothing: true, status: :not_found unless @project.present? && @project.user == @user
  47.    end
  48.  end
The todos controller will look similar, even having to find a project in order to fulfill the RESTfulness requirement (one uniquely identifiable resource per endpoint).

4.2.2.1 Defensive Programming

Defensive programming is a software design principle that dictates that a piece of software should be designed to continue functioning in unforeseen circumstances. Because your API will be exposed to third-party developers, allowing them to submit arbitrary inputs, it is important to apply this practice in API design.

This is why has_key? is used above rather than simple existence checking. If @json['project'] came in as false, or null, a simple existence check would return false, even though we can not say with any degree of accuracy that no JSON request body will ever have a false node at a depth of one.

The more significant defensive choice was the inclusion of responds_to?(:[]). This is due to the fact that, if the request body were say {"project": "noteIAmNotAnObject"}@json['project']['name'] would result in a server error. In the spirit of defensive programming, when building APIs, ask yourself, "what is the least expected, most random, or most malicious input a user can submit?" Then write code to handle it.

4.2.2.2 HTTP Status Codes

While it is tempting to simply return 200 (OK), 404 (Not Found), and 500 (Internal Server Error), HTTP status codes — very much like HTTP verbs — have well-defined meanings. For the benefit of other developers, use status codes that make sense. For example, if we have a uniqueness constraint on Project name, we should return a conflict status on creation attempt for name clashes to let the developers understand where they went wrong.

The exception to the rule is when an item exists but the API user does not have the right access privileges to act on it. While it might be tempting to return a 403 (Forbidden), this in and of itself provides an attacker with information about the existence of the item. Instead, return a 404 if the user cannot access the record, no matter what the reason.

4.2.2.3 Code DRY?

While the above does achieve the desired result, it is far from DRY. There are repeated JSON validations and a duplicate database read, once for read only on update, and once for update rejection on a non existing item for create. Additionally, any nested route, such as /api/v1/projects/:name/todos will require the same find methods so as to uniquely identify the correct resource.

5 A better way

First, we'll extract functionality common to all API endpoints into the BaseApiController.
  1. def validate_json(condition)
  2.   unless condition
  3.     render nothing: true, status: :bad_request
  4.   end
  5. end

  6. def update_values(ivar, attributes)
  7.   instance_variable_get(ivar).assign_attributes(attributes)
  8.   if instance_variable_get(ivar).save
  9.     render nothing: true, status: :ok
  10.   else
  11.     render nothing: true, status: :bad_request
  12.   end
  13. end

  14. def check_existence(ivar, object, finder)
  15.   instance_variable_set(ivar, instance_eval(object+"."+finder))
  16. end
This turns the create and update methods into calls to update_values, while the Project JSON validations call validate_json:
  1. before_filter only: :create do |c|
  2.   meth = c.method(:validate_json) 
  3.   meth.call (@json.has_key?('project') && @json['project'].responds_to?(:[]) && @json['project']['name'])
  4. end
  5. before_filter only: :update do |c|
  6.   meth = c.method(:validate_json)
  7.   meth.call (@json.has_key?('project'))
  8. end
  9. before_filter only: :create do |c|
  10.   meth = c.method(:check_existence)
  11.   meth.call(@project, "Project", "find_by_name(@json['project']['name'])"
  12. end
  13. def create
  14.   if @project.present?
  15.     render nothing: true, status: :conflict
  16.   else
  17.     @project = Project.new
  18.      update_values :@project, @json['project']
  19.   end
  20. end
The other, possibly more significant improvement is introducing a multi-tiered inheritance hierarchy into your controllers. A good way to break this out is based on route nesting. Todos are nested within Projects; therefore, any Todo will need to find a Project.
  1. class ApiProjectRouteController < BaseApiController
  2.   private
  3.     def find_project
  4.       @project = Project.find_by_name(params[:name])
  5.       render nothing: true, status: :not_found unless @project.present? && @project.user == @user
  6.     end
  7.     def find_todo
  8.       @todo = #...
  9.     end
  10.     #other finders also go here.
  11. end      
ApiProjectsController now needs to inherit from ApiProjectRouteController rather then BaseApiController.
  1.  class ApiProjectsController < ApiProjectRouteController
  2.    #...
  3.  end
  4.  class ApiTodosController < ApiProjectRouteController
  5.    #...
  6.  end
6 Custom behavior

Unfortunately, APIs do not exist in a vacuum. The system will have its own set of predefined behaviors, and on occasion, despite the best of intentions it will be necessary to expose behavior through the API that is not available otherwise, or may even clash with the application's existing behavior. A specific, fairly common example would be the relaxing of validations.

For the sake of clarity, let us walk through an example. Let's assume that our system's Project model has a priority column that is required.
  1. class Project < ActiveRecord::Base
  2.   has_many :todos
  3.   belongs_to :user
  4.   validates :priority, presence: :true
  5.   validates :name, presence: :true
  6. end
Now let us assume that a major customer would like to integrate an in-house solution that allows Project Managers to bulk create Project entries without priority, as priorities have not yet been decided. However, the regular UI users should not gain these increased privileges. How could this be achieved? In short, we need the model to be aware of the request source, and apply one set of validations in case the request came from the API, and another otherwise.

The first thing to do, is to add this concept at the controller level. Adding a method to the BaseApiController:
  1. before_filter :indicate_source
  2. def indicate_source
  3.   @api = true
  4. end
The second thing to do is to allow the model to validate conditionally.
  1. class Project < ActiveRecord::Base
  2.   after_initialize :set_ivars
  3.   has_many :todos
  4.   belongs_to :user
  5.   validates :priority, presence: :true, if: lambda{ |model| model.instance_variable_get(:@strict_priority_validation) }
  6.   validates :name, presence: :true
  7.   private
  8.     def set_ivars
  9.       @strict_priority_validation = true
  10.     end
  11. end
Now every time a model is instantiated it will set its validations to be strict, and apply the priority validation if strictness is true.

The final piece of the puzzle is sharing state between the controller and the model to override model level instance variables. To do this, we can define a PORO (Plain Old Ruby Object):
  1. class ProjectValidationPicker
  2.     def pick_a_validation(project, api=false)
  3.         if api
  4.            project.instance_variable_set(:@strict_priority_validation, false)
  5.         else
  6.           project.instance_variable_set(:@strict_priority_validation, true)
  7.         end
  8.     end
  9.  end
And for the final piece of the puzzle, this object needs to be used on update/create. Handily, we already have a function on BaseApiController to do just that. Lets change this method to pull in a validation picker if it exists and to set the api appropriately.
  1. def update_values(ivar, attributes)
  2.   instance_variable_get(ivar).assign_attributes(attributes)
  3.   validation_picker = check_validation_picker_existence(ivar)
  4.   validation_picker.send(:new).pick_a_validation(instance_variable_get(ivar), @api) if validation_picker
  5.   if instance_variable_get(ivar).save
  6.     render nothing: true, status: :ok
  7.   else
  8.     render nothing: true, status: :bad_request
  9.   end
  10. end
  11. def check_validation_picker_existence(ivar)
  12.   Module.const_get (ivar.to_s[1..-1] + "_validation_picker").camelize rescue false
  13. end
7 Debugging

Unfortunately, no code is ever perfect the first time it is written. While a detailed analysis of either of these tools is outside the scope of this article, it is worthy of note that both the Unix curl command, and the Google Apps Postman REST client allow crafting of custom requests to arbitrary endpoints.

8 Testing

With the code above, we have created a flexible, DRY, RESTful API. It allows us to have behavior that is unique to the API, while maintaining the same Database Models. But how can this be tested? Since the bulk of the lifting is done at the controller level, and since every request is a stateless transaction, request level specs are the most obvious fit. The simplest way to achieve this is controller tests, which do not differ significantly from the usual model for controller endpoint tests. Fundamentally, we craft JSON requests, and send them to the endpoints. A simple example might look something like this:
  1. describe ApiProjectsController do
  2.   before do
  3.     @base_json = { api_token: @user.api_token }
  4.     @project_json = {project: {priority: "4", name: "foo"}}
  5.     @new_project_json = @base_json.merge(@project_json)
  6.   end

  7.   describe "actions" do
  8.     describe "#create" do
  9.        before do
  10.         @request.env['RAW_POST_DATA'] = @new_project_json.to_json
  11.          lambda do
  12.           post :create
  13.         end.should change(Project, :count).by(1)
  14.       end

  15.      it "returns ok" do
  16.         expect(response.status).to eq(200)
  17.         expect(Project.all.last.priority).to eq(@new_project_json[:priority])
  18.         expect(Project.all.last.name).to eq(@new_project_json[:name])
  19.       end
  20.     end
  21.   end
  22. end
9 Other approaches and considerations

It is worth mentioning that the code outlined above represents only one possible approach to building a RESTful API in a Rails app. In fact it has made two, relatively significant tradeoffs.
The first, is that every request requires its own authentication. It is possible to avoid making this sacrifice using session cookies which Devise can also generate. I would argue that this complicates third party integration as it requires the developer to keep track of the session cookie, passing it in with every request instead of the api_token, as well as handling session expiration. In addition, it leaves the system exposed to attack, if the cookie origin is not scrutinized sufficiently, or even if the API consumer stands up to go to the restroom.
The second is that the in-house UI does not by default hit the same API endpoints. One solution would be to have Devise generate and expire a secondary, UI-only auth token, which does not trigger the API validation (maintains @api as false in BaseApiController), this may be stored in another column, or a different datastore entirely. Non-persistent in-memory datastores like Redis are particularly well suited to this application.
Finally it is worth noting that while this demo simply returns the entire resource, it is best practice to use a serializer to limit the subset of keys returned to what it is safe and/or necessary to expose.
10 Summary

We have covered how to build a REST api in an existing Rails application from the ground up, how to expose the endpoints, how to route to them, and how to allow custom behavior. We have touched on testing and debugging. While the example was fairly trivial, it is my hope that you can use it as a template for building scalable, reusable APIs.
Written by Abraham Polishchuk

If you found this post interesting, follow and support us.
Suggest for you:

Ruby Scripting for Software Testers

Python, Ruby, Shell - Scripting for Beginner

Professional Rails Code Along

Thursday, August 11, 2016

Building a RESTful API in a Rails Application_part1


1 Introduction

There comes a time in the development lifecycle of most web applications when a third-party integration becomes necessary. One of the simplest ways to do so is to expose a REST API for consumption. This article will walk you through a possible approach to designing and implementing a REST API in an intentionally simplistic task management web application, and will cover some best practices to ensure maintainability of the code.

2 Requirements, Assumptions

This article is going to assume some familiarity with the Rails framework, the Ruby programming language in general, and at least some familiarity with the Rails ecosystem by way of Devise, RSpec, and Capybara. When this does not significantly impact DRYness (DRY stands for "Don't Repeat Yourself," a mantra of software development), the more verbose syntax was intentionally chosen for readability.

2.1 The theoretical application

We will build out an API which corresponds to a task management application. It will contain a User model to represent users with access to the system, a Project model to represent projects, and a Todo model representing specific tasks to be done within a project. As such, a User will have many Projects, and a Project will have many Todos.

3 Theory. What makes an API RESTful?
  • + Statelessness: Client state should not be stored on the server between requests. Said another way, each individual request should have no context of the requests that came before it.
  • + Resource identification per request: Each request should uniquely identify a single resource. Said differently, each request that modifies the database should act on one and only one row of one and only one table.Requests that only fetch information should get zero or more rows from one table.
  • + Representational state transfer: The resource endpoints should return representations of the resource as data, usually XML or JSON. The returned information should be sufficient for the client to uniquely identify and manipulate the database row(s) in question.
While there are other criteria which need to be fulfilled for a theoretically pure REST API, these suffice in practice.

4. A basic REST API in Rails

4.1 Routes

Rails provides a fantastic tool for defining endpoints in the form of routes:
  1. ApiDemoApp::Application.routes.draw do
  2.   scope '/api' do
  3.     scope '/v1' do
  4.       scope '/projects' do
  5.         get '/' => 'api_projects#index'
  6.         post '/' => 'api_projects#create'
  7.         scope '/:name' do
  8.           get '/' => 'api_projects#show'
  9.           put '/' => 'api_projects#update'
  10.           scope '/todos' do
  11.             get '/' => 'api_todos#index'
  12.             post '/' => 'api_todos#create'
  13.             scope '/:todo_name' do
  14.               get '/' => 'api_todos#show'
  15.               put '/' => 'api_todos#update'
  16.             end
  17.           end
  18.         end
  19.       end
  20.     end
  21.   end
  22. end 
4.1.1 Naming

While Rails will let you use PUT and POST more or less interchangeably, your API will be consumed by other developers. As such, it is best practice to go for the principle of least surprise – POST for create, PUT for update, PATCH for upsert (update and insert). Another reason to use the correct methods is that your application will be maintained by developers who are not you, possibly long after you are gone. Using methods which conform to standard practice (index, show, create, and update) ensures that this is a simpler task.

4.1.3 Versioning

Once your API is exposed, you need to assume that somebody is consuming it. Therefore, an existing API should never be modified, except for critical bugfixes. Rather than changing existing endpoints, expose a new version. One way to do this might be to create versioned controllers and routes (as above). With comprehensive test coverage, backwards compatibility can be ensured. A corollary of the above is that one should only expose an API that has gone through rigorous internal testing.

4.1.4 Route Parameters

While it is possible to identify routes based on the id column of the targeted resource, this does presume a higher degree of knowledge by the consuming application. A deliberate tradeoff — that needs to be made on a case by case basis — using unique database ids in the route chain allows users to access short routes, and simplifies resource lookup, while exposing internal database ids to the consumer and requiring the consumer to maintain a reference to ids on their end. Using public, but possibly not unique, identifiers like name reduces the amount of system internals that needs to be exposed, while allowing the client to easily lookup any data needed to make a request. The downfall is longer nested routes.

4.2 Controllers

4.2.1 BaseController and Authentication

A base API controller is useful to handle authentication and extract common API functionality. There are many possible schemes, but a common approach is to require reauthentication on a per-request level. This is probably the simplest way to ensure statelessness.
  1. class BaseApiController < ApplicationController
  2.     before_filter :parse_request, :authenticate_user_from_token!

  3.     private
  4.        def authenticate_user_from_token!
  5.          if !@json['api_token']
  6.            render nothing: true, status: :unauthorized
  7.          else
  8.            @user = nil
  9.            User.find_each do |u|
  10.              if Devise.secure_compare(u.api_token, @json['api_token'])
  11.                @user = u
  12.              end
  13.            end
  14.          end
  15.        end

  16.        def parse_request
  17.          @json = JSON.parse(request.body.read)
  18.        end
  19.     end
4.2.1.1 Security

Devise.secure_compare helps avoid timing attacks. While the comparison algorithm used by Devise is not strictly speaking constant time as it uses newly allocated memory and is capable of invoking the Garbage Collector as a result, it is much nearer constant time then custom comparison routines. Similarly, the Users loop does not break, thus preventing an attacker from establishing api token validity based on response time.
Written by Abraham Polishchuk

If you found this post interesting, follow and support us.
Suggest for you:

The Complete Ruby on Rails Developer Course

Learn Ruby on Rails from Scratch

Ruby Scripting for Software Testers

Python, Ruby, Shell - Scripting for Beginner

Professional Rails Code Along