Can I add a required param to devise sign up? - ruby-on-rails

Is there any simple way of adding a required param for registration on Devise?
I added Devise since I thought it should "handle users for me" but as it seems to be going everything I want besides the basics seems to be a hassle...
I already added the parameters, the thing is I can't find how to make it required... Or how to easily override the signup method and make the check myself.

"Out of the box" the Devise gem is very powerful, but when you start to step out of the box there is a significant amount of modification that has to be done to the underlying code.
I was a big user of devise when I first started using Rails. However in the last year I have found it easier to create my own authentication. Do a google search on 'rails authentication from scratch'. There are lots of good blog posts on the topic.
Building your own authentication is not terribly difficult, and gives you the flexibility to add whatever fields and customization you want. Additionally its lightweight (you only build what you need), and you are not exposed to the whims of gem updates and changes. Finally, you get the satisfaction of knowing you built it yourself.
Good luck!

I found the solution, you should add to your model
validates_presence_of :username
(and in my case)
validates_uniqueness_of :username
that should make devise automatically validate and through errors if something goes wrong.

Related

Best way to further secure rails app from?

I am using rails 3.2 and devise 1.5.3.
I added an admin attribute in my model as described in option 2 on the devise wiki How To: Add an Admin Role
I added this in a post controller for force logins:
before_filter :authenticate_user!
I wrote some logic to hide the edit/new links in my views based on whether you're an admin or not.
I feel like there's more I should be doing.. Should I add anything else to new/edit/delete actions to make them more secure? If so, where?
your answer may be working but it is pretty difficult to ensure security in the whole app if you are using some logic to hide the edit/new links in my views and I'm pretty sure no amount of security testing would give you the feeling that maybe you are forgetting about something
for example I someone could log in,,,, (not having admin profile) and go to (in the URL),:
/users/edit/3 and start damaging your valuable information....
situation is: Devise only provides authentication,,, but authorization has to be enforced in some other way or else I could be able to do the above things...
for that I would highly recommend CanCan (from rbates ofcourse) which is the one I have tested personally and is PRETTY easy to configure just by reading the docs and examples in github..... hope it helps!
Your authentication and authorization mechanism is in charge of taking care of security for you, and you should make sure it's regularly updated with security updates.
That sinking feeling that you have about missing something can only reliably be covered by tests. So, write some tests that verify that the way you've setup your Devise installation is, in fact, correct, and they non-admin users do not have access to anything they shouldn't have access to. Then be very careful to make sure you update your security restrictions as you add new things.
You don't need to write tests to make sure Devise works - but you do need to write tests to make sure that your use of it is what you think it is (i.e. if non-admins shouldn't be able to get to the admin page, write a test that logs in as a non-admin, try to access that page, and verify in the test that the user is redirected and, if you have an 'access denied' message, that's it's firing). That way, if you inadvertently break security access later, you at least stand a chance that it'll be caught by a test in your test suite.
Run your test suite before every deploy, making sure that all tests (especially security tests) are running and passing. Then be vigilant thereafter, and that's about all you can do.

Rails 3 user authentication with heroku

Rolling my first heroku app and am currently working on user authentication. (As well as authentication... for example user 1 cant access user 3's stuff).
Is it easier just to roll my own scaffolded authentication? Or use something like devise? I can do the standard salted password authentication, store the user id in the session, and then pull from the database in controllers but is that secure? Would devise be better in the long run?
Thanks for the advice :)
Devise is highly recommended, I think it would save much of your time and it currently do all the magic you need involving the session with a good security.
If you want to take on the challenge (which isn't really that big), I strongly suggest that you roll your own system. Having previously used both Authlogic and Devise I've come to the conclusion, that building your own has more advantages in the long run:
You thoroughly understand how the system works (which is quite important when it comes to authentication, I believe)
Devise and Authlogic is build with a specific use case in mind, and although they can be modified, my experience is that it's a pain. At some point, you will probably feel limited by both systems.
You know where to start and what to do, if you want to add features to the system
If you decide to roll your own, Ryan Bates has created an excellent screen cast on just that. Also, don't forget to test it!
Go with Devise unless you have a solid understanding of how to make a decent authentication system, AND you have a good reason to not use Devise.
And if you do roll your own, make sure you use bcrypt.

Authentication with Ruby on Rails & Devise

I am about to build a new site in ruby on rails for residents at my college.
The site will allow residents to change their passwords for the college-firewalls (which means there are certain requirements).
On the site, each resident will have an account with a number of data assigned to it, and for this I need some authentication.
I've been studying Devise for almost the entire day now, but im starting to wonder if I have a too complicated task, to complete it with Devise.
Problem is, I need the passwords to be stored with DES-encryption, something Im not sure if Devise can handle.
Another thing is, users can't make their own profile. Admins will do that (to ensure correct data), which means that user-creation is not the default one. Since there are no controllers for this, is it even possible to do it that way?
I'm not sure if I should keep on going with Devise, or bite the bullet and write it all from scratch instead. Some opinions would be appreciated.
This page on the Devise wiki ( https://github.com/plataformatec/devise/wiki/How-To:-Create-a-custom-encryptor ) tells you how to set up a custom encryptor.
To make it so that admins create a user, remove the :registerable module from the User model. Then add a user resource to your app, example:
scope 'admin' do
resources :users
end
Set up the new/edit pages with your profile fields, etc., normal rails programming.
For an example using CanCan to control access to the users resource, have a look at this post: http://zyphmartin.com/blog/manage-users-with-devise-and-cancan.
If devise does not exactly do what you need, maybe this recent webcast from Ryan Bates will help you.

Rails authentication with custom fields

I have a rails app where I need to add authentication. The problem is that I have a legacy database with custom user and password fields (t_user and t_pass). Plus, t_pass is not encrypted.
What I'm looking for is something like http_basic, but where I can have methods like current_user, and probably with a better user interface. I don't need validation, password reset, anything. Just a way to authenticate my way. I'd use restful_authentication but I'm on rails 3. I saw a fork that works with rails 3 but I was wondering if there is a better way to handle this situation?
It looks to me like you could probably do what you need using Devise and a bit of extra playing around. Specifically, you'll want to:
Make sure you create your user model table using your legacy auth table.
Override valid_password? on this model to check against your t_pass field.
Override self.find_for_database_authentication to find your model based on the t_user field.
If you want to support registration, you'll probably need to write a new encryption strategy as well.
Just a word of warning though: Storing passwords in plain text is very bad practice. If you have any choice at all, I'd seriously consider doing a migration of existing users into Devise's standard structure, with crypted passwords.
If you are looking for alternative gems to use then you can try Devise. You can extend/change the default settings to achieve what you want.
Devise and Authlogic are two potential options. Can't comment on Devise I'm afraid as I've never used it. Seems to be very popular at the moment though.
The following would get you started with Authlogic:
class User < ActiveRecord::Base
acts_as_authentic do |config|
config.login_field = :t_user
config.crypted_password_field = :t_pass
config.crypto_provider = YourCryptoProvider
end
...
end
There's a railscast on the basics of getting authlogic going.
The difficult part of this is that you would need to create your own crypto provider class as described http://rdoc.info/github/binarylogic/authlogic/master/Authlogic/CryptoProviders as authlogic doesn't provide a plain text password check method.
As discussed above, look into migrating your passwords to encrypted versions if that's an option for you, it will stop you from fighting against the auth frameworks so much.

How do I effectively use Devise and Doorkeeper in my rails API?

I am having a hard time getting my head around the responsibilities and capabilities of the popular Doorkeeper and Devise gems. I am not overly experienced in authorization and authentication so pardon me if I misunderstood certain aspects of those areas. I do try hard and if I do something I want to do it the right way, so here is my current situation:
I want to build an API-only rails application that is responsible for authenticating and authorizing users as they sign up and use the service. I handpicked two fairly popular gems called Doorkeeper (authorization) and Devise (authentication).
I currently have this structure in place and it works, however, I'm having issues fully getting behind what the responsibilities of these gems are. So as far as I understand, the Devise gem serves as an authentication layer, meaning that the user can be identified and logged in (additional features will be discussed below). Doorkeeper on the other hand will ensure that resources can only be accessed by members who are authorized to do so. I have chosen Doorkeeper for OAuth2 integration because my server needs to be able to give access to the API to potential third parties in the future.
My question first and foremost is whether my assumptions about those gems is correct.
Here is the current authentication/authorization flow:
Issue: User signs up, how do I leverage Devise to send a confirmation email if my API is devoid of the preconfigured views provided by Devise? (Side Note: The traits Recoverable, Rememberable, Trackable, and Confirmable are in the User model/migration.)
Similarly, I would love to know how to implement a potential password reset. Notice that references to examples would suffice too as long as they are applicable to my use case.
I know that Devise offers these capabilities, but it's hard to make out how to do it without hitting their preconfigured (view?) routes.
For example, when a user signs up, he hits my own user_controller's create method, which basically just creates a new user, is that supposed to automatically send a confirmation email (if we assume that my mail config is correct)?
I am not entirely sure whether avoiding the preconfigured routes makes a lot of sense, that's why I'd like to hear from more experienced people who may have used those gems in the past if my thinking is correct or whether I'm completely off on this.
I've done exactly what you're looking for and I really think this is a good choice. I've never regret it. What you're actually trying to do is to have the exact same behaviour that native Devise implementation but on an Engine via API. Plus, you want to apply it to a Doorkeeper authorisation.
Short answer is: override default views/controller/routes.
Why should I override views?
You're using Rails API means response will be JSON but you're using a certain standard to wrap it and Devise might not be the same. For example, if you want to respect OpenAPI standards, it's not possible natively (please correct me if I'm wrong).
This leads to an override of the controller as well to be 100% sur of what you're returning. I would also add an extra layer here about versioning. Now you're plans might be fixed but you don't know about tomorrow.
Overriding controller leads to an override of the routes itselves.
Wait, how am I suppose to do that?
On your global Gemfile.rb
# Gemfile.rb
gem 'devise'
Nothing changes for devise initializers if it's on an engine or not
Keep config/initializers/devise.rb as usual
Routes are now defined on your engine:
# your_engine/config/routes.rb
YourEngine::Engine.routes.draw do
namespace :v1, format: false, defaults: { format: :json } do
devise_for :users, controllers: { sessions: 'your_engine/v1/users/sessions',
registrations: 'your_engine/v1/users/registrations',
confirmations: 'your_engine/v1/users/confirmations',
unlocks: 'your_engine/v1/users/unlocks',
omniauth_callbacks: 'your_engine/v1/users/omniauth_callbacks',
passwords: 'your_engine/v1/users/passwords' },
skip: %i[sessions]
end
end
I've deliberately skipped sessions since we're talking about API and there is no such things (for now).
Add Devise to Doorkeeper using resource owner password credentials:
Doorkeeper.configure do
base_controller 'ActionController::API'
api_only
resource_owner_from_credentials do |routes|
user = User.find_for_database_authentication(:email => params[:email])
if user && (user.valid_for_authentication? { user.valid_password?(params[:password]) })
user
end
end
end
All your controllers must inherit from Device controllers. I inspired myself from it to made my overrides.
This way, you can have your API entrypoint for Devise but you can also have another one with a non-api access building another Engine. It's the same process but requirements come from a different order that for the API (views -> controllers -> routes). For Devise on an engine, I would say order of comprehension is routes -> controllers -> views.
I hope this helps you. Good luck! 😉
Devise is really made to do everything for you, if you bypass the automatic mecanisms and want to re-implement them by hand... you WILL make a mistake.
Don't bypass controllers mecanism and use the devise's wiki for small customizations like changing the redirection after creation/update.
Devise handles confirmation emails (confirmable) and password reset (recoverable) system for you so use their system, it is just options to activate.
If you wanna change their view (we always want to customize the layout) you can :
rails g devise:views
It will keep the devise flow, with your custom views.
If you wanna stop using a specific mecanism, just remove it from the model.
devise :database_authenticatable, :registerable, :confirmable, :recoverable
Avoid preconfigured routes would have made sense if did not used them at all (meaning removing the option and using except in routes), but as you want all the mecanisms Devise provides it does not make sense here.
Their Wiki is really dense but read it again and again, everything you need is here.
Finally :
Yes Gatekeeper provides a good OAuth2 provider system and mixes up very well with Devise, so you made a good choice here. Their views system is also customizable.
You might also want to take a look at cancancan that handle roles and rights for your users (simple, API, admin, etc).
Hope it helps !

Resources