fs_auth 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +40 -0
- data/app/controllers/application_controller.rb +3 -0
- data/app/controllers/users_controller.rb +125 -0
- data/app/filters/AdminRequired.rb +21 -0
- data/app/filters/LoginRequired.rb +11 -0
- data/app/filters/WebmasterRequired.rb +21 -0
- data/app/models/user.rb +62 -0
- data/app/views/users/_login.html.erb +28 -0
- data/app/views/users/_user.html.erb +11 -0
- data/app/views/users/admin.html.erb +17 -0
- data/app/views/users/change_password.html.erb +26 -0
- data/app/views/users/delete.html.erb +2 -0
- data/app/views/users/edit.html.erb +29 -0
- data/app/views/users/forgot_password.html.erb +9 -0
- data/app/views/users/login.html.erb +28 -0
- data/app/views/users/logout.html.erb +2 -0
- data/app/views/users/signup.html.erb +35 -0
- data/app/views/users/welcome.html.erb +1 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20111222014537_create_users.rb +18 -0
- data/lib/fs_auth.rb +22 -0
- data/lib/fs_auth/engine.rb +5 -0
- data/lib/fs_auth/version.rb +3 -0
- data/lib/tasks/fs_auth_tasks.rake +4 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +56 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/fs_auth_test.rb +7 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- 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
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,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
|
data/app/models/user.rb
ADDED
@@ -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,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 %>
|