parlement 0.3 → 0.4
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/CHANGES +16 -0
- data/README +36 -3
- data/Rakefile +8 -12
- data/app/controllers/account_controller.rb +2 -0
- data/app/controllers/elt_controller.rb +1 -5
- data/app/controllers/subscriber_controller.rb +1 -1
- data/app/helpers/elt_helper.rb +30 -10
- data/app/models/elt.rb +2 -1
- data/app/models/mail.rb +41 -41
- data/app/models/mail_notify.rb +27 -10
- data/app/views/account/_login.rhtml +9 -7
- data/app/views/account/_show.rhtml +4 -4
- data/app/views/elt/_elt.rhtml +52 -51
- data/app/views/elt/_list.rhtml +22 -14
- data/app/views/elt/new.rhtml +1 -1
- data/app/views/elt/show.rhtml +15 -16
- data/app/views/layouts/top.rhtml +13 -1
- data/app/views/person/show.rhtml +1 -7
- data/config/boot.rb +32 -7
- data/config/database.yml +3 -0
- data/config/environment.rb +3 -1
- data/config/environments/development.rb +1 -1
- data/db/ROOT/parlement/ddRing.txt +14 -0
- data/db/ROOT/parlement/top-politics.txt +12 -0
- data/db/ROOT/perso.txt +1 -1
- data/db/development_structure.sql +30 -16
- data/db/schema.rb +18 -10
- data/db/schema.sql +34 -34
- data/public/javascripts/application.js +2 -0
- data/public/javascripts/blank.gif +0 -0
- data/public/javascripts/borders.js +687 -0
- data/public/javascripts/controls.js +95 -30
- data/public/javascripts/dragdrop.js +161 -21
- data/public/javascripts/effects.js +310 -211
- data/public/javascripts/ie7-load.htc +1 -0
- data/public/javascripts/prototype.js +228 -28
- data/test/fixtures/attachments.yml +3 -0
- data/test/fixtures/mail/mail_ruby +1 -0
- data/test/fixtures/people.yml +14 -0
- data/test/functional/account_controller_test.rb +3 -2
- data/test/unit/mail_notify_test.rb +2 -0
- data/test/unit/mail_test.rb +59 -6
- data/test/unit/person_test.rb +1 -1
- data/vendor/plugins/engines/CHANGELOG +92 -0
- data/vendor/plugins/engines/MIT-LICENSE +21 -0
- data/vendor/plugins/engines/README +325 -39
- data/vendor/plugins/engines/generators/engine/USAGE +26 -0
- data/vendor/plugins/engines/generators/engine/engine_generator.rb +199 -0
- data/vendor/plugins/engines/generators/engine/templates/README +85 -0
- data/vendor/plugins/engines/generators/engine/templates/init_engine.erb +13 -0
- data/vendor/plugins/engines/generators/engine/templates/install.erb +4 -0
- data/vendor/plugins/engines/generators/engine/templates/lib/engine.erb +6 -0
- data/vendor/plugins/engines/generators/engine/templates/licenses/GPL +18 -0
- data/vendor/plugins/engines/generators/engine/templates/licenses/LGPL +19 -0
- data/vendor/plugins/engines/generators/engine/templates/licenses/MIT +22 -0
- data/vendor/plugins/engines/generators/engine/templates/licenses/None +1 -0
- data/vendor/plugins/engines/generators/engine/templates/public/javascripts/engine.js +0 -0
- data/vendor/plugins/engines/generators/engine/templates/public/stylesheets/engine.css +0 -0
- data/vendor/plugins/engines/generators/engine/templates/tasks/engine.rake +0 -0
- data/vendor/plugins/engines/generators/engine/templates/test/test_helper.erb +13 -0
- data/vendor/plugins/engines/init.rb +18 -3
- data/vendor/plugins/engines/lib/bundles/require_resource.rb +124 -0
- data/vendor/plugins/engines/lib/bundles.rb +77 -0
- data/vendor/plugins/engines/lib/{action_mailer_extensions.rb → engines/action_mailer_extensions.rb} +15 -36
- data/vendor/plugins/engines/lib/{action_view_extensions.rb → engines/action_view_extensions.rb} +40 -33
- data/vendor/plugins/engines/lib/engines/active_record_extensions.rb +19 -0
- data/vendor/plugins/engines/lib/engines/dependencies_extensions.rb +118 -0
- data/vendor/plugins/engines/lib/engines/migration_extensions.rb +53 -0
- data/vendor/plugins/engines/lib/{ruby_extensions.rb → engines/ruby_extensions.rb} +14 -28
- data/vendor/plugins/engines/lib/engines/testing_extensions.rb +323 -0
- data/vendor/plugins/engines/lib/engines.rb +258 -148
- data/vendor/plugins/engines/tasks/engines.rake +161 -0
- data/vendor/plugins/engines/test/action_view_extensions_test.rb +9 -0
- data/vendor/plugins/engines/test/ruby_extensions_test.rb +24 -3
- data/vendor/plugins/guid/README.TXT +14 -4
- data/vendor/plugins/guid/init.rb +9 -2
- data/vendor/plugins/guid/lib/uuidtools.rb +22 -15
- data/vendor/plugins/login_engine/CHANGELOG +14 -0
- data/vendor/plugins/login_engine/README +93 -7
- data/vendor/plugins/login_engine/app/controllers/user_controller.rb +30 -20
- data/vendor/plugins/login_engine/app/helpers/user_helper.rb +1 -1
- data/vendor/plugins/login_engine/app/views/user/forgot_password.rhtml +2 -2
- data/vendor/plugins/login_engine/db/migrate/001_initial_schema.rb +25 -0
- data/vendor/plugins/login_engine/install.rb +4 -0
- data/vendor/plugins/login_engine/lib/login_engine/authenticated_system.rb +11 -5
- data/vendor/plugins/login_engine/lib/login_engine/authenticated_user.rb +15 -9
- data/vendor/plugins/login_engine/lib/login_engine.rb +7 -3
- data/vendor/plugins/login_engine/test/functional/user_controller_test.rb +22 -19
- data/vendor/plugins/login_engine/test/test_helper.rb +4 -8
- data/vendor/plugins/login_engine/test/unit/user_test.rb +31 -11
- metadata +60 -57
- data/app/models/attachment.rb +0 -6
- data/public/attachment/file/architecture.png +0 -0
- data/public/attachment/file/architecture.svg +0 -8972
- data/public/attachment/file/security.svg +0 -8960
- data/public/engine_files/login_engine/stylesheets/login_engine.css +0 -81
- data/public/oldREADME +0 -190
- data/public/stylesheets/default.css +0 -235
- data/public/stylesheets/live_tree.css +0 -62
- data/public/stylesheets/scaffold.css +0 -74
- data/script/about +0 -3
- data/script/benchmarker +0 -19
- data/script/breakpointer +0 -3
- data/script/console +0 -3
- data/script/create_db +0 -7
- data/script/destroy +0 -3
- data/script/generate +0 -3
- data/script/performance/benchmarker +0 -3
- data/script/performance/profiler +0 -3
- data/script/plugin +0 -3
- data/script/process/reaper +0 -3
- data/script/process/spawner +0 -3
- data/script/process/spinner +0 -3
- data/script/profiler +0 -34
- data/script/runner +0 -3
- data/script/server +0 -3
- data/test/unit/user_test.rb +0 -94
- data/vendor/plugins/engines/lib/dependencies_extensions.rb +0 -56
- data/vendor/plugins/engines/lib/testing_extensions.rb +0 -33
- data/vendor/plugins/login_engine/db/schema.rb +0 -25
- data/vendor/plugins/login_engine/test/fixtures/templates/users.yml +0 -41
- /data/public/images/{eltBackground.png → eltBackground.jng} +0 -0
@@ -2,7 +2,7 @@ ENV["RAILS_ENV"] = "test"
|
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/../../../../config/environment')
|
3
3
|
require 'test_help'
|
4
4
|
|
5
|
-
class
|
5
|
+
class RubyExtensionsTest < Test::Unit::TestCase
|
6
6
|
|
7
7
|
def setup
|
8
8
|
# create the module to be used for config testing
|
@@ -33,13 +33,21 @@ class EnginesTest < Test::Unit::TestCase
|
|
33
33
|
assert_equal(123, TestModule.config(:monkey))
|
34
34
|
assert_equal(456, TestModule.config(:donkey))
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
|
+
def test_config_can_store_hash
|
38
|
+
TestModule.config :hash, :key1 => 'val1', :key2 => 'val2'
|
39
|
+
assert_equal({:key1 => 'val1', :key2 => 'val2'}, TestModule.config(:hash))
|
40
|
+
end
|
41
|
+
|
37
42
|
def test_config_cant_overwrite_existing_config_values
|
38
43
|
TestModule.config :monkey, 123
|
39
44
|
assert_equal(123, TestModule.config(:monkey))
|
40
45
|
TestModule.config :monkey, 456
|
41
46
|
assert_equal(123, TestModule.config(:monkey))
|
42
47
|
|
48
|
+
TestModule.config :monkey => 456
|
49
|
+
assert_equal(123, TestModule.config(:monkey))
|
50
|
+
|
43
51
|
# in this case, the resulting Hash only has {:baboon => "goodbye!"} - that's Ruby, users beware.
|
44
52
|
TestModule.config :baboon => "hello", :baboon => "goodbye!"
|
45
53
|
assert_equal("goodbye!", TestModule.config(:baboon))
|
@@ -47,9 +55,22 @@ class EnginesTest < Test::Unit::TestCase
|
|
47
55
|
|
48
56
|
def test_config_force_new_value
|
49
57
|
TestModule.config :monkey, 123
|
58
|
+
TestModule.config :man, 321
|
50
59
|
assert_equal(123, TestModule.config(:monkey))
|
60
|
+
assert_equal(321, TestModule.config(:man))
|
51
61
|
TestModule.config :monkey, 456, :force
|
52
|
-
assert_equal(456, TestModule.config(:monkey))
|
62
|
+
assert_equal(456, TestModule.config(:monkey))
|
63
|
+
TestModule.config :monkey => 456, :man => 654, :force => true
|
64
|
+
assert_equal(456, TestModule.config(:monkey))
|
65
|
+
assert_equal(654, TestModule.config(:man))
|
66
|
+
TestModule.config :monkey => 789, :man => 987, :force => false
|
67
|
+
assert_equal(456, TestModule.config(:monkey))
|
68
|
+
assert_equal(654, TestModule.config(:man))
|
69
|
+
|
70
|
+
TestModule.config :hash, :key1 => 'val1', :key2 => 'val2'
|
71
|
+
assert_equal({:key1 => 'val1', :key2 => 'val2'}, TestModule.config(:hash))
|
72
|
+
TestModule.config :hash => {:key1 => 'val3', :key2 => 'val4'}, :force => true
|
73
|
+
assert_equal({:key1 => 'val3', :key2 => 'val4'}, TestModule.config(:hash))
|
53
74
|
end
|
54
75
|
|
55
76
|
# this test is somewhat redundant, but it might be an idea to havbe it explictly anyway
|
@@ -1,4 +1,4 @@
|
|
1
|
-
This plugin for ActiveRecord makes the "ID" field into a URL-safe GUID
|
1
|
+
# This plugin for ActiveRecord makes the "ID" field into a URL-safe GUID
|
2
2
|
# It is a mashup by Andy Singleton <andy@assembla.com> that includes
|
3
3
|
# * the UUID class from Bob Aman.
|
4
4
|
# * the plugin skeleton from Demetrius Nunes
|
@@ -13,7 +13,17 @@
|
|
13
13
|
# Install as a plugin in the rails directory vendor/plugin/guid
|
14
14
|
# define ID as char(22)
|
15
15
|
# call "usesguid" in ActiveRecord class declaration, like
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
class Mymodel < ActiveRecord::Base
|
17
|
+
usesguid
|
18
|
+
|
19
19
|
# if your ID field is not called "ID", call "usesguid :column =>'IdColumnName' "
|
20
|
+
|
21
|
+
# if you create your tables with migrations, you need to bypass the rails default primary key index. Do this:
|
22
|
+
|
23
|
+
create_table :mytable, :id => false do |t|
|
24
|
+
t.column :id, :string, :limit => 22
|
25
|
+
... more fields
|
26
|
+
end
|
27
|
+
|
28
|
+
execute "ALTER TABLE mytable ADD PRIMARY KEY (id)"
|
29
|
+
|
data/vendor/plugins/guid/init.rb
CHANGED
@@ -15,9 +15,16 @@
|
|
15
15
|
# Install as a plugin in the rails directory vendor/plugin/guid
|
16
16
|
# define ID as char(22)
|
17
17
|
# call "usesguid" in ActiveRecord class declaration, like
|
18
|
-
#
|
19
|
-
#
|
18
|
+
# class Mymodel < ActiveRecord::Base
|
19
|
+
# usesguid
|
20
20
|
#
|
21
21
|
# if your ID field is not called "ID", call "usesguid :column =>'IdColumnName' "
|
22
22
|
|
23
|
+
# if you create your tables with migrations, you need to bypass the rails default primary key index. Do this:
|
24
|
+
# create_table :mytable, :id => false do |t|
|
25
|
+
# t.column :id, :string, :limit => 22
|
26
|
+
# ... more fields
|
27
|
+
# end
|
28
|
+
# execute "ALTER TABLE mytable ADD PRIMARY KEY (id)"
|
29
|
+
|
23
30
|
require 'usesguid'
|
@@ -21,7 +21,7 @@
|
|
21
21
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
#++
|
23
23
|
|
24
|
-
UUID_TOOLS_VERSION = "0.
|
24
|
+
UUID_TOOLS_VERSION = "1.0.0"
|
25
25
|
|
26
26
|
$:.unshift(File.dirname(__FILE__))
|
27
27
|
|
@@ -474,23 +474,29 @@ class UUID
|
|
474
474
|
end
|
475
475
|
else
|
476
476
|
begin
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
ifconfig_output = `ifconfig | grep HWaddr | cut -c39-`
|
482
|
-
mac_addresses = ifconfig_output.scan(
|
483
|
-
Regexp.new("(#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"))
|
484
|
-
end
|
485
|
-
if mac_addresses.size == 0
|
486
|
-
ifconfig_output = `/sbin/ifconfig`
|
477
|
+
mac_addresses = []
|
478
|
+
if File.exists?('/sbin/ifconfig')
|
479
|
+
ifconfig_output =
|
480
|
+
`/sbin/ifconfig 2>&1`
|
487
481
|
mac_addresses = ifconfig_output.scan(
|
488
482
|
Regexp.new("ether (#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"))
|
489
|
-
|
490
|
-
|
491
|
-
|
483
|
+
if mac_addresses.size == 0
|
484
|
+
ifconfig_output =
|
485
|
+
`/sbin/ifconfig | grep HWaddr | cut -c39- 2>&1`
|
486
|
+
mac_addresses = ifconfig_output.scan(
|
487
|
+
Regexp.new("(#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"))
|
488
|
+
end
|
489
|
+
else
|
490
|
+
ifconfig_output =
|
491
|
+
`ifconfig 2>&1`
|
492
492
|
mac_addresses = ifconfig_output.scan(
|
493
|
-
Regexp.new("(#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"))
|
493
|
+
Regexp.new("ether (#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"))
|
494
|
+
if mac_addresses.size == 0
|
495
|
+
ifconfig_output =
|
496
|
+
`ifconfig | grep HWaddr | cut -c39- 2>&1`
|
497
|
+
mac_addresses = ifconfig_output.scan(
|
498
|
+
Regexp.new("(#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"))
|
499
|
+
end
|
494
500
|
end
|
495
501
|
if mac_addresses.size > 0
|
496
502
|
@@mac_address = mac_addresses.first.first
|
@@ -519,6 +525,7 @@ class UUID
|
|
519
525
|
hash.update(rand.to_s)
|
520
526
|
hash.update(hash.object_id.to_s)
|
521
527
|
hash.update(self.methods.inspect)
|
528
|
+
hash.update($:.to_s)
|
522
529
|
begin
|
523
530
|
random_device = nil
|
524
531
|
if File.exists? "/dev/urandom"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
= v1.0.1
|
2
|
+
* Added CHANGELOG
|
3
|
+
* Changed wording for when password forgotten to 'reset', rather than 'retrieve'. (snowblink@gmail.com)
|
4
|
+
* Fixed new location of engines testing extensions. (lazyatom@gmail.com)
|
5
|
+
* Removed schema.db from Login Engine; migrations should be used instead. (snowblink@gmail.com)
|
6
|
+
* Updated User Controller tests to parse the user_id and email out of the URL in the email body. (snowblink@gmail.com)
|
7
|
+
* Ticket #89 (lazyatom@gmail.com) User creation halts the after_save callback chain.
|
8
|
+
* Ticket #97 (dcorbin@machturtle.com) The forgotten_password view generates invalid HTML
|
9
|
+
* Ticket #112 (segabor@gmail.com) Authentication system will break even on successful login
|
10
|
+
* Added simple email validation to the User model. (snowblink@gmail.com)
|
11
|
+
This should also take care of the unit test failures detailed in Ticket #114 (morris@wolfman.com)
|
12
|
+
* Ticket #118 (augustz@augustz.com) SVN source for login_engine not found
|
13
|
+
* Ticket #119 (Goynang) Unit tests for engines fail after default install
|
14
|
+
* Ticket #126 (lazyatom@gmail.com) Add install.rb to login engine
|
@@ -7,14 +7,28 @@ This is a Rails Engine version of the Salted Login Generator, a most excellent l
|
|
7
7
|
* A few new functions have been thrown in
|
8
8
|
* It's... uh.... a Rails Engine now ;-)
|
9
9
|
|
10
|
-
However, what I'm trying to say is that 99.9999% of the credit for this should go to Tobias Luetke (xal) and the folks that worked on the original Salted Login generator code. I've just wrapped it into something runnable with the Rails Engine system.
|
10
|
+
However, what I'm trying to say is that 99.9999% of the credit for this should go to Joe Hosteny, Tobias Luetke (xal) and the folks that worked on the original Salted Login generator code. I've just wrapped it into something runnable with the Rails Engine system.
|
11
11
|
|
12
12
|
Please also bear in mind that this is a work in progress, and things like testing are wildly up in the air... but they will fall into place very soon. And now, on with the show.
|
13
13
|
|
14
14
|
|
15
15
|
= Installation
|
16
16
|
|
17
|
-
Installing the Login Engine is fairly simple
|
17
|
+
Installing the Login Engine is fairly simple.
|
18
|
+
|
19
|
+
Your options are:
|
20
|
+
1. Install as a rails plugin:
|
21
|
+
$ script/plugin install login_engine
|
22
|
+
2. Use svn:externals
|
23
|
+
$ svn propedit svn:externals vendor/plugins
|
24
|
+
|
25
|
+
You can choose to use the latest stable release:
|
26
|
+
login_engine http://svn.rails-engines.org/plugins/login_engine
|
27
|
+
|
28
|
+
Or a tagged release (recommended for releases of your code):
|
29
|
+
login_engine http://svn.rails-engines.org/logine_engine/tags/<TAGGED_RELEASE>
|
30
|
+
|
31
|
+
There are a few configuration steps that you'll need to take to get everything running smoothly. Listed below are the changes to your application you will need to make.
|
18
32
|
|
19
33
|
=== Setup your Rails application
|
20
34
|
|
@@ -85,7 +99,11 @@ You'll need to configure it properly so that email can be sent. One of the easie
|
|
85
99
|
|
86
100
|
=== Create the DB schema
|
87
101
|
|
88
|
-
After you have done the modifications the the ApplicationController and its helper, you can import the user model into the database. An ActiveRecord schema.rb file is provided in login_engine/db/schema.rb
|
102
|
+
After you have done the modifications the the ApplicationController and its helper, you can import the user model into the database. An ActiveRecord schema.rb file is provided in login_engine/db/schema.rb, along with migration information in login_engine/db/migrate/.
|
103
|
+
|
104
|
+
You *MUST* check that these files aren't going to interfere with anything in your application.
|
105
|
+
|
106
|
+
You can change the table name used by adding
|
89
107
|
|
90
108
|
module LoginEngine
|
91
109
|
|
@@ -94,9 +112,9 @@ After you have done the modifications the the ApplicationController and its help
|
|
94
112
|
|
95
113
|
end
|
96
114
|
|
97
|
-
|
115
|
+
...to the LoginEngine configuration in <tt>environment.rb</tt>. Then run from the root of your project:
|
98
116
|
|
99
|
-
rake
|
117
|
+
rake engine_migrate ENGINE=login
|
100
118
|
|
101
119
|
to import the schema into your database.
|
102
120
|
|
@@ -109,6 +127,23 @@ If you want the default stylesheet, add the following line to your layout:
|
|
109
127
|
|
110
128
|
... somewhere in the <head> section of your HTML layout file.
|
111
129
|
|
130
|
+
== Integrate flash messages into your layout
|
131
|
+
|
132
|
+
LoginEngine does not display any flash messages in the views it contains, and thus you must display them yourself. This allows you to integrate any flash messages into your existing layout. LoginEngine adheres to the emerging flash usage standard, namely:
|
133
|
+
|
134
|
+
* :warning - warning (failure) messages
|
135
|
+
* :notice - success messages
|
136
|
+
* :message - neutral (reminder, informational) messages
|
137
|
+
|
138
|
+
This gives you the flexibility to theme the different message classes separately. In your layout you should check for and display flash[:warning], flash[:notice] and flash[:message]. For example:
|
139
|
+
|
140
|
+
<% for name in [:notice, :warning, :message] %>
|
141
|
+
<% if flash[name] %>
|
142
|
+
<%= "<div id=\"#{name}\">#{flash[name]}</div>" %>
|
143
|
+
<% end %>
|
144
|
+
<% end %>
|
145
|
+
|
146
|
+
Alternately, you could look at using the flash helper plugin (available from https://opensvn.csie.org/traccgi/flash_helper_plugin/trac.cgi/), which supports the same naming convention.
|
112
147
|
|
113
148
|
|
114
149
|
= How to use the Login Engine
|
@@ -144,7 +179,53 @@ Of course, you can override this Engine behaviour in your application - see belo
|
|
144
179
|
|
145
180
|
== Configuration
|
146
181
|
|
147
|
-
|
182
|
+
The following configuration variables are set in lib/login_engine.rb. If you wish to override them, you should set them BEFORE calling Engines.start (it is possible to set them after, but it's simpler to just do it before. Please refer to the Engine documentation for the #config method for more information).
|
183
|
+
|
184
|
+
For example, the following might appear at the bottom of /config/environment.rb:
|
185
|
+
|
186
|
+
module LoginEngine
|
187
|
+
config :salt, 'my salt'
|
188
|
+
config :app_name, 'My Great App'
|
189
|
+
config :app_url, 'http://www.wow-great-domain.com'
|
190
|
+
end
|
191
|
+
|
192
|
+
Engines.start
|
193
|
+
|
194
|
+
=== Configuration Options
|
195
|
+
|
196
|
+
+email_from+:: The email from which registration/administration emails will appear to
|
197
|
+
come from. Defaults to 'webmaster@your.company'.
|
198
|
+
+admin_email+:: The email address users are prompted to contact if passwords cannot
|
199
|
+
be emailed. Defaults to 'webmaster@your.company'.
|
200
|
+
+app_url+:: The URL of the site sent to users for signup/forgotten passwords, etc.
|
201
|
+
Defaults to 'http://localhost:3000/'.
|
202
|
+
+app_name+:: The application title used in emails. Defaults to 'TestApp'.
|
203
|
+
+mail_charset+:: The charset used in emails. Defaults to 'utf-8'.
|
204
|
+
+security_token_life_hours+:: The life span of security tokens, in hours. If a security
|
205
|
+
token is older than this when it is used to try and authenticate
|
206
|
+
a user, it will be discarded. In other words, the amount of time
|
207
|
+
new users have between signing up and clicking the link they
|
208
|
+
are sent. Defaults to 24 hours.
|
209
|
+
+two_column_input+:: If true, forms created with the UserHelper#form_input method will
|
210
|
+
use a two-column table. Defaults to true.
|
211
|
+
+changeable_fields+:: An array of fields within the user model which the user
|
212
|
+
is allowed to edit. The Salted Hash Login generator documentation
|
213
|
+
states that you should NOT include the email field in this
|
214
|
+
array, although I am not sure why. Defaults to +[ 'firstname', 'lastname' ]+.
|
215
|
+
+delayed_delete+:: Set to true to allow delayed deletes (i.e., delete of record
|
216
|
+
doesn't happen immediately after user selects delete account,
|
217
|
+
but rather after some expiration of time to allow this action
|
218
|
+
to be reverted). Defaults to false.
|
219
|
+
+delayed_delete_days+:: The time delay used for the 'delayed_delete' feature. Defaults to
|
220
|
+
7 days.
|
221
|
+
+user_table+:: The table to store User objects in. Defaults to "users" (or "user" if
|
222
|
+
ActiveRecord pluralization is disabled).
|
223
|
+
+use_email_notification+:: If false, no emails will be sent to the user. As a consequence,
|
224
|
+
users who signup are immediately verified, and they cannot request
|
225
|
+
forgotten passwords. Defaults to true.
|
226
|
+
+confirm_account+:: An overriding flag to control whether or not user accounts must be
|
227
|
+
verified by email. This overrides the +user_email_notification+ flag.
|
228
|
+
Defaults to true.
|
148
229
|
|
149
230
|
== Overriding controllers and views
|
150
231
|
|
@@ -198,6 +279,11 @@ One of the more common problems people have seen is that after verifying an acco
|
|
198
279
|
|
199
280
|
The most common cause of this problem is that the DB and session get out of sync. In particular, it always happens for me after recreating the DB if I have run the server previously. To fix the problem, remove the /tmp/ruby* session files (from wherever they are for your installation) while the server is stopped, and then restart. This usually is the cause of the problem.
|
200
281
|
|
282
|
+
= Notes
|
283
|
+
|
284
|
+
=== Database Schemas & Testing
|
285
|
+
|
286
|
+
Currently, since not all databases appear to support structure cloning, the tests will load the entire schema into your test database, potentially blowing away any other test structures you might have. If this presents an issue for your application, comment out the line in test/test_helper.rb
|
201
287
|
|
202
288
|
|
203
289
|
= Database Schema Details
|
@@ -255,4 +341,4 @@ You need a database table corresponding to the User model. This is provided as a
|
|
255
341
|
delete_after DATETIME default NULL
|
256
342
|
);
|
257
343
|
|
258
|
-
Of course your user model can have any amount of extra fields. This is just a starting point.
|
344
|
+
Of course your user model can have any amount of extra fields. This is just a starting point.
|
@@ -12,20 +12,25 @@ class UserController < ApplicationController
|
|
12
12
|
# 'validate_key' action instead.
|
13
13
|
end
|
14
14
|
|
15
|
+
# The action used to log a user in. If the user was redirected to the login page
|
16
|
+
# by the login_required method, they should be sent back to the page they were
|
17
|
+
# trying to access. If not, they will be sent to "/user/home".
|
15
18
|
def login
|
16
19
|
return if generate_blank
|
17
|
-
@user = User.new(params[:user])
|
20
|
+
@user = User.new(params[:user])
|
18
21
|
if session[:user] = User.authenticate(params[:user][:login], params[:user][:password])
|
19
22
|
session[:user].logged_in_at = Time.now
|
20
23
|
session[:user].save
|
21
24
|
flash[:notice] = 'Login successful'
|
22
|
-
|
25
|
+
redirect_to_stored_or_default :action => 'home'
|
23
26
|
else
|
24
27
|
@login = params[:user][:login]
|
25
28
|
flash.now[:warning] = 'Login unsuccessful'
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
32
|
+
# Register as a new user. Upon successful registration, the user will be sent to
|
33
|
+
# "/user/login" to enter their details.
|
29
34
|
def signup
|
30
35
|
return if generate_blank
|
31
36
|
params[:user].delete('form')
|
@@ -33,14 +38,14 @@ class UserController < ApplicationController
|
|
33
38
|
begin
|
34
39
|
User.transaction(@user) do
|
35
40
|
@user.new_password = true
|
36
|
-
unless LoginEngine.config(:use_email_notification)
|
41
|
+
unless LoginEngine.config(:use_email_notification) and LoginEngine.config(:confirm_account)
|
37
42
|
@user.verified = 1
|
38
43
|
end
|
39
44
|
if @user.save
|
40
45
|
key = @user.generate_security_token
|
41
|
-
url = url_for(:action => 'home',
|
42
|
-
flash[:notice] = 'Signup successful!'
|
43
|
-
if LoginEngine.config(:use_email_notification)
|
46
|
+
url = url_for(:action => 'home', :user_id => @user.id, :key => key)
|
47
|
+
flash[:notice] = 'Signup successful! Please log in.'
|
48
|
+
if LoginEngine.config(:use_email_notification) and LoginEngine.config(:confirm_account)
|
44
49
|
UserNotify.deliver_signup(@user, params[:user][:password], url)
|
45
50
|
flash[:notice] << ' Please check your registered email account to verify your account registration and continue with the login.'
|
46
51
|
end
|
@@ -50,6 +55,7 @@ class UserController < ApplicationController
|
|
50
55
|
rescue Exception => e
|
51
56
|
flash.now[:notice] = nil
|
52
57
|
flash.now[:warning] = 'Error creating account: confirmation email not sent'
|
58
|
+
logger.error "Unable to send confirmation E-Mail:"
|
53
59
|
logger.error e
|
54
60
|
end
|
55
61
|
end
|
@@ -61,10 +67,11 @@ class UserController < ApplicationController
|
|
61
67
|
|
62
68
|
def change_password
|
63
69
|
return if generate_filled_in
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
70
|
+
if do_change_password_for(@user)
|
71
|
+
# since sometimes we're changing the password from within another action/template...
|
72
|
+
#redirect_to :action => params[:back_to] if params[:back_to]
|
73
|
+
redirect_back_or_default :action => 'change_password'
|
74
|
+
end
|
68
75
|
end
|
69
76
|
|
70
77
|
protected
|
@@ -73,17 +80,16 @@ class UserController < ApplicationController
|
|
73
80
|
User.transaction(user) do
|
74
81
|
user.change_password(params[:user][:password], params[:user][:password_confirmation])
|
75
82
|
if user.save
|
76
|
-
#@user.reload
|
77
|
-
#puts "changed password: #{@user.salted_password}"
|
78
83
|
if LoginEngine.config(:use_email_notification)
|
79
84
|
UserNotify.deliver_change_password(user, params[:user][:password])
|
80
85
|
flash[:notice] = "Updated password emailed to #{@user.email}"
|
81
86
|
else
|
82
87
|
flash[:notice] = "Password updated."
|
83
88
|
end
|
84
|
-
|
85
|
-
redirect_to :action => params[:back_to] if params[:back_to]
|
89
|
+
return true
|
86
90
|
else
|
91
|
+
flash[:warning] = 'There was a problem saving the password. Please retry.'
|
92
|
+
return false
|
87
93
|
end
|
88
94
|
end
|
89
95
|
rescue
|
@@ -104,7 +110,7 @@ class UserController < ApplicationController
|
|
104
110
|
|
105
111
|
# Email disabled... we are unable to provide the password
|
106
112
|
if !LoginEngine.config(:use_email_notification)
|
107
|
-
flash[:message] = "Please contact the system admin at #{LoginEngine.config(:admin_email)} to
|
113
|
+
flash[:message] = "Please contact the system admin at #{LoginEngine.config(:admin_email)} to reset your password."
|
108
114
|
redirect_back_or_default :action => 'login'
|
109
115
|
return
|
110
116
|
end
|
@@ -121,7 +127,7 @@ class UserController < ApplicationController
|
|
121
127
|
begin
|
122
128
|
User.transaction(user) do
|
123
129
|
key = user.generate_security_token
|
124
|
-
url = url_for(:action => 'change_password',
|
130
|
+
url = url_for(:action => 'change_password', :user_id => user.id, :key => key)
|
125
131
|
UserNotify.deliver_forgot_password(user, url)
|
126
132
|
flash[:notice] = "Instructions on resetting your password have been emailed to #{params[:user][:email]}"
|
127
133
|
end
|
@@ -161,7 +167,11 @@ class UserController < ApplicationController
|
|
161
167
|
|
162
168
|
def delete
|
163
169
|
get_user_to_act_on
|
164
|
-
do_delete_user(@user)
|
170
|
+
if do_delete_user(@user)
|
171
|
+
logout
|
172
|
+
else
|
173
|
+
redirect_back_or_default :action => 'home'
|
174
|
+
end
|
165
175
|
end
|
166
176
|
|
167
177
|
protected
|
@@ -171,21 +181,21 @@ class UserController < ApplicationController
|
|
171
181
|
User.transaction(user) do
|
172
182
|
key = user.set_delete_after
|
173
183
|
if LoginEngine.config(:use_email_notification)
|
174
|
-
url = url_for(:action => 'restore_deleted',
|
184
|
+
url = url_for(:action => 'restore_deleted', :user_id => user.id, :key => key)
|
175
185
|
UserNotify.deliver_pending_delete(user, url)
|
176
186
|
end
|
177
187
|
end
|
178
188
|
else
|
179
189
|
destroy(@user)
|
180
190
|
end
|
181
|
-
|
191
|
+
return true
|
182
192
|
rescue
|
183
193
|
if LoginEngine.config(:use_email_notification)
|
184
194
|
flash.now[:warning] = 'The delete instructions were not sent. Please try again later.'
|
185
195
|
else
|
186
196
|
flash.now[:notice] = 'The account has been scheduled for deletion. It will be removed in #{LoginEngine.config(:delayed_delete_days)} days.'
|
187
197
|
end
|
188
|
-
|
198
|
+
return false
|
189
199
|
end
|
190
200
|
end
|
191
201
|
|
@@ -26,7 +26,7 @@ module UserHelper
|
|
26
26
|
end)
|
27
27
|
# lname = "#{form_name}_#{field_name}_form"
|
28
28
|
# prompt = l(:"#{lname}")
|
29
|
-
if LoginEngine.config(:
|
29
|
+
if LoginEngine.config(:two_column_input)
|
30
30
|
<<-EOL
|
31
31
|
<tr class="two_columns">
|
32
32
|
<td class="prompt"><label>#{prompt}:</label></td>
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<p>Enter your email address in the field below and click 'Reset Password' to have instructions on how to retrieve your forgotten password emailed to you.</p>
|
8
8
|
|
9
9
|
<%= start_form_tag_helper %>
|
10
|
-
<%=
|
10
|
+
<label>Email Address:</label> <%= text_field("user", "email", "size" => 30) %>
|
11
11
|
|
12
12
|
<div class="button-bar">
|
13
13
|
<%= submit_tag 'Submit request' %>
|
@@ -15,4 +15,4 @@
|
|
15
15
|
</div>
|
16
16
|
<%= end_form_tag %>
|
17
17
|
</div>
|
18
|
-
</div>
|
18
|
+
</div>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class InitialSchema < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table LoginEngine.config(:user_table), :force => true do |t|
|
4
|
+
t.column "login", :string, :limit => 80, :default => "", :null => false
|
5
|
+
t.column "salted_password", :string, :limit => 40, :default => "", :null => false
|
6
|
+
t.column "email", :string, :limit => 60, :default => "", :null => false
|
7
|
+
t.column "firstname", :string, :limit => 40
|
8
|
+
t.column "lastname", :string, :limit => 40
|
9
|
+
t.column "salt", :string, :limit => 40, :default => "", :null => false
|
10
|
+
t.column "verified", :integer, :default => 0
|
11
|
+
t.column "role", :string, :limit => 40
|
12
|
+
t.column "security_token", :string, :limit => 40
|
13
|
+
t.column "token_expiry", :datetime
|
14
|
+
t.column "created_at", :datetime
|
15
|
+
t.column "updated_at", :datetime
|
16
|
+
t.column "logged_in_at", :datetime
|
17
|
+
t.column "deleted", :integer, :default => 0
|
18
|
+
t.column "delete_after", :datetime
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.down
|
23
|
+
drop_table LoginEngine.config(:user_table)
|
24
|
+
end
|
25
|
+
end
|
@@ -54,7 +54,6 @@ module LoginEngine
|
|
54
54
|
|
55
55
|
# call overwriteable reaction to unauthorized access
|
56
56
|
access_denied
|
57
|
-
return false
|
58
57
|
end
|
59
58
|
|
60
59
|
# overwrite if you want to have special behavior in case the user is not authorized
|
@@ -73,7 +72,7 @@ module LoginEngine
|
|
73
72
|
end
|
74
73
|
|
75
74
|
# move to the last store_location call or to the passed default one
|
76
|
-
def
|
75
|
+
def redirect_to_stored_or_default(default=nil)
|
77
76
|
if session['return-to'].nil?
|
78
77
|
redirect_to default
|
79
78
|
else
|
@@ -82,13 +81,20 @@ module LoginEngine
|
|
82
81
|
end
|
83
82
|
end
|
84
83
|
|
84
|
+
def redirect_back_or_default(default=nil)
|
85
|
+
if request.env["HTTP_REFERER"].nil?
|
86
|
+
redirect_to default
|
87
|
+
else
|
88
|
+
redirect_to(request.env["HTTP_REFERER"]) # same as redirect_to :back
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
85
92
|
def user?
|
86
93
|
# First, is the user already authenticated?
|
87
94
|
return true if not session[:user].nil?
|
88
95
|
|
89
96
|
# If not, is the user being authenticated by a token?
|
90
|
-
|
91
|
-
id = params[:user][:id]
|
97
|
+
id = params[:user_id]
|
92
98
|
key = params[:key]
|
93
99
|
if id and key
|
94
100
|
session[:user] = User.authenticate_by_token(id, key)
|
@@ -104,4 +110,4 @@ module LoginEngine
|
|
104
110
|
session[:user]
|
105
111
|
end
|
106
112
|
end
|
107
|
-
end
|
113
|
+
end
|
@@ -13,10 +13,11 @@ module LoginEngine
|
|
13
13
|
|
14
14
|
attr_accessor :new_password
|
15
15
|
|
16
|
-
validates_presence_of :login
|
17
|
-
validates_length_of :login, :within => 3..40
|
18
|
-
validates_uniqueness_of :login
|
19
|
-
validates_uniqueness_of :email
|
16
|
+
validates_presence_of :login
|
17
|
+
validates_length_of :login, :within => 3..40
|
18
|
+
validates_uniqueness_of :login
|
19
|
+
validates_uniqueness_of :email
|
20
|
+
validates_format_of :email, :with => /^[^@]+@.+$/
|
20
21
|
|
21
22
|
validates_presence_of :password, :if => :validate_password?
|
22
23
|
validates_confirmation_of :password, :if => :validate_password?
|
@@ -27,9 +28,9 @@ module LoginEngine
|
|
27
28
|
|
28
29
|
attr_accessor :password, :password_confirmation
|
29
30
|
|
30
|
-
after_save
|
31
|
+
after_save :falsify_new_password
|
31
32
|
after_validation :crypt_password
|
32
|
-
|
33
|
+
|
33
34
|
end
|
34
35
|
base.extend(ClassMethods)
|
35
36
|
end
|
@@ -37,15 +38,15 @@ module LoginEngine
|
|
37
38
|
module ClassMethods
|
38
39
|
|
39
40
|
def authenticate(login, pass)
|
40
|
-
u =
|
41
|
+
u = find(:first, :conditions => ["login = ? AND verified = 1 AND deleted = 0", login])
|
41
42
|
return nil if u.nil?
|
42
|
-
|
43
|
+
find(:first, :conditions => ["login = ? AND salted_password = ? AND verified = 1", login, AuthenticatedUser.salted_password(u.salt, AuthenticatedUser.hashed(pass))])
|
43
44
|
end
|
44
45
|
|
45
46
|
def authenticate_by_token(id, token)
|
46
47
|
# Allow logins for deleted accounts, but only via this method (and
|
47
48
|
# not the regular authenticate call)
|
48
|
-
u =
|
49
|
+
u = find(:first, :conditions => ["id = ? AND security_token = ?", id, token])
|
49
50
|
return nil if u.nil? or u.token_expired?
|
50
51
|
return nil if false == u.update_expiry
|
51
52
|
u
|
@@ -129,6 +130,11 @@ module LoginEngine
|
|
129
130
|
end
|
130
131
|
end
|
131
132
|
|
133
|
+
def falsify_new_password
|
134
|
+
@new_password = false
|
135
|
+
true
|
136
|
+
end
|
137
|
+
|
132
138
|
def new_security_token(hours = nil)
|
133
139
|
write_attribute('security_token', AuthenticatedUser.hashed(self.salted_password + Time.now.to_i.to_s + rand.to_s))
|
134
140
|
write_attribute('token_expiry', Time.at(Time.now.to_i + token_lifetime(hours)))
|