authentasaurus 0.4.1

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 (116) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +173 -0
  3. data/TODO +4 -0
  4. data/app/controllers/areas_controller.rb +4 -0
  5. data/app/controllers/groups_controller.rb +4 -0
  6. data/app/controllers/permissions_controller.rb +4 -0
  7. data/app/controllers/recoveries_controller.rb +2 -0
  8. data/app/controllers/registrations_controller.rb +2 -0
  9. data/app/controllers/sessions_controller.rb +2 -0
  10. data/app/controllers/user_invitations_controller.rb +4 -0
  11. data/app/controllers/users_controller.rb +4 -0
  12. data/app/controllers/validations_controller.rb +2 -0
  13. data/app/models/area.rb +2 -0
  14. data/app/models/authentasaurus_emailer.rb +2 -0
  15. data/app/models/group.rb +2 -0
  16. data/app/models/permission.rb +2 -0
  17. data/app/models/recovery.rb +2 -0
  18. data/app/models/session.rb +2 -0
  19. data/app/models/user.rb +3 -0
  20. data/app/models/user_invitation.rb +2 -0
  21. data/app/models/user_sync.rb +3 -0
  22. data/app/models/validation.rb +2 -0
  23. data/app/views/areas/edit.html.erb +7 -0
  24. data/app/views/areas/index.html.erb +11 -0
  25. data/app/views/areas/new.html.erb +7 -0
  26. data/app/views/areas/show.html.erb +7 -0
  27. data/app/views/authentasaurus_emailer/invitation_mail.html.erb +4 -0
  28. data/app/views/authentasaurus_emailer/recovery_mail.html.erb +7 -0
  29. data/app/views/authentasaurus_emailer/validation_mail.html.erb +6 -0
  30. data/app/views/groups/edit.html.erb +7 -0
  31. data/app/views/groups/index.html.erb +11 -0
  32. data/app/views/groups/new.html.erb +7 -0
  33. data/app/views/groups/show.html.erb +7 -0
  34. data/app/views/permissions/edit.html.erb +19 -0
  35. data/app/views/permissions/index.html.erb +17 -0
  36. data/app/views/permissions/new.html.erb +19 -0
  37. data/app/views/permissions/show.html.erb +7 -0
  38. data/app/views/recoveries/edit.html.erb +24 -0
  39. data/app/views/recoveries/new.html.erb +15 -0
  40. data/app/views/registrations/new.html.erb +21 -0
  41. data/app/views/sessions/new.html.erb +41 -0
  42. data/app/views/sessions/no_access.html.erb +1 -0
  43. data/app/views/user_invitations/index.html.erb +14 -0
  44. data/app/views/user_invitations/new.html.erb +9 -0
  45. data/app/views/users/edit.html.erb +27 -0
  46. data/app/views/users/index.html.erb +19 -0
  47. data/app/views/users/new.html.erb +27 -0
  48. data/app/views/users/show.html.erb +11 -0
  49. data/app/views/validations/activate.html.erb +6 -0
  50. data/app/views/validations/resend_validation_email.html.erb +6 -0
  51. data/config/locales/en.yml +34 -0
  52. data/generators/authentasaurus/USAGE +2 -0
  53. data/generators/authentasaurus/authentasaurus_generator.rb +9 -0
  54. data/generators/authentasaurus/templates/authentasaurus_tasks.rake +48 -0
  55. data/generators/authentasaurus/templates/defaults.yml +51 -0
  56. data/generators/authentasaurus/templates/initializer.rb +3 -0
  57. data/generators/authentasaurus_views/USAGE +12 -0
  58. data/generators/authentasaurus_views/authentasaurus_views_generator.rb +87 -0
  59. data/generators/authentasaurus_views/templates/views/areas/edit.html.erb +7 -0
  60. data/generators/authentasaurus_views/templates/views/areas/index.html.erb +11 -0
  61. data/generators/authentasaurus_views/templates/views/areas/new.html.erb +7 -0
  62. data/generators/authentasaurus_views/templates/views/areas/show.html.erb +7 -0
  63. data/generators/authentasaurus_views/templates/views/authentasaurus_emailer/invitation_mail.html.erb +4 -0
  64. data/generators/authentasaurus_views/templates/views/authentasaurus_emailer/recovery_mail.html.erb +7 -0
  65. data/generators/authentasaurus_views/templates/views/authentasaurus_emailer/validation_mail.html.erb +6 -0
  66. data/generators/authentasaurus_views/templates/views/groups/edit.html.erb +7 -0
  67. data/generators/authentasaurus_views/templates/views/groups/index.html.erb +11 -0
  68. data/generators/authentasaurus_views/templates/views/groups/new.html.erb +7 -0
  69. data/generators/authentasaurus_views/templates/views/groups/show.html.erb +7 -0
  70. data/generators/authentasaurus_views/templates/views/permissions/edit.html.erb +19 -0
  71. data/generators/authentasaurus_views/templates/views/permissions/index.html.erb +17 -0
  72. data/generators/authentasaurus_views/templates/views/permissions/new.html.erb +19 -0
  73. data/generators/authentasaurus_views/templates/views/permissions/show.html.erb +7 -0
  74. data/generators/authentasaurus_views/templates/views/recoveries/edit.html.erb +24 -0
  75. data/generators/authentasaurus_views/templates/views/recoveries/new.html.erb +15 -0
  76. data/generators/authentasaurus_views/templates/views/registrations/new.html.erb +21 -0
  77. data/generators/authentasaurus_views/templates/views/sessions/new.html.erb +41 -0
  78. data/generators/authentasaurus_views/templates/views/sessions/no_access.html.erb +1 -0
  79. data/generators/authentasaurus_views/templates/views/user_invitations/index.html.erb +14 -0
  80. data/generators/authentasaurus_views/templates/views/user_invitations/new.html.erb +9 -0
  81. data/generators/authentasaurus_views/templates/views/users/edit.html.erb +27 -0
  82. data/generators/authentasaurus_views/templates/views/users/index.html.erb +19 -0
  83. data/generators/authentasaurus_views/templates/views/users/new.html.erb +27 -0
  84. data/generators/authentasaurus_views/templates/views/users/show.html.erb +11 -0
  85. data/generators/authentasaurus_views/templates/views/validations/activate.html.erb +6 -0
  86. data/generators/authentasaurus_views/templates/views/validations/resend_validation_email.html.erb +6 -0
  87. data/lib/action_controller/authorization.rb +215 -0
  88. data/lib/action_view/authorization.rb +123 -0
  89. data/lib/active_record/acts_as_authenticatable.rb +80 -0
  90. data/lib/active_record/acts_as_authenticatable_validatable.rb +32 -0
  91. data/lib/active_record/authenticatable.rb +56 -0
  92. data/lib/active_resource/acts_as_authenticatable.rb +42 -0
  93. data/lib/active_resource/authenticatable.rb +22 -0
  94. data/lib/authentasaurus.rb +21 -0
  95. data/lib/authentasaurus/areas_controller.rb +71 -0
  96. data/lib/authentasaurus/authentasaurus_controller.rb +2 -0
  97. data/lib/authentasaurus/groups_controller.rb +73 -0
  98. data/lib/authentasaurus/models/area.rb +8 -0
  99. data/lib/authentasaurus/models/authentasaurus_emailer.rb +31 -0
  100. data/lib/authentasaurus/models/group.rb +8 -0
  101. data/lib/authentasaurus/models/permission.rb +9 -0
  102. data/lib/authentasaurus/models/recovery.rb +23 -0
  103. data/lib/authentasaurus/models/session.rb +63 -0
  104. data/lib/authentasaurus/models/user_invitation.rb +21 -0
  105. data/lib/authentasaurus/models/validation.rb +18 -0
  106. data/lib/authentasaurus/permissions_controller.rb +71 -0
  107. data/lib/authentasaurus/recoveries_controller.rb +59 -0
  108. data/lib/authentasaurus/registrations_controller.rb +32 -0
  109. data/lib/authentasaurus/sessions_controller.rb +45 -0
  110. data/lib/authentasaurus/user_invitations_controller.rb +39 -0
  111. data/lib/authentasaurus/users_controller.rb +71 -0
  112. data/lib/authentasaurus/validations_controller.rb +34 -0
  113. data/lib/helpers/migrations.rb +171 -0
  114. data/lib/helpers/routing.rb +90 -0
  115. data/rails/init.rb +37 -0
  116. metadata +188 -0
@@ -0,0 +1,123 @@
1
+ # Defines authorization helpers for ActionController
2
+ module ActionView::Authorization
3
+
4
+ def self.included(base) # :nodoc:
5
+ base.send :include, InstanceMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ private
10
+ # Returns an object of the current user
11
+ def current_user(user_model = nil)
12
+ user_model = User if user_model.nil?
13
+ return user_model.find session[:user_id] if session[:user_id]
14
+ end
15
+
16
+ # Checks if the current user is logged in and redirects to the login path if the user is not logged in.
17
+ #
18
+ # If skip_request is set to true, the user won't be redirected to the original url after he/she logs in.
19
+ def check_logged_in(skip_request = false, user_model = nil)
20
+ unless is_logged_in?(user_model)
21
+ login_required skip_request
22
+ end
23
+ end
24
+
25
+ # Checks if the current user is logged in and has write permission over the current controller, redirects to no access
26
+ # page if the user hasn't the permissions and redirects to the login path if the user is not logged in
27
+ #
28
+ # If skip_request is set to true, the user won't be redirected to the original url after he/she logs in.
29
+ def check_write_permissions(skip_request = false, user_model = nil)
30
+ if is_logged_in?(user_model)
31
+ user_permissions = session[:user_permissions]
32
+ check = user_permissions[:write].find { |perm| perm==self.controller_name || perm=="all" }
33
+ unless check
34
+ redirect_to no_access_sessions_path
35
+ end
36
+ else
37
+ login_required skip_request
38
+ end
39
+ end
40
+
41
+ # Checks if the current user is logged in and has read permission over the current controller, redirects to no access
42
+ # page if the user hasn't the permissions and redirects to the login path if the user is not logged in
43
+ #
44
+ # If skip_request is set to true, the user won't be redirected to the original url after he/she logs in.
45
+ def check_read_permissions(skip_request = false, user_model = nil)
46
+ if is_logged_in?(user_model)
47
+ user_permissions = session[:user_permissions]
48
+ check = user_permissions[:read].find { |perm| perm==self.controller_name || perm=="all" }
49
+ unless check
50
+ redirect_to no_access_sessions_path
51
+ end
52
+ else
53
+ login_required skip_request
54
+ end
55
+ end
56
+
57
+ # Checks if the current user is logged in but takes no further action
58
+ def is_logged_in?(user_model)
59
+ user_model = User if user_model.nil?
60
+ unless user_model.find_by_id(session[:user_id])
61
+ return cookie_login?(user_model)
62
+ end
63
+ return true
64
+ end
65
+
66
+ # Logs in the user through a remember me cookie
67
+ def cookie_login?(user_model)
68
+ user_model = User if user_model.nil?
69
+
70
+ if cookies[:remember_me_token]
71
+ user = user_model.find_by_remember_me_token cookies[:remember_me_token]
72
+ if user.nil?
73
+ cookies.delete :remember_me_token
74
+ return false
75
+ else
76
+ session[:user_id] = user.id
77
+ session[:user_permissions] = {:read => user.permissions.collect{|per| per.area.name if per.read}, :write => user.permissions.collect{|per| per.area.name if per.write}}
78
+ return true
79
+ end
80
+ else
81
+ return false
82
+ end
83
+ end
84
+
85
+ # Redirects the user to the login page
86
+ #
87
+ # If skip_request is set to true, the user won't be redirected to the original url after he/she logs in.
88
+ def login_required(skip_request)
89
+ unless(skip_request)
90
+ session[:original_url]=request.url
91
+ end
92
+ flash[:notice] = t(:login_required, :scope => [:authentasaurus, :action_controller, :errors, :messages])
93
+ redirect_to new_session_path
94
+ end
95
+
96
+ # Checks if the current user has the appropriate permission
97
+ #
98
+ # *ex*: has?(:write) or has?(:read, :users)
99
+ def has?(permission, area = nil, user_model = User)
100
+ return false unless is_logged_in? user_model
101
+ check = false
102
+ case permission
103
+ when :write
104
+ unless area
105
+ user_permissions = session[:user_permissions]
106
+ check = user_permissions[:write].find { |perm| perm==self.controller_name || perm=="all" }
107
+ else
108
+ user_permissions = session[:user_permissions]
109
+ check = user_permissions[:write].find { |perm| perm==area.to_s || perm=="all" }
110
+ end
111
+ when :read
112
+ unless area
113
+ user_permissions = session[:user_permissions]
114
+ check = user_permissions[:read].find { |perm| perm==self.controller_name || perm=="all" }
115
+ else
116
+ user_permissions = session[:user_permissions]
117
+ check = user_permissions[:read].find { |perm| perm==area.to_s || perm=="all" }
118
+ end
119
+ end
120
+ return check
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,80 @@
1
+ module ActiveRecord::ActsAsAuthenticatable
2
+ def self.included(base)
3
+ base.send :extend, ClassMethods
4
+ base.send :include, InstanceMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ require 'digest/sha1'
9
+ ## Authenticates the username and password
10
+ def authenticate(username, password)
11
+ user=self.find_by_username username
12
+ if user
13
+ expected_password=encrypt_password(password, user.password_seed)
14
+ user = nil unless expected_password == user.hashed_password && user.active
15
+ end
16
+ return user
17
+ end
18
+
19
+ ## Encrypts the password using the given seed
20
+ def encrypt_password(password, password_seed)
21
+ pass_to_hash=password + "Securasaurus" + password_seed
22
+ Digest::SHA1.hexdigest(pass_to_hash)
23
+ end
24
+ end
25
+
26
+ module InstanceMethods
27
+ ## Password attribute (used when creating a user)
28
+ def password
29
+ return @password
30
+ end
31
+
32
+ def password=(pwd)
33
+ @password = pwd
34
+ return if pwd.blank?
35
+ create_salt
36
+ self.hashed_password = self.class.encrypt_password(@password, self.password_seed)
37
+ end
38
+
39
+ ## New password attribute (used when editing a user)
40
+ def new_password
41
+ return @new_password
42
+ end
43
+
44
+ def new_password=(pwd)
45
+ @new_password = pwd
46
+ return if pwd.blank?
47
+ create_salt
48
+ self.hashed_password = self.class.encrypt_password(@new_password, self.password_seed)
49
+ end
50
+
51
+ def activate
52
+ self.update_attribute :active, true
53
+ end
54
+
55
+ def deactivate
56
+ self.update_attribute :active, false
57
+ end
58
+
59
+ def create_remember_me_token
60
+ pass_to_hash=Time.now.to_i.to_s + "Securasaurus" + password_seed
61
+ self.update_attribute :remember_me_token, Digest::SHA1.hexdigest(pass_to_hash)
62
+ self.remember_me_token
63
+ end
64
+
65
+ private
66
+ def new_password_blank?
67
+ self.new_password.blank?
68
+ end
69
+
70
+ ## Creates password seed (salt)
71
+ def create_salt
72
+ self.password_seed = self.object_id.to_s + rand.to_s
73
+ end
74
+
75
+ ## Dont delete the last user
76
+ def dont_delete_admin
77
+ raise "You cannot delete the last admin" if self.id == 1 || User.count == 1
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,32 @@
1
+ module ActiveRecord::ActsAsAuthenticatableValidatable
2
+ def self.included(base)
3
+ base.send :extend, ActiveRecord::ActsAsAuthenticatable::ClassMethods
4
+ base.send :include, ActiveRecord::ActsAsAuthenticatable::InstanceMethods
5
+ base.send :extend, ClassMethods
6
+ base.send :include, InstanceMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ ## Authenticates the username and password
11
+ def authenticate(username, password)
12
+ user=self.find_by_username username
13
+ if user
14
+ expected_password=encrypt_password(password, user.password_seed)
15
+ user = nil unless expected_password == user.hashed_password && user.active && user.validation.nil?
16
+ end
17
+ return user
18
+ end
19
+ end
20
+
21
+ module InstanceMethods
22
+ private
23
+ def create_validation
24
+ unless self.active
25
+ validation = Validation.new(:user => self, :email => self.email, :validation_code => User.encrypt_password(self.username,self.password_seed))
26
+ unless validation.save
27
+ raise "Could not create validation record"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,56 @@
1
+ module ActiveRecord::Authenticatable
2
+ def self.included(base)
3
+ base.send :extend, ClassMethods
4
+ end
5
+
6
+ module ClassMethods
7
+ def authenticatable(*args)
8
+ options = args.extract_options!
9
+ args = args.flatten
10
+ # Associations
11
+ belongs_to :group
12
+ has_many :permissions, :through => :group
13
+ # Validation
14
+ # basic attributes
15
+ validates_presence_of :username, :hashed_password, :password_seed, :email, :name
16
+ validates_uniqueness_of :username, :email
17
+ validates_format_of :email, :with => %r{[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}}
18
+ # password validations
19
+ validates_confirmation_of :password, :on => :create
20
+ validates_presence_of :password, :on => :create
21
+ validates_length_of :password, :minimum => 6, :on => :create
22
+ # new password
23
+ validates_confirmation_of :new_password, :on => :update, :unless => :new_password_blank?
24
+ validates_length_of :new_password, :minimum => 6, :on => :update, :unless => :new_password_blank?
25
+ # format of password
26
+ if args.include?(:strong_password)
27
+ validates_format_of :password, :with => %r{[a-z]}, :on => :create, :message => :"authenticatable.lower_case_password"
28
+ validates_format_of :password, :with => %r{[A-Z]}, :on => :create, :message => :"authenticatable.upper_case_password"
29
+ validates_format_of :password, :with => %r{[0-9]}, :on => :create, :message => :"authenticatable.digit_password"
30
+ validates_format_of :password, :with => %r{[@$%!&]}, :on => :create, :message => :"authenticatable.symbol_password"
31
+ # new password
32
+ validates_format_of :new_password, :with => %r{[a-z]}, :on => :update, :message => :"authenticatable.lower_case_password", :unless => :new_password_blank?
33
+ validates_format_of :new_password, :with => %r{[A-Z]}, :on => :update, :message => :"authenticatable.upper_case_password", :unless => :new_password_blank?
34
+ validates_format_of :new_password, :with => %r{[0-9]}, :on => :update, :message => :"authenticatable.digit_password", :unless => :new_password_blank?
35
+ validates_format_of :new_password, :with => %r{[@$%!&]}, :on => :update, :message => :"authenticatable.symbol_password", :unless => :new_password_blank?
36
+ end
37
+
38
+ # Accessors
39
+ attr_accessor :password_confirmation, :new_password_confirmation
40
+
41
+ # dont delete admin
42
+ before_destroy :dont_delete_admin
43
+
44
+ #validation
45
+ if args.include?(:validatable)
46
+ has_one :validation, :as => :user
47
+ before_create :create_validation
48
+ # include authentication methods including validation
49
+ include ActiveRecord::ActsAsAuthenticatableValidatable
50
+ else
51
+ # include authentication methods
52
+ include ActiveRecord::ActsAsAuthenticatable
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,42 @@
1
+ module ActiveResource::ActsAsAuthenticatable
2
+ def self.included(base)
3
+ base.send :extend, ClassMethods
4
+ base.send :include, InstanceMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ ## Authenticates the username and password
9
+ def authenticate(username, password)
10
+
11
+ if self.sync_to
12
+ user = self.new Hash.from_xml(self.post(:signin,:username => username, :password => password).body).values.first
13
+ end
14
+
15
+ unless user.nil?
16
+ if self.sync && !self.sync_to.nil?
17
+ last_update = user.attributes.delete "updated_at"
18
+ local_user = self.sync_to.find_or_initialize_by_username user.username, user.attributes
19
+
20
+ if local_user.updated_at < last_update
21
+ local_user.update_attributes user.attributes
22
+ end
23
+ end
24
+ end
25
+ return user
26
+ end
27
+ end
28
+
29
+ module InstanceMethods
30
+ def sync
31
+ if self.class.sync && !self.class.sync_to.nil?
32
+ user = self.dup
33
+ last_update = user.attributes.delete "updated_at"
34
+ local_user = self.class.sync_to.find_or_initialize_by_username user.username, user.attributes
35
+
36
+ local_user.update_attributes user.attributes
37
+ else
38
+ false
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,22 @@
1
+ require 'active_resource/acts_as_authenticatable'
2
+ module ActiveResource::Authenticatable
3
+ def self.included(base)
4
+ base.send :extend, ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+
9
+ def authenticatable(*args)
10
+ options = args.extract_options!
11
+
12
+ self.site = options[:site] || AUTHENTASAURUS[:modules][:remote][self.name.underscore.gsub(/_sync/, "").to_sym][:site]
13
+ self.element_name = options[:session_element].try(:to_s) || AUTHENTASAURUS[:modules][:remote][self.name.underscore.gsub(/_sync/, "").to_sym][:session_element]
14
+ self.sync = options[:sync] || AUTHENTASAURUS[:modules][:remote][self.name.underscore.gsub(/_sync/, "").to_sym][:sync]
15
+ self.sync_to = options[:sync_to].try(:to_s).try(:camelize).try(:constantize) #|| AUTHENTASAURUS[:modules][:remote][self.name.underscore.gsub(/_sync/, "").to_sym][:sync_to].camelize.constantize
16
+
17
+
18
+ # include authentication methods
19
+ include ActiveResource::ActsAsAuthenticatable
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module Authentasaurus
2
+ def self.evaluate_method(method, *args, &block)
3
+ case method
4
+ when Symbol
5
+ object = args.shift
6
+ object.send(method, *args, &block)
7
+ when String
8
+ eval(method, args.first.instance_eval { binding })
9
+ when Proc, Method
10
+ method.call(*args, &block)
11
+ else
12
+ if method == true || method == false
13
+ return method
14
+ else
15
+ raise ArgumentError,
16
+ "Callbacks must be a symbol denoting the method to call, a string to be evaluated, " +
17
+ "a block to be invoked, or a condition."
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,71 @@
1
+ class Authentasaurus::AreasController < Authentasaurus::AuthentasaurusController
2
+
3
+ def index
4
+ @areas= Area.find :all
5
+
6
+ respond_to do |format|
7
+ format.html
8
+ end
9
+ end
10
+
11
+ def show
12
+ @area = Area.find params[:id]
13
+
14
+ respond_to do |format|
15
+ format.html
16
+ end
17
+ end
18
+
19
+ def new
20
+ @area = Area.new
21
+
22
+ respond_to do |format|
23
+ format.html
24
+ end
25
+ end
26
+
27
+ def create
28
+ @area = Area.new params[:area]
29
+
30
+ respond_to do |format|
31
+ if @area.save
32
+ flash.now[:notice] = "Area created"
33
+ format.html { redirect_to :action=>:index }
34
+ else
35
+ flash.now[:notice] = "Error creating area"
36
+ format.html { render :new }
37
+ end
38
+ end
39
+ end
40
+
41
+ def edit
42
+ @area = Area.find params[:id]
43
+
44
+ respond_to do |format|
45
+ format.html
46
+ end
47
+ end
48
+
49
+ def update
50
+ @area = Area.find params[:id]
51
+
52
+ respond_to do |format|
53
+ if @area.update_attributes(params[:area])
54
+ flash.now[:notice] = "Area updated"
55
+ format.html { redirect_to @area }
56
+ else
57
+ flash.now[:notice] = "Error updating area"
58
+ format.html { render :edit }
59
+ end
60
+ end
61
+ end
62
+
63
+ def destroy
64
+ @area = Area.find params[:id]
65
+ @area.destroy
66
+
67
+ respond_to do |format|
68
+ format.html { redirect_to :action=>:index }
69
+ end
70
+ end
71
+ end