auth_eng 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +12 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/javascripts/auth_eng/application.js +15 -0
  5. data/app/assets/javascripts/auth_eng/users.js +2 -0
  6. data/app/assets/stylesheets/auth_eng/application.css +13 -0
  7. data/app/assets/stylesheets/auth_eng/users.css +4 -0
  8. data/app/controllers/auth_eng/application_controller.rb +4 -0
  9. data/app/controllers/auth_eng/confirmations_controller.rb +69 -0
  10. data/app/controllers/auth_eng/users_controller.rb +77 -0
  11. data/app/helpers/auth_eng/application_helper.rb +4 -0
  12. data/app/helpers/auth_eng/users_helper.rb +4 -0
  13. data/app/models/auth_eng/user.rb +45 -0
  14. data/app/views/auth_eng/confirmations/show.html.haml +12 -0
  15. data/app/views/auth_eng/devise/confirmations/new.html.erb +12 -0
  16. data/app/views/auth_eng/devise/confirmations/show.html.haml +12 -0
  17. data/app/views/auth_eng/devise/mailer/confirmation_instructions.html.erb +5 -0
  18. data/app/views/auth_eng/devise/mailer/reset_password_instructions.html.erb +8 -0
  19. data/app/views/auth_eng/devise/mailer/unlock_instructions.html.erb +7 -0
  20. data/app/views/auth_eng/devise/passwords/edit.html.erb +16 -0
  21. data/app/views/auth_eng/devise/passwords/new.html.erb +12 -0
  22. data/app/views/auth_eng/devise/registrations/edit.html.erb +25 -0
  23. data/app/views/auth_eng/devise/registrations/new.html.erb +18 -0
  24. data/app/views/auth_eng/devise/sessions/new.html.erb +16 -0
  25. data/app/views/auth_eng/devise/shared/_links.erb +25 -0
  26. data/app/views/auth_eng/devise/unlocks/new.html.erb +12 -0
  27. data/app/views/auth_eng/users/_form.html.erb +25 -0
  28. data/app/views/auth_eng/users/edit.html.erb +6 -0
  29. data/app/views/auth_eng/users/index.html.erb +29 -0
  30. data/app/views/auth_eng/users/new.html.erb +5 -0
  31. data/app/views/auth_eng/users/show.html.erb +25 -0
  32. data/app/views/layouts/auth_eng/application.html.erb +15 -0
  33. data/config/initializers/devise.rb +232 -0
  34. data/config/locales/devise.en.yml +58 -0
  35. data/config/routes.rb +21 -0
  36. data/db/migrate/20120921104821_devise_create_auth_eng_users.rb +49 -0
  37. data/db/migrate/20120924150140_create_delayed_jobs.rb +22 -0
  38. data/lib/auth_eng.rb +4 -0
  39. data/lib/auth_eng/engine.rb +5 -0
  40. data/lib/auth_eng/version.rb +3 -0
  41. data/lib/tasks/auth_eng_tasks.rake +4 -0
  42. data/test/auth_eng_test.rb +7 -0
  43. data/test/fixtures/auth_eng/users.yml +11 -0
  44. data/test/functional/auth_eng/users_controller_test.rb +41 -0
  45. data/test/integration/navigation_test.rb +10 -0
  46. data/test/test_helper.rb +15 -0
  47. data/test/unit/auth_eng/user_test.rb +9 -0
  48. data/test/unit/helpers/auth_eng/users_helper_test.rb +6 -0
  49. metadata +132 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Gustavo Lobo
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,12 @@
1
+ AuthEng
2
+ =======
3
+
4
+ Motivation
5
+ ----------
6
+ What led me to the creation of this engine was the fact that on several projects that I have worked on, always have the same problems with the gem devise, and almost always because I want that the authentication follows a flow that devise doesn't follow by default.
7
+
8
+ For example, I don't want people to be able to register themselves, I want it to be done by an authenticated user. And then, these people should receive an account confirmation/activation email, and when they click the link in that email, they can choose their own password.
9
+
10
+ So, I decided to create an engine, trying to make it as easy as possible to integrate with a newly created application.
11
+
12
+ Later I will try to clarify the flow of this engine. Any suggestion, thanks.
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'AuthEng'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rake/testtask'
31
+
32
+ Rake::TestTask.new(:test) do |t|
33
+ t.libs << 'lib'
34
+ t.libs << 'test'
35
+ t.pattern = 'test/**/*_test.rb'
36
+ t.verbose = false
37
+ end
38
+
39
+
40
+ task :default => :test
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require_tree .
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ module AuthEng
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,69 @@
1
+ require_dependency "auth_eng/application_controller"
2
+
3
+ module AuthEng
4
+ class ConfirmationsController < Devise::PasswordsController
5
+ # Remove the first skip_before_filter (:require_no_authentication) if you
6
+ # don't want to enable logged users to access the confirmation page.
7
+ skip_before_filter :require_no_authentication
8
+ skip_before_filter :authenticate_user!
9
+
10
+ # PUT /resource/confirmation
11
+ def update
12
+ params[:confirmation_token] ||= params[:user][:confirmation_token]
13
+ @confirmation_token = params[:user][:confirmation_token]
14
+ with_unconfirmed_confirmable do
15
+ if @confirmable.has_no_password?
16
+ @confirmable.attempt_set_password(params[:user])
17
+ if @confirmable.valid?
18
+ do_confirm
19
+ else
20
+ do_show
21
+ @confirmable.errors.clear #so that we wont render :new
22
+ end
23
+ else
24
+ self.class.add_error_on(self, :email, :password_allready_set)
25
+ end
26
+ end
27
+ if !@confirmable.errors.empty?
28
+ do_show #Change this if you don't have the views on default path
29
+ end
30
+ end
31
+
32
+ # GET /resource/confirmation?confirmation_token=abcdef
33
+ def show
34
+ params[:confirmation_token] ||= params[:user][:confirmation_token]
35
+ with_unconfirmed_confirmable do
36
+ if @confirmable.has_no_password?
37
+ do_show
38
+ else
39
+ do_confirm
40
+ end
41
+ end
42
+ if !@confirmable.errors.empty?
43
+ render 'auth_eng/confirmations/show' #Change this if you don't have the views on default path
44
+ end
45
+ end
46
+
47
+ protected
48
+
49
+ def with_unconfirmed_confirmable
50
+ @confirmable = User.find_or_initialize_with_error_by(:confirmation_token, params[:confirmation_token])
51
+ if !@confirmable.new_record?
52
+ @confirmable.only_if_unconfirmed {yield}
53
+ end
54
+ end
55
+
56
+ def do_show
57
+ @confirmation_token = params[:confirmation_token]
58
+ @requires_password = true
59
+ self.resource = @confirmable
60
+ render 'auth_eng/confirmations/show' #Change this if you don't have the views on default path
61
+ end
62
+
63
+ def do_confirm
64
+ @confirmable.confirm!
65
+ set_flash_message :notice, :confirmed
66
+ sign_in_and_redirect(resource_name, @confirmable)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,77 @@
1
+ require_dependency "auth_eng/application_controller"
2
+
3
+ module AuthEng
4
+ class UsersController < ApplicationController
5
+
6
+ before_filter :authenticate_user!
7
+
8
+ def index
9
+ @users = User.all
10
+
11
+ respond_to do |format|
12
+ format.html # index.html.erb
13
+ format.json { render json: @users }
14
+ end
15
+ end
16
+
17
+ def show
18
+ @user = User.find(params[:id])
19
+
20
+ respond_to do |format|
21
+ format.html # show.html.erb
22
+ format.json { render json: @user }
23
+ end
24
+ end
25
+
26
+ def new
27
+ @user = User.new
28
+
29
+ respond_to do |format|
30
+ format.html # new.html.erb
31
+ format.json { render json: @user }
32
+ end
33
+ end
34
+
35
+ def edit
36
+ @user = User.find(params[:id])
37
+ end
38
+
39
+ def create
40
+ @user = User.new(params[:user])
41
+
42
+ respond_to do |format|
43
+ if @user.save
44
+ format.html { redirect_to @user, notice: 'User was successfully created.' }
45
+ format.json { render json: @user, status: :created, location: @user }
46
+ else
47
+ format.html { render action: "new" }
48
+ format.json { render json: @user.errors, status: :unprocessable_entity }
49
+ end
50
+ end
51
+ end
52
+
53
+ def update
54
+ @user = User.find(params[:id])
55
+
56
+ respond_to do |format|
57
+ if @user.update_attributes(params[:user])
58
+ format.html { redirect_to @user, notice: 'User was successfully updated.' }
59
+ format.json { head :no_content }
60
+ else
61
+ format.html { render action: "edit" }
62
+ format.json { render json: @user.errors, status: :unprocessable_entity }
63
+ end
64
+ end
65
+ end
66
+
67
+ def destroy
68
+ @user = User.find(params[:id])
69
+ @user.destroy
70
+
71
+ respond_to do |format|
72
+ format.html { redirect_to users_url }
73
+ format.json { head :no_content }
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,4 @@
1
+ module AuthEng
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module AuthEng
2
+ module UsersHelper
3
+ end
4
+ end
@@ -0,0 +1,45 @@
1
+ module AuthEng
2
+ class User < ActiveRecord::Base
3
+ # Include default devise modules. Others available are:
4
+ # :token_authenticatable, :confirmable,
5
+ # :lockable, :timeoutable and :omniauthable
6
+ devise :database_authenticatable, :confirmable,
7
+ :recoverable, :rememberable, :trackable, :validatable
8
+
9
+ # Setup accessible (or protected) attributes for your model
10
+ attr_accessible :name, :email, :password, :password_confirmation, :remember_me
11
+ # attr_accessible :title, :body
12
+
13
+ acts_as_paranoid :column => 'deleted_at', :type => 'time'
14
+
15
+ def only_if_unconfirmed
16
+ pending_any_confirmation {yield}
17
+ end
18
+
19
+ # new function to set the password without knowing the current password used in our confirmation controller.
20
+ def attempt_set_password(params)
21
+ p = {}
22
+ p[:password] = params[:password]
23
+ p[:password_confirmation] = params[:password_confirmation]
24
+ update_attributes(p)
25
+ end
26
+
27
+ # new function to return whether a password has been set
28
+ def has_no_password?
29
+ self.encrypted_password.blank?
30
+ end
31
+
32
+ # Password is required if it is being set, but not for new records
33
+ def password_required?
34
+ if !persisted?
35
+ false
36
+ else
37
+ !password.nil? || !password_confirmation.nil?
38
+ end
39
+ end
40
+
41
+ def send_on_create_confirmation_instructions
42
+ Devise::Mailer.delay.confirmation_instructions(self)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,12 @@
1
+ #dashboard
2
+ %h1.blue= "Account Activation"
3
+ #ics_form
4
+ .ics_form
5
+ = semantic_form_for resource, :as => resource_name, :url => update_user_confirmation_path, :html => {:method => 'put'} do |f|
6
+ = f.inputs do
7
+ = f.input :password
8
+ = f.input :password_confirmation
9
+ = f.input :confirmation_token, :input_html => {:value => @confirmation_token}
10
+
11
+ .group.navform.wat-cf
12
+ = f.submit
@@ -0,0 +1,12 @@
1
+ <h2>Resend confirmation instructions</h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
4
+ <%= devise_error_messages! %>
5
+
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email %></div>
8
+
9
+ <div><%= f.submit "Resend confirmation instructions" %></div>
10
+ <% end %>
11
+
12
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,12 @@
1
+ #dashboard
2
+ %h1.blue= "Account Activation"
3
+ #ics_form
4
+ .ics_form
5
+ = semantic_form_for resource, :as => resource_name, :url => update_user_confirmation_path, :html => {:method => 'put'} do |f|
6
+ = f.inputs do
7
+ = f.input :password
8
+ = f.input :password_confirmation
9
+ = f.input :confirmation_token, :value => @confirmation_token, :as => :hidden
10
+
11
+ .group.navform.wat-cf
12
+ = f.submit
@@ -0,0 +1,5 @@
1
+ <p>Welcome <%= @resource.email %>!</p>
2
+
3
+ <p>You can confirm your account email through the link below:</p>
4
+
5
+ <p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %></p>
@@ -0,0 +1,8 @@
1
+ <p>Hello <%= @resource.email %>!</p>
2
+
3
+ <p>Someone has requested a link to change your password, and you can do this through the link below.</p>
4
+
5
+ <p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %></p>
6
+
7
+ <p>If you didn't request this, please ignore this email.</p>
8
+ <p>Your password won't change until you access the link above and create a new one.</p>
@@ -0,0 +1,7 @@
1
+ <p>Hello <%= @resource.email %>!</p>
2
+
3
+ <p>Your account has been locked due to an excessive amount of unsuccessful sign in attempts.</p>
4
+
5
+ <p>Click the link below to unlock your account:</p>
6
+
7
+ <p><%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) %></p>
@@ -0,0 +1,16 @@
1
+ <h2>Change your password</h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
4
+ <%= devise_error_messages! %>
5
+ <%= f.hidden_field :reset_password_token %>
6
+
7
+ <div><%= f.label :password, "New password" %><br />
8
+ <%= f.password_field :password %></div>
9
+
10
+ <div><%= f.label :password_confirmation, "Confirm new password" %><br />
11
+ <%= f.password_field :password_confirmation %></div>
12
+
13
+ <div><%= f.submit "Change my password" %></div>
14
+ <% end %>
15
+
16
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,12 @@
1
+ <h2>Forgot your password?</h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
4
+ <%= devise_error_messages! %>
5
+
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email %></div>
8
+
9
+ <div><%= f.submit "Send me reset password instructions" %></div>
10
+ <% end %>
11
+
12
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,25 @@
1
+ <h2>Edit <%= resource_name.to_s.humanize %></h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
4
+ <%= devise_error_messages! %>
5
+
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email %></div>
8
+
9
+ <div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
10
+ <%= f.password_field :password, :autocomplete => "off" %></div>
11
+
12
+ <div><%= f.label :password_confirmation %><br />
13
+ <%= f.password_field :password_confirmation %></div>
14
+
15
+ <div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
16
+ <%= f.password_field :current_password %></div>
17
+
18
+ <div><%= f.submit "Update" %></div>
19
+ <% end %>
20
+
21
+ <h3>Cancel my account</h3>
22
+
23
+ <p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.</p>
24
+
25
+ <%= link_to "Back", :back %>