fs_auth 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +40 -0
  4. data/app/controllers/application_controller.rb +3 -0
  5. data/app/controllers/users_controller.rb +125 -0
  6. data/app/filters/AdminRequired.rb +21 -0
  7. data/app/filters/LoginRequired.rb +11 -0
  8. data/app/filters/WebmasterRequired.rb +21 -0
  9. data/app/models/user.rb +62 -0
  10. data/app/views/users/_login.html.erb +28 -0
  11. data/app/views/users/_user.html.erb +11 -0
  12. data/app/views/users/admin.html.erb +17 -0
  13. data/app/views/users/change_password.html.erb +26 -0
  14. data/app/views/users/delete.html.erb +2 -0
  15. data/app/views/users/edit.html.erb +29 -0
  16. data/app/views/users/forgot_password.html.erb +9 -0
  17. data/app/views/users/login.html.erb +28 -0
  18. data/app/views/users/logout.html.erb +2 -0
  19. data/app/views/users/signup.html.erb +35 -0
  20. data/app/views/users/welcome.html.erb +1 -0
  21. data/config/routes.rb +3 -0
  22. data/db/migrate/20111222014537_create_users.rb +18 -0
  23. data/lib/fs_auth.rb +22 -0
  24. data/lib/fs_auth/engine.rb +5 -0
  25. data/lib/fs_auth/version.rb +3 -0
  26. data/lib/tasks/fs_auth_tasks.rake +4 -0
  27. data/test/dummy/README.rdoc +261 -0
  28. data/test/dummy/Rakefile +7 -0
  29. data/test/dummy/app/assets/javascripts/application.js +15 -0
  30. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  31. data/test/dummy/app/controllers/application_controller.rb +3 -0
  32. data/test/dummy/app/helpers/application_helper.rb +2 -0
  33. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  34. data/test/dummy/config.ru +4 -0
  35. data/test/dummy/config/application.rb +56 -0
  36. data/test/dummy/config/boot.rb +10 -0
  37. data/test/dummy/config/database.yml +25 -0
  38. data/test/dummy/config/environment.rb +5 -0
  39. data/test/dummy/config/environments/development.rb +37 -0
  40. data/test/dummy/config/environments/production.rb +67 -0
  41. data/test/dummy/config/environments/test.rb +37 -0
  42. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  43. data/test/dummy/config/initializers/inflections.rb +15 -0
  44. data/test/dummy/config/initializers/mime_types.rb +5 -0
  45. data/test/dummy/config/initializers/secret_token.rb +7 -0
  46. data/test/dummy/config/initializers/session_store.rb +8 -0
  47. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  48. data/test/dummy/config/locales/en.yml +5 -0
  49. data/test/dummy/config/routes.rb +58 -0
  50. data/test/dummy/public/404.html +26 -0
  51. data/test/dummy/public/422.html +26 -0
  52. data/test/dummy/public/500.html +25 -0
  53. data/test/dummy/public/favicon.ico +0 -0
  54. data/test/dummy/script/rails +6 -0
  55. data/test/fs_auth_test.rb +7 -0
  56. data/test/integration/navigation_test.rb +10 -0
  57. data/test/test_helper.rb +15 -0
  58. metadata +142 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
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.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = FsAuth
2
+
3
+ This project rocks and uses MIT-LICENSE.
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 = 'FsAuth'
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,3 @@
1
+ class ApplicationController < ActionController::Base
2
+
3
+ end
@@ -0,0 +1,125 @@
1
+ require 'LoginRequired'
2
+ require 'WebmasterRequired'
3
+
4
+ class UsersController < ApplicationController
5
+ before_filter LoginRequired, :only=>[:welcome, :change_password, :hidden]
6
+ before_filter WebmasterRequired, :only => [:admin, :save, :edit]
7
+
8
+ def signup
9
+ if params[:user]
10
+ @user = User.new(params[:user])
11
+
12
+ if User.count == 0
13
+ @user.role = 0
14
+ end
15
+
16
+ if request.post? and @user.login
17
+ if @user.save
18
+ session[:user] = User.authenticate(@user.login, @user.password)
19
+ flash[:message] = "Signup successful"
20
+ redirect_to :controller => "users", :action => "welcome"
21
+ else
22
+ flash[:warning] = "Signup unsuccessful"
23
+ end
24
+ end
25
+ else
26
+ @user = User.new()
27
+ end
28
+ end
29
+
30
+ def login
31
+ if params[:user]
32
+ if @user = User.authenticate(params[:user][:login], params[:user][:password])
33
+ session[:user] = @user
34
+ session[:last_touched] = Time.now
35
+ flash[:message] = "Login successful"
36
+ return_to_previous()
37
+ else
38
+ @user = User.new()
39
+ session[:user] = nil
40
+ reset_session
41
+
42
+ flash[:warning] = "Login unsuccessful"
43
+ end
44
+ else
45
+ @user = User.new()
46
+ end
47
+ end
48
+
49
+ def logout
50
+ session.delete(:user)
51
+ flash[:message] = 'Logged out'
52
+ if request.referer
53
+ redirect_to request.referer
54
+ else
55
+ redirect_to "/"
56
+ end
57
+ end
58
+
59
+ def forgot_password
60
+ if request.post?
61
+ u= User.find_by_email(params[:user][:email])
62
+ if u and u.send_new_password
63
+ flash[:message] = "A new password has been sent by email."
64
+ redirect_to :action=>'login'
65
+ else
66
+ flash[:warning] = "Couldn't send password"
67
+ end
68
+ end
69
+ end
70
+
71
+ def change_password
72
+ @user=User.find(session[:user][:id])
73
+
74
+ if params[:user]
75
+ if params[:user][:password].blank?
76
+ @user.errors.add(:password, "is required")
77
+ elsif params[:user][:password_confirmation].blank?
78
+ @user.errors.add(:password_confirmation, "is required")
79
+ elsif @user.update_attributes(params[:user])
80
+ logger.debug "User pass: #{@user.password}"
81
+
82
+ flash[:message]="Password Changed"
83
+ end
84
+ end
85
+ end
86
+
87
+ def admin
88
+ @users = User.all
89
+ end
90
+
91
+ def edit
92
+ @user = User.find_by_login(params[:id])
93
+ end
94
+
95
+ def save
96
+ @user = User.find_by_login(params[:id])
97
+ logger.debug "User login: #{params[:id]}"
98
+ logger.debug "User object: #{params[:user]}"
99
+
100
+ if @user.update_attributes!(params[:user])
101
+ flash[:message]="Successfully saved"
102
+ else
103
+ flash[:error]="Could not save user"
104
+ end
105
+
106
+ redirect_to request.referer
107
+ end
108
+
109
+
110
+ def welcome
111
+ end
112
+
113
+ def hidden
114
+ end
115
+
116
+ def return_to_previous
117
+ if(session[:return_to])
118
+ return_to = session[:return_to]
119
+ session[:return_to] = nil
120
+ redirect_to return_to
121
+ else
122
+ redirect_to "/"
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,21 @@
1
+ class AdminRequired
2
+ def self.filter(controller)
3
+ # Check if the user is even lgged in
4
+ # If not then redirect them to the login page
5
+ unless controller.session[:user]
6
+ controller.flash[:warning] = 'Please login to continue'
7
+ controller.session[:return_to] = controller.request.fullpath
8
+ controller.redirect_to :controller => 'users', :action => 'login'
9
+ return false
10
+ end
11
+
12
+ unless controller.session[:user] and controller.session[:user][:role] <= 1
13
+ controller.flash[:warning] = 'Please login to continue'
14
+ controller.session[:return_to] = controller.request.fullpath
15
+ controller.render :inline => "You are not authorized for this part of the application! Return <a href='/'>home</a>"
16
+ return false
17
+ end
18
+
19
+ return true
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ class LoginRequired
2
+ def self.filter(controller)
3
+ unless controller.session[:user]
4
+ controller.flash[:warning] = 'Please login to continue'
5
+ controller.session[:return_to] = controller.request.fullpath
6
+ controller.redirect_to :controller => "users", :action => "login"
7
+ return false
8
+ end
9
+ return true
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ class WebmasterRequired
2
+ def self.filter(controller)
3
+ # Check if the user is even lgged in
4
+ # If not then redirect them to the login page
5
+ unless controller.session[:user]
6
+ controller.flash[:warning] = 'Please login to continue'
7
+ controller.session[:return_to] = controller.request.fullpath
8
+ controller.redirect_to :controller => 'users', :action => 'login'
9
+ return false
10
+ end
11
+
12
+ unless controller.session[:user] and controller.session[:user][:role] <= 0
13
+ controller.flash[:warning] = 'You are not authorized for this part of the application!'
14
+ controller.session[:return_to] = controller.request.fullpath
15
+ controller.render :inline => "You are not authorized for this part of the application! Return <a href='/'>home</a>"
16
+ return false
17
+ end
18
+
19
+ return true
20
+ end
21
+ end
@@ -0,0 +1,62 @@
1
+ class User < ActiveRecord::Base
2
+ validates_length_of :login, :within => 3..40
3
+ validates_length_of :password, :within => 5..40, :allow_blank => true
4
+ validates_presence_of :login, :email, :salt, :crypted_password
5
+ validates_uniqueness_of :login, :email
6
+ validates_confirmation_of :password
7
+ validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :message => "Invalid email"
8
+
9
+ validates :password, :confirmation => true
10
+
11
+ # These are protected so they can't be forged by users
12
+ attr_protected :id, :salt
13
+
14
+ attr_accessor :password
15
+
16
+ # Assign password field encrypts into crypted_password database-backed field
17
+ def password=(pass)
18
+ @password=pass
19
+ self.salt = User.random_string(10) if !self.salt?
20
+ self.crypted_password = User.encrypt(@password, self.salt)
21
+ end
22
+
23
+ # Authenticate
24
+ def self.authenticate(login, pass)
25
+ u = find(:first, :conditions=>["login = ?", login])
26
+ return nil if u.nil?
27
+ return u if User.encrypt(pass, u.salt) == u.crypted_password
28
+ return nil
29
+ end
30
+
31
+ def is_webmaster
32
+ return self.role == 0
33
+ end
34
+
35
+ def is_admin
36
+ return self.role <= 1
37
+ end
38
+
39
+ # Called if the user forgets their password; sets it to a random one, emails that to the user's email address
40
+ def send_new_password
41
+ new_pass = User.random_string(10)
42
+ self.password = self.password_confirmation = new_pass
43
+ self.save
44
+ Notifications.deliver_forgot_password(self.email, self.login, new_pass)
45
+ end
46
+
47
+ protected
48
+
49
+ # Used to make salt
50
+ def self.random_string(len)
51
+ #generate a random password consisting of strings and digits
52
+ chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
53
+ newpass = ""
54
+ 1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
55
+ return newpass
56
+ end
57
+
58
+ # SHA1 encrypt
59
+ def self.encrypt(pass, salt)
60
+ Digest::SHA1.hexdigest(pass+salt)
61
+ end
62
+ end
@@ -0,0 +1,28 @@
1
+ <% if session[:user] == nil -%>
2
+ <div class="login">
3
+ <div class="login_form">
4
+ <%= form_for(:user, :url => { :controller => 'users', :action => "login"}) do |f| %>
5
+
6
+ <div>
7
+ <label for="user_login">Login:</label>
8
+ <%= text_field "user", "login", :size => 20 %>
9
+ </div>
10
+
11
+ <div>
12
+ <label for="user_password">Password:</label>
13
+ <%= password_field "user", "password", :size => 20 %>
14
+ </div>
15
+
16
+ <div>
17
+ <%= submit_tag "Log in" %>
18
+ </div>
19
+
20
+ <% end %>
21
+ </div>
22
+ <div class="login_extras">
23
+ <%= link_to 'Register', :controller => 'users', :action => 'signup' %> |
24
+ <%= link_to 'Forgot my password', :controller => 'users', :action => 'forgot_password' %>
25
+ </div>
26
+ </div>
27
+
28
+ <% end -%>
@@ -0,0 +1,11 @@
1
+ <% if @logged_in_user != nil && @logged_in_user.login != nil %>
2
+
3
+ <span class="logged_in_user">
4
+ Welcome, <%= @logged_in_user.login %>!<br />
5
+ <% if @logged_in_user.is_webmaster %>
6
+ <%= link_to 'Administration', :controller => 'users', :action => 'admin' %> |
7
+ <% end %>
8
+ <%= link_to 'Change Password', :controller => 'users', :action => 'change_password' %> |
9
+ <%= link_to 'Logout', :controller => 'users', :action => 'logout' %>
10
+ </span>
11
+ <% end -%>
@@ -0,0 +1,17 @@
1
+ <% if session[:user].is_webmaster %>
2
+ <% @users.each do |user| %>
3
+ <table>
4
+ <tr>
5
+ <th>Login</th>
6
+ <th>Email</th>
7
+ <th>Role</th>
8
+ <th>Actions</th>
9
+ <tr>
10
+ <td><%= user.login %></td>
11
+ <td><%= user.email %></td>
12
+ <td><%= user.role %></td>
13
+ <td><%= link_to 'Edit', :controller => 'users', :action => 'edit', :id => user.login %></td>
14
+ </tr>
15
+ </table>
16
+ <% end %>
17
+ <% end %>
@@ -0,0 +1,26 @@
1
+ <h1>Change password</h1>
2
+ <%= form_for(@user, :url => { :controller => 'users', :action => "change_password"}) do |f| %>
3
+ <% if @user.errors.any? %>
4
+ <div id="error_explanation">
5
+ <h2><%= pluralize(@user.errors.count, "error") %> prohibited you from registering:</h2>
6
+
7
+ <ul>
8
+ <% @user.errors.full_messages.each do |msg| %>
9
+ <li><%= msg %></li>
10
+ <% end %>
11
+ </ul>
12
+ </div>
13
+ <% end %>
14
+
15
+ <div class="field">
16
+ <%= f.label :password %><br />
17
+ <%= f.password_field :password %>
18
+ </div>
19
+ <div class="field">
20
+ <%= f.label :password_confirmation %><br />
21
+ <%= f.password_field :password_confirmation %>
22
+ </div>
23
+ <div class="actions">
24
+ <%= f.submit %>
25
+ </div>
26
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <h1>User#delete</h1>
2
+ <p>Find me in app/views/user/delete.rhtml</p>
@@ -0,0 +1,29 @@
1
+ <%= form_for @user, :url => { :action => "save", :id => @user.login } do |f| %>
2
+
3
+ <% if flash[:message] != nil %>
4
+ <p id="notice">notice: <%= flash[:message] %></p>
5
+ <% end %>
6
+ <% if flash[:error] != nil %>
7
+ <p id="error">error: <%= flash[:error] %></p>
8
+ <% end %>
9
+
10
+ <div class="field">
11
+ <%= f.label :login %><br />
12
+ <%= f.text_field :login %>
13
+ </div>
14
+
15
+ <div class="field">
16
+ <%= f.label :email %><br />
17
+ <%= f.text_field :email %>
18
+ </div>
19
+
20
+ <div class="field">
21
+ <%= f.label :role %><br />
22
+ <%= f.text_field :role %>
23
+ </div>
24
+
25
+ <div class="actions">
26
+ <%= f.submit %>
27
+ </div>
28
+
29
+ <% end %>