theworkinggroup-wristband 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. data/README.rdoc +130 -0
  2. data/Rakefile +39 -0
  3. data/generators/wristband/templates/app/controllers/sessions_controller.rb +50 -0
  4. data/generators/wristband/templates/app/controllers/users_controller.rb +47 -0
  5. data/generators/wristband/templates/app/models/user.rb +30 -0
  6. data/generators/wristband/templates/app/models/user_notifier.rb +54 -0
  7. data/generators/wristband/templates/app/views/sessions/new.html.haml +17 -0
  8. data/generators/wristband/templates/app/views/user_notifier/email_verification.text.html.rhtml +7 -0
  9. data/generators/wristband/templates/app/views/user_notifier/email_verification.text.plain.rhtml +9 -0
  10. data/generators/wristband/templates/app/views/user_notifier/forgot_password.text.html.rhtml +10 -0
  11. data/generators/wristband/templates/app/views/user_notifier/forgot_password.text.plain.rhtml +10 -0
  12. data/generators/wristband/templates/app/views/users/forgot_password.html.haml +10 -0
  13. data/generators/wristband/templates/app/views/users/index.html.haml +6 -0
  14. data/generators/wristband/templates/db/migrate/create_wristband_tables.rb +28 -0
  15. data/generators/wristband/wristband_generator.rb +69 -0
  16. data/init.rb +1 -0
  17. data/lib/wristband.rb +121 -0
  18. data/lib/wristband/application_extensions.rb +78 -0
  19. data/lib/wristband/authority_check.rb +160 -0
  20. data/lib/wristband/support.rb +28 -0
  21. data/lib/wristband/user_extensions.rb +89 -0
  22. data/test/database.yml +3 -0
  23. data/test/fixtures/crypted_password_users.yml +12 -0
  24. data/test/fixtures/plain_text_password_users.yml +4 -0
  25. data/test/fixtures/users.yml +23 -0
  26. data/test/schema.rb +34 -0
  27. data/test/test_helper.rb +40 -0
  28. data/test/unit/crypted_password_users_test.rb +81 -0
  29. data/test/unit/has_authorities_test.rb +49 -0
  30. data/test/unit/plain_text_password_user_test.rb +92 -0
  31. data/wristband.gemspec +32 -0
  32. metadata +97 -0
data/README.rdoc ADDED
@@ -0,0 +1,130 @@
1
+ = Wristband plugin
2
+ Author:: {The Working Group, Inc}[http://www.theworkinggroup.ca]
3
+ Version:: 1.0.0
4
+
5
+ The Wristband plug-in simplifies the user authentication process necessary in most web applications.
6
+
7
+ It handles:
8
+
9
+ * Login and logout
10
+ * Password storage with encryption
11
+ * Remember me functionality
12
+ * Authority definitions
13
+
14
+
15
+ == Usage
16
+
17
+ From a clean project
18
+ (assuming you just did <tt>rails myproject</tt> )
19
+
20
+ <b>1.</b> Install the plugin
21
+ cd vendor/plugins
22
+ svn export http://twg.unfuddle.com/svn/twg_twgplugins/wristband/trunk wristband
23
+
24
+ <b>2.</b> Run the wristband generator:
25
+ script/generate wristband
26
+
27
+ This will output something like:
28
+
29
+ exists app/models
30
+ create app/models/user.rb
31
+ create app/controllers/users_controller.rb
32
+ create app/views/users/index.html.haml
33
+ exists app/controllers
34
+ create app/controllers/sessions_controller.rb
35
+ create app/views/sessions/new.html.haml
36
+ exists db/migrate
37
+ exists db/migrate
38
+ create db/migrate/001_wristband.rb
39
+ route specific routes
40
+ route map.resources :sessions, :users
41
+
42
+ <b>3.</b> Run migrations
43
+
44
+ rake db:migrate
45
+
46
+ <b>4.</b> Restart your server
47
+
48
+ <b>5.</b> Add whatever validations you need in your User model
49
+
50
+ <b>6.</b> Read the documentation on each one of the generated files
51
+
52
+
53
+ == Configuration
54
+
55
+
56
+ === User model
57
+
58
+ class User < ActiveRecord::Base
59
+ wristband [options]
60
+ end
61
+
62
+ ==== Options:
63
+
64
+ [:login_with] Array of fields you want to authenticate the user with. Default: usename
65
+
66
+ wristband :login_with => [:username, :email]
67
+
68
+
69
+ [:before_authentication] Array of functions run after the user authentication takes place. Default: []
70
+
71
+ wristband :before_authentication => :do_something
72
+
73
+
74
+ [:after_authentication] Array of functions run before the user authentication takes place. Default: []
75
+
76
+ wristband :after_authentication => :do_something
77
+
78
+
79
+ [:plain_text_password] If true the password won't be encrypted. Default: false
80
+
81
+ wristband :plain_text_password => true
82
+
83
+ [:has_authorities] If true the password won't be encrypted. Default: false
84
+
85
+ wristband :plain_text_password => true
86
+
87
+ ==== Remarks:
88
+
89
+ * While password_crypt is limited to 40 characters, the standard output of the hashing function used to encrypt it, there is no such limit on the length of the password as input by the user.
90
+ * There are no default restrictions on the content of the username. These should be added as required.
91
+ * A user's password is stored encrypted by default but support for plain- text passwords is also provided. Leaving 'password_salt' as blank or nil means the password is not encrypted. This makes the content of user
92
+ fixtures easy to read and understand.
93
+ * The 'remember_token' field is used for login authentication via persistent cookie. This value changes each time the user's password is reassigned.
94
+
95
+
96
+ == Functionality
97
+
98
+ === 1. Remember me
99
+ If you want to automatically login a user when he comes back to your site, add <tt>before_filter :login_from_cookie</tt> to your AplicationController.
100
+
101
+ === 2. Authority Definitions
102
+
103
+ Check the documentation on the link:files/lib/authority_check_rb.html file
104
+
105
+ ==== Other Reading
106
+
107
+ "The Emerging Standards Bureau" on naming methods
108
+ http://giantrobots.thoughtbot.com/2008/4/10/the-emerging-standards-bureau
109
+
110
+
111
+ == Database configuration
112
+
113
+ The generator gives you a head start.
114
+ The basic columns are defined as such:
115
+
116
+ create_table :users do |t|
117
+ t.string :email
118
+ t.string :password_crypt, :limit => 40
119
+ t.string :password_salt, :limit => 40
120
+ t.string :remember_token
121
+ t.string :email_validation_key
122
+ t.string :role
123
+ t.datetime :created_at
124
+ t.datetime :updated_at
125
+ # Add your own stuff here ...
126
+ end
127
+
128
+
129
+
130
+
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ require 'rake/testtask'
6
+ require 'rake/rdoctask'
7
+
8
+ desc 'Default: run unit tests.'
9
+ task :default => :test
10
+
11
+ desc 'Test the wristband plugin.'
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << 'lib'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = true
16
+ end
17
+
18
+
19
+ desc 'Generate documentation for the wristband plugin.'
20
+ Rake::RDocTask.new(:rdoc) do |rdoc|
21
+ rdoc.rdoc_dir = 'rdoc'
22
+ rdoc.title = 'Wristband'
23
+ rdoc.options << '--line-numbers' << '--inline-source'
24
+ rdoc.rdoc_files.include('README')
25
+ rdoc.rdoc_files.include('lib/**/*.rb')
26
+ end
27
+
28
+
29
+ Echoe.new('wristband', '1.0.0') do |p|
30
+ p.description = "Simplifies the process of authenticating and authorizing users."
31
+ p.url = "http://github.com/theworkinggroup/wristband"
32
+ p.author = "Jack Neto"
33
+ p.email = "jack@theworkinggroup.ca"
34
+ p.ignore_pattern = ["tmp/*", "script/*"]
35
+ p.development_dependencies = []
36
+ end
37
+
38
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
39
+
@@ -0,0 +1,50 @@
1
+ # -----------------------------------------------
2
+ # This file was generated by the acts_as_authenticated_user plugin
3
+ # Edit as needed ...
4
+ #
5
+ # More details at http://www.theworkinggroup.ca/rails/plugins/wristband
6
+ # -----------------------------------------------
7
+ class SessionsController < ApplicationController
8
+
9
+ # login_required is defined by the wristband plugin
10
+ # if the user is not logged in it will call respond_not_logged_in
11
+ before_filter :login_required, :only => :destroy
12
+
13
+ # This one is just usefull to have
14
+ before_filter :redirect_if_logged_in, :only => [:new, :create]
15
+
16
+ def new
17
+ # ...
18
+ end
19
+
20
+ # Logs the user in
21
+ # Adjust as necessary
22
+ def create
23
+ if @user = authenticate_and_login(params[:user][:username], params[:user][:password], params[:user][:remember_me]=='1')
24
+ flash[:notice] = "Welcome, you are now logged in."
25
+ redirect_to users_path
26
+ else
27
+ flash[:notice] = 'Login failed.'
28
+ redirect_to login_path
29
+ end
30
+ end
31
+
32
+ # Logs out the user
33
+ # Adjust as necessary
34
+ def destroy
35
+ logout
36
+ redirect_to home_path
37
+ end
38
+
39
+ private
40
+ def redirect_if_logged_in
41
+ redirect_to home_path if logged_in?
42
+ end
43
+
44
+ # This will be called by the login_required filter when the user is not logged in
45
+ # You can replace this with whatever you want.
46
+ # You can also move this to Application controller so it can be shared with other controllers.
47
+ def respond_not_logged_in
48
+ redirect_to login_path
49
+ end
50
+ end
@@ -0,0 +1,47 @@
1
+ # -----------------------------------------------
2
+ # This file was generated by the acts_as_authenticated_user plugin
3
+ # Edit as needed ...
4
+ #
5
+ # More details at http://www.theworkinggroup.ca/rails/plugins/wristband
6
+ # -----------------------------------------------
7
+ class UsersController < ApplicationController
8
+
9
+ # login_required is defined by the wristband plugin
10
+ # if the user is not logged in it will call respond_not_logged_in
11
+ before_filter :login_required
12
+
13
+
14
+ def verify_email
15
+ @user = User.verify_email!(params[:email_validation_key])
16
+ flash[:notice] = 'Your email address has been verified. You may now login to your account.'
17
+ redirect_to login_path
18
+ rescue UserVerificationError => error
19
+ flash[:error] = error.message
20
+ redirect_to login_path
21
+ end
22
+
23
+ def forgot_password
24
+ if request.post?
25
+ if @user = User.find_by_username(params[:user][:username])
26
+ @user.password = Wristband::Support.random_string(6)
27
+ @user.save!
28
+ UserNotifier::deliver_forgot_password(@user)
29
+ flash[:notice] = 'A new password has been generated and emailed to the address you entered.'
30
+ redirect_to login_path and return
31
+ else
32
+ @user = User.new
33
+ @user.errors.add("email", "Cannot find that email address, did you mistype?")
34
+ end
35
+ end
36
+ end
37
+
38
+
39
+ private
40
+ # This will be called by the login_required filter when the user is not logged in
41
+ # You can replace this with whatever you want.
42
+ # You can also move this to Application controller so it can be shared with other controllers.
43
+ def respond_not_logged_in
44
+ redirect_to login_path
45
+ end
46
+
47
+ end
@@ -0,0 +1,30 @@
1
+ # -----------------------------------------------
2
+ # This file was generated by the acts_as_authenticated_user plugin
3
+ # Edit as needed ...
4
+ #
5
+ # More details at http://www.theworkinggroup.ca/rails/plugins/wristband
6
+ # -----------------------------------------------
7
+ class User < ActiveRecord::Base
8
+
9
+ # Add your own stuff here...
10
+ # Possible options are:
11
+ #
12
+ # :login_with
13
+ # The fields a user will be validated againts.
14
+ # Defaults to :username
15
+ #
16
+ # :password_column
17
+ # Sets the name of your password column.
18
+ # If :plain_text_password => true it defaults to :password otherwise it defaults to :password_crypt
19
+ #
20
+ # :plain_text_password
21
+ # Defaults to false
22
+ #
23
+ # :before_authentication
24
+ # Stuff you may want to do before authentication
25
+ #
26
+ # :after_authentication
27
+ # Stuff you may want to do after authentication
28
+ #
29
+ wristband
30
+ end
@@ -0,0 +1,54 @@
1
+ # -----------------------------------------------
2
+ # This file was generated by the acts_as_authenticated_user plugin
3
+ # Edit as needed ...
4
+ #
5
+ # More details at http://www.theworkinggroup.ca/rails/plugins/wristband
6
+ # -----------------------------------------------
7
+ class UserNotifier < ActionMailer::Base
8
+ # Define on you config/environments folder:
9
+ # development:
10
+ # HOST_NAME = 'localhost:3000'
11
+ # SITE_URL = 'http://localhost:3000'
12
+ # FROM_EMAIL = 'your_email@your_domain.com'
13
+ # test:
14
+ # HOST_NAME = 'localhost:3000'
15
+ # SITE_URL = 'http://localhost:3000'
16
+ # FROM_EMAIL = 'your_email@your_domain.com'
17
+ # staging:
18
+ # HOST_NAME = 'staging.yourapp.com'
19
+ # SITE_URL = 'http://staging.yourapp.com'
20
+ # FROM_EMAIL = 'info@staging.yourapp.com'
21
+ # production:
22
+ # HOST_NAME = 'yourapp.com'
23
+ # SITE_URL = 'http://www.yourapp.com'
24
+ # FROM_EMAIL = 'info@yourapp.com'
25
+
26
+ default_url_options[:host] = HOST_NAME
27
+
28
+ def email_verification(user)
29
+ setup_email(user)
30
+ @subject += "Your account has been created. Please verify your email address"
31
+ end
32
+
33
+ def forgot_password(user)
34
+ setup_email(user)
35
+ @subject += "You have requested a new password"
36
+ end
37
+
38
+
39
+ protected
40
+ # Change YourApp to whatever you application is called
41
+ def setup_email(user)
42
+ @recipients = user.email
43
+ @body[:user] = user
44
+ @from = FROM_EMAIL
45
+ @subject = case ENV['RAILS_ENV']
46
+ when 'development': "[YourApp Development] "
47
+ when 'staging': "[YourApp Staging] "
48
+ else "[YourApp] "
49
+ end
50
+ @sent_on = Time.now
51
+ headers "Reply-to" => FROM_EMAIL
52
+ end
53
+
54
+ end
@@ -0,0 +1,17 @@
1
+ %h1 Login
2
+
3
+ = error_messages_for :user
4
+ - form_for :user, @user, :url => sessions_path, :builder => CustomForm do |f|
5
+ = f.text_field :username
6
+ = f.password_field :password
7
+ = f.check_box :remember_me, :label => 'Remember me when I come back'
8
+ = f.submit 'Log In'
9
+
10
+
11
+ %p
12
+ Did you forget your password?
13
+ = link_to 'Recover it here.', forgot_password_path
14
+ %p
15
+ If you don't have a login yet, click
16
+ = link_to 'here', register_path
17
+ to register.
@@ -0,0 +1,7 @@
1
+ <p>Hi,</p>
2
+
3
+ <p>Your account has been set up.</p>
4
+
5
+ <p>To verify your email address so that you may login, please click <%= link_to 'here', verify_email_url(@user.email_validation_key) %>.</p>
6
+
7
+ <p>Thanks</p>
@@ -0,0 +1,9 @@
1
+ Hi,
2
+
3
+ Your account has been set up.
4
+
5
+ To verify your email address so that you may login, please visit the following link:
6
+
7
+ <%= verify_email_url(@user.email_validation_key) %>
8
+
9
+ Thanks
@@ -0,0 +1,10 @@
1
+ <p>Hi,</p>
2
+
3
+ <p>A new password was requested for this email address.</p>
4
+
5
+ <p>Your new password is: <b><%= @user.password %></b> </p>
6
+
7
+ <p><%= link_to 'Click here to login', login_url %>.</p>
8
+ <p>Once you have logged in, you can edit your profile and change your password to something you can easily remember.</p>
9
+
10
+ <p>Thanks</p>
@@ -0,0 +1,10 @@
1
+ Hi,
2
+
3
+ A new password was requested for this email address.
4
+
5
+ Your new password is: <b><%= @user.password %></b>
6
+
7
+ To login go to: <%= login_url %>.
8
+ Once you have logged in, you can edit your profile and change your password to something you can easily remember.
9
+
10
+ Thanks
@@ -0,0 +1,10 @@
1
+ %h1 Password Recovery
2
+
3
+ %p
4
+ If you have forgotten your Password, please enter your email address below.
5
+ %br/
6
+ You will be sent an email with new login information.
7
+
8
+ - form_for :user, @user, :url => forgot_password_path do |f|
9
+ = f.text_field :email, :label => 'Your Email:'
10
+ = f.submit 'Recover Username/Password', link_to('Cancel', login_path)
@@ -0,0 +1,6 @@
1
+ %h1= "Hi #{session_user.username}"
2
+
3
+ - if logged_in?
4
+ = link_to 'Logout', logout_path
5
+ - else
6
+ = link_to 'Login', login_path
@@ -0,0 +1,28 @@
1
+ # -----------------------------------------------
2
+ # This file was generated by the wristband plugin
3
+ # Edit as needed ...
4
+ #
5
+ # More details at http://www.theworkinggroup.ca/rails/plugins/wristband
6
+ # -----------------------------------------------
7
+ class CreateWristbandTables < ActiveRecord::Migration
8
+ def self.up
9
+ create_table :users do |t|
10
+ # uncomment if you want a username in addition to an email
11
+ # t.string :username
12
+ t.string :email
13
+ t.string :password_crypt, :limit => 40
14
+ t.string :password_salt, :limit => 40
15
+ t.string :remember_token
16
+ t.string :email_validation_key
17
+ t.datetime :validated_at
18
+ t.string :role
19
+ t.datetime :created_at
20
+ t.datetime :updated_at
21
+ # Add your own stuff here ...
22
+ end
23
+ end
24
+
25
+ def self.down
26
+ drop_table :users
27
+ end
28
+ end