Login an account in feature test mode (Rspec request specs)

582 views
Skip to first unread message

Tiago Cardoso

unread,
Sep 12, 2016, 7:58:13 AM9/12/16
to Rodauth
I'm trying to replace a basic rails-devise stack with a roda-rodauth one. Although setting it up is easy, completely rewriting the specs might be a bit more cumbersome, specifically there is already a lot of support for rspec and capybara/cucumber. 


My main issue right now is finding or adding replacements to the rspec/capybara helpers. For instance, the warden gem (which devise builds on top of) adds its own spec helpers within the gem: https://github.com/hassox/warden/blob/master/lib/warden/test/helpers.rb . The main "feature" here is the "login_as" method, which will mock a valid authenticated user session when triggering the request spec. 

I haven't seen similar helpers in rodauth, nor a description on how to develop your own. Is this something which could be feasibly implemented?

Jeremy Evans

unread,
Sep 12, 2016, 10:56:47 AM9/12/16
to Rodauth
There's nothing built in, but this should be fairly easy:

visit '/login'
fill_in "login", :with=>'f...@bar.com'
fill_in "password", :with=>'valid_password'
click_button 'Login'

Modify that as appropriate and stick it in a method, then call it in a before block or elsewhere where you want to login.

Thanks,
Jeremy

Tiago Cardoso

unread,
Sep 14, 2016, 2:39:42 AM9/14/16
to Rodauth
I was aware that simulating a login/logout would be the quickest way to go. However, I was looking more for a built-in way to build the authenticated session directly (I was concerned about those pesky controller specs, and even rack-test). As these might be perceived as an anti-pattern, I'll have to agree if you don't see any value in adding these methods, although these could easen possible migrations. 

Jeremy Evans

unread,
Sep 14, 2016, 11:06:17 AM9/14/16
to Rodauth
On Tuesday, September 13, 2016 at 11:39:42 PM UTC-7, Tiago Cardoso wrote:
I was aware that simulating a login/logout would be the quickest way to go. However, I was looking more for a built-in way to build the authenticated session directly (I was concerned about those pesky controller specs, and even rack-test). As these might be perceived as an anti-pattern, I'll have to agree if you don't see any value in adding these methods, although these could easen possible migrations. 

As far as I know, there isn't anything for building authenticated sessions directly, though as long as you have access to the session secret, you should be able to do so.  Note that building authenticated sessions directly would not be specific to Roda or Rodauth, but anything using Rack::Session::Cookie, so you should probably discuss such a project on a rack-specific forum.

Thanks,
Jeremy 

Tiago Cardoso

unread,
Sep 16, 2016, 10:09:51 AM9/16/16
to Rodauth
Continuing on the topic, and what jwt support concerns for APIs, I don't have a login form to simulate authentication. The only way is to build a jwt token. For that, I've built the following helper method in my setup: 

 def jwt_token(user)
    @jwt_token ||= begin
      session    = { account_id: user.id }
      jwt_secret = ENV["JWT_SECRET"]
      jwt_algorithm =  "HS256" 
      JWT.encode(session, jwt_secret, jwt_algorithm)
 end

You can already see that the problem here is, I set the project jwt_secret and jwt_algorithm, among others, directly when setting up rodauth, and there is no way to access them from the outside, which means that, as soon as I switch the defaults, this method will not work anymore. Is there a way to access roda plugin configuration variables, or would this be a feature worth implementing?

Jeremy Evans

unread,
Sep 16, 2016, 10:44:13 AM9/16/16
to Rodauth
Note that Rodauth does not support usage of JWTs that it did not itself generate, so you are kind of on your own here.  One supportedway to do things with the existing API would be to make an internal JSON request to the login endpoint, but instead of returning the JSON directly to the client, process it internally.

That being said, you should be able to get all metadata you want via rodauth.jwt_secret and rodauth.jwt_algorithm.  I'm open to extracting out a method from set_jwt that you could call (maybe rodauth.jwt) that would do what you want.

Thanks,
Jeremy

Tiago Cardoso

unread,
Sep 19, 2016, 3:00:07 AM9/19/16
to Rodauth
The API login endpoint seems to be a decent solution. In case you have some documentation on how to easen migration from devise/warden to rodauth, I'd highly recommend you adding this suggestion, it is very helpful. 

Jeremy Evans

unread,
Sep 19, 2016, 11:38:32 AM9/19/16
to Rodauth
On Monday, September 19, 2016 at 12:00:07 AM UTC-7, Tiago Cardoso wrote:
The API login endpoint seems to be a decent solution. In case you have some documentation on how to easen migration from devise/warden to rodauth, I'd highly recommend you adding this suggestion, it is very helpful. 

There currently is no documentation on migration from Devise/Warden to Rodauth.  I'm not sure documentation on an API login endpoint would make sense in regards to a Devise migration, since as far as I know, Devise itself does not support an API mode (you have to use an external extension to Devise).

I don't have any personal experience using Devise or Warden, so I'm not qualified to write such a migration guide.  However, I'd certainly consider accepting such a guide if it was submitted as a pull request.

Thanks,
Jeremy
Reply all
Reply to author
Forward
0 new messages