Blog @ ckgagan

Sharing Sharing Sharing.

Ask Confirmtion of User Before Leaving the Page.

Its really annoying when the page redirects to previous page while filling up the form by accident. Specially in chrome when the form field is not in focus and the user hits backspace button, the page gets redirected to previous page. We can stop this by asking the confirmation to user if they wanted to redirect to other page.

First of all we need to determine if we want to show the confirmation or not to the user when they tried to redirect from the page. We can use a variable for this. Lets say it to be

var needToConfirm = false;

and set it to false denoting that we don’t want to show the confirmation.

window.onbeforeunload event gets triggered everytime the page gets reloaded or redirected. We can attach a method to this event handler.

window.onbeforeunload = confirmExit;

Now we need a function that will return the confirmation message when this variable is set to true. The function might look like

function confirmExit()
{
  if (needToConfirm)
  {
    return "{message}";
  }
}

Here message is the string we want to show in confirmation box.

Lets take an example where user is filling up a form. When the form fields are updated, set needToConfirm variable to true. This way when the use tries to navigate away by accident, confirmation dialog will be displayed. But bear in mind, we need to set this variable to false when user clicks the submit button. This way the confirmation dialog will not be displayed while form is submitted.

Protect Sensitive Data Using 128 Bit Encryption

Protect sensitive data using 128 bit encryption

There comes a time, every developer need to protect sensitive information stored in database such as debit/credit card infomation(although I wouldn’t recommend to store such data) or other sensitive information of that level. That means we need to store those informations in such a way that its not readable directly(encrypted) and must be able to get the information back when needed. We can achieve this using ezcrypto gem. EzCrypto is an easy to use wrapper around the OpenSSL ruby library and uses AES 128 bit encryption algorithm. So lets see how can we use it in our ruby applicaiton.

First of all we need to require the gem

require 'ezcrypto'

Ezcrypto gem uses a key to encrypt the data and the key can be generated using a password and a salt. Then we use the key’s encrypt method to encrypt our sensitive data.

key = EzCrypto::Key.with_password('password', 'system salt')
encrypted_text = key.encrypt('This is the text we want to encrypt')

encrypted_text is the text we will be saving in database.

Now to decypher what has been encrypted and saved in the database, we need the same key which has been used for encryption else it will throw OpenSSL::Cipher::CipherError exception

key = EzCrypto::Key.with_password('password', 'system salt')
decrypted_text = key.decrypt(encrypted_text)

Best way to generate the key is to either get password from user himself while decryption or to use the user login password itself. We can store the system salt in our ruby application itself. This way we can make sure that the only user is able to decrypt the sensitive information.

Sample example is given below:

require 'ezcrypto'
begin
key = EzCrypto::Key.with_password('password', 'some system salt')
encrypted_text = key.encrypt('This is my secret text')

# key generated second time to decrypt the secret text
key = EzCrypto::Key.with_password('password', 'some system salt')

decrypted_text = key.decrypt(encrypted_text)
puts "The decrypted text is: #{decrypted_text}"
rescue OpenSSL::Cipher::CipherError
  puts "Error while decrypting"
end

#=> The decrypted text is: This is my secret text

If the key was generated with wrong password say “password1” and the key is used for decrypting the encrypted_text, the output would be

#=> Error while decrypting

ActiveRecord Like Callbacks Using ActiveModel

ActiveRecord like callbacks using ActiveModel

We have seen ActiveRecord callbacks which are executed before or after the object is created or updated. But how do we provide the similar interface for none persistent models. Well here ActiveModel callbacks comes to rescue. ActiveModel Callbacks provides an interface for any class to have Active Record like callbacks. Similar to active record, the callback chain is aborted as soon as one of the methods in the chain returns false.

First of all we will need to require active_model

require 'active_model'

then extend any ruby class with

class Transaction
  extend ::ActiveModel::Callbacks
end

Then we need to define a list of methods that we want callbacks attached to using define_model_callbacks

define_model_callbacks :withdraw, :deposit

Here :withdraw and :deposit are the methods where we want to attach callbacks

Defining callback methods using define_model_callbacks allows us to define methods which can be executed before, after and around the model methods ie:; withdraw and deposit methods

This will provide all three standard callbacks (before, around and after) for both the :withdraw and :deposit methods. To implement, we wrap the methods we want callbacks on in a block so that the callbacks get a chance to fire:

def withdraw
  run_callbacks :withdraw do
    # Our withdraw code here
  end
end

def deposit
  run_callbacks :deposit do
    # Our deposit code here
  end
end

run_callbacks tells to run callbacks along with the main model method.

Now we can define which method to execute when (before, after or around) the model method is invoked in the following way.

before_withdraw :check_if_authentic_user
after_deposit :send_confirmation

So we define check_if_authentic_user method and this method gets executed before withdraw method gets executed. Similarly send_confirmation method gets executed after deposit method gets executed.

So our class our overall code becomes

require 'active_model'

class Transaction
  extend ::ActiveModel::Callbacks

  define_model_callbacks :withdraw, :deposit

  before_withdraw :check_if_authentic_user
  after_deposit :send_confirmation

  def withdraw
    run_callbacks :withdraw do
      puts "Money withdrawn"
    end
  end

  def deposit
    run_callbacks :deposit do
      puts "deposited"
    end
  end

  def check_if_authentic_user
    puts "Checking if user is authentic"
  end

  def send_confirmation
    puts "Confirmation sent"
  end

end


transaction = Transaction.new
transaction.withdraw
transaction.deposit

Outputs

Checking if user is authentic
Money withdrawn
deposited
Confirmation sent

But if we return false from the callback method then the callback chain gets terminated.

For example replace check_if_authentic_user with this.

def check_if_authentic_user
  puts "Authenticating user..."
  false
end

Our output would be

Authenticating user...
deposited
Confirmation sent

Since callback method check_if_authentic_user returned false the main :withdraw method never gets executed