How to re-generate the user.confirmation_token - ruby-on-rails

I'm looking for a way to regenerate the user.confirmation_token. In my app, I allow users to deactivate their account with user.deleted_at. If a deactivate user tries to re-activate their account, I want to see a confirmation_instructions mail but need a confirmation token set. Is there a way with devise to re-generate the user.confirmation_token inside the RegistrationsController?

Theres the generate_confirmation_token method in the Confirmable module which is applied to other classes via ActiveSupport::Concern. Like you see here:
https://github.com/plataformatec/devise/blob/master/lib/devise/models/confirmable.rb
Reapllying this method on your User object should do the Trick.
// The generate_confirmation_token method is protected so it cant be called from outside the class. You can run send_confirmation_instructions which generates the token and delivers a registration mail.
// Watching at the source if the confirmable module of the gem let it look like the method does. If it isnt possible by default you need to costumize the gem. You can get the gemsets path by the following command in the bash
rvm gemset path
then in the gems directory you will find the version of devise installed. In the lib/devise/models/confirmable.rb file you can add a not protected method that calls the generate_confirmation_token method. You can only call it from that module because its protected.

Related

Adding api to an existing rails project with devise

I need to add some api for moobile to my existing project in rails. I am using devise gem for authentication. The first api needed are user registration, login, profile update , some posting feature etc.I am following https://github.com/lynndylanhurley/devise_token_auth this to create api, but it creates user.rb and migration as well as a duplicate routes. Am I doing something wrong. Please help me to solve the issue . Thanks in advance
I have added devise token authentication for api. Also created a seperate application controller for api's. All the api controller extends this application controller. The api routes starts with /api/
Documentation says:
A model will be created in the app/models directory. If the model already exists, a concern will be included at the top of the file.
And
A migration file will be created in the db/migrate directory. Inspect the migrations file, add additional columns if necessary, and then run the migration:
So
Can I use this gem alongside standard Devise?
Yes! But you will need to enable the support of separate routes for standard Devise.
https://github.com/lynndylanhurley/devise_token_auth#can-i-use-this-gem-alongside-standard-devise
Personally, I wouldn't use Devise for your authentication but would create a custom one next to Devise just for your API. Devise can become a bit buggy later on in the process when using it for API-authentication. Then for your authorization you could use Pundit. You might want to use Regulator next to it for controller namespaced authorization polices(it's not under development anymore, but it does the job).
There's a nice tutorial about this process:
API Tutorial
Here you can find Pundit:
Pundit Gem
And here's the Regulator gem:
Regulator Gem

Where is the code that Devise generates?

I installed the Devise gem into my Rails app, and ran rails generate devise:install and rails generate devise User.
Without my doing anything, the url users/sign_up already has a view somehow. The problem is, I can't find the template that is being rendered anywhere. It's certainly not under app/views/users. I chose some text on the page and ran a search for it within my app, and got back 0 results.
Then I tried to sign up with the form, and got the following error:
NoMethodError in Devise::RegistrationsController#create
undefined method `current_sign_in_ip' for #<User:xxxxxxxxxxx>
I then searched for this controller, but there is no RegistrationsController in my app, and no Devise file. None of the files I'm looking for were generated by the two commands I mentioned above, either.
The Devise documentation doesn't seem to shed any light on where the Devise code is kept.
Is the code even in my app? I'm so confused.
Using Devise, you're able to generate the templates which Devise depends on for logins, password resets, etc. using the following command:
rails generate devise:views
This will create copies of the templates for Devise in your views directory.
For controllers, you can access/override their functionality by subclassing them in your own code. They're under the Devise namespace:
class NewRegistrationsController < Devise::RegistrationsController
# do stuff here
end
Then point the router to use this new controller:
devise_for :users, controllers: { registrations: 'new_registrations' }
The code for the controllers can be found in Devise's source code - you can reference it to better understand what each controller is doing.
Hope that helps!
This is standard practice for Rails "engines" (which almost all gems are) -
Think of them as libraries / dependencies... wherein they provide access to a lot of pre-compiled functionality through several hooks (often provided by an API).
One of the reasons I'd actually recommend people to write their own gem is because it helps you appreciate how the whole thing works. I wrote a gem, it uses views just like Devise:
These views are not seen in the application because they're appended to your Rails app at runtime. It's basically how the PATH var works in cmd, if you've ever had the pleasure of working with programmatic compilation etc.
Thus, Devise's "views" are stored in the Devise gem. This is appended to your Ruby installation... [Ruby install dir]/lib/ruby/gems/[ver]/gems, loaded at RunTime just like the PATH var...
Whilst you can generate your Devise views (as mentioned in the other answers), this is the base line of how it's able to access them without any prior references.
NoMethodError in Devise::RegistrationsController#create
undefined method `current_sign_in_ip' for #<User:xxxxxxxxxxx>
This means you don't have the current_sign_in_ip attribute for your Devise installation. I answered your question about this specifically here...
Devise error: undefined method `current_sign_in_ip'
All the devise MVC files are inside the gem. Below is my devise views directory. You could check yours as well. Go to your project root.
gem show 'devise'
/Users/saurabh/.rvm/gems/ruby-2.1.0/gems/devise-3.2.4
cd /Users/saurabh/.rvm/gems/ruby-2.1.0/gems/devise-3.2.4/app/views
You can generate views in your project if you wish to customize.
rails generate devise:views
All code of devise can be easily go through by devise and if you are using rubyMine you can view devise code in external libraries in devise folder.
To generate template for your model
rails generate devise:views
and then you can change your view as you want for your application.

Rails get username of currently logged windows user

I need to get the username of the currently logged windows user. Could it be done easily?
The username of the account running the script can be accessed via something like:
puts ENV['USERNAME']
Beware that if you're running it as a system service the username will probably come back as "SYSTEM"
If that isn't enough to suite your needs there is an alternative method outlined here: https://stackoverflow.com/a/3544741/648695
You can use the Ruby etc module
require 'etc'
Etc.getlogin
The doc is avaiable here: http://ruby-doc.org/stdlib-2.0.0/libdoc/etc/rdoc/Etc.html#method-c-getlogin
Returns the short user name of the currently logged in user.
As far as I know, unless you're using active directory that would require a microsoft framework website, I don't think you'll find a way in rails.
There are a few discussion points here that may help: Can you get a Windows (AD) username in PHP?
Same question here: is there a way to read a clients windows login name using ruby on rails
Anyways, just copying my own answer below...
This is what worked for me but there are some limitations:
won't work in Chrome: undefined method 'encode' for nil:NilClass
won't validate user credentials
If you don't care about these issues, go ahead:
In your rails application, add Rekado's gem to your Gemfile: gem 'ntlm-sso', '=0.0.1'
Create an initialiser config/initializers/ntlm-sso.rb with:
require 'rack'
require 'rack/auth/ntlm-sso'
class NTLMAuthentication
def initialize(app)
#app = app
end
def call(env)
auth = Rack::Auth::NTLMSSO.new(#app)
return auth.call(env)
end
end
On your application.rb file, add the line: config.middleware.use "NTLMAuthentication"
Call request.env["REMOTE_USER"] on your view or controller to get current username.
PS: Let me know if you find anyway to make it work on Chrome or to validate user credentials.

Ruby on Rails - Prompting user for password

I'm trying to add some basic file-download functionality to my Rails application and have the password_hash and password_salt fields for my file model. I also have a function in which a download link to the file is generated, however I'm not totally sure (as I'm sort of reasonably new to Ruby and Rails) how I'd go about actually prompting the user for a password and checking this before proceeding with the file download.
Any help would be appreciated.
You should target you link to a controller and send the file like this:
before_filter :login_required
def download
send_file '/home/railsway/downloads/huge.zip', :type=>"application/zip"
end
this way you can check the password in you before filter using HTTP Basic Auth for example.
more info: http://www.therailsway.com/2009/2/22/file-downloads-done-right

Setting locale on a per-user basis when using devise and rails 3

I have just been through one of my apps converting the authentication from authlogic to devise. By and large this has been amazingly straight-forward to do but there is one issue I can't find an easy fix for.
In the app, the user has the option of choosing their locale. Then whenever they login, they view the app in the language they choose. Previously, I did this by simply setting the locale in the create method of my UserSessions controller.
With Devise, all the controllers are automatically setup, which is great. I know that I could create a custom Controller that extends the DeviseController and do it like this but, from what I understand, that means that I will also need to create all the views to go with it which seems a bit over the top when I just need to run one extra line of code.
Is there an easier way of specifying some code to be run on a successful devise authentication?
I found the solution I was looking for here
As I just wanted to set the locale for the user when they logged in, all I needed was to add the following method to my ApplicationController
def after_sign_in_path_for(resource_or_scope)
if resource_or_scope.is_a?(User) && resource_or_scope.locale != I18n.locale
I18n.locale = resource_or_scope.locale
end
super
end
Have you executed rails generate devise:views? This will output the Devise view files for you, and then you should be able to move them to a location that matches your new extended Devise controller name.
Devise is locale aware, which means that your views should automatically load language translations for you.
All you need to do is provide a "devise.[:locale].yml" file in the root "locales" folder of your rails application for each language translation that you wish to support.
The Devise wiki has a bunch of locale translations that have been provided to save you some work:
https://github.com/plataformatec/devise/wiki/I18n

Resources