Do I need a "Users" controller when using Devise in Rails - ruby-on-rails-4

I am a Rails newbie. I am working on a small Rails4 project trying to improve my skills.
I am loosely following M.Hartl's tutorial.
As per the tutorial a custom user authentication is built.
However I would like to use Devise for User authentication.
Do I still need to have a Users controller as in the tutorial?
In which cases should I use/not use a Users controller when already using Devise?
Concerning the tutorial, do I just skip the controller generating part or do I have to map the actions to Devise?

You only need a users controller if you want to manage users separately from the normal signup/update process. I have a users controller so that admins can manage (create, edit, update, delete) users independently of the normal devise signup/update process.
The conflict with devise is probably because you have devise_for :users … in your routes file to set up devise and also have resources :users for your UsersController. This means that devise and your UsersController will be trying to share some of the same /users routes. You need to separate them out by changing the path that one of them is mapped to. You could either add, for example, :path => 'u' to your devise_for statement so that devise routes are mapped to /u and won't conflict with your UsersController on /users. Alternatively you could leave the devise_for alone (therefore still using /users) and instead change your UsersController routing to, for example, resources :users_admin, :controller => 'users' which would move your UsersControllers routes to be mapped to /users_admin. Note that this would change the path helpers from, for example, users_path to users_admin_path.
UPDATE
Following your comment/edit, I've had a quick look at the tutorial and I think that devise basically gives you the equivalent functionality of the user-related functionality which is developed from section 5.4 to about sections 9.1 or 9.2. (plus some extra stuff, for example, email confirmation, password reset, account lockout etc.). However, that doesn't mean that it's a drop-in replacement for that functionality, if you want to try and merge Devise with that tutorial. There are some things that look like they would work (e.g. Devise also defines a current_user method), but the routes etc. would be different, and devise splits things up into more controllers (separate controllers for registration, sign in/out, password reset…). The admin-type functionality (like in sections 2.2, 9.3, 9.4 - create/edit/delete/list other users) is what I've added a separate UsersController for in my app. Devise doesn't define a UsersController, but does use the users routes if you do devise_for :users without a path as I mentioned above.
So, more specifically:
You would only need a UsersController if you want to enable admin-type functionality allowing viewing/editing/deleting all users.
If you wanted to use devise in the tutorial, it would probably need some work to massage things to fit, changing helper links on pages etc. Sorry I'm not more specific; I haven't done that tutorial.
You would be missing out on the extra understanding that comes from doing it all manually yourself, but devise is a popular engine, so it's good to know as well. If you have the time, you could do the tutorial entirely, and then again with devise! It would help you understand some of the kind of stuff devise is doing behind the scenes. P.S: It can be instructive to look at the devise source code, even if you don't understand it all immediately.

Related

Ember Octane How to convert custom mixins

This question is related to: Does Ember Octane Route class support using mixins? Mixins are officially deprecated in Ember Octane.
Question:
What is the best option to replace Ember mixins with and how do I implement it?
Context:
I have custom mixins that expand functionality offered by ember-simple-auth (~v1.8.2), which was not available at the time the methods were created (see below). I am currently using ember-simple-auth 3.0.0 https://github.com/simplabs/ember-simple-auth. In the documentation on github, they appear to be using their own mixins on Ember Octane as you can see:
// my-engine/addon/routes/index.js
import Route from '#ember/routing/route';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default class IndexRoute extends Route.extend(AuthenticatedRouteMixin) {
triggerAuthentication() {
this.transitionToExternal('login');
}
}
It appears that I am not the only one having this issue as Simple Auth doesn't know what route they want to go down either: https://github.com/simplabs/ember-simple-auth/issues/2185
Options:
Pure native classes, sharing functionality via class inheritance.
Utility functions which can be imported and used in multiple classes.
Services which can be injected into multiple classes, sharing
functionality and state between them.
I have the following authentication mixins:
Application Route: This handles whether the user is logged in and whether the user has two-factor authentication (2FA) enabled, and if it is enabled, it verifies that the user has been authenticated through 2FA. This is because simple auth did not offer 2FA at the time of development of the mixin(s)
Authenticated Route: Makes sure the user is logged in. If they are not logged in then the user is routed to the login page. Once they login, they are routed back to the page that they initially tried to go to
UnAuthenticated Route: Prevents logged in users from going to certain routes that logged in users should not go to
Firstly I want to make very clear that mixins are not "officially deprecated" in Ember, and to my knowledge there's not even an active RFC about it. As the Upgrade Guides explain, Glimmer components do not support mixins due to not extending EmberObject, but the pre-existing framework classes (Route, Controller, etc) necessarily have to or it would be a breaking change.
There is no best option to replace mixins as it depends on the usage of the API. If you are asking how to replace ember-simple-auth mixins, my answer is that you can't until the addon itself provides alternative APIs. Mixins and the example code you posted will continue working for the foreseeable future.
You can see an example of using class inheritance to share functionality in this PR.
when i migrated to ember Octane i tried to replace ember-simple-auth mixins, i found that it would take me lot of time than rewriting my own authentication service, my example in this twiddle, i am using cookies, Auth service
if you are not using cookies , you could customize your adapter to include a token in the headers
I circled back with ESA on Git, and the same issue I cited in my OP has been closed with a new issue that has subsequently been merged:
https://github.com/simplabs/ember-simple-auth/pull/2198
ESA has now updated their library to get rid of route mixins.

React limit access to specific users

I'm building an App using react and django as backend.
I have JWT authentication set up and working. But I am wondering if it is safe to include menu items and logic of views that will be displayed only to specific users and will include sensitive information. Of course these views will only be visible to the relevant users.
My question is if it possible for someone to extract the info from the react build? And if so, what is the best practice to avoid such situation?
Your javascript code should not contain sensitive information. Such information should be dynamically fetched and checking permissions on a per request basis when the screen is actually rendered that needs to display it.
If you even want to hide certain screens so that users can't see certain features on your app that are not available to them you either need to bundle those screens into another app and serve that on another url or you can dynamically fetch javascript containing these views.
Usually this is not worth the effort as you should concentrate on correctly checking permissions for your api.
EDIT:
Assuming i'd like to dynamically fetch the JS with the sensitive views and add those to my app, how do i do that?
I assume you are using webpack 2 for bundling your react app? Then you need to use dynamic imports for the parts that need to be dynamically loaded. Then in django you need a custom view that serves your static files and checks for permission to access this part of your react app when it is requested.
This tutorial explains how to lazy load components using webpack 2.
I am guessing that you encode user roles in the JWT token itself and exact it using something like jwt-decode then match the to roles to render different components.
For example you might be doing something like check for a 'admin' role and render a link in nav bar for /admin route.Which i think i safe to do.
But what if a user looks into your code and sees that there's a /admin route and tries to access it?
So u also got to have logic inside the route to check for role 'admin' and serve something like a '404' if the role doesn't match.
You can dynamically fetch any route once the user role matches.

How to disable Spree API functionality from existing app

I have a Rails app developed using the Spree gem. For security reasons, I'd like to disable all the API functionality - ability to make REST calls, the methods, routes. I realize that most of the API functionality cannot be invoked without an API token.
What's the best way to 'turn off' the API features?
Best way == least intrusive to existing code base
The best I've come up with so far is adding this to my host application's application.rb inside the Application class:
initializer "delete_spree_api_routes", after: "add_routing_paths" do |app|
app.routes_reloader.paths.delete_if { |path| path =~ /\/spree(-[^\/]+)?\/api\/config\/routes.rb/ }
end
What this does is immediately deletes all of the paths from the routes if they were loaded from routes.rb provided by the Spree API. It's a bit ugly but it does the job.
EDIT: I'd recommend being careful with this as Spree uses its own API in a few cases such as retrieving the list of states for a country (GET /api/v1/states)

cancancan and devise testing for rails app

I've been researching how to test my Ability and Users for a small test rails wiki i'm building and i'm having difficulty wrapping my brain around how to test either or both ?.
I think i'd like to sign_in a user as admin/editor etc. and test that user behaves like it should. I'd like to also test that Pages are displaying the correct information for an authenticated user.
This is more then one problem and i'm looking for some basic nudging less then an answer :).
I use Rspec, Cancancan, Rails 4 and devise for authentication.
I've read up on a few ways none of which worked for me:
Cancan example
Another ex i tried for cancan
Devise and rails 4 I'm using route authentication for devise.
Devise and sign_in
In any case here are my files. I'll just link to my git repo
my abilities.rb
pages.rb
users.rb
pages_controller.rb
I have factories as well but what's the trick to doing the following
Signing in users: The examples suggest using the devise test helpers then creating a signed_in user stub. I haven't quite succeeded at this yet :( so a nudge in the right direction
Devise and abilities: My understanding is I need to use the cancan/matchers then make some factories for admin/editor or any views and then do my usual tests once i've logged in a user and instantiated abilities. also failed at all the examples I tried.
Finally testing the controller for pages: I required again logging in the user with the correct ability and then testing each action for each users to see if i received the correct records back?
Maybe i'm not separating out the roles enough or i'm missing some important steps from what I could read but even a small nudge on any of these would be much appreciated.
You may have seen this, but this CanCan page https://github.com/ryanb/cancan/wiki/Testing-Abilities describes some basic high-level methodology behind testing the ability class. TL;DR Focus heavily on testing the Ability class itself and keep the controller tests light.

What is the best way to do Rails 4 link_to :delete if JS may be disabled?

Here's a very standard bit of code (Rails 4):
<%= link_to 'Log out', logout_path, :method => :delete %>
However, here's a nonstandard consideration: no Javascript. Without Javascript, jquery_ujs doesn't get its hooks in, so the link creates a plain GET /logout, which has no route.
Why? Because I want to support a Tor hidden site version of the site, and I have to assume that Tor users (coming most likely via the Tor Browser Bundle) will have JavaScript disabled. (I deliberately do not want to enable JS for them, to prevent various potential privacy leaks. I also don't want to permit XSRF attacks that would e.g. allow someone to log out my users with a GET, nor make the UI ugly with a button.)
The hidden site is lower functionality than the main site (e.g. no payments accepted via tor), but some basic things like login/logout really ought to work correctly.
What's the best way to support this?
Maybe you can create a form using a form helper. This would allow you to specify the method to use. What Rails will do is generate a hidden field inside that form that specifies the HTTP method, which on submitting is then used by Rails to determine which controller action to call.
The only thing left to do then is to write some CSS to make the submit button look like a link, but you can easily find that on the webs.