wristband 0.0.0 → 1.0.2

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.
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