login_generator 1.1.0 → 1.2.0
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/templates/README +27 -50
- data/templates/controller.rb +27 -14
- data/templates/controller_test.rb +20 -22
- data/templates/login_system.rb +5 -5
- data/templates/user.rb +8 -36
- data/templates/user_test.rb +18 -8
- data/templates/user_test.rb.orig +101 -0
- data/templates/view_login.rhtml +2 -2
- metadata +40 -33
data/templates/README
CHANGED
@@ -30,29 +30,29 @@ The model :user is required when you are hitting problems to the degree of
|
|
30
30
|
|
31
31
|
You need a database table corresponding to the User model.
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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
56
|
|
57
57
|
Of course your user model can have any amount of extra fields. This is just a
|
58
58
|
starting point
|
@@ -77,43 +77,20 @@ controller which you requested earlier. Simple huh?
|
|
77
77
|
|
78
78
|
How do I...
|
79
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
80
|
... restrict access to only a few methods?
|
87
81
|
|
88
82
|
A: Use before_filters build in scoping.
|
89
83
|
Example:
|
90
|
-
before_filter :login_required
|
91
|
-
before_filter :login_required
|
84
|
+
before_filter :login_required :only => [:myaccount, :changepassword]
|
85
|
+
before_filter :login_required :except => [:index]
|
92
86
|
|
93
87
|
... check if a user is logged-in in my views?
|
94
88
|
|
95
|
-
A: @session[
|
89
|
+
A: @session['user'] will tell you. Here is an example helper which you can use to make this more pretty:
|
96
90
|
Example:
|
97
91
|
def user?
|
98
|
-
!@session[
|
92
|
+
!@session['user'].nil?
|
99
93
|
end
|
100
94
|
|
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
95
|
|
115
|
-
|
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
|
96
|
+
You can find more help at http://wiki.rubyonrails.com/rails/show/LoginGenerator
|
data/templates/controller.rb
CHANGED
@@ -1,33 +1,46 @@
|
|
1
1
|
class <%= class_name %>Controller < ApplicationController
|
2
|
+
model :user
|
2
3
|
layout 'scaffold'
|
3
4
|
|
4
5
|
def login
|
5
6
|
case @request.method
|
6
7
|
when :post
|
7
|
-
|
8
|
+
if @session['user'] = User.authenticate(@params['user_login'], @params['user_password'])
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
@login = @params[:user_login]
|
10
|
+
flash['notice'] = "Login successful"
|
11
|
+
redirect_back_or_default :action => "welcome"
|
12
|
+
else
|
13
|
+
@login = @params['user_login']
|
14
|
+
@message = "Login unsuccessful"
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
def signup
|
20
|
-
@
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
case @request.method
|
21
|
+
when :post
|
22
|
+
@user = User.new(@params['user'])
|
23
|
+
|
24
|
+
if @user.save
|
25
|
+
@session['user'] = User.authenticate(@user.login, @params['user']['password'])
|
26
|
+
flash['notice'] = "Signup successful"
|
27
|
+
redirect_back_or_default :action => "welcome"
|
28
|
+
end
|
29
|
+
when :get
|
30
|
+
@user = User.new
|
26
31
|
end
|
27
32
|
end
|
28
33
|
|
34
|
+
def delete
|
35
|
+
if @params['id']
|
36
|
+
@user = User.find(@params['id'])
|
37
|
+
@user.destroy
|
38
|
+
end
|
39
|
+
redirect_back_or_default :action => "welcome"
|
40
|
+
end
|
41
|
+
|
29
42
|
def logout
|
30
|
-
@session[
|
43
|
+
@session['user'] = nil
|
31
44
|
end
|
32
45
|
|
33
46
|
def welcome
|
@@ -1,9 +1,6 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../test_helper'
|
2
2
|
require '<%= file_name %>_controller'
|
3
3
|
|
4
|
-
# Set salt to 'change-me' because thats what the fixtures assume.
|
5
|
-
User.salt = 'change-me'
|
6
|
-
|
7
4
|
# Raise errors beyond the default web-based presentation
|
8
5
|
class <%= class_name %>Controller; def rescue_action(e) raise e end; end
|
9
6
|
|
@@ -18,56 +15,57 @@ class <%= class_name %>ControllerTest < Test::Unit::TestCase
|
|
18
15
|
end
|
19
16
|
|
20
17
|
def test_auth_bob
|
21
|
-
@request.session[
|
18
|
+
@request.session['return-to'] = "/bogus/location"
|
22
19
|
|
23
|
-
post :login,
|
24
|
-
assert_session_has
|
20
|
+
post :login, "user_login" => "bob", "user_password" => "test"
|
21
|
+
assert_session_has "user"
|
25
22
|
|
26
|
-
assert_equal @bob, @response.session[
|
23
|
+
assert_equal @bob, @response.session["user"]
|
27
24
|
|
28
25
|
assert_redirect_url "/bogus/location"
|
29
26
|
end
|
30
27
|
|
31
28
|
def test_signup
|
32
|
-
@request.session[
|
29
|
+
@request.session['return-to'] = "/bogus/location"
|
33
30
|
|
34
|
-
post :signup,
|
35
|
-
assert_session_has
|
31
|
+
post :signup, "user" => { "login" => "newbob", "password" => "newpassword", "password_confirmation" => "newpassword" }
|
32
|
+
assert_session_has "user"
|
36
33
|
|
37
34
|
assert_redirect_url "/bogus/location"
|
38
35
|
end
|
39
36
|
|
40
37
|
def test_bad_signup
|
41
|
-
@request.session[
|
38
|
+
@request.session['return-to'] = "/bogus/location"
|
42
39
|
|
43
|
-
post :signup,
|
44
|
-
assert_invalid_column_on_record "user",
|
40
|
+
post :signup, "user" => { "login" => "newbob", "password" => "newpassword", "password_confirmation" => "wrong" }
|
41
|
+
assert_invalid_column_on_record "user", "password"
|
45
42
|
assert_success
|
46
43
|
|
47
|
-
post :signup,
|
48
|
-
assert_invalid_column_on_record "user",
|
44
|
+
post :signup, "user" => { "login" => "yo", "password" => "newpassword", "password_confirmation" => "newpassword" }
|
45
|
+
assert_invalid_column_on_record "user", "login"
|
49
46
|
assert_success
|
50
47
|
|
51
|
-
post :signup,
|
52
|
-
assert_invalid_column_on_record "user", [
|
48
|
+
post :signup, "user" => { "login" => "yo", "password" => "newpassword", "password_confirmation" => "wrong" }
|
49
|
+
assert_invalid_column_on_record "user", ["login", "password"]
|
53
50
|
assert_success
|
54
51
|
end
|
55
52
|
|
56
53
|
def test_invalid_login
|
57
|
-
post :login,
|
54
|
+
post :login, "user_login" => "bob", "user_password" => "not_correct"
|
58
55
|
|
59
|
-
assert_session_has_no
|
56
|
+
assert_session_has_no "user"
|
60
57
|
|
58
|
+
assert_template_has "message"
|
61
59
|
assert_template_has "login"
|
62
60
|
end
|
63
61
|
|
64
62
|
def test_login_logoff
|
65
63
|
|
66
|
-
post :login,
|
67
|
-
assert_session_has
|
64
|
+
post :login, "user_login" => "bob", "user_password" => "test"
|
65
|
+
assert_session_has "user"
|
68
66
|
|
69
67
|
get :logout
|
70
|
-
assert_session_has_no
|
68
|
+
assert_session_has_no "user"
|
71
69
|
|
72
70
|
end
|
73
71
|
|
data/templates/login_system.rb
CHANGED
@@ -46,7 +46,7 @@ module LoginSystem
|
|
46
46
|
return true
|
47
47
|
end
|
48
48
|
|
49
|
-
if @session[
|
49
|
+
if @session['user'] and authorize?(@session['user'])
|
50
50
|
return true
|
51
51
|
end
|
52
52
|
|
@@ -71,16 +71,16 @@ module LoginSystem
|
|
71
71
|
# store current uri in the session.
|
72
72
|
# we can return to this location by calling return_location
|
73
73
|
def store_location
|
74
|
-
@session[
|
74
|
+
@session['return-to'] = @request.request_uri
|
75
75
|
end
|
76
76
|
|
77
77
|
# move to the last store_location call or to the passed default one
|
78
78
|
def redirect_back_or_default(default)
|
79
|
-
if @session[
|
79
|
+
if @session['return-to'].nil?
|
80
80
|
redirect_to default
|
81
81
|
else
|
82
|
-
redirect_to_url @session[
|
83
|
-
@session[
|
82
|
+
redirect_to_url @session['return-to']
|
83
|
+
@session['return-to'] = nil
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
data/templates/user.rb
CHANGED
@@ -3,57 +3,29 @@ require 'digest/sha1'
|
|
3
3
|
# this model expects a certain database layout and its based on the name/login pattern.
|
4
4
|
class User < ActiveRecord::Base
|
5
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
6
|
def self.authenticate(login, pass)
|
17
7
|
find_first(["login = ? AND password = ?", login, sha1(pass)])
|
18
8
|
end
|
19
|
-
|
20
9
|
|
10
|
+
def change_password(pass)
|
11
|
+
update_attribute "password", self.class.sha1(pass)
|
12
|
+
end
|
13
|
+
|
21
14
|
protected
|
22
15
|
|
23
|
-
# Apply SHA1 encryption to the supplied password.
|
24
|
-
# We will additionally surround the password with a salt
|
25
|
-
# for additional security.
|
26
16
|
def self.sha1(pass)
|
27
|
-
Digest::SHA1.hexdigest("
|
17
|
+
Digest::SHA1.hexdigest("change-me--#{pass}--")
|
28
18
|
end
|
29
19
|
|
30
20
|
before_create :crypt_password
|
31
21
|
|
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
22
|
def crypt_password
|
36
|
-
write_attribute
|
23
|
+
write_attribute("password", self.class.sha1(password))
|
37
24
|
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
25
|
|
55
|
-
validates_confirmation_of :password
|
56
26
|
validates_length_of :login, :within => 3..40
|
57
27
|
validates_length_of :password, :within => 5..40
|
58
28
|
validates_presence_of :login, :password, :password_confirmation
|
29
|
+
validates_uniqueness_of :login, :on => :create
|
30
|
+
validates_confirmation_of :password, :on => :create
|
59
31
|
end
|
data/templates/user_test.rb
CHANGED
@@ -1,21 +1,30 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../test_helper'
|
2
2
|
|
3
|
-
# Set salt to 'change-me' because thats what the fixtures assume.
|
4
|
-
User.salt = 'change-me'
|
5
|
-
|
6
3
|
class UserTest < Test::Unit::TestCase
|
4
|
+
self.use_instantiated_fixtures = true
|
7
5
|
|
8
6
|
fixtures :users
|
9
7
|
|
10
|
-
def test_auth
|
11
|
-
|
8
|
+
def test_auth
|
12
9
|
assert_equal @bob, User.authenticate("bob", "test")
|
13
10
|
assert_nil User.authenticate("nonbob", "test")
|
14
|
-
|
11
|
+
|
15
12
|
end
|
16
13
|
|
14
|
+
|
15
|
+
def test_passwordchange
|
16
|
+
|
17
|
+
@longbob.change_password("nonbobpasswd")
|
18
|
+
assert_equal @longbob, User.authenticate("longbob", "nonbobpasswd")
|
19
|
+
assert_nil User.authenticate("longbob", "longtest")
|
20
|
+
@longbob.change_password("longtest")
|
21
|
+
assert_equal @longbob, User.authenticate("longbob", "longtest")
|
22
|
+
assert_nil User.authenticate("longbob", "nonbobpasswd")
|
23
|
+
|
24
|
+
end
|
25
|
+
|
17
26
|
def test_disallowed_passwords
|
18
|
-
|
27
|
+
|
19
28
|
u = User.new
|
20
29
|
u.login = "nonbob"
|
21
30
|
|
@@ -84,7 +93,8 @@ class UserTest < Test::Unit::TestCase
|
|
84
93
|
u.password = u.password_confirmation = "bobs_secure_password"
|
85
94
|
assert u.save
|
86
95
|
|
87
|
-
assert_equal '98740ff87bade6d895010bceebbd9f718e7856bb', u.password
|
96
|
+
assert_equal '98740ff87bade6d895010bceebbd9f718e7856bb', u.password
|
97
|
+
|
88
98
|
end
|
89
99
|
|
90
100
|
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class UserTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
fixtures :users
|
6
|
+
|
7
|
+
def test_auth
|
8
|
+
|
9
|
+
assert_equal @bob, User.authenticate("bob", "test")
|
10
|
+
assert_nil User.authenticate("nonbob", "test")
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def test_passwordchange
|
16
|
+
|
17
|
+
@longbob.change_password("nonbobpasswd")
|
18
|
+
assert_equal @longbob, User.authenticate("longbob", "nonbobpasswd")
|
19
|
+
assert_nil User.authenticate("longbob", "longtest")
|
20
|
+
@longbob.change_password("longtest")
|
21
|
+
assert_equal @longbob, User.authenticate("longbob", "longtest")
|
22
|
+
assert_nil User.authenticate("longbob", "nonbobpasswd")
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_disallowed_passwords
|
27
|
+
|
28
|
+
u = User.new
|
29
|
+
u.login = "nonbob"
|
30
|
+
|
31
|
+
u.password = u.password_confirmation = "tiny"
|
32
|
+
assert !u.save
|
33
|
+
assert u.errors.invalid?('password')
|
34
|
+
|
35
|
+
u.password = u.password_confirmation = "hugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehugehuge"
|
36
|
+
assert !u.save
|
37
|
+
assert u.errors.invalid?('password')
|
38
|
+
|
39
|
+
u.password = u.password_confirmation = ""
|
40
|
+
assert !u.save
|
41
|
+
assert u.errors.invalid?('password')
|
42
|
+
|
43
|
+
u.password = u.password_confirmation = "bobs_secure_password"
|
44
|
+
assert u.save
|
45
|
+
assert u.errors.empty?
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_bad_logins
|
50
|
+
|
51
|
+
u = User.new
|
52
|
+
u.password = u.password_confirmation = "bobs_secure_password"
|
53
|
+
|
54
|
+
u.login = "x"
|
55
|
+
assert !u.save
|
56
|
+
assert u.errors.invalid?('login')
|
57
|
+
|
58
|
+
u.login = "hugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhugebobhug"
|
59
|
+
assert !u.save
|
60
|
+
assert u.errors.invalid?('login')
|
61
|
+
|
62
|
+
u.login = ""
|
63
|
+
assert !u.save
|
64
|
+
assert u.errors.invalid?('login')
|
65
|
+
|
66
|
+
u.login = "okbob"
|
67
|
+
assert u.save
|
68
|
+
assert u.errors.empty?
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def test_collision
|
74
|
+
u = User.new
|
75
|
+
u.login = "existingbob"
|
76
|
+
u.password = u.password_confirmation = "bobs_secure_password"
|
77
|
+
assert !u.save
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
def test_create
|
82
|
+
u = User.new
|
83
|
+
u.login = "nonexistingbob"
|
84
|
+
u.password = u.password_confirmation = "bobs_secure_password"
|
85
|
+
|
86
|
+
assert u.save
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_sha1
|
91
|
+
u = User.new
|
92
|
+
u.login = "nonexistingbob"
|
93
|
+
u.password = u.password_confirmation = "bobs_secure_password"
|
94
|
+
assert u.save
|
95
|
+
|
96
|
+
assert_equal '98740ff87bade6d895010bceebbd9f718e7856bb', u.password
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
end
|
data/templates/view_login.rhtml
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
<div title="Account login" id="loginform" class="form">
|
4
4
|
<h3>Please login</h3>
|
5
5
|
|
6
|
-
<%% if @
|
7
|
-
<div id="message"><%%= @
|
6
|
+
<%% if @message %>
|
7
|
+
<div id="message"><%%= @message %></div>
|
8
8
|
<%% end %>
|
9
9
|
|
10
10
|
<label for="user_login">Login:</label><br/>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.8.
|
2
|
+
rubygems_version: 0.8.11
|
3
3
|
specification_version: 1
|
4
4
|
name: login_generator
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.
|
7
|
-
date:
|
6
|
+
version: 1.2.0
|
7
|
+
date: 2006-04-17 00:00:00 -04:00
|
8
8
|
summary: "[Rails] Login generator."
|
9
9
|
require_paths:
|
10
|
-
|
10
|
+
- .
|
11
11
|
email: tobi@leetsoft.com
|
12
12
|
homepage: http://www.rubyonrails.org/show/Generators
|
13
13
|
rubyforge_project:
|
@@ -18,43 +18,50 @@ bindir: bin
|
|
18
18
|
has_rdoc: false
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
version: 0.0.0
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
25
24
|
version:
|
26
25
|
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
27
28
|
authors:
|
28
|
-
|
29
|
+
- Tobias Luetke
|
29
30
|
files:
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
31
|
+
- USAGE
|
32
|
+
- login_generator.rb
|
33
|
+
- templates/controller.rb
|
34
|
+
- templates/controller_test.rb
|
35
|
+
- templates/helper.rb
|
36
|
+
- templates/login_system.rb
|
37
|
+
- templates/README
|
38
|
+
- templates/user.rb
|
39
|
+
- templates/user_test.rb
|
40
|
+
- templates/user_test.rb.orig
|
41
|
+
- templates/users.yml
|
42
|
+
- templates/view_login.rhtml
|
43
|
+
- templates/view_logout.rhtml
|
44
|
+
- templates/view_signup.rhtml
|
45
|
+
- templates/view_welcome.rhtml
|
44
46
|
test_files: []
|
47
|
+
|
45
48
|
rdoc_options: []
|
49
|
+
|
46
50
|
extra_rdoc_files: []
|
51
|
+
|
47
52
|
executables: []
|
53
|
+
|
48
54
|
extensions: []
|
55
|
+
|
49
56
|
requirements: []
|
57
|
+
|
50
58
|
dependencies:
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
version:
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: rails
|
61
|
+
version_requirement:
|
62
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 0.10.0
|
67
|
+
version:
|