fetty-generators 1.7.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/README.rdoc +42 -36
- data/Rakefile +1 -3
- data/lib/generators/fetty.rb +160 -10
- data/lib/generators/fetty/authentication/USAGE +4 -0
- data/lib/generators/fetty/authentication/authentication_generator.rb +171 -0
- data/lib/generators/fetty/authentication/templates/controllers/reset_passwords_controller.rb +45 -0
- data/lib/generators/fetty/authentication/templates/controllers/sessions_controller.rb +30 -0
- data/lib/generators/fetty/authentication/templates/controllers/users_controller.rb +78 -0
- data/lib/generators/fetty/authentication/templates/helpers/reset_passwords_helper.rb +2 -0
- data/lib/generators/fetty/authentication/templates/helpers/sessions_helper.rb +2 -0
- data/lib/generators/fetty/authentication/templates/helpers/users_helper.rb +2 -0
- data/lib/generators/fetty/authentication/templates/lib/sessions_authentication.rb +53 -0
- data/lib/generators/fetty/authentication/templates/lib/users_authentication.rb +110 -0
- data/lib/generators/fetty/authentication/templates/mailers/setup_mail.rb +11 -0
- data/lib/generators/fetty/authentication/templates/mailers/user_mailer.rb +14 -0
- data/lib/generators/fetty/authentication/templates/models/active_record/create_users.rb +17 -0
- data/lib/generators/fetty/authentication/templates/models/active_record/user.rb +15 -0
- data/lib/generators/fetty/authentication/templates/models/mongoid/user.rb +23 -0
- data/lib/generators/fetty/authentication/templates/spec/controllers/reset_passwords_controller_spec.rb +93 -0
- data/lib/generators/fetty/authentication/templates/spec/controllers/sessions_controller_spec.rb +61 -0
- data/lib/generators/fetty/authentication/templates/spec/controllers/users_controller_spec.rb +158 -0
- data/lib/generators/fetty/authentication/templates/spec/models/user_spec.rb +108 -0
- data/lib/generators/fetty/authentication/templates/spec/routing/reset_passwords_routing_spec.rb +21 -0
- data/lib/generators/fetty/authentication/templates/spec/routing/sessions_routing_spec.rb +17 -0
- data/lib/generators/fetty/authentication/templates/spec/routing/users_routing_spec.rb +37 -0
- data/lib/generators/fetty/authentication/templates/spec/support/user_factories.rb +6 -0
- data/lib/generators/fetty/authentication/templates/views/layouts/application.html.erb +33 -0
- data/lib/generators/fetty/authentication/templates/views/reset_passwords/edit.html.erb +19 -0
- data/lib/generators/fetty/authentication/templates/views/reset_passwords/new.html.erb +14 -0
- data/lib/generators/fetty/authentication/templates/views/sessions/new.html.erb +22 -0
- data/lib/generators/fetty/authentication/templates/views/user_mailer/user_activation.text.erb +4 -0
- data/lib/generators/fetty/authentication/templates/views/user_mailer/user_forgot_password.text.erb +7 -0
- data/lib/generators/fetty/authentication/templates/views/users/_table.html.erb +23 -0
- data/lib/generators/fetty/authentication/templates/views/users/edit.html.erb +21 -0
- data/lib/generators/fetty/authentication/templates/views/users/index.html.erb +7 -0
- data/lib/generators/fetty/authentication/templates/views/users/index.js.erb +1 -0
- data/lib/generators/fetty/authentication/templates/views/users/new.html.erb +23 -0
- data/lib/generators/fetty/authentication/templates/views/users/show.html.erb +19 -0
- data/lib/generators/fetty/messages/USAGE +4 -0
- data/lib/generators/fetty/messages/messages_generator.rb +136 -0
- data/lib/generators/fetty/messages/templates/assets/javascripts/jquery.tokeninput.js +718 -0
- data/lib/generators/fetty/messages/templates/assets/javascripts/messages.js +19 -0
- data/lib/generators/fetty/messages/templates/assets/stylesheets/messages.css +87 -0
- data/lib/generators/fetty/messages/templates/assets/stylesheets/token-input-facebook.css +122 -0
- data/lib/generators/fetty/messages/templates/controllers/messages_controller.rb +109 -0
- data/lib/generators/fetty/messages/templates/helpers/messages_helper.rb +2 -0
- data/lib/generators/fetty/messages/templates/lib/users_messages.rb +67 -0
- data/lib/generators/fetty/messages/templates/models/active_record/create_messages.rb +24 -0
- data/lib/generators/fetty/messages/templates/models/active_record/message.rb +67 -0
- data/lib/generators/fetty/messages/templates/models/mongoid/message.rb +81 -0
- data/lib/generators/fetty/messages/templates/spec/controllers/messages_controller_spec.rb +78 -0
- data/lib/generators/fetty/messages/templates/spec/models/message_spec.rb +53 -0
- data/lib/generators/fetty/messages/templates/spec/routing/messages_routing_spec.rb +61 -0
- data/lib/generators/fetty/messages/templates/spec/support/message_factories.rb +8 -0
- data/lib/generators/fetty/messages/templates/views/_head.html.erb +20 -0
- data/lib/generators/fetty/messages/templates/views/_messages.html.erb +56 -0
- data/lib/generators/fetty/messages/templates/views/_tabs_panel.html.erb +11 -0
- data/lib/generators/fetty/messages/templates/views/index.html.erb +10 -0
- data/lib/generators/fetty/messages/templates/views/index.js.erb +1 -0
- data/lib/generators/fetty/messages/templates/views/new.html.erb +26 -0
- data/lib/generators/fetty/messages/templates/views/show.html.erb +35 -0
- data/lib/generators/fetty/scaffold/USAGE +2 -52
- data/lib/generators/fetty/scaffold/scaffold_generator.rb +96 -329
- data/lib/generators/fetty/scaffold/templates/controllers/active_record/controller.rb +60 -0
- data/lib/generators/fetty/scaffold/templates/controllers/mongoid/controller.rb +60 -0
- data/lib/generators/fetty/scaffold/templates/helpers/helper.rb +2 -0
- data/lib/generators/fetty/scaffold/templates/models/active_record/migration.rb +16 -0
- data/lib/generators/fetty/scaffold/templates/models/active_record/model.rb +10 -0
- data/lib/generators/fetty/scaffold/templates/models/mongoid/model.rb +16 -0
- data/lib/generators/fetty/scaffold/templates/test/rspec/controller.rb +98 -0
- data/lib/generators/fetty/scaffold/templates/test/rspec/factories.rb +26 -0
- data/lib/generators/fetty/scaffold/templates/test/rspec/helper.rb +15 -0
- data/lib/generators/fetty/scaffold/templates/test/rspec/model.rb +9 -0
- data/lib/generators/fetty/scaffold/templates/test/rspec/request.rb +11 -0
- data/lib/generators/fetty/scaffold/templates/test/rspec/routing.rb +41 -0
- data/lib/generators/fetty/scaffold/templates/test/test_unit/controller.rb +62 -0
- data/lib/generators/fetty/scaffold/templates/{fixtures.yml → test/test_unit/fixtures.yml} +2 -0
- data/lib/generators/fetty/scaffold/templates/test/test_unit/helper.rb +4 -0
- data/lib/generators/fetty/scaffold/templates/test/test_unit/model.rb +7 -0
- data/lib/generators/fetty/scaffold/templates/views/_form.html.erb +20 -0
- data/lib/generators/fetty/scaffold/templates/views/_table.html.erb +48 -0
- data/lib/generators/fetty/scaffold/templates/views/edit.html.erb +13 -0
- data/lib/generators/fetty/scaffold/templates/views/index.html.erb +15 -0
- data/lib/generators/fetty/scaffold/templates/views/{erb/index.js.erb → index.js.erb} +0 -0
- data/lib/generators/fetty/scaffold/templates/views/new.html.erb +9 -0
- data/lib/generators/fetty/scaffold/templates/views/show.html.erb +28 -0
- data/lib/generators/fetty/setup/USAGE +3 -20
- data/lib/generators/fetty/setup/setup_generator.rb +122 -61
- data/lib/generators/fetty/setup/templates/ability.rb +0 -0
- data/lib/generators/fetty/setup/templates/ckeditor.rb +54 -0
- data/lib/generators/fetty/setup/templates/ckeditor.tar.gz +0 -0
- data/lib/generators/fetty/setup/templates/escape_utils.rb +7 -0
- data/lib/generators/fetty/setup/templates/file_uploader.rb +15 -0
- data/lib/generators/fetty/setup/templates/image_uploader.rb +48 -0
- data/lib/generators/fetty/setup/templates/spec_helper.rb +44 -0
- data/lib/generators/fetty/views/USAGE +5 -0
- data/lib/generators/fetty/{layout/templates/stylesheet.css → views/templates/application.css} +184 -166
- data/lib/generators/fetty/views/templates/application.html.erb +23 -0
- data/lib/generators/fetty/{layout → views}/templates/application.js +0 -0
- data/lib/generators/fetty/views/templates/application_helper.rb +10 -0
- data/lib/generators/fetty/views/templates/down_arrow.gif +0 -0
- data/lib/generators/fetty/{layout → views}/templates/error_messages_helper.rb +0 -0
- data/lib/generators/fetty/{layout → views}/templates/layout_helper.rb +0 -0
- data/lib/generators/fetty/views/templates/up_arrow.gif +0 -0
- data/lib/generators/fetty/views/views_generator.rb +51 -0
- data/lib/generators/scaffold.rb +204 -0
- metadata +126 -111
- data/LICENSE +0 -20
- data/lib/generators/fetty/layout/USAGE +0 -26
- data/lib/generators/fetty/layout/layout_generator.rb +0 -44
- data/lib/generators/fetty/layout/templates/layout.html.erb +0 -32
- data/lib/generators/fetty/layout/templates/layout.html.haml +0 -34
- data/lib/generators/fetty/layout/templates/no-devise-links-layout.html.erb +0 -23
- data/lib/generators/fetty/layout/templates/no-devise-links-layout.html.haml +0 -23
- data/lib/generators/fetty/layout/templates/stylesheet.sass +0 -163
- data/lib/generators/fetty/scaffold/templates/actions/create.rb +0 -8
- data/lib/generators/fetty/scaffold/templates/actions/destroy.rb +0 -5
- data/lib/generators/fetty/scaffold/templates/actions/edit.rb +0 -3
- data/lib/generators/fetty/scaffold/templates/actions/index.rb +0 -10
- data/lib/generators/fetty/scaffold/templates/actions/new.rb +0 -3
- data/lib/generators/fetty/scaffold/templates/actions/show.rb +0 -3
- data/lib/generators/fetty/scaffold/templates/actions/update.rb +0 -8
- data/lib/generators/fetty/scaffold/templates/controller.rb +0 -7
- data/lib/generators/fetty/scaffold/templates/helper.rb +0 -2
- data/lib/generators/fetty/scaffold/templates/migration.rb +0 -16
- data/lib/generators/fetty/scaffold/templates/model.rb +0 -7
- data/lib/generators/fetty/scaffold/templates/tests/rspec/actions/create.rb +0 -11
- data/lib/generators/fetty/scaffold/templates/tests/rspec/actions/destroy.rb +0 -6
- data/lib/generators/fetty/scaffold/templates/tests/rspec/actions/edit.rb +0 -4
- data/lib/generators/fetty/scaffold/templates/tests/rspec/actions/index.rb +0 -4
- data/lib/generators/fetty/scaffold/templates/tests/rspec/actions/new.rb +0 -4
- data/lib/generators/fetty/scaffold/templates/tests/rspec/actions/show.rb +0 -4
- data/lib/generators/fetty/scaffold/templates/tests/rspec/actions/update.rb +0 -11
- data/lib/generators/fetty/scaffold/templates/tests/rspec/controller.rb +0 -8
- data/lib/generators/fetty/scaffold/templates/tests/rspec/model.rb +0 -7
- data/lib/generators/fetty/scaffold/templates/tests/shoulda/actions/create.rb +0 -13
- data/lib/generators/fetty/scaffold/templates/tests/shoulda/actions/destroy.rb +0 -8
- data/lib/generators/fetty/scaffold/templates/tests/shoulda/actions/edit.rb +0 -6
- data/lib/generators/fetty/scaffold/templates/tests/shoulda/actions/index.rb +0 -6
- data/lib/generators/fetty/scaffold/templates/tests/shoulda/actions/new.rb +0 -6
- data/lib/generators/fetty/scaffold/templates/tests/shoulda/actions/show.rb +0 -6
- data/lib/generators/fetty/scaffold/templates/tests/shoulda/actions/update.rb +0 -13
- data/lib/generators/fetty/scaffold/templates/tests/shoulda/controller.rb +0 -5
- data/lib/generators/fetty/scaffold/templates/tests/shoulda/model.rb +0 -7
- data/lib/generators/fetty/scaffold/templates/tests/testunit/actions/create.rb +0 -11
- data/lib/generators/fetty/scaffold/templates/tests/testunit/actions/destroy.rb +0 -6
- data/lib/generators/fetty/scaffold/templates/tests/testunit/actions/edit.rb +0 -4
- data/lib/generators/fetty/scaffold/templates/tests/testunit/actions/index.rb +0 -4
- data/lib/generators/fetty/scaffold/templates/tests/testunit/actions/new.rb +0 -4
- data/lib/generators/fetty/scaffold/templates/tests/testunit/actions/show.rb +0 -4
- data/lib/generators/fetty/scaffold/templates/tests/testunit/actions/update.rb +0 -11
- data/lib/generators/fetty/scaffold/templates/tests/testunit/controller.rb +0 -5
- data/lib/generators/fetty/scaffold/templates/tests/testunit/model.rb +0 -7
- data/lib/generators/fetty/scaffold/templates/views/erb/_form.html.erb +0 -22
- data/lib/generators/fetty/scaffold/templates/views/erb/_table.html.erb +0 -50
- data/lib/generators/fetty/scaffold/templates/views/erb/edit.html.erb +0 -12
- data/lib/generators/fetty/scaffold/templates/views/erb/index.html.erb +0 -13
- data/lib/generators/fetty/scaffold/templates/views/erb/new.html.erb +0 -9
- data/lib/generators/fetty/scaffold/templates/views/erb/show.html.erb +0 -26
- data/lib/generators/fetty/scaffold/templates/views/haml/_form.html.haml +0 -8
- data/lib/generators/fetty/scaffold/templates/views/haml/_table.html.haml +0 -33
- data/lib/generators/fetty/scaffold/templates/views/haml/edit.html.haml +0 -14
- data/lib/generators/fetty/scaffold/templates/views/haml/index.html.haml +0 -12
- data/lib/generators/fetty/scaffold/templates/views/haml/index.js.haml +0 -1
- data/lib/generators/fetty/scaffold/templates/views/haml/new.html.haml +0 -8
- data/lib/generators/fetty/scaffold/templates/views/haml/show.html.haml +0 -23
@@ -0,0 +1,45 @@
|
|
1
|
+
class ResetPasswordsController < ApplicationController
|
2
|
+
skip_before_filter :authenticate_user!
|
3
|
+
|
4
|
+
def new
|
5
|
+
end
|
6
|
+
|
7
|
+
def create
|
8
|
+
if @user = User.first(:conditions => { :username => params[:login] }) || User.first(:conditions => { :email => params[:login] })
|
9
|
+
if @user.activated?
|
10
|
+
@user.send_forgot_password_instructions!
|
11
|
+
flash.now[:notice] = "We've sent an email to #{@user.email} containing instructions on how to reset your password."
|
12
|
+
render :action => 'new'
|
13
|
+
else
|
14
|
+
raise "Account has never been activated, please activate your account first before resetting your password."
|
15
|
+
end
|
16
|
+
else
|
17
|
+
raise "Could not find any account with that username / email address."
|
18
|
+
end
|
19
|
+
rescue Exception => e
|
20
|
+
flash.now[:alert] = e.message
|
21
|
+
render :action => 'new'
|
22
|
+
end
|
23
|
+
|
24
|
+
def edit
|
25
|
+
unless @user = User.first(:conditions => { :id => params[:id], :token => params[:token] })
|
26
|
+
redirect_to new_reset_password_url, :alert => "Unable to find an account, Please follow the URL from your email / send the new reset instructions!"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def update
|
31
|
+
if @user = User.first(:conditions => { :id => params[:id], :token => params[:token] })
|
32
|
+
if @user.reset_password(params[:password],params[:password_confirmation]) == UsersAuthentication::Status::Valid
|
33
|
+
redirect_to new_session_url, :notice => "Your password was successfully updated, Please login using your new password!"
|
34
|
+
else
|
35
|
+
raise "Unable to reset your password!"
|
36
|
+
end
|
37
|
+
else
|
38
|
+
raise "Unable to find an account, Please follow the URL from your email / send the new reset instructions!"
|
39
|
+
end
|
40
|
+
rescue Exception => e
|
41
|
+
flash.now[:alert] = e.message
|
42
|
+
render :action => 'edit'
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class SessionsController < ApplicationController
|
2
|
+
skip_before_filter :authenticate_user!, :except => [:destroy]
|
3
|
+
|
4
|
+
def new
|
5
|
+
end
|
6
|
+
|
7
|
+
def create
|
8
|
+
@user = User.authenticate!(params[:login], params[:password])
|
9
|
+
if @user.is_a? User
|
10
|
+
set_session_or_cookies(@user,params[:remember_me])
|
11
|
+
redirect_to redirect_to_target_or_default_url, :notice => "Sign in successfully."
|
12
|
+
elsif @user == UsersAuthentication::Status::Unexist
|
13
|
+
raise "User account not found! please sign up first."
|
14
|
+
elsif @user == UsersAuthentication::Status::InvalidPassword
|
15
|
+
raise "Invalid username or password."
|
16
|
+
elsif @user == UsersAuthentication::Status::Inactivated
|
17
|
+
raise "Please activate your account first! check your email."
|
18
|
+
end
|
19
|
+
rescue Exception => e
|
20
|
+
set_session_or_cookies(nil)
|
21
|
+
flash.now[:alert] = e.message
|
22
|
+
render :action => 'new'
|
23
|
+
end
|
24
|
+
|
25
|
+
def destroy
|
26
|
+
set_session_or_cookies(nil)
|
27
|
+
redirect_to root_url, :notice => "Successfully sign out."
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class UsersController < ApplicationController
|
2
|
+
skip_before_filter :authenticate_user!, :except => [:index, :edit, :update, :destroy]
|
3
|
+
|
4
|
+
def index
|
5
|
+
@users = User.all
|
6
|
+
|
7
|
+
respond_to do |format|
|
8
|
+
format.html # index.html.erb
|
9
|
+
format.xml { render :xml => @users }
|
10
|
+
format.js
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def show
|
15
|
+
@user = User.find(params[:id])
|
16
|
+
end
|
17
|
+
|
18
|
+
def new
|
19
|
+
@user = User.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def create
|
23
|
+
@user = User.new(:username => params[:username], :email => params[:email], :password => params[:password], :password_confirmation => params[:password_confirmation])
|
24
|
+
if @user.save
|
25
|
+
@user.send_activation_mail
|
26
|
+
redirect_to new_session_url, :notice => "Activation link has been sent to your email. Please activate first!"
|
27
|
+
else
|
28
|
+
raise "Unable to create user account."
|
29
|
+
end
|
30
|
+
rescue Exception => e
|
31
|
+
flash.now[:alert] = e.message
|
32
|
+
render :action => 'new'
|
33
|
+
end
|
34
|
+
|
35
|
+
def edit
|
36
|
+
@user = User.find(params[:id])
|
37
|
+
end
|
38
|
+
|
39
|
+
def update
|
40
|
+
@user = User.find(params[:id])
|
41
|
+
if @user.update_attributes(:username => params[:username], :email => params[:email], :password => params[:password], :password_confirmation => params[:password_confirmation])
|
42
|
+
redirect_to user_path(@user), :notice => "Your profile has been updated."
|
43
|
+
else
|
44
|
+
raise "Unable to update your profile."
|
45
|
+
end
|
46
|
+
rescue Exception => e
|
47
|
+
flash.now[:alert] = e.message
|
48
|
+
render :action => 'edit'
|
49
|
+
end
|
50
|
+
|
51
|
+
def destroy
|
52
|
+
@user = User.find(params[:id])
|
53
|
+
if current_user === @user
|
54
|
+
set_session_or_cookies(nil)
|
55
|
+
@user.destroy
|
56
|
+
redirect_to new_session_url, :notice => "Your account has been deleted."
|
57
|
+
else
|
58
|
+
@user.destroy
|
59
|
+
redirect_to users_url, :notice => "account has been deleted."
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def activate
|
64
|
+
@user = User.activate!(params[:id],params[:token])
|
65
|
+
if @user.is_a? User
|
66
|
+
set_session_or_cookies(@user)
|
67
|
+
redirect_to root_url, :notice => "Your account has been activated!"
|
68
|
+
elsif @user == UsersAuthentication::Status::Unexist
|
69
|
+
raise "Invalid user account and activation code"
|
70
|
+
elsif @user == UsersAuthentication::Status::Activated
|
71
|
+
raise "You already activated this account."
|
72
|
+
end
|
73
|
+
rescue Exception => e
|
74
|
+
set_session_or_cookies(nil)
|
75
|
+
redirect_to new_session_url, :alert => e.message
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module SessionsAuthentication
|
2
|
+
|
3
|
+
def self.included(receiver)
|
4
|
+
receiver.send :helper_method, :current_user, :user_signed_in?
|
5
|
+
end
|
6
|
+
|
7
|
+
def current_user
|
8
|
+
@current_user ||= ( signin_from_session || signin_from_cookies )
|
9
|
+
end
|
10
|
+
|
11
|
+
def user_signed_in?
|
12
|
+
current_user ? true : false
|
13
|
+
end
|
14
|
+
|
15
|
+
def authenticate_user!
|
16
|
+
unless user_signed_in?
|
17
|
+
redirect_to new_session_url, :alert => "You must sign in first before accessing this page."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_session_or_cookies(user,remember = false)
|
22
|
+
if user
|
23
|
+
@current_user = user
|
24
|
+
if remember
|
25
|
+
cookies.permanent.signed[:user_id] = user.id
|
26
|
+
else
|
27
|
+
session[:user_id] = user.id
|
28
|
+
end
|
29
|
+
else
|
30
|
+
@current_user = nil
|
31
|
+
session[:user_id] = nil if session[:user_id]
|
32
|
+
cookies.delete :user_id if cookies.signed[:user_id]
|
33
|
+
reset_session
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def signin_from_session
|
38
|
+
User.find(session[:user_id]) if session[:user_id]
|
39
|
+
end
|
40
|
+
|
41
|
+
def signin_from_cookies
|
42
|
+
User.find(cookies.signed[:user_id]) if cookies.signed[:user_id]
|
43
|
+
end
|
44
|
+
|
45
|
+
def redirect_to_target_or_default_url(default = root_url)
|
46
|
+
if request.env["HTTP_REFERER"].blank? || request.env["HTTP_REFERER"] == new_session_url
|
47
|
+
default
|
48
|
+
else
|
49
|
+
request.env["HTTP_REFERER"]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module UsersAuthentication
|
2
|
+
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
def authenticate!(login, pass)
|
6
|
+
user = first(:conditions => { :username => login }) || first(:conditions => { :email => login })
|
7
|
+
case
|
8
|
+
when user.nil? then return UsersAuthentication::Status::Unexist
|
9
|
+
when !user.password_match?(pass) then return UsersAuthentication::Status::InvalidPassword
|
10
|
+
when !user.activated? then return UsersAuthentication::Status::Inactivated
|
11
|
+
else
|
12
|
+
return user
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def activate!(id,token)
|
17
|
+
user = first(:conditions => { :id => id, :token => token })
|
18
|
+
case
|
19
|
+
when user.nil? then return UsersAuthentication::Status::Unexist
|
20
|
+
when user.activated? then return UsersAuthentication::Status::Activated
|
21
|
+
else
|
22
|
+
user.update_attribute(:activated_at, Time.now.utc)
|
23
|
+
user.clear_token!
|
24
|
+
return user
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
module InstanceMethods
|
31
|
+
|
32
|
+
def send_activation_mail
|
33
|
+
UserMailer.user_activation(self).deliver
|
34
|
+
end
|
35
|
+
|
36
|
+
def send_forgot_password_instructions!
|
37
|
+
self.make_token!
|
38
|
+
UserMailer.user_forgot_password(self).deliver
|
39
|
+
end
|
40
|
+
|
41
|
+
def reset_password(new_pass,new_pass_conf)
|
42
|
+
self.password = new_pass
|
43
|
+
self.password_confirmation = new_pass_conf
|
44
|
+
self.save
|
45
|
+
unless self.password_match?(new_pass)
|
46
|
+
return Status::Error
|
47
|
+
else
|
48
|
+
self.clear_token!
|
49
|
+
return Status::Valid
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def password_match?(pass)
|
54
|
+
self.password_hash == encrypt_password(pass)
|
55
|
+
end
|
56
|
+
|
57
|
+
def activated?
|
58
|
+
!self.activated_at.nil?
|
59
|
+
end
|
60
|
+
|
61
|
+
def make_token!
|
62
|
+
self.update_attribute(:token, generate_token)
|
63
|
+
end
|
64
|
+
|
65
|
+
def clear_token!
|
66
|
+
self.update_attribute(:token, nil)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def generate_token
|
72
|
+
ActiveSupport::SecureRandom.urlsafe_base64
|
73
|
+
end
|
74
|
+
|
75
|
+
def encrypt_password(pass)
|
76
|
+
BCrypt::Engine.hash_secret(pass, self.password_salt)
|
77
|
+
end
|
78
|
+
|
79
|
+
def prepare_password
|
80
|
+
unless password.blank?
|
81
|
+
self.password_salt = BCrypt::Engine.generate_salt
|
82
|
+
self.password_hash = encrypt_password(password)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def prepare_activation
|
87
|
+
self.token = generate_token
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.included(receiver)
|
93
|
+
receiver.send :attr_accessor, :password, :password_confirmation
|
94
|
+
receiver.send :before_save, :prepare_password
|
95
|
+
receiver.send :before_create, :prepare_activation
|
96
|
+
|
97
|
+
receiver.extend ClassMethods
|
98
|
+
receiver.send :include, InstanceMethods
|
99
|
+
end
|
100
|
+
|
101
|
+
class Status
|
102
|
+
Valid = 0
|
103
|
+
Unexist = 1
|
104
|
+
InvalidPassword = 2
|
105
|
+
Inactivated = 3
|
106
|
+
Activated = 4
|
107
|
+
Error = 5
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
ActionMailer::Base.smtp_settings = {
|
2
|
+
:address => "smtp.gmail.com",
|
3
|
+
:port => 587,
|
4
|
+
:domain => "your_app",
|
5
|
+
:user_name => "your_username",
|
6
|
+
:password => "your_password",
|
7
|
+
:authentication => "plain",
|
8
|
+
:enable_starttls_auto => true
|
9
|
+
}
|
10
|
+
|
11
|
+
ActionMailer::Base.default_url_options[:host] = "localhost:3000"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class UserMailer < ActionMailer::Base
|
2
|
+
default :from => "from@example.com"
|
3
|
+
|
4
|
+
def user_forgot_password(user)
|
5
|
+
@user = user
|
6
|
+
mail(:to => user.email, :subject => "Reset Password Instructions")
|
7
|
+
end
|
8
|
+
|
9
|
+
def user_activation(user)
|
10
|
+
@user = user
|
11
|
+
mail(:to => user.email, :subject => "Account Activation")
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateUsers < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :users do |t|
|
4
|
+
t.string :username
|
5
|
+
t.string :email
|
6
|
+
t.string :password_hash
|
7
|
+
t.string :password_salt
|
8
|
+
t.datetime :activated_at
|
9
|
+
t.string :token
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
drop_table :users
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
|
3
|
+
attr_accessible :username, :email, :password, :password_confirmation, :activated_at, :token
|
4
|
+
|
5
|
+
validates_presence_of :username, :email
|
6
|
+
validates_uniqueness_of :username, :email
|
7
|
+
validates_format_of :username, :with => /\A[-\w\._@]+\z/i, :message => "should only contain letters, numbers, or .-_@"
|
8
|
+
validates_format_of :email, :with => /\A[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}\z/i, :message => "not a valid email address"
|
9
|
+
validates_presence_of :password, :on => :create
|
10
|
+
validates_confirmation_of :password
|
11
|
+
validates_length_of :password, :minimum => 6
|
12
|
+
|
13
|
+
include UsersAuthentication
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class User
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::Timestamps
|
4
|
+
include UsersAuthentication
|
5
|
+
|
6
|
+
attr_accessible :username, :email, :password, :password_confirmation, :activated_at, :token
|
7
|
+
|
8
|
+
field :username, :type => String
|
9
|
+
field :email, :type => String
|
10
|
+
field :password_hash, :type => String
|
11
|
+
field :password_salt, :type => String
|
12
|
+
field :activated_at, :type => Time
|
13
|
+
field :token, :type => String
|
14
|
+
|
15
|
+
validates_presence_of :username, :email
|
16
|
+
validates_uniqueness_of :username, :email
|
17
|
+
validates_format_of :username, :with => /\A[-\w\._@]+\z/i, :message => "should only contain letters, numbers, or .-_@"
|
18
|
+
validates_format_of :email, :with => /\A[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}\z/i, :message => "not a valid email address"
|
19
|
+
validates_presence_of :password, :on => :create
|
20
|
+
validates_confirmation_of :password
|
21
|
+
validates_length_of :password, :minimum => 6
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ResetPasswordsController do
|
4
|
+
|
5
|
+
describe "GET new" do
|
6
|
+
it "should render the reset password page" do
|
7
|
+
get :new
|
8
|
+
response.should be_success
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "POST create" do
|
13
|
+
describe "with valid login" do
|
14
|
+
it "should send reset password instructions through mail" do
|
15
|
+
user = Factory(:user, :activated_at => Date.today)
|
16
|
+
User.stub(:first).with(:conditions => { :username => "some@email.com" }).and_return(user)
|
17
|
+
post :create, :login => "some@email.com"
|
18
|
+
assigns(:user).should be_a(User)
|
19
|
+
flash[:notice].should_not be_nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "with invalid login" do
|
24
|
+
it "should not send reset password instructions if user not found" do
|
25
|
+
User.stub(:first).with(:conditions => { :username => "some@email.com" }).and_return(nil)
|
26
|
+
post :create, :login => "some@email.com"
|
27
|
+
assigns(:user).should be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should not send reset password instructions if user not activated" do
|
31
|
+
user = Factory(:user)
|
32
|
+
User.stub(:first).with(:conditions => { :username => "some@email.com" }).and_return(user)
|
33
|
+
post :create, :login => "some@email.com"
|
34
|
+
assigns(:user).should be_a(User)
|
35
|
+
assigns(:user).activated_at.should be_nil
|
36
|
+
end
|
37
|
+
|
38
|
+
after(:each) do
|
39
|
+
flash[:alert].should_not be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
after(:each) do
|
44
|
+
response.should render_template(:new)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "GET edit" do
|
49
|
+
before(:each) do
|
50
|
+
@user = Factory(:user, :token => "sometoken")
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should assigns @user and render page if given parameters are valid" do
|
54
|
+
User.stub(:first).with(:conditions => { :id => @user.id.to_s, :token => @user.token.to_s }).and_return(@user)
|
55
|
+
get :edit, :id => @user.id.to_s, :token => @user.token.to_s
|
56
|
+
assigns(:user).should eql(@user)
|
57
|
+
response.should be_success
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should not render page and redirect to reset password page" do
|
61
|
+
User.stub(:first).with(:conditions => { :id => @user.id.to_s, :token => @user.token.to_s }).and_return(nil)
|
62
|
+
get :edit, :id => @user.id.to_s, :token => @user.token.to_s
|
63
|
+
assigns(:user).should be_nil
|
64
|
+
response.should redirect_to(new_reset_password_path)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "PUT update" do
|
69
|
+
describe "with valid params" do
|
70
|
+
it "should reset password" do
|
71
|
+
user = Factory(:user, :token => "sometoken")
|
72
|
+
User.stub(:first).with(:conditions => { :id => user.id.to_s, :token => user.token.to_s }).and_return(user)
|
73
|
+
User.any_instance.stub(:reset_password).with("secret","secret").and_return(UsersAuthentication::Status::Valid)
|
74
|
+
put :update, :id => user.id.to_s, :token => user.token.to_s, :password => "secret", :password_confirmation => "secret"
|
75
|
+
assigns(:user).should eql(user)
|
76
|
+
flash[:notice].should_not be_nil
|
77
|
+
response.should redirect_to(new_session_path)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "with invalid params" do
|
82
|
+
it "should not send reset password instructions if user not found" do
|
83
|
+
user = Factory(:user, :token => "sometoken")
|
84
|
+
User.stub(:first).with(:conditions => { :id => user.id.to_s, :token => user.token.to_s }).and_return(nil)
|
85
|
+
put :update, :id => user.id.to_s, :token => user.token.to_s
|
86
|
+
assigns(:user).should be_nil
|
87
|
+
flash[:alert].should_not be_nil
|
88
|
+
response.should render_template(:edit)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|