Authenticate your QA’s

Ben
Smart Pension Technology
3 min readDec 3, 2018

--

For an easy life, get into your authenticated application without having to type in a username and password.

TLDR; add a custom strategy in here:config/initializer/devise.rb like so:

config.warden do |manager|
manager.strategies.add(:qa_mode) do
def valid?
ENV['RAILS_ENV'] == 'staging`
end
def authenticate!
user = User.find_by(email: QA_USER_EMAIL)
user ? success!(user) : fail('Could not find qa user')
end
end
manager.default_strategies(scope: :admin_user).unshift(:qa_mode)
end

We deploy many times a day. It could be fresh features, optimisations or bug fixes, one constant is quality. To ensure that quality we have team of dedicated, laser sighted QA engineers hammering away at our application weeding out any defects that slipped through the test suite.

A QA’s job is hard one, and as as a developer you can help improve their lot by making repetitive tasks less painful. For a QA there is nothing more repetitive than logging into the application.

Take our admin system for example, when a change is made to this area, a QA Engineer will be required to go the freshly deployed review app, create a admin user, then visit the admin url, type in the email address, type in the password, click login then finally they are ready to start the QA process.

How can we improve this?

We use Ruby on Rails and the Devise gem for authentication, so whenever we call the method to trigger authentication

authenticate_admin_user!

we want to just authenticate, rather than ask for a username and password. We also want to avoid scatteringif statements in our code to check if we are running in test mode

Add the new strategy

Add a new strategy to Warden (which Devise uses under the hood), either inline like so:

config.warden do |manager|
manager.strategies.add(:qa_mode) do
...
end
end

Or add a class which implements the strategy like this:

config.warden do |manager|
manager.strategies.add(:qa_mode, MyApp::Devise::Strategy)
end

Choose whichever you find best suites your needs.

The Strategy

Warden has a number of strategies it uses for authentication. It will run through the list until it authenticates, fails or gets to the end of the list.

With the above in mind the most simple strategy contains only 1 method

def authenticate!
...
end

This should result in calling 1 of three other methods

success!(user)

Calling this method tells warden to stop running through strategies and authenticate using the passed in object.

fail(“failure message”)

Calling this method tells warden to continue to the next strategies as this one has failed.

fail!(“failure message”)

Calling this method tells warden to stop running through strategies and fail authentication.

A strategy can contain more methods which hook into Wardens logic, one of which is valid? .
Warden uses this to test if it can attempt to apply a strategy, in our strategy we use it to see if Rails is running in the staging environment, if so, it can apply the strategy if not, do not.
This is important as otherwise in production we would just be letting anyone into our admin system.

Apply the strategy

Now Warden knows of our new strategy, we can add the it to the front of list of strategies, using unshift like so:

manager.default_strategies(scope: :admin_user).unshift(:qa_mode)

Note the scope passed to default_strategies , this is needed as we want this strategy applied whenever we call authenticate_admin_user! as apposed to authenticate_user!

With all this in place our code can be well tested without hindering the QA team.

--

--