wristband 0.0.0 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Gemfile +2 -1
  2. data/Gemfile.lock +3 -3
  3. data/README.md +121 -38
  4. data/Rakefile +1 -0
  5. data/VERSION +1 -1
  6. data/app/controllers/application_controller.rb +0 -6
  7. data/app/controllers/passwords_controller.rb +43 -0
  8. data/app/controllers/sessions_controller.rb +6 -7
  9. data/app/controllers/users_controller.rb +1 -26
  10. data/app/helpers/form_helper.rb +8 -0
  11. data/app/mailers/user_mailer.rb +4 -26
  12. data/app/models/user.rb +1 -2
  13. data/app/views/passwords/edit.html.haml +7 -0
  14. data/app/views/passwords/new.html.haml +15 -0
  15. data/app/views/sessions/new.html.haml +1 -5
  16. data/app/views/user_mailer/password_reset.html.haml +7 -0
  17. data/app/views/user_mailer/password_reset.text.haml +6 -0
  18. data/config/environment.rb +1 -0
  19. data/config/initializers/formatted_form_builder.rb +141 -0
  20. data/config/routes.rb +6 -9
  21. data/db/migrate/01_create_users_table.rb +5 -3
  22. data/db/schema.rb +7 -4
  23. data/lib/generators/wristband/wristband_generator.rb +26 -15
  24. data/lib/wristband/application_extensions.rb +1 -0
  25. data/lib/wristband/user_extensions.rb +7 -17
  26. data/lib/wristband.rb +1 -3
  27. data/test/dummy/user.rb +1 -1
  28. data/test/functional/passwords_controller_test.rb +62 -0
  29. data/test/functional/sessions_controller_test.rb +93 -0
  30. data/test/test_helper.rb +1 -5
  31. data/test/unit/has_authorities_test.rb +1 -8
  32. data/test/unit/session_user_test.rb +46 -4
  33. data/test/unit/user_mailer_test.rb +18 -0
  34. data/test/unit/user_test.rb +1 -72
  35. data/test/unit/wristband_test.rb +74 -0
  36. data/wristband.gemspec +27 -10
  37. metadata +62 -29
  38. data/app/views/user_mailer/email_verification.text.html.rhtml +0 -7
  39. data/app/views/user_mailer/email_verification.text.plain.rhtml +0 -9
  40. data/app/views/user_mailer/forgot_password.text.html.rhtml +0 -10
  41. data/app/views/user_mailer/forgot_password.text.plain.rhtml +0 -10
data/Gemfile CHANGED
@@ -2,9 +2,10 @@ source 'http://rubygems.org'
2
2
 
3
3
  gem 'rails', '3.0.3'
4
4
  gem 'haml', '3.0.25'
5
+ gem 'formatted_form', '1.0.0'
5
6
 
6
7
  group :development, :test do
7
- gem 'sqlite3-ruby', :require => 'sqlite3'
8
+ gem 'sqlite3'
8
9
  gem "jeweler"
9
10
  end
10
11
 
data/Gemfile.lock CHANGED
@@ -34,6 +34,7 @@ GEM
34
34
  abstract (>= 1.0.0)
35
35
  faker (0.9.4)
36
36
  i18n (~> 0.4)
37
+ formatted_form (1.0.0)
37
38
  git (1.2.5)
38
39
  haml (3.0.25)
39
40
  i18n (0.5.0)
@@ -68,8 +69,6 @@ GEM
68
69
  thor (~> 0.14.4)
69
70
  rake (0.8.7)
70
71
  sqlite3 (1.3.3)
71
- sqlite3-ruby (1.3.3)
72
- sqlite3 (>= 1.3.3)
73
72
  test_dummy (0.2.6)
74
73
  thor (0.14.6)
75
74
  treetop (1.4.9)
@@ -81,8 +80,9 @@ PLATFORMS
81
80
 
82
81
  DEPENDENCIES
83
82
  faker
83
+ formatted_form (= 1.0.0)
84
84
  haml (= 3.0.25)
85
85
  jeweler
86
86
  rails (= 3.0.3)
87
- sqlite3-ruby
87
+ sqlite3
88
88
  test_dummy
data/README.md CHANGED
@@ -11,6 +11,7 @@ It handles:
11
11
 
12
12
  * Login and logout
13
13
  * Password storage with encryption
14
+ * Password recovery
14
15
  * Remember me functionality
15
16
  * Authority definitions
16
17
 
@@ -25,30 +26,6 @@ It handles:
25
26
 
26
27
  bundle install
27
28
 
28
- ### 3. (optional) Run the wristband generator:
29
-
30
- rails g wristband
31
-
32
- This will output something like:
33
-
34
- create app/models/user.rb
35
- create app/models/session_user.rb
36
- create app/controllers/users_controller.rb
37
- create app/controllers/sessions_controller.rb
38
- create app/views/users/show.html.haml
39
- create app/views/sessions/new.html.haml
40
- create app/mailers/user_mailer.rb
41
- create app/views/user_mailer/forgot_password.text.html.rhtml
42
- create app/views/user_mailer/forgot_password.text.plain.rhtml
43
- create app/views/user_mailer/email_verification.text.html.rhtml
44
- create app/views/user_mailer/email_verification.text.plain.rhtml
45
- create db/migrate/20110123214541_create_users_table.rb
46
-
47
- ### 4. (optional) Run migrations:
48
-
49
- rake db:migrate
50
-
51
-
52
29
  ## Configuration
53
30
 
54
31
 
@@ -60,32 +37,32 @@ This will output something like:
60
37
 
61
38
  ### Options:
62
39
 
63
- **:login_with** - Array of fields you want to authenticate the user with. Default: email
40
+ **:login_with** - Array of fields you want to authenticate the user with. *Default: `:email`*
64
41
 
65
42
  wristband :login_with => [:username, :email]
66
43
 
67
44
 
68
- **:before_authentication** - Array of functions run after the user authentication takes place. Default: []
45
+ **:before_authentication** - Array of functions run after the user authentication takes place. *Default: `[]`*
69
46
 
70
47
  wristband :before_authentication => :do_something
71
48
 
72
49
 
73
- **:after_authentication** - Array of functions run before the user authentication takes place. Default: []
50
+ **:after_authentication** - Array of functions run before the user authentication takes place. *Default: `[]`*
74
51
 
75
52
  wristband :after_authentication => :do_something
76
53
 
77
-
78
- **:has_authorities** - The different user authorities are defined in a separate class so as to reduce clutter in the User model itself. Default: false
79
-
80
- wristband :has_authorities => true
81
-
82
- **:roles** - Use this to define the different roles the user can assume. Make sure you have a role column on your users table. It will generate functions like `is_<role>?` for each one of the roles youdefine.
54
+ **:roles** - Use this to define the different roles the user can assume. Make sure you have a role column on your users table. It will generate functions like `is_<role>?` for each one of the roles you define.
83
55
 
84
56
  wristband :roles => [:regular_user, :admin]
85
57
 
86
58
  will generate `user.is_regular_user?` and `user.is_admin?`
87
59
 
88
60
 
61
+ **:has_authorities** - The different user authorities are defined in a separate class so as to reduce clutter in the User model itself. *Default: `false`*
62
+
63
+ wristband :has_authorities => true
64
+
65
+ Look for more details below.
89
66
 
90
67
  ## Notes
91
68
 
@@ -93,21 +70,127 @@ This will output something like:
93
70
  2. **Authority Definitions** - Checkout the documentation on wristband/authority_check_rb
94
71
 
95
72
 
96
- ## Database configuration
97
73
 
98
- The generator gives you a head start.
74
+ ## Personalization
75
+
76
+ Wristband comes with a generator that provides you with all the files you need to get started
77
+
78
+ rails g wristband
79
+
80
+ This will output something like:
81
+
82
+ == Models ==
83
+ create app/models/user.rb
84
+ create app/models/session_user.rb
85
+ == Controllers ==
86
+ create app/controllers/users_controller.rb
87
+ create app/controllers/sessions_controller.rb
88
+ create app/controllers/passwords_controller.rb
89
+ == Views ==
90
+ create app/views/users/show.html.haml
91
+ create app/views/sessions/new.html.haml
92
+ create app/views/passwords/new.html.haml
93
+ create app/views/passwords/edit.html.haml
94
+ == User Mailer ==
95
+ create app/mailers/user_mailer.rb
96
+ create app/views/user_mailer/password_reset.html.haml
97
+ create app/views/user_mailer/password_reset.text.haml
98
+ == Test helper and Dummies ==
99
+ create test/test_helper.rb
100
+ create test/dummy/user.rb
101
+ == Unit tests ==
102
+ create test/unit/user_test.rb
103
+ create test/unit/session_user_test.rb
104
+ create test/unit/user_mailer_test.rb
105
+ == Functional tests ==
106
+ create test/functional/sessions_controller_test.rb
107
+ create test/functional/passwords_controller_test.rb
108
+ == Migration ==
109
+ create db/migrate/20110123214541_create_users_table.rb
110
+
111
+ ### Database configuration
112
+
99
113
  The basic columns are defined as such:
100
114
 
101
115
  create_table :users do |t|
102
116
  t.string :email
103
- t.string :email_validation_key
104
- t.datetime :validated_at
105
- t.string :password_crypt, :limit => 40
117
+ t.string :password_hash, :limit => 40
106
118
  t.string :password_salt, :limit => 40
119
+ t.string :perishable_token
107
120
  t.string :remember_token
108
121
  t.string :role
109
122
  t.timestamps
110
123
  end
111
124
 
112
125
 
126
+ # AuthorityCheck
127
+
128
+ First you need to tell Wristband that you you want to define permissions for your user:
129
+
130
+ class User < ActiveRecord::Base
131
+ wristband :has_authorities => true
132
+ end
133
+
134
+ This will refer to the class `UserAuthorityCheck` for all authority tests, but the name of this module can be defined as required:
135
+
136
+ class User < ActiveRecord::Base
137
+ has_authorities => :permissions
138
+ end
139
+
140
+ That would reference the class `UserPermissions` instead for all tests.
141
+
142
+ A sample authority checking class is defined as:
143
+
144
+ class UserAuthorityCheck < AuthorityCheck
145
+ def wear_shoes?
146
+ unless (@user.name.match(/^a/i))
147
+ fail!("Only people with names that start with 'A' can wear shoes.")
148
+ end
149
+ end
150
+ end
151
+
152
+ **Note the syntax:** All authority checks are defined as ending with a trailing question mark character.
153
+
154
+ A check is considered to have passed if
155
+
156
+ * a call to `allow!` has been made, or
157
+ * no calls to `fail!` have been made.
158
+
159
+ Once defined, the user authorities are checked via a call to a `User` instance:
160
+
161
+ user.has_authority_to?(:wear_shoes)
162
+
163
+ While the `has_authority_to?` method returns only true or false, a call to `has_objections_to?` will return nil on success or any error messages if there is a failure.
164
+
165
+
166
+ ## Passing parameters to the authority methods
167
+
168
+ Any call to these tests may include options in the form of a Hash:
169
+
170
+ user.has_authority_to?(:send_message, :text => "Foo bar")
171
+
172
+ These options can be acted upon within the authority check:
173
+
174
+ def send_message?
175
+ if (options[:text].match(/foo/i))
176
+ fail!("Messages may not contain forbidden words.")
177
+ end
178
+ end
179
+
180
+ ## Before chains
181
+
182
+ In addition to defining straight tests, a chain can be defined to run before
183
+ any of the tests themselves. This allows certain calls to be over-ruled. For
184
+ example:
185
+
186
+ before_check :allow_if_admin!
187
+
188
+ def allow_if_admin!
189
+ if (@user.is_admin?)
190
+ allow!
191
+ end
192
+ end
193
+
194
+ In this case, the 'allow_if_admin!` method will be called before any checks are performed. If the `allow!` method is executed, all subsequent tests are halted and the check is considered to have passed.
195
+
113
196
  Have fun!!
data/Rakefile CHANGED
@@ -14,6 +14,7 @@ begin
14
14
  gem.authors = ['Jack Neto', 'The Working Group Inc']
15
15
  gem.add_dependency('rails', '>=3.0.3')
16
16
  gem.add_dependency('haml', '>=3.0.25')
17
+ gem.add_dependency('formatted_form', '>=1.0.0')
17
18
  end
18
19
  Jeweler::GemcutterTasks.new
19
20
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 1.0.2
@@ -1,10 +1,4 @@
1
1
  class ApplicationController < ActionController::Base
2
2
  protect_from_forgery
3
3
 
4
- before_filter :login_required
5
-
6
- protected
7
- def login_required
8
- redirect_to login_path unless logged_in?
9
- end
10
4
  end
@@ -0,0 +1,43 @@
1
+ class PasswordsController < ApplicationController
2
+ before_filter :redirect_if_logged_in, :only => [ :new, :create ]
3
+ before_filter :load_user_by_perishable_token, :only => [:edit, :update]
4
+
5
+ def new
6
+ # ...
7
+ end
8
+
9
+ def create
10
+ user = User.find_by_email!(params[:email])
11
+ user.reset_perishable_token!
12
+ UserMailer.password_reset(user).deliver
13
+ redirect_to login_path, :notice => 'Email to reset password successfully sent.'
14
+ rescue ActiveRecord::RecordNotFound
15
+ flash.now[:alert] = 'Your email was not found. Did you mistype?'
16
+ render :action => :new
17
+ end
18
+
19
+ def edit
20
+ # ...
21
+ end
22
+
23
+ def update
24
+ @user.update_attributes!(params[:user].merge(:perishable_token => nil))
25
+ login_as_user(@user)
26
+ redirect_to user_path(@user), :notice => 'Your password was successfully updated!'
27
+ rescue ActiveRecord::RecordInvalid
28
+ flash[:notice] = 'An error occurred. Please try again.'
29
+ redirect_to login_path
30
+ end
31
+
32
+
33
+ protected
34
+ def load_user_by_perishable_token
35
+ @user = User.find_by_perishable_token!(params[:id])
36
+ rescue ActiveRecord::RecordNotFound
37
+ redirect_to login_path
38
+ end
39
+
40
+ def redirect_if_logged_in
41
+ redirect_to user_path(current_user) if logged_in?
42
+ end
43
+ end
@@ -1,31 +1,30 @@
1
1
  class SessionsController < ApplicationController
2
2
  before_filter :login_required, :only => :destroy
3
- before_filter :redirect_if_logged_in, :only => [ :new, :create, :forgot_password ]
3
+ before_filter :redirect_if_logged_in, :only => [ :new, :create ]
4
4
  before_filter :build_user_session, :only => [ :new, :create ]
5
5
 
6
6
  def create
7
7
  if @session_user.save
8
8
  login(@session_user)
9
- flash[:notice] = "Welcome, you are now logged in."
10
- redirect_to user_path(current_user)
9
+ redirect_to(user_path(current_user), :notice => "Welcome, you are now logged in.")
11
10
  else
12
- flash[:error] = 'Login failed. Did you mistype?'
11
+ flash[:alert] = 'Login failed. Did you mistype?'
13
12
  render :action => :new
14
13
  end
15
14
  end
16
15
 
17
16
  def destroy
18
17
  logout
19
- redirect_to root_path
18
+ redirect_to login_path
20
19
  end
21
20
 
22
- private
21
+ protected
23
22
  def build_user_session
24
23
  @session_user = SessionUser.new(params[:session_user])
25
24
  end
26
25
 
27
26
  def redirect_if_logged_in
28
- redirect_to root_path if logged_in?
27
+ redirect_to user_path(current_user) if logged_in?
29
28
  end
30
29
 
31
30
  def login_required
@@ -1,32 +1,7 @@
1
1
  class UsersController < ApplicationController
2
2
  before_filter :login_required
3
3
 
4
- def verify_email
5
- @user = User.verify_email!(params[:email_validation_key])
6
- flash[:notice] = 'Your email address has been verified. You may now login to your account.'
7
- redirect_to login_path
8
- rescue UserVerificationError => error
9
- flash[:error] = error.message
10
- redirect_to login_path
11
- end
12
-
13
- def forgot_password
14
- if request.post?
15
- if @user = User.find_by_email(params[:user][:email])
16
- @user.password = Wristband::Support.random_string(6)
17
- @user.save!
18
- UserNotifier::deliver_forgot_password(@user)
19
- flash[:notice] = 'A new password has been generated and emailed to the address you entered.'
20
- redirect_to login_path and return
21
- else
22
- @user = User.new
23
- @user.errors.add("email", "Cannot find that email address, did you mistype?")
24
- end
25
- end
26
- end
27
-
28
-
29
- private
4
+ protected
30
5
  def login_required
31
6
  redirect_to login_path unless logged_in?
32
7
  end
@@ -0,0 +1,8 @@
1
+ module FormHelper
2
+ def formatted_form_for(record_or_name_or_array, *args, &proc)
3
+ options = args.extract_options!
4
+ options.merge!(:builder => FormattedFormBuilder)
5
+ (options[:html] ||= { }).merge!(:class => "#{options[:html][:class]} formatted")
6
+ form_for(record_or_name_or_array, *(args << options), &proc)
7
+ end
8
+ end
@@ -1,33 +1,11 @@
1
1
  class UserMailer < ActionMailer::Base
2
2
  default :from => "from@example.com"
3
3
 
4
- default_url_options[:host] = HOST_NAME
5
-
6
- def email_verification(user)
7
- setup_email(user)
8
- @subject += "Your account has been created. Please verify your email address"
9
- end
4
+ default_url_options[:host] = 'open-porch.local'
10
5
 
11
- def forgot_password(user)
12
- setup_email(user)
13
- @subject += "You have requested a new password"
6
+ def password_reset(user)
7
+ @user = user
8
+ mail(:to => user.email, :subject => "You have requested a new password")
14
9
  end
15
10
 
16
-
17
- protected
18
- # Change YourApp to whatever you application is called
19
- def setup_email(user)
20
- @recipients = user.email
21
- @body[:user] = user
22
- @from = FROM_EMAIL
23
- @subject = case ENV['RAILS_ENV']
24
- when 'development'
25
- "[YourApp Development] "
26
- when 'staging'
27
- "[YourApp Staging] "
28
- else "[YourApp] "
29
- end
30
- @sent_on = Time.now
31
- headers "Reply-to" => FROM_EMAIL
32
- end
33
11
  end
data/app/models/user.rb CHANGED
@@ -2,7 +2,7 @@ class User < ActiveRecord::Base
2
2
 
3
3
  # == Constants ============================================================
4
4
 
5
- ROLES = [:admin, :regular_user]
5
+ ROLES = %W{admin regular_user}
6
6
 
7
7
  # == Extensions ===========================================================
8
8
 
@@ -48,5 +48,4 @@ class User < ActiveRecord::Base
48
48
  def password_required?
49
49
  self.new_record?
50
50
  end
51
-
52
51
  end
@@ -0,0 +1,7 @@
1
+ %h1 Enter a new Password
2
+
3
+ = formatted_form_for @user, :url => { :action => :update, :id => params[:id] } do |form|
4
+ = form.error_messages
5
+ = form.password_field :password, :autocomplete => :off
6
+ = form.password_field :password_confirmation, :label => 'Password Confim'
7
+ = form.submit 'Update'
@@ -0,0 +1,15 @@
1
+ %h1 Reset your password
2
+
3
+ = form_tag passwords_path, :class => 'formatted' do
4
+ .form_element.text_field_element
5
+ .label Email
6
+ .value= text_field_tag :email
7
+
8
+ .form_element.submit_element
9
+ = submit_tag 'Send Reset Password Email'
10
+
11
+
12
+
13
+ %p
14
+ Already have an account?
15
+ = link_to 'Login', login_path
@@ -8,8 +8,4 @@
8
8
 
9
9
  %p
10
10
  Did you forget your password?
11
- = link_to 'Recover it here.', forgot_password_path
12
- %p
13
- If you don't have a login yet, click
14
- = link_to 'here', register_path
15
- to register.
11
+ = link_to 'Recover it here.', new_password_path
@@ -0,0 +1,7 @@
1
+ %p
2
+ Hi
3
+ %p
4
+ A new password was requested for this email address. Please ignore this if you think this email is sent to you in error.
5
+
6
+ %h2
7
+ = link_to 'Reset your password', edit_password_url(:id => @user.perishable_token)
@@ -0,0 +1,6 @@
1
+ Hi,
2
+
3
+ A new password was requested for this email address. Please ignore this if you think this email is sent to you in error.
4
+
5
+ To reset your password please follow this link:
6
+ = edit_password_url(:id => @user.perishable_token)
@@ -3,3 +3,4 @@ require File.expand_path('../application', __FILE__)
3
3
 
4
4
  # Initialize the rails application
5
5
  Wristband::Application.initialize!
6
+
@@ -0,0 +1,141 @@
1
+ class FormattedFormBuilder < ActionView::Helpers::FormBuilder
2
+
3
+ %w[ date_select text_field password_field text_area file_field datetime_select ].each do |selector|
4
+ src = <<-end_src
5
+ def #{selector}(method, options = {})
6
+ if (options[:simple] == true)
7
+ super(method, options)
8
+ else
9
+ options.merge!(:size=> '') if #{%w{text_field password_field}.include?(selector)}
10
+ standard_field('#{selector}', method, options) { super(method, options) }
11
+ end
12
+ end
13
+ end_src
14
+ class_eval src, __FILE__, __LINE__
15
+ end
16
+
17
+ def standard_field(type, method, options={}, &block)
18
+ description = options.delete(:desc)
19
+ content = options.delete(:content)
20
+ prev_content = options.delete(:prev_content)
21
+ label = label_for(method, options)
22
+ required = options.delete(:required)
23
+ check_box_details = options.delete(:check_box_details)
24
+ text_snippet = options.delete(:text_snippet)
25
+ %{
26
+ <div class='form_element #{type}_element'>
27
+ #{"<div class='text_snippet'>"+text_snippet+"</div>" if text_snippet}
28
+ <div class='label'>
29
+ #{description(description) || '&nbsp;' if type == 'check_box' }
30
+ #{label if type != 'check_box' }
31
+ #{@template.content_tag(:span, '*', :class => 'required_ind') if required }
32
+ </div>
33
+ <div class='value'>
34
+ #{prev_content}#{yield}#{content}
35
+ #{error_messages_for(method)}
36
+ #{description(description) if type != 'check_box'}
37
+ #{description(check_box_details) if type == 'check_box'}
38
+ </div>
39
+ </div>
40
+ }.html_safe
41
+ end
42
+
43
+ # generic container for all things form
44
+ def element(label = '&nbsp;', value = '', type = 'text_field', &block)
45
+ value += @template.capture(&block) if block_given?
46
+ %{
47
+ <div class='form_element #{type}_element'>
48
+ <div class='label'>
49
+ #{label}
50
+ </div>
51
+ <div class='value'>
52
+ #{value}
53
+ </div>
54
+ </div>
55
+ }.html_safe
56
+ end
57
+
58
+ def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
59
+ options[:content] = label_for(method, options)
60
+ options[:label] = ''
61
+ standard_field('check_box', method, options) { super(method, options, checked_value, unchecked_value) }
62
+ end
63
+
64
+ def radio_button(method, tag_value, options = {})
65
+ if options && options[:choices]
66
+ radios = options.delete(:choices).collect{|choice| %{<div class="radio_button">}+super(method, choice[0], options) + %{<label for="#{object_name.to_s.gsub(']', '').gsub('[', '_')}_#{method}_#{choice[0]}">#{choice[1]}</label></div>}}.join.html_safe
67
+ standard_field('radio_button', method, options) { radios }
68
+ elsif options && options[:value_name]
69
+ standard_field('radio_button', method, options) { super(method, tag_value) + %{<label for="#{object_name}_#{method}_#{tag_value}">#{options[:value_name]}</label><div class="clearfloat"></div>}.html_safe}
70
+ else
71
+ standard_field('radio_button', method, options) { super(method, tag_value, options = {}) }
72
+ end
73
+ end
74
+
75
+ def select(method, choices, options = {}, html_options = {})
76
+ standard_field('select', method, options) { super(method, choices, options, html_options) }
77
+ end
78
+
79
+ def hidden_field(method, options = {}, html_options = {})
80
+ super(method, options)
81
+ end
82
+
83
+ def submit(value, options={}, &block)
84
+ cancel_link = @template.capture(&block) if block_given?
85
+ cancel_link ||= options[:cancel_url] ? ' or ' + options.delete(:cancel_url) : ''
86
+ if options[:show_ajax_loader]
87
+ options[:onclick] = "$(this).parent().next().css('display', 'block');$(this).parent().hide();"
88
+ end
89
+ if options[:image_button] == true
90
+ submit_id = Time.now.usec
91
+ out = @template.content_tag(:div,
92
+ %{
93
+ #{super(value, options.merge(:style=>'visibility:hidden;position: absolute', :id => submit_id)).html_safe}
94
+ <a class="red_button" href="" onclick="$('##{submit_id}').closest('form').submit();return false"><span>#{value}</span></a>
95
+ #{cancel_link.html_safe}
96
+ }.html_safe, :class => 'form_element submit_element').html_safe
97
+
98
+ else
99
+ out = @template.content_tag(:div, super(value, options) + cancel_link.html_safe, :class => 'form_element submit_element').html_safe
100
+ end
101
+
102
+ if options[:show_ajax_loader]
103
+ out << %{
104
+ <div class="form_element submit_element" style="display:none">
105
+ <div class="submit_ajax_loader">#{options[:show_ajax_loader]}</div>
106
+ </div>
107
+ }.html_safe
108
+ end
109
+ out.html_safe
110
+ end
111
+
112
+ def label_for(method, options)
113
+ label = options.delete(:label) || method.to_s.titleize.capitalize
114
+ "<label for=\"#{object_name}_#{method}\">#{label}</label>"
115
+ end
116
+
117
+ def description(description)
118
+ "<div class='description'>#{description}</div>" unless description.nil?
119
+ end
120
+
121
+ def error_messages
122
+ if object && !object.errors.empty?
123
+ message = object.errors[:base].present? ? object.errors[:base]: 'There were some problems submitting this form. Please correct all the highlighted fields and try again'
124
+ @template.content_tag(:div, message, :class => 'form_error')
125
+ end
126
+ end
127
+
128
+ def error_messages_for(method)
129
+ if (object and object.respond_to?(:errors) and errors = object.errors[method])
130
+ "<div class='errors'>#{errors.is_a?(Array) ? errors.first : errors}</div>"
131
+ else
132
+ ''
133
+ end
134
+ end
135
+
136
+ def formatted_fields_for(record_or_name_or_array, *args, &block)
137
+ options = args.extract_options!
138
+ options.merge!(:builder => FormattedFormBuilder)
139
+ fields_for(record_or_name_or_array, *(args << options), &block)
140
+ end
141
+ end
data/config/routes.rb CHANGED
@@ -1,11 +1,8 @@
1
- Rails::Application.routes.draw do
2
-
3
- post '/login', :to => 'sessions#create'
4
- get '/login', :to => 'sessions#new'
5
- get '/logout', :to => 'sessions#destroy'
6
- match '/forgot_password', :to => 'sessions#forgot_password'
7
-
8
- resources :users
9
- match '/register', :to => 'users#new'
1
+ Rails.application.routes.draw do
2
+ post '/login' => 'sessions#create'
3
+ get '/login' => 'sessions#new'
4
+ get '/logout' => 'sessions#destroy'
10
5
 
6
+ resources :users
7
+ resources :passwords, :only => [:new, :create, :edit, :update]
11
8
  end