post only after confirming email - ruby-on-rails

Guys in Rails how do I implement confirmation emails such that a nonuser can post only after confirming the email. So any regular person without an account views the site, submits post, verifies email and then the post is active. I already have devise installed but it seems its more for authenticating users. Whats the approach to take to implement the feature above and is there a specific gem to use?

i think you will need to think in a different way
in your posts list/show actions you can show posts for active users, so if users didn't confirm their account their posts won't be displayed and once they confirm their posts will be shown automatically.

I guess devise' confirmable module can be used for the same. Devise is not just for authenticating . Just like :database_authenticatable for authentication, :confirmable is to verify if an account is already confirmed.
More details on using confirmable can be seen here DeviseConfirmable

I cannot specify a gem (and that is off topic).
Typically you generate a unique and unguessable (long and random) token, store it along with the entity that it finalises, have a route in your app that can accept the token and set a flag in the associated entity (in your case the post). Then construct the confirmation link that invokes that route - including the token data that you just generated - to put in the email.
You might add two fields to the posts table (that you keep hidden from the web page):
email_confirm_token (indexed unique string)
email_confirmed (bool)
And only display posts that have email_confirmed set.
The Ruby standard lib SecureRandom class is a good source of token data.
If you want to verify more than one type of entity, you might want to factor this out. The concept is sometimes called a "nonce"

Related

How to implement per-page authorization in Rails

Rails has some very good methods for role based authorization, e.g., cancan
But how can you grant authorization to specific pages, rather than controllers/actions.
For example, take the case of an app that contains a receipt or invoice model. A User can log in and generate an invoice. The User then needs to send his customer a URL to that invoice. The customer should not be able to access invoices of other customers, particularly important as Rails generates sequential and easily guessable path names (e.g., /invoices/1, /invoices/2, etc.).
Ideally the customer should not need to signup to view these pages. One solution might be to generate a random password on Invoice creation, and send this to the customer to unlock that page specific page.
This sounds like an issue that should be reasonably common, but after Googling I have not found much information of use (though I may be using incorrect search terms).
So I would like to know:
Is this something I should be attempting with Rails?
Are there any gems or example apps that I could study?
What are the potential considerations/ pitfalls of this approach?
Hi if the user you wish to have access was registered in the system it would be no issue at all as you could generate a permission record.
How ever your concern with the predictable urls can be easily solved by :
FriendlyID(https://github.com/norman/friendly_id)
or my personal favourite
Vanity permalinks (http://blog.teamtreehouse.com/creating-vanity-urls-in-rails)
Ideally the customer should not need to signup to view these pages. One solution might be to generate a random password on Invoice creation, and send this to the customer to unlock that page specific page.
So anyone with the information should be able to access it. One solution is to obfuscate the url or use a UUID, so don't give out /invoices/1, instead give /invoices/8a20ae59-30d5-41b6-86d3-ac66e3b43e9d. The url is unguessable. Still the url is the only piece of information one needs to access the contents.
If you want two-factor authorization, then the easiest way is to use http basic auth, generate a password from the url and your secret_base, and send it to the user separately. As it's generated, you don't need to store it, you can always check it by generating it again.

Confirm multiple emails with devise

I am using rails+devise. I want the user to be able to confirm multiple e-mails (the app would send for each address a mail with a "confirm" link, and then the user have one or many confirmed mails). It is possible to confirm one with :confirmable (doc :
http://rubydoc.info/github/plataformatec/devise/master/Devise/Models/Confirmable )
I thought that i could play with
- (Object) resend_confirmation_instructions
by changing the address but this is not the best solution.
Is there a solution with devise or do i have to implement this specific functionnality?
You'll have to implement this yourself. Devise has one email per account, by default.
You'd not only need to handle multiple emails, but presumably you'd also want multiple confirmation_token's, along with multiples of the other database fields relating to email confirmation (find them in the devise migration file that gets generated). I don't imagine this will be a simple thing to solve with devise.
However, this sounds like a counter intuitive thing to do. Perhaps you should update your question to include the requirements of your app, and the reason why you need to get confirmation from multiple email addresses. Someone may have a solution for how to architect your app such that it doesn't need this feature.

confirm comment by email on Rails

I'm creating a rails blog app.
No visitor can sign up.
The app will allow any visitor to post comment on a post.
However, this comment will be persisted if and only the visitors clicks on a unique confirmation email that said visitor receives when subimming the comment for review.
How could I do this?
Is there a gem for that?
You could do it many ways, but providing a unique token would be a standard way to do it.
So the Comment model would have a column called confirmation_token which you could set to be random when the comment is created and a column called active which is false by default. Then you send a confirmation email with a link that has that token as a param:
http://www.mysite.com/comment/85/?confirm=<insert confirmation_token>
When that page is visited, you pick up the confirmation_token in your controller and set the active column to true if the token in the url matches the token in the database.
This is how many different types of confirmation are done, including most plain vanilla registrations (e.g. through Devise).

Adding confirmed to a nearly complete rails application

I am coming to the end of my rails project now and I have done everything I wish to do apart from confirm the users account through email before creating it. I already have it to send an email to the user but I want the user to contain a link. It's far too late to add devise now as I already have a users table etc.
I have heard of having a confirmed field in the users table and having it set to false and then true on user confirmation, but I have no idea on how to implement this. Any ideas?
If anyone else has some other solutions or links to tutorials showing how to add such feature then that would be outstanding. The end is so close yet so far.
It's never too late to add devise. If I were you, I'd do exactly this.
But, if I were to implement confirmation functionality myself, this is how I would go about this:
For each user, make a hash (as in MD5 hash). There are many ways: 1) for each user generate its own and store in a dedicated table column; 2) make one out of password salt, user id and (optionally) some static strings; 3) something else.
Send a user an email with a link, which contains his id and that hash.
When someone hits your confirmation url, you extract user id and hash from query string, and compare them with what you have. If they match, then you mark user as confirmed.

Email confirmation in Rails without using any existing authentication gems/plugins

I'm working on this alerting service in Rails. And really, all I need to do is, when a user signs up, send a confirmation email to the user. And upon confirmation from the user, activate the user. I tried playing around with Matt Hooks' Authlogic email activation tutorial, but its really leading nowhere. So , any ideas how I can do this with minimum fuss ?
Thanks !
UPDATE
So how i got devise to do the job for me is :
Install the gem.
Create a migration for devise's confirmable fields.
Specify
devise :confirmable
in your model.
Create a confirm method in the relevant controller(and a route for that method) which would update the confirmed_at attribute of the relevant model.
The devise generator creates a few views for you, one which is confirmation_instructions.html.erb. Customize the path there.
I used Rails 2.3.2 and I 've used this method along with Authlogic's authentication and it worked well. I do plan to switch to devise completely.
In all honesty, I wanted to accept both answers (unfortunately I can't do that), but its just that the devise solution seemed a easier solution.
Assuming given the title that you definitely want to avoid Devise, Authlogic and friends, here's what I think you need to do:
Create 'confirmation code' and 'confirmed' attributes in your user model.
Create a new controller method on your user controller that expects a user id and confirmation code, looks up the user and then checks if the code in the parameter matches the code stored in the DB. If so, it clears the code and sets confirmed = true.
Create a route that maps e.g. /users/1/confirm/code to your new controller method.
Create an ActionMailer template for the e-mail you want to send. This should accept a user as a parameter, and use the confirmation code of the user to send a mail containing a link to your new route.
Create an observer for your user model. If the record is created or the e-mail address modified, then generate a random confirmation code, set it into the model and clear the confirmed flag. Then trigger your ActionMailer.
Create a helper method which allows views to check if the current user is confirmed.
Use this method to enable/disable functionality as appropriate. Remember to protect your controller methods as appropriate as well as your view logic.
You could also make use of scopes for selecting users.
class User < ActiveRecord::Base
scope :certified, where(:certified => true)
end
And then in your code:
#user = User.certified.find_by_username(foo)
Devise is an other excellent authentication gem that comes with email activation build in, perhaps you could give it a go.

Resources