Removing An Included Module From A Class IN RUBY

Q - What happens when a module is included in a class?
A - As per the documentation, Module#append_features is called by Module#include which in turn adds the constants, methods and module variables.

Q - So how the members of a module be removed from a class?
A - Looks like there are two options. Use Module#undef_method or Module#remove_method. Module#undef_method prevents the class from responding to calls from the method. Module#remove_method completely removes the method from the class. What this means is that Module#undef_method will cause a class to throw NoMethodError even if the method is defined in a super class. Module#remove_method will just remove the method from the class leaving the super class methods intact.

Module#remove_method looks a probable solution. So let's set up a test where a module called Print that gets input and puts output.

Let's create a class Hello that uses this module to get the name of the user and greet the user.

Lets add an exclude method to Module

And finally, the actual test

When this test is executed the console output is

Q - So Module#include is not literally including the methods in the Print module in Hello class?
A - Yes and Ruby seems to be doing something else that makes it seem so. Thankfully, Ruby is Open Source and this function in MRI from the class.c file will answer our questions.

A cursory look at this function tells us that at line number 31 & 32, the module is inserted into the class hierarchy. This can be verified by printing Hello.ancestors

Q - Does Ruby provide a way to alter the class hierarchy?
A - No. So we'll have to make do with using Module.undef_method instead of Module.remove_method in our implementation of Module.exclude. After swapping out remove_method for undef_method the exclude method works.

Oh and if someone is interested in building an Object#unextend, Object#extend in turn calls Module#include so the procedure should be almost the same as for Module#exclude.

Shishir is an engineer at C42 Engineering. If you liked this post, please consider...

/

HMAC-Based API Authentication in Ruby

Username and Password based authentication is for humans. It is insecure for communication between applications. To establish a secure communication between REST client and service we prefer HMAC method for authentication. And to keep things simple,  we put in place an example to authenticate client requests. We'll hand roll a REST client using ruby net http library. Connect that client to E4 payment gateway and 
accept telecheck payments. E4 exposes a legacy REST services. Which doesn't encrypt transaction and response code is always HTTP OK - 200. We should always encrypt any sensitive data sent to any REST service and use appropriate HTTP codes in responses.

When we consider security for REST based APIs, we often go with HTTPS. HTTPS creates a secure channel over an insecure network. This ensures reasonable protection from eavesdroppers and man-in-the-middle attacks, provided that adequate cipher suites are used and that the server certificate is verified and trusted. HTTPS piggybacks HTTP entirely on top of TLS, the entirety of the underlying HTTP protocol can be encrypted. However when we need an additional level of security, HTTPS doesn't cut out well. We need an alternative, for instance we might need to track usage of our API for each customer and need to know exactly who's making the calls.

A common way to solve this problem is by signing the message based on a shared secret between the client and service. This signature is called HMAC (Hash-based Message Authentication Code), with which we create a message authentication code (MAC) for a request based on a secret key that we've shared.

Client calculates the HMAC key based of HTTP-Method, Content-SHA1, Content-Type, Data Header and Path. Client then sends that signed request to service. Service on the other hand normalizes the request in the same manner as the client did, and calculates the HMAC value. If the HMAC from the client matches the calculated HMAC from the server. Surety of message integrity is guaranteed and client can be easily identified.

Conclusion

Different REST services uses different ways to calculate HMAC. Some uses new lines (prefer using "\n" instead of '\n') while other uses commas or any other character for separating parameters. Read the API documentation carefully because if you miss out on one small thing like parameters separator. This will result in wrong HMAC calculation and API request won't authorize.

Ranjeet is an engineer at C42 Engineering. If you liked this post, please consider...

/

Rails and HTTP ERROR Status Codes

One of the things that is really important while writing a library for rails is being able to recognize the exceptions that are raised by the library and handling them appropriately, so that rails can translate the handled exception to an appropriate status code and a message for the client.

The mapping between the exceptions and the corresponding rails error symbols is made available to us as a mutable hash, class variable rescue_responses on ActionDispatch::ExceptionWrapper.

To add the status corresponding to the exceptions that are raised by the library, a way to do it is by adding

config.action_dispatch.rescue_responses.merge!( 'MyEngine::SomeError’ => :unprocessable_entity)

to the library’s Railtie. This would imply that when the exception MyEngine::SomeError is raised, it is handled as an unprocessable_entity.

Rails leverages rack/utils library’s SYMOBL_TO_STATUS_CODE to translate the error symbol to an appropriate status code.

References: https://github.com/rack/rack/blob/master/lib/rack/utils.rb#L576 for a list of HTTP status codes and messages that are available on rack.

https://github.com/rails/rails/blob/master/activerecord/lib/active_record/railtie.rb#L25 is an example of how activerecord exceptions are mapped to the corresponding rails error symbols.

Vineeth is an engineer at C42 Engineering. If you liked this post, please consider...

/

Debugging Ruby on Rails applications

LOGS

This one of the best tools in your toolbox. Logs are great for both debugging and for application analytics.

For maximum detail, the log level should be set to 'debug'. Rails' development mode, for example, defaults the log level to 'debug'.

In Rails you can enable logs by changing the following configuration in the relevant environment initializer file.

 

The available log levels in are: :debug, :info, :warn, :error, :fatal, and :unknown.

Rails logs many events (like requests and responses) by default, but this is rarely sufficient for a typical production application. You will need to also log other information that is relevant to your problem or solution.  Let’s do this through an example.

Ive a web application written in Rails which allows users to register with their email addresses. I also have requirement to allow users to register with valid email addresses. To check validity weve registered with a third-party email validation service. This validation service provides a REST APIs over HTTP, but does not offer a ruby library to integrate with our Rails application.

Let’s take look at the following code snippet.

It works correctly and validates email address but we don't know what was the response sent by the email validation service was.   

We can improve the situation by adding logging statements.

When logging, one must consider storage, security and performance implications, especially when logging to disk. Be cautious about what you log, and how much is being logged.

Using the :debug level will have a greater performance penalty than :fatal, as a far greater number of strings are being evaluated and written to the log output (e.g. disk).

meta-programming

Let's re-use the previous example. In this scenario, let’s assume the ruby client for the email validation service API does not have a logging feature.  

Great. Now in production, we discover that users are unable to register because the email validation service is consistently returning an invalid response. How do we examine the response to determine the cause? Let’s look at the following code.

I’ve temporarily (while I’m debugging ruby client) redefined validate method for EmailValidationService in users controller, adding logging feature to ruby client. This way, I should be able to log the response from validation service. This is one of easiest way to add basic debugging support to third-party gems.

Debugging tools

Special purpose debugging tools allow for powerful, interactive debugging. There are several popular tools in the space, with a great deal of material on their respective sites. Here are three popular debuggers:

Better Errors : https://github.com/charliesome/better_errors

Byebug : https://github.com/deivid-rodriguez/byebug

Pry-debugger : https://github.com/nixme/pry-debugger

Sumit is an engineer at C42 Engineering. If you liked this post, please consider...

/

Ruby Arrays: The difference between copy and dup

On the occassions that I need to clone something in Ruby, that something is usually a custom object, or an array containing custom objects.

Choices

Ruby offers Object#clone and Object#dup as standard features. But what exactly is the difference?

The (now sadly retierd) RubySpec suite is usually the best place to evaluate questions like this one.

As you can see from the excerpts above, at the Object level the difference is that clone copies over the frozen state of the source object, dup does not.

If you're interested in the common behaviours of clone and dup, they are defined in this shared spec.

Arrays

Arrays do a little bit more, of course. Once again, here are the RubySpec specs that show the differences between clone and dup for Arrays.

Basically, clone will (in addition to copying the frozen state) also copy over any singleton methods that have been defined exclusively on the source instance of the Array. dup will not.


Sidu is a Partner at C42 Engineering. If you liked this post, please consider...

/