casein 3.1.0

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 (76) hide show
  1. data/Gemfile +1 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +215 -0
  4. data/Rakefile +40 -0
  5. data/app/controllers/casein/casein_controller.rb +72 -0
  6. data/app/controllers/casein/password_resets_controller.rb +66 -0
  7. data/app/controllers/casein/user_sessions_controller.rb +40 -0
  8. data/app/controllers/casein/users_controller.rb +102 -0
  9. data/app/helpers/casein/casein_helper.rb +170 -0
  10. data/app/mailers/casein/casein_notification.rb +44 -0
  11. data/app/models/casein/user.rb +55 -0
  12. data/app/models/casein/user_session.rb +8 -0
  13. data/app/views/casein/casein/blank.html.erb +1 -0
  14. data/app/views/casein/casein_notification/generate_new_password.erb +12 -0
  15. data/app/views/casein/casein_notification/new_user_information.erb +12 -0
  16. data/app/views/casein/casein_notification/password_reset_instructions.erb +11 -0
  17. data/app/views/casein/password_resets/edit.html.erb +48 -0
  18. data/app/views/casein/user_sessions/new.html.erb +66 -0
  19. data/app/views/casein/users/index.html.erb +35 -0
  20. data/app/views/casein/users/new.html.erb +46 -0
  21. data/app/views/casein/users/show.html.erb +94 -0
  22. data/app/views/layouts/casein_auth.html.erb +24 -0
  23. data/app/views/layouts/casein_main.html.erb +61 -0
  24. data/config/routes.rb +19 -0
  25. data/lib/casein.rb +3 -0
  26. data/lib/casein/engine.rb +12 -0
  27. data/lib/generators/casein/install/USAGE +1 -0
  28. data/lib/generators/casein/install/install_generator.rb +37 -0
  29. data/lib/generators/casein/install/templates/app/helpers/casein/config_helper.rb +46 -0
  30. data/lib/generators/casein/install/templates/app/views/casein/layouts/_left_navigation.html.erb +2 -0
  31. data/lib/generators/casein/install/templates/app/views/casein/layouts/_right_navigation.html.erb +1 -0
  32. data/lib/generators/casein/install/templates/db/migrate/casein_create_users.rb +30 -0
  33. data/lib/generators/casein/install/templates/public/casein/javascripts/custom.js +3 -0
  34. data/lib/generators/casein/install/templates/public/casein/stylesheets/custom.css +3 -0
  35. data/lib/generators/casein/install/templates/public/robots.txt +5 -0
  36. data/lib/generators/casein/scaffold/USAGE +1 -0
  37. data/lib/generators/casein/scaffold/scaffold_generator.rb +97 -0
  38. data/lib/generators/casein/scaffold/templates/controller.rb +60 -0
  39. data/lib/generators/casein/scaffold/templates/migration.rb +13 -0
  40. data/lib/generators/casein/scaffold/templates/model.rb +3 -0
  41. data/lib/generators/casein/scaffold/templates/views/_form.html.erb +9 -0
  42. data/lib/generators/casein/scaffold/templates/views/_table.html.erb +17 -0
  43. data/lib/generators/casein/scaffold/templates/views/index.html.erb +11 -0
  44. data/lib/generators/casein/scaffold/templates/views/new.html.erb +18 -0
  45. data/lib/generators/casein/scaffold/templates/views/show.html.erb +18 -0
  46. data/lib/generators/casein/update/USAGE +1 -0
  47. data/lib/generators/casein/update/templates/public/casein/images/casein.png +0 -0
  48. data/lib/generators/casein/update/templates/public/casein/images/header.png +0 -0
  49. data/lib/generators/casein/update/templates/public/casein/images/icons/add.png +0 -0
  50. data/lib/generators/casein/update/templates/public/casein/images/icons/delete.png +0 -0
  51. data/lib/generators/casein/update/templates/public/casein/images/icons/table.png +0 -0
  52. data/lib/generators/casein/update/templates/public/casein/images/login/alertBg.png +0 -0
  53. data/lib/generators/casein/update/templates/public/casein/images/login/background.png +0 -0
  54. data/lib/generators/casein/update/templates/public/casein/images/login/bottom.png +0 -0
  55. data/lib/generators/casein/update/templates/public/casein/images/login/loginBoxBg.png +0 -0
  56. data/lib/generators/casein/update/templates/public/casein/images/login/loginBoxBottom.png +0 -0
  57. data/lib/generators/casein/update/templates/public/casein/images/login/loginBoxTop.png +0 -0
  58. data/lib/generators/casein/update/templates/public/casein/images/login/loginSubmit.png +0 -0
  59. data/lib/generators/casein/update/templates/public/casein/images/login/recoverSubmit.png +0 -0
  60. data/lib/generators/casein/update/templates/public/casein/images/login/top.png +0 -0
  61. data/lib/generators/casein/update/templates/public/casein/images/nav.png +0 -0
  62. data/lib/generators/casein/update/templates/public/casein/images/rightNav.png +0 -0
  63. data/lib/generators/casein/update/templates/public/casein/images/rightNavButton.png +0 -0
  64. data/lib/generators/casein/update/templates/public/casein/images/visitSiteNav.png +0 -0
  65. data/lib/generators/casein/update/templates/public/casein/javascripts/casein.js +25 -0
  66. data/lib/generators/casein/update/templates/public/casein/javascripts/jquery.js +154 -0
  67. data/lib/generators/casein/update/templates/public/casein/javascripts/login.js +24 -0
  68. data/lib/generators/casein/update/templates/public/casein/javascripts/rails.js +132 -0
  69. data/lib/generators/casein/update/templates/public/casein/stylesheets/elements.css +307 -0
  70. data/lib/generators/casein/update/templates/public/casein/stylesheets/login.css +133 -0
  71. data/lib/generators/casein/update/templates/public/casein/stylesheets/screen.css +206 -0
  72. data/lib/generators/casein/update/update_generator.rb +40 -0
  73. data/lib/railties/tasks.rake +31 -0
  74. data/test/casein3_test.rb +8 -0
  75. data/test/test_helper.rb +3 -0
  76. metadata +174 -0
@@ -0,0 +1,102 @@
1
+ module Casein
2
+ class UsersController < Casein::CaseinController
3
+
4
+ unloadable
5
+
6
+ before_filter :needs_admin, :except => [:show, :destroy, :update, :update_password]
7
+ before_filter :needs_admin_or_current_user, :only => [:show, :destroy, :update, :update_password]
8
+
9
+ def index
10
+ @casein_page_title = "Users"
11
+ @users = Casein::User.paginate :order => "login", :page => params[:page]
12
+ end
13
+
14
+ def new
15
+ @casein_page_title = "Add a new user"
16
+ @casein_user = Casein::User.new
17
+ @casein_user.time_zone = Rails::Application.config.time_zone
18
+ end
19
+
20
+ def create
21
+ @casein_user = Casein::User.new params[:casein_user]
22
+
23
+ if @casein_user.save
24
+ flash[:notice] = "An email has been sent to " + @casein_user.name + " with the new account details"
25
+ redirect_to casein_users_path
26
+ else
27
+ flash.now[:warning] = "There were problems when trying to create a new user"
28
+ render :action => :new
29
+ end
30
+ end
31
+
32
+ def show
33
+ @casein_user = Casein::User.find params[:id]
34
+ @casein_page_title = @casein_user.name + " | View User"
35
+ end
36
+
37
+ def update
38
+ @casein_user = Casein::User.find params[:id]
39
+ @casein_page_title = @casein_user.name + " | Update User"
40
+
41
+ if @casein_user.update_attributes params[:casein_user]
42
+ flash[:notice] = @casein_user.name + " has been updated"
43
+ else
44
+ flash.now[:warning] = "There were problems when trying to update this user"
45
+ render :action => :show
46
+ return
47
+ end
48
+
49
+ if @session_user.is_admin?
50
+ redirect_to casein_users_path
51
+ else
52
+ redirect_to :controller => :casein, :action => :index
53
+ end
54
+ end
55
+
56
+ def update_password
57
+ @casein_user = Casein::User.find params[:id]
58
+ @casein_page_title = @casein_user.name + " | Update Password"
59
+
60
+ if @casein_user.valid_password? params[:form_current_password]
61
+ if @casein_user.update_attributes params[:casein_user]
62
+ flash.now[:notice] = "Your password has been changed"
63
+ else
64
+ flash.now[:warning] = "There were problems when trying to change the password"
65
+ end
66
+ else
67
+ flash.now[:warning] = "The current password is incorrect"
68
+ end
69
+
70
+ render :action => :show
71
+ end
72
+
73
+ def reset_password
74
+ @casein_user = Casein::User.find params[:id]
75
+ @casein_page_title = @casein_user.name + " | Reset Password"
76
+
77
+ @casein_user.notify_of_new_password = true unless @casein_user.id == @session_user.id
78
+
79
+ if @casein_user.update_attributes params[:casein_user]
80
+ if @casein_user.id == @session_user.id
81
+ flash.now[:notice] = "Your password has been reset"
82
+ else
83
+ flash.now[:notice] = "Password has been reset and " + @casein_user.name + " has been notified by email"
84
+ end
85
+
86
+ else
87
+ flash.now[:warning] = "There were problems when trying to reset this user's password"
88
+ end
89
+ render :action => :show
90
+ end
91
+
92
+ def destroy
93
+ user = Casein::User.find params[:id]
94
+ if user.is_admin? == false || Casein::User.has_more_than_one_admin
95
+ user.destroy
96
+ flash[:notice] = user.name + " has been deleted"
97
+ end
98
+ redirect_to casein_users_path
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,170 @@
1
+ module Casein
2
+ module CaseinHelper
3
+
4
+ def casein_get_version_info
5
+ YAML::load_file File.join(File.dirname(__FILE__), '..', '..', '..', 'VERSION.yml')
6
+ end
7
+
8
+ def casein_get_full_version_string
9
+ version_info = casein_get_version_info
10
+ "v.#{version_info['major']}.#{version_info['minor']}.#{version_info['patch']}"
11
+ end
12
+
13
+ def casein_get_short_version_string
14
+ version_info = casein_get_version_info
15
+ "v.#{version_info['major']}"
16
+ end
17
+
18
+ def casein_generate_page_title
19
+
20
+ if @casein_page_title.nil?
21
+ return casein_config_website_name
22
+ end
23
+
24
+ @casein_page_title + " > " + casein_config_website_name
25
+ end
26
+
27
+ def casein_get_access_level_text level
28
+ case level
29
+ when $CASEIN_USER_ACCESS_LEVEL_ADMIN
30
+ return "Administrator"
31
+ when $CASEIN_USER_ACCESS_LEVEL_USER
32
+ return "User"
33
+ else
34
+ return "Unknown"
35
+ end
36
+ end
37
+
38
+ def casein_get_access_level_array
39
+ [["Administrator", $CASEIN_USER_ACCESS_LEVEL_ADMIN], ["User", $CASEIN_USER_ACCESS_LEVEL_USER]]
40
+ end
41
+
42
+ def casein_table_cell_link contents, link, options = {}
43
+
44
+ if options.key? :casein_truncate
45
+ contents = truncate(contents, :length => options[:casein_truncate], :omission => "...")
46
+ end
47
+
48
+ link_to "#{contents}", link
49
+ end
50
+
51
+ def casein_show_icon icon_name
52
+ "<div class='icon'><img src='/casein/images/icons/#{icon_name}.png' alt='' /></div>".html_safe
53
+ end
54
+
55
+ def casein_show_row_icon icon_name
56
+ "<div class='iconRow'><img src='/casein/images/icons/#{icon_name}.png' alt='' /></div>".html_safe
57
+ end
58
+
59
+ # Styled form tag helpers
60
+
61
+ def casein_text_field form, obj, attribute, options = {}
62
+ casein_form_tag_wrapper(form.text_field(attribute, options.merge({:class => 'caseinTextField'})), form, obj, attribute, options).html_safe
63
+ end
64
+
65
+ def casein_password_field form, obj, attribute, options = {}
66
+ casein_form_tag_wrapper(form.password_field(attribute, options.merge({:class => 'caseinTextField'})), form, obj, attribute, options).html_safe
67
+ end
68
+
69
+ def casein_text_area form, obj, attribute, options = {}
70
+ casein_form_tag_wrapper(form.text_area(attribute, options.merge({:class => 'caseinTextArea'})), form, obj, attribute, options).html_safe
71
+ end
72
+
73
+ def casein_text_area_big form, obj, attribute, options = {}
74
+ casein_form_tag_wrapper(form.text_area(attribute, options.merge({:class => 'caseinTextAreaBig'})), form, obj, attribute, options).html_safe
75
+ end
76
+
77
+ def casein_check_box form, obj, attribute, options = {}
78
+ form_tag = form.check_box(attribute, options)
79
+
80
+ if options.key? :casein_box_label
81
+ form_tag = "<div>" + form_tag + "<span class=\"rcText\">#{options[:casein_box_label]}</span></div>".html_safe
82
+ end
83
+
84
+ casein_form_tag_wrapper(form_tag, form, obj, attribute, options).html_safe
85
+ end
86
+
87
+ def casein_check_box_group form, obj, check_boxes = {}
88
+ form_tags = ""
89
+
90
+ for check_box in check_boxes
91
+ form_tags += casein_check_box form, obj, check_box[0], check_box[1]
92
+ end
93
+
94
+ casein_form_tag_wrapper form_tag, form, obj, attribute, options
95
+ end
96
+
97
+ def casein_radio_button form, obj, attribute, tag_value, options = {}
98
+ form_tag = form.radio_button(obj, attribute, tag_value, options)
99
+
100
+ if options.key? :casein_button_label
101
+ form_tag = "<div>" + form_tag + "<span class=\"rcText\">#{options[:casein_button_label]}</span></div>".html_safe
102
+ end
103
+
104
+ casein_form_tag_wrapper(form_tag, form, obj, attribute, options).html_safe
105
+ end
106
+
107
+ def casein_radio_button_group form, obj, radio_buttons = {}
108
+ form_tags = ""
109
+
110
+ for radio_button in radio_buttons
111
+ form_tags += casein_radio_button form, obj, check_box[0], check_box[1], check_box[2]
112
+ end
113
+
114
+ casein_form_tag_wrapper(form_tag, form, obj, attribute, options).html_safe
115
+ end
116
+
117
+ def casein_select form, obj, attribute, option_tags, options = {}
118
+ casein_form_tag_wrapper(form.select(attribute, option_tags, options, {:class => 'caseinSelect'}), form, obj, attribute, options).html_safe
119
+ end
120
+
121
+ def casein_time_zone_select form, obj, attribute, option_tags, options = {}
122
+ casein_form_tag_wrapper(form.time_zone_select(attribute, option_tags, options, {:class => 'caseinSelect'}), form, obj, attribute, options).html_safe
123
+ end
124
+
125
+ def casein_collection_select form, obj, object, attribute, collection, value_method, text_method, options = {}
126
+ casein_form_tag_wrapper(collection_select(object, attribute, collection, value_method, text_method, options, {:class => 'caseinSelect'}), form, obj, attribute, options).html_safe
127
+ end
128
+
129
+ def casein_date_select form, obj, attribute, options = {}
130
+ casein_form_tag_wrapper(form.date_select(attribute, options, {:class => 'caseinDateTimeSelect'}), form, obj, attribute, options).html_safe
131
+ end
132
+
133
+ def casein_time_select form, obj, attribute, options = {}
134
+ casein_form_tag_wrapper(form.time_select(attribute, options, {:class => 'caseinDateTimeSelect'}), form, obj, attribute, options).html_safe
135
+ end
136
+
137
+ def casein_datetime_select form, obj, attribute, options = {}
138
+ casein_form_tag_wrapper(form.datetime_select(attribute, options, {:class => 'caseinDateTimeSelect'}), form, obj, attribute, options).html_safe
139
+ end
140
+
141
+ def casein_file_field form, obj, object_name, attribute, options = {}
142
+ contents = '<div class="caseinFileFieldContainer">' + file_field(object_name, attribute, options) + '</div>'
143
+ casein_form_tag_wrapper(contents, form, obj, attribute, options).html_safe
144
+ end
145
+
146
+ def casein_hidden_field form, obj, attribute, options = {}
147
+ form.hidden_field(obj, attribute, options).html_safe
148
+ end
149
+
150
+ protected
151
+
152
+ def casein_form_tag_wrapper form_tag, form, obj, attribute, options = {}
153
+ unless options.key? :casein_label
154
+ human_attribute_name = attribute.to_s.humanize
155
+ else
156
+ human_attribute_name = options[:casein_label]
157
+ end
158
+
159
+ html = "<p>"
160
+
161
+ if obj && obj.errors[attribute].any?
162
+ html += "<span class='formError'>#{human_attribute_name} #{obj.errors[attribute].first}</span>".html_safe
163
+ else
164
+ html += form.label(attribute, human_attribute_name)
165
+ end
166
+
167
+ html += "</p>\n<p>#{form_tag}</p>"
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,44 @@
1
+ module Casein
2
+
3
+ require 'casein/config_helper'
4
+ include Casein::ConfigHelper
5
+
6
+ class CaseinNotification < ActionMailer::Base
7
+
8
+ default :from => casein_config_email_from_address
9
+
10
+ self.prepend_view_path File.join(File.dirname(__FILE__), '..', 'views', 'casein')
11
+
12
+ def generate_new_password casein_user, host, pass
13
+ @name = casein_user.name
14
+ @host = host
15
+ @login = casein_user.login
16
+ @pass = pass
17
+ @from_text = casein_config_website_name
18
+
19
+ mail(:to => casein_user.email, :subject => "[#{casein_config_website_name}] New password")
20
+ end
21
+
22
+ def new_user_information casein_user, host, pass
23
+ @name = casein_user.name
24
+ @host = host
25
+ @login = casein_user.login
26
+ @pass = pass
27
+ @from_text = casein_config_website_name
28
+
29
+ mail(:to => casein_user.email, :subject => "[#{casein_config_website_name}] New user account")
30
+ end
31
+
32
+ def password_reset_instructions casein_user, host
33
+ ActionMailer::Base.default_url_options[:host] = host.gsub("http://", "")
34
+ @name = casein_user.name
35
+ @host = host
36
+ @login = casein_user.login
37
+ @reset_password_url = edit_casein_password_reset_url + "/?token=#{casein_user.perishable_token}"
38
+ @from_text = casein_config_website_name
39
+
40
+ mail(:to => casein_user.email, :subject => "[#{casein_config_website_name}] Password reset instructions")
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,55 @@
1
+ include Casein::ConfigHelper
2
+
3
+ $CASEIN_USER_ACCESS_LEVEL_ADMIN = 0
4
+ $CASEIN_USER_ACCESS_LEVEL_USER = 10
5
+
6
+ module Casein
7
+ class User < ActiveRecord::Base
8
+
9
+ def self.table_name
10
+ self.to_s.gsub("::", "_").tableize
11
+ end
12
+
13
+ acts_as_authentic { |c| c.validate_email_field = false }
14
+
15
+ attr_accessor :notify_of_new_password
16
+
17
+ after_create :send_create_notification
18
+ after_update :send_update_notification
19
+ before_validation :check_time_zone
20
+
21
+ validates_presence_of :login, :name, :email
22
+ validates_uniqueness_of :login
23
+ validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
24
+ validates_presence_of :time_zone
25
+
26
+ def self.has_more_than_one_admin
27
+ Casein::User.where(:access_level => $CASEIN_USER_ACCESS_LEVEL_ADMIN).count > 1
28
+ end
29
+
30
+ def send_create_notification
31
+ Casein::CaseinNotification.new_user_information(self, casein_config_hostname, @password).deliver
32
+ end
33
+
34
+ def send_update_notification
35
+ if notify_of_new_password
36
+ notify_of_new_password = false
37
+ Casein::CaseinNotification.generate_new_password(self, casein_config_hostname, @password).deliver
38
+ end
39
+ end
40
+
41
+ def send_password_reset_instructions
42
+ reset_perishable_token!
43
+ Casein::CaseinNotification.password_reset_instructions(self, casein_config_hostname).deliver
44
+ end
45
+
46
+ def check_time_zone
47
+ self.time_zone = Rails::Application.config.time_zone unless self.time_zone
48
+ end
49
+
50
+ def is_admin?
51
+ access_level == $CASEIN_USER_ACCESS_LEVEL_ADMIN
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,8 @@
1
+ module Casein
2
+ class UserSession < ::Authlogic::Session::Base
3
+ include ActiveModel::Conversion
4
+ def persisted?
5
+ false
6
+ end
7
+ end
8
+ end
@@ -0,0 +1 @@
1
+ <h2>Welcome to the <%= casein_config_website_name %> administration system</h2>
@@ -0,0 +1,12 @@
1
+ Dear <%= @name %>,<br />
2
+ <br />
3
+ Your password has been reset by an administrator for your account at:<br />
4
+ <br />
5
+ <%= @host %>/casein<br />
6
+ <br />
7
+ Login: <%= @login %><br />
8
+ New password: <%= @pass %><br />
9
+ <br />
10
+ From<br />
11
+ <br />
12
+ <%= @from_text %>
@@ -0,0 +1,12 @@
1
+ Dear <%= @name %>,<br />
2
+ <br />
3
+ A new user account has been created for you at:<br />
4
+ <br />
5
+ <%= @host %>/casein<br />
6
+ <br />
7
+ Login: <%= @login %><br />
8
+ Password: <%= @pass %><br />
9
+ <br />
10
+ From<br />
11
+ <br />
12
+ <%= @from_text %>
@@ -0,0 +1,11 @@
1
+ Dear <%= @name %>,<br />
2
+ <br />
3
+ A request to reset the password for login '<%= @login %>' has been made.<br />
4
+ If you did not make this request, simply ignore this email.<br />
5
+ Otherwise, click the link below to proceed:<br />
6
+ <br />
7
+ <%= @reset_password_url %><br />
8
+ <br />
9
+ From<br />
10
+ <br />
11
+ <%= @from_text %>
@@ -0,0 +1,48 @@
1
+ <%= form_for @reset_user, :url => casein_password_reset_path do |f| %>
2
+
3
+ <% if @reset_user.errors.any? %>
4
+ <div class="error">
5
+ <p>
6
+ <% @reset_user.errors.keys.each do |key| %>
7
+ <%= (key.to_s.humanize + " ") unless key == :base %>
8
+ <%= @reset_user.errors[key].first %>
9
+ <% end %>
10
+ </p>
11
+ </div>
12
+ <% end %>
13
+
14
+ <% if flash[:warning] %>
15
+ <div class="error">
16
+ <p><%= flash[:warning] %></p>
17
+ </div>
18
+ <% end %>
19
+
20
+ <% if flash[:notice] %>
21
+ <div class="notice">
22
+ <p><%= flash[:notice] %></p>
23
+ </div>
24
+ <% end %>
25
+
26
+ <%= hidden_field_tag :token, params[:token] %>
27
+
28
+ <div class="text">
29
+ <p>
30
+ <%= f.label :password, "Password:" %>
31
+ <%= f.password_field :password, :class => "caseinTextField" %>
32
+ </p>
33
+ </div>
34
+
35
+ <div class="text">
36
+ <p>
37
+ <%= f.label :password_confirmation, "Confirm password:" %>
38
+ <%= f.password_field :password_confirmation, :class => "caseinTextField" %>
39
+ </p>
40
+ </div>
41
+
42
+ <div class="submit_remember">
43
+ <p>
44
+ <%= f.submit "Reset password", :class => "caseinSubmit" %>
45
+ </p>
46
+ </div>
47
+
48
+ <% end %>