login_generator 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/USAGE +24 -0
- data/login_generator.rb +36 -0
- data/templates/README +119 -0
- data/templates/controller.rb +36 -0
- data/templates/controller_test.rb +74 -0
- data/templates/helper.rb +2 -0
- data/templates/login_system.rb +87 -0
- data/templates/user.rb +59 -0
- data/templates/user_test.rb +91 -0
- data/templates/users.yml +16 -0
- data/templates/view_login.rhtml +22 -0
- data/templates/view_logout.rhtml +10 -0
- data/templates/view_signup.rhtml +17 -0
- data/templates/view_welcome.rhtml +13 -0
- metadata +60 -0
data/USAGE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
NAME
|
2
|
+
login - creates a functional login system
|
3
|
+
|
4
|
+
SYNOPSIS
|
5
|
+
login [Controller name]
|
6
|
+
|
7
|
+
Good names are Account Myaccount Security
|
8
|
+
|
9
|
+
DESCRIPTION
|
10
|
+
This generator creates a general purpose login system.
|
11
|
+
|
12
|
+
Included:
|
13
|
+
- a User model which uses sha1 encryption for passwords
|
14
|
+
- a Controller with signup, login, welcome and logoff actions
|
15
|
+
- a mixin which lets you easily add advanced authentication
|
16
|
+
features to your abstract base controller
|
17
|
+
- a user_model.sql with the minimal sql required to get the model to work.
|
18
|
+
- extensive unit and functional test cases to make sure nothing breaks.
|
19
|
+
|
20
|
+
EXAMPLE
|
21
|
+
./script/generate login Account
|
22
|
+
|
23
|
+
This will generate an Account controller with login and logout methods.
|
24
|
+
The model is always called User
|
data/login_generator.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
class LoginGenerator < Rails::Generator::NamedBase
|
2
|
+
def manifest
|
3
|
+
record do |m|
|
4
|
+
|
5
|
+
# Login module, controller class, functional test, and helper.
|
6
|
+
m.template "login_system.rb", "lib/login_system.rb"
|
7
|
+
m.template "controller.rb", File.join("app/controllers", class_path, "#{file_name}_controller.rb")
|
8
|
+
m.template "controller_test.rb", File.join("test/functional", class_path, "#{file_name}_controller_test.rb")
|
9
|
+
m.template "helper.rb", File.join("app/helpers", class_path, "#{file_name}_helper.rb")
|
10
|
+
|
11
|
+
# Model class, unit test, fixtures, and example schema.
|
12
|
+
m.template "user.rb", "app/models/user.rb"
|
13
|
+
m.template "user_test.rb", "test/unit/user_test.rb"
|
14
|
+
m.template "users.yml", "test/fixtures/users.yml"
|
15
|
+
|
16
|
+
# Layout and stylesheet.
|
17
|
+
m.template "scaffold:layout.rhtml", "app/views/layouts/scaffold.rhtml"
|
18
|
+
m.template "scaffold:style.css", "public/stylesheets/scaffold.css"
|
19
|
+
|
20
|
+
# Views.
|
21
|
+
m.directory File.join("app/views", class_path, file_name)
|
22
|
+
login_views.each do |action|
|
23
|
+
m.template "view_#{action}.rhtml",
|
24
|
+
File.join("app/views", class_path, file_name, "#{action}.rhtml")
|
25
|
+
end
|
26
|
+
|
27
|
+
m.template "README", "README_LOGIN"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_accessor :controller_class_name
|
32
|
+
|
33
|
+
def login_views
|
34
|
+
%w(welcome login logout signup)
|
35
|
+
end
|
36
|
+
end
|
data/templates/README
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
== Installation
|
2
|
+
|
3
|
+
Done generating the login system. but there are still a few things you have to
|
4
|
+
do manually. First open your application.rb and add
|
5
|
+
|
6
|
+
require_dependency "login_system"
|
7
|
+
|
8
|
+
to the top of the file and include the login system with
|
9
|
+
|
10
|
+
include LoginSystem
|
11
|
+
|
12
|
+
The beginning of your ApplicationController.
|
13
|
+
It should look something like this :
|
14
|
+
|
15
|
+
require_dependency "login_system"
|
16
|
+
|
17
|
+
class ApplicationController < ActionController::Base
|
18
|
+
include LoginSystem
|
19
|
+
model :user
|
20
|
+
|
21
|
+
After you have done the modifications the the AbstractController you can import
|
22
|
+
the user model into the database. This model is meant as an example and you
|
23
|
+
should extend it. If you just want to get things up and running you can find
|
24
|
+
some create table syntax in db/user_model.sql.
|
25
|
+
|
26
|
+
The model :user is required when you are hitting problems to the degree of
|
27
|
+
"Session could not be restored becuase not all items in it are known"
|
28
|
+
|
29
|
+
== Requirements
|
30
|
+
|
31
|
+
You need a database table corresponding to the User model.
|
32
|
+
|
33
|
+
mysql syntax:
|
34
|
+
CREATE TABLE users (
|
35
|
+
id int(11) NOT NULL auto_increment,
|
36
|
+
login varchar(80) default NULL,
|
37
|
+
password varchar(40) default NULL,
|
38
|
+
PRIMARY KEY (id)
|
39
|
+
);
|
40
|
+
|
41
|
+
postgres :
|
42
|
+
CREATE TABLE "users" (
|
43
|
+
"id" SERIAL NOT NULL UNIQUE,
|
44
|
+
"login" VARCHAR(80),
|
45
|
+
"password" VARCHAR,
|
46
|
+
PRIMARY KEY("id")
|
47
|
+
) WITH OIDS;
|
48
|
+
|
49
|
+
|
50
|
+
sqlite:
|
51
|
+
CREATE TABLE 'users' (
|
52
|
+
'id' INTEGER PRIMARY KEY NOT NULL,
|
53
|
+
'user' VARCHAR(80) DEFAULT NULL,
|
54
|
+
'password' VARCHAR(40) DEFAULT NULL
|
55
|
+
);
|
56
|
+
|
57
|
+
Of course your user model can have any amount of extra fields. This is just a
|
58
|
+
starting point
|
59
|
+
|
60
|
+
== How to use it
|
61
|
+
|
62
|
+
Now you can go around and happily add "before_filter :login_required" to the
|
63
|
+
controllers which you would like to protect.
|
64
|
+
|
65
|
+
After integrating the login system with your rails application navigate to your
|
66
|
+
new controller's signup method. There you can create a new account. After you
|
67
|
+
are done you should have a look at your DB. Your freshly created user will be
|
68
|
+
there but the password will be a sha1 hashed 40 digit mess. I find this should
|
69
|
+
be the minimum of security which every page offering login&password should give
|
70
|
+
its customers. Now you can move to one of those controllers which you protected
|
71
|
+
with the before_filter :login_required snippet. You will automatically be re-
|
72
|
+
directed to your freshly created login controller and you are asked for a
|
73
|
+
password. After entering valid account data you will be taken back to the
|
74
|
+
controller which you requested earlier. Simple huh?
|
75
|
+
|
76
|
+
== Tips & Tricks
|
77
|
+
|
78
|
+
How do I...
|
79
|
+
|
80
|
+
... access the user who is currently logged in
|
81
|
+
|
82
|
+
A: You can get the user object from the session using @session['user']
|
83
|
+
Example:
|
84
|
+
Welcome <%%= @session[:user].name %>
|
85
|
+
|
86
|
+
... restrict access to only a few methods?
|
87
|
+
|
88
|
+
A: Use before_filters build in scoping.
|
89
|
+
Example:
|
90
|
+
before_filter :login_required, :only => [:myaccount, :changepassword]
|
91
|
+
before_filter :login_required, :except => [:index]
|
92
|
+
|
93
|
+
... check if a user is logged-in in my views?
|
94
|
+
|
95
|
+
A: @session[:user] will tell you. Here is an example helper which you can use to make this more pretty:
|
96
|
+
Example:
|
97
|
+
def user?
|
98
|
+
!@session[:user].nil?
|
99
|
+
end
|
100
|
+
|
101
|
+
... return a user to the page they came from before logging in?
|
102
|
+
|
103
|
+
A: The user will be send back to the last url which called the method "store_location"
|
104
|
+
Example:
|
105
|
+
User was at /articles/show/1, wants to log in.
|
106
|
+
in articles_controller.rb, add store_location to the show function and send the user
|
107
|
+
to the login form.
|
108
|
+
After he logs in he will be send back to /articles/show/1
|
109
|
+
|
110
|
+
|
111
|
+
You can find more help at http://wiki.rubyonrails.com/rails/show/LoginGenerator
|
112
|
+
|
113
|
+
== Changelog
|
114
|
+
|
115
|
+
1.1.0 Major security bugfix and modernisation
|
116
|
+
1.0.5 Bugfix in generator code
|
117
|
+
1.0.2 Updated the readme with more tips&tricks
|
118
|
+
1.0.1 Fixed problem in the readme
|
119
|
+
1.0.0 First gem release
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class <%= class_name %>Controller < ApplicationController
|
2
|
+
layout 'scaffold'
|
3
|
+
|
4
|
+
def login
|
5
|
+
case @request.method
|
6
|
+
when :post
|
7
|
+
if @session[:user] = User.authenticate(@params[:user_login], @params[:user_password])
|
8
|
+
|
9
|
+
flash['notice'] = "Login successful"
|
10
|
+
redirect_back_or_default :action => "welcome"
|
11
|
+
else
|
12
|
+
flash.now['notice'] = "Login unsuccessful"
|
13
|
+
|
14
|
+
@login = @params[:user_login]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def signup
|
20
|
+
@user = User.new(@params[:user])
|
21
|
+
|
22
|
+
if @request.post? and @user.save
|
23
|
+
@session[:user] = User.authenticate(@user.login, @params[:user][:password])
|
24
|
+
flash['notice'] = "Signup successful"
|
25
|
+
redirect_back_or_default :action => "welcome"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def logout
|
30
|
+
@session[:user] = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def welcome
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
require '<%= file_name %>_controller'
|
3
|
+
|
4
|
+
# Set salt to 'change-me' because thats what the fixtures assume.
|
5
|
+
User.salt = 'change-me'
|
6
|
+
|
7
|
+
# Raise errors beyond the default web-based presentation
|
8
|
+
class <%= class_name %>Controller; def rescue_action(e) raise e end; end
|
9
|
+
|
10
|
+
class <%= class_name %>ControllerTest < Test::Unit::TestCase
|
11
|
+
|
12
|
+
fixtures :users
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@controller = <%= class_name %>Controller.new
|
16
|
+
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
|
17
|
+
@request.host = "localhost"
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_auth_bob
|
21
|
+
@request.session[:return_to] = "/bogus/location"
|
22
|
+
|
23
|
+
post :login, :user_login => "bob", :user_password => "test"
|
24
|
+
assert_session_has :user
|
25
|
+
|
26
|
+
assert_equal @bob, @response.session[:user]
|
27
|
+
|
28
|
+
assert_redirect_url "/bogus/location"
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_signup
|
32
|
+
@request.session[:return_to] = "/bogus/location"
|
33
|
+
|
34
|
+
post :signup, :user => { :login => "newbob", :password => "newpassword", :password_confirmation => "newpassword" }
|
35
|
+
assert_session_has :user
|
36
|
+
|
37
|
+
assert_redirect_url "/bogus/location"
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_bad_signup
|
41
|
+
@request.session[:return_to] = "/bogus/location"
|
42
|
+
|
43
|
+
post :signup, :user => { :login => "newbob", :password => "newpassword", :password_confirmation => "wrong" }
|
44
|
+
assert_invalid_column_on_record "user", :password
|
45
|
+
assert_success
|
46
|
+
|
47
|
+
post :signup, :user => { :login => "yo", :password => "newpassword", :password_confirmation => "newpassword" }
|
48
|
+
assert_invalid_column_on_record "user", :login
|
49
|
+
assert_success
|
50
|
+
|
51
|
+
post :signup, :user => { :login => "yo", :password => "newpassword", :password_confirmation => "wrong" }
|
52
|
+
assert_invalid_column_on_record "user", [:login, :password]
|
53
|
+
assert_success
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_invalid_login
|
57
|
+
post :login, :user_login => "bob", :user_password => "not_correct"
|
58
|
+
|
59
|
+
assert_session_has_no :user
|
60
|
+
|
61
|
+
assert_template_has "login"
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_login_logoff
|
65
|
+
|
66
|
+
post :login, :user_login => "bob", :user_password => "test"
|
67
|
+
assert_session_has :user
|
68
|
+
|
69
|
+
get :logout
|
70
|
+
assert_session_has_no :user
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
data/templates/helper.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require_dependency "user"
|
2
|
+
|
3
|
+
module LoginSystem
|
4
|
+
|
5
|
+
protected
|
6
|
+
|
7
|
+
# overwrite this if you want to restrict access to only a few actions
|
8
|
+
# or if you want to check if the user has the correct rights
|
9
|
+
# example:
|
10
|
+
#
|
11
|
+
# # only allow nonbobs
|
12
|
+
# def authorize?(user)
|
13
|
+
# user.login != "bob"
|
14
|
+
# end
|
15
|
+
def authorize?(user)
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
# overwrite this method if you only want to protect certain actions of the controller
|
20
|
+
# example:
|
21
|
+
#
|
22
|
+
# # don't protect the login and the about method
|
23
|
+
# def protect?(action)
|
24
|
+
# if ['action', 'about'].include?(action)
|
25
|
+
# return false
|
26
|
+
# else
|
27
|
+
# return true
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
def protect?(action)
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
# login_required filter. add
|
35
|
+
#
|
36
|
+
# before_filter :login_required
|
37
|
+
#
|
38
|
+
# if the controller should be under any rights management.
|
39
|
+
# for finer access control you can overwrite
|
40
|
+
#
|
41
|
+
# def authorize?(user)
|
42
|
+
#
|
43
|
+
def login_required
|
44
|
+
|
45
|
+
if not protect?(action_name)
|
46
|
+
return true
|
47
|
+
end
|
48
|
+
|
49
|
+
if @session[:user] and authorize?(@session[:user])
|
50
|
+
return true
|
51
|
+
end
|
52
|
+
|
53
|
+
# store current location so that we can
|
54
|
+
# come back after the user logged in
|
55
|
+
store_location
|
56
|
+
|
57
|
+
# call overwriteable reaction to unauthorized access
|
58
|
+
access_denied
|
59
|
+
return false
|
60
|
+
end
|
61
|
+
|
62
|
+
# overwrite if you want to have special behavior in case the user is not authorized
|
63
|
+
# to access the current operation.
|
64
|
+
# the default action is to redirect to the login screen
|
65
|
+
# example use :
|
66
|
+
# a popup window might just close itself for instance
|
67
|
+
def access_denied
|
68
|
+
redirect_to :controller=>"/<%= file_name %>", :action =>"login"
|
69
|
+
end
|
70
|
+
|
71
|
+
# store current uri in the session.
|
72
|
+
# we can return to this location by calling return_location
|
73
|
+
def store_location
|
74
|
+
@session[:return_to] = @request.request_uri
|
75
|
+
end
|
76
|
+
|
77
|
+
# move to the last store_location call or to the passed default one
|
78
|
+
def redirect_back_or_default(default)
|
79
|
+
if @session[:return_to].nil?
|
80
|
+
redirect_to default
|
81
|
+
else
|
82
|
+
redirect_to_url @session[:return_to]
|
83
|
+
@session[:return_to] = nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
data/templates/user.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
# this model expects a certain database layout and its based on the name/login pattern.
|
4
|
+
class User < ActiveRecord::Base
|
5
|
+
|
6
|
+
# Please change the salt to something else,
|
7
|
+
# Every application should use a different one
|
8
|
+
@@salt = 'change-me'
|
9
|
+
cattr_accessor :salt
|
10
|
+
|
11
|
+
# Authenticate a user.
|
12
|
+
#
|
13
|
+
# Example:
|
14
|
+
# @user = User.authenticate('bob', 'bobpass')
|
15
|
+
#
|
16
|
+
def self.authenticate(login, pass)
|
17
|
+
find_first(["login = ? AND password = ?", login, sha1(pass)])
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
# Apply SHA1 encryption to the supplied password.
|
24
|
+
# We will additionally surround the password with a salt
|
25
|
+
# for additional security.
|
26
|
+
def self.sha1(pass)
|
27
|
+
Digest::SHA1.hexdigest("#{salt}--#{pass}--")
|
28
|
+
end
|
29
|
+
|
30
|
+
before_create :crypt_password
|
31
|
+
|
32
|
+
# Before saving the record to database we will crypt the password
|
33
|
+
# using SHA1.
|
34
|
+
# We never store the actual password in the DB.
|
35
|
+
def crypt_password
|
36
|
+
write_attribute "password", self.class.sha1(password)
|
37
|
+
end
|
38
|
+
|
39
|
+
before_update :crypt_unless_empty
|
40
|
+
|
41
|
+
# If the record is updated we will check if the password is empty.
|
42
|
+
# If its empty we assume that the user didn't want to change his
|
43
|
+
# password and just reset it to the old value.
|
44
|
+
def crypt_unless_empty
|
45
|
+
if password.empty?
|
46
|
+
user = self.class.find(self.id)
|
47
|
+
self.password = user.password
|
48
|
+
else
|
49
|
+
write_attribute "password", self.class.sha1(password)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
validates_uniqueness_of :login, :on => :create
|
54
|
+
|
55
|
+
validates_confirmation_of :password
|
56
|
+
validates_length_of :login, :within => 3..40
|
57
|
+
validates_length_of :password, :within => 5..40
|
58
|
+
validates_presence_of :login, :password, :password_confirmation
|
59
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
# Set salt to 'change-me' because thats what the fixtures assume.
|
4
|
+
User.salt = 'change-me'
|
5
|
+
|
6
|
+
class UserTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
fixtures :users
|
9
|
+
|
10
|
+
def test_auth
|
11
|
+
|
12
|
+
assert_equal @bob, User.authenticate("bob", "test")
|
13
|
+
assert_nil User.authenticate("nonbob", "test")
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_disallowed_passwords
|
18
|
+
|
19
|
+
u = User.new
|
20
|
+
u.login = "nonbob"
|
21
|
+
|
22
|
+
u.password = u.password_confirmation = "tiny"
|
23
|
+
assert !u.save
|
24
|
+
assert u.errors.invalid?('password')
|
25
|
+
|
26
|
+
u.password = u.password_confirmation = "hugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehuge"
|
27
|
+
assert !u.save
|
28
|
+
assert u.errors.invalid?('password')
|
29
|
+
|
30
|
+
u.password = u.password_confirmation = ""
|
31
|
+
assert !u.save
|
32
|
+
assert u.errors.invalid?('password')
|
33
|
+
|
34
|
+
u.password = u.password_confirmation = "bobs_secure_password"
|
35
|
+
assert u.save
|
36
|
+
assert u.errors.empty?
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_bad_logins
|
41
|
+
|
42
|
+
u = User.new
|
43
|
+
u.password = u.password_confirmation = "bobs_secure_password"
|
44
|
+
|
45
|
+
u.login = "x"
|
46
|
+
assert !u.save
|
47
|
+
assert u.errors.invalid?('login')
|
48
|
+
|
49
|
+
u.login = "hugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhug"
|
50
|
+
assert !u.save
|
51
|
+
assert u.errors.invalid?('login')
|
52
|
+
|
53
|
+
u.login = ""
|
54
|
+
assert !u.save
|
55
|
+
assert u.errors.invalid?('login')
|
56
|
+
|
57
|
+
u.login = "okbob"
|
58
|
+
assert u.save
|
59
|
+
assert u.errors.empty?
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def test_collision
|
65
|
+
u = User.new
|
66
|
+
u.login = "existingbob"
|
67
|
+
u.password = u.password_confirmation = "bobs_secure_password"
|
68
|
+
assert !u.save
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def test_create
|
73
|
+
u = User.new
|
74
|
+
u.login = "nonexistingbob"
|
75
|
+
u.password = u.password_confirmation = "bobs_secure_password"
|
76
|
+
|
77
|
+
assert u.save
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_sha1
|
82
|
+
u = User.new
|
83
|
+
u.login = "nonexistingbob"
|
84
|
+
u.password = u.password_confirmation = "bobs_secure_password"
|
85
|
+
assert u.save
|
86
|
+
|
87
|
+
assert_equal '98740ff87bade6d895010bceebbd9f718e7856bb', u.password
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
end
|
data/templates/users.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
2
|
+
|
3
|
+
bob:
|
4
|
+
id: 1000001
|
5
|
+
login: bob
|
6
|
+
password: 9a91e1d8d95b6315991a88121bb0aa9f03ba0dfc # test
|
7
|
+
|
8
|
+
existingbob:
|
9
|
+
id: 1000002
|
10
|
+
login: existingbob
|
11
|
+
password: 9a91e1d8d95b6315991a88121bb0aa9f03ba0dfc # test
|
12
|
+
|
13
|
+
longbob:
|
14
|
+
id: 1000003
|
15
|
+
login: longbob
|
16
|
+
password: 8e9b1a9a38e66ca572a5e8fdac8e256848842dfa # longtest
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<%%= start_form_tag :action=> "login" %>
|
2
|
+
|
3
|
+
<div title="Account login" id="loginform" class="form">
|
4
|
+
<h3>Please login</h3>
|
5
|
+
|
6
|
+
<%% if @flash['notice'] %>
|
7
|
+
<div id="message"><%%= @flash['notice'] %></div>
|
8
|
+
<%% end %>
|
9
|
+
|
10
|
+
<label for="user_login">Login:</label><br/>
|
11
|
+
<input type="text" name="user_login" id="user_login" size="30" value="<%= @login %>"/><br/>
|
12
|
+
|
13
|
+
<label for="user_password">Password:</label><br/>
|
14
|
+
<input type="password" name="user_password" id="user_password" size="30"/>
|
15
|
+
|
16
|
+
<br/>
|
17
|
+
<input type="submit" name="login" value="Login »" class="primary" />
|
18
|
+
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<%%= end_form_tag %>
|
22
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%%= start_form_tag :action=> "signup" %>
|
2
|
+
|
3
|
+
<div title="Account signup" id="signupform" class="form">
|
4
|
+
<h3>Signup</h3>
|
5
|
+
<%%= error_messages_for 'user' %><br/>
|
6
|
+
|
7
|
+
<label for="user_login">Desired login:</label><br/>
|
8
|
+
<%%= text_field "user", "login", :size => 30 %><br/>
|
9
|
+
<label for="user_password">Choose password:</label><br/>
|
10
|
+
<%%= password_field "user", "password", :size => 30 %><br/>
|
11
|
+
<label for="user_password_confirmation">Confirm password:</label><br/>
|
12
|
+
<%%= password_field "user", "password_confirmation", :size => 30 %><br/>
|
13
|
+
|
14
|
+
<input type="submit" value="Signup »" class="primary" />
|
15
|
+
|
16
|
+
<%%= end_form_tag %>
|
17
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
<div class="memo">
|
3
|
+
<h3>Welcome</h3>
|
4
|
+
|
5
|
+
<p>You are now logged into the system...</p>
|
6
|
+
<p>
|
7
|
+
Since you are here it's safe to assume the application never called store_location, otherwise
|
8
|
+
you would have been redirected somewhere else after a successful login.
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<%%= link_to "« logout", :action=>"logout"%>
|
12
|
+
|
13
|
+
</div>
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.10.1
|
3
|
+
specification_version: 1
|
4
|
+
name: login_generator
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.1.0
|
7
|
+
date: 2005-04-09
|
8
|
+
summary: "[Rails] Login generator."
|
9
|
+
require_paths:
|
10
|
+
- "."
|
11
|
+
email: tobi@leetsoft.com
|
12
|
+
homepage: http://www.rubyonrails.org/show/Generators
|
13
|
+
rubyforge_project:
|
14
|
+
description: Generates Rails code implementing a login system for your Rails app.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
authors:
|
28
|
+
- Tobias Luetke
|
29
|
+
files:
|
30
|
+
- USAGE
|
31
|
+
- login_generator.rb
|
32
|
+
- templates/controller.rb
|
33
|
+
- templates/controller_test.rb
|
34
|
+
- templates/helper.rb
|
35
|
+
- templates/login_system.rb
|
36
|
+
- templates/README
|
37
|
+
- templates/user.rb
|
38
|
+
- templates/user_test.rb
|
39
|
+
- templates/users.yml
|
40
|
+
- templates/view_login.rhtml
|
41
|
+
- templates/view_logout.rhtml
|
42
|
+
- templates/view_signup.rhtml
|
43
|
+
- templates/view_welcome.rhtml
|
44
|
+
test_files: []
|
45
|
+
rdoc_options: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
executables: []
|
48
|
+
extensions: []
|
49
|
+
requirements: []
|
50
|
+
dependencies:
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: rails
|
53
|
+
version_requirement:
|
54
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
55
|
+
requirements:
|
56
|
+
-
|
57
|
+
- ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 0.10.0
|
60
|
+
version:
|