muck-users 0.2.23 → 0.3.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 (67) hide show
  1. data/README.rdoc +3 -1
  2. data/VERSION +1 -1
  3. data/app/controllers/admin/muck/access_codes_controller.rb +78 -0
  4. data/app/controllers/admin/muck/roles_controller.rb +34 -24
  5. data/app/controllers/admin/muck/users_controller.rb +56 -21
  6. data/app/controllers/muck/access_code_requests_controller.rb +27 -0
  7. data/app/controllers/muck/activations_controller.rb +0 -1
  8. data/app/controllers/muck/users_controller.rb +122 -110
  9. data/app/models/role.rb +5 -2
  10. data/app/models/user_mailer.rb +7 -0
  11. data/app/views/access_code_requests/new.html.erb +7 -0
  12. data/app/views/access_code_requests/show.html.erb +1 -0
  13. data/app/views/admin/access_codes/_access_code.html.erb +8 -0
  14. data/app/views/admin/access_codes/_form.html.erb +15 -0
  15. data/app/views/admin/access_codes/_user.html.erb +6 -0
  16. data/app/views/admin/access_codes/bulk.html.erb +12 -0
  17. data/app/views/admin/access_codes/edit.html.erb +6 -0
  18. data/app/views/admin/access_codes/index.html.erb +18 -0
  19. data/app/views/admin/access_codes/new.html.erb +6 -0
  20. data/app/views/admin/access_codes/show.html.erb +30 -0
  21. data/app/views/admin/permissions/_permission.html.erb +3 -0
  22. data/app/views/admin/roles/_role.html.erb +5 -9
  23. data/app/views/admin/roles/edit.html.erb +4 -17
  24. data/app/views/admin/roles/index.html.erb +16 -8
  25. data/app/views/admin/roles/new.html.erb +4 -16
  26. data/app/views/admin/roles/show.html.erb +3 -7
  27. data/app/views/admin/users/_activate.html.erb +2 -2
  28. data/app/views/admin/users/_row.html.erb +8 -2
  29. data/app/views/admin/users/_table.html.erb +10 -15
  30. data/app/views/admin/users/permissions.html.erb +8 -0
  31. data/app/views/user_mailer/access_code.text.html.erb +3 -0
  32. data/app/views/user_mailer/access_code.text.plain.erb +5 -0
  33. data/app/views/users/_signup_form.html.erb +7 -0
  34. data/app/views/users/welcome.html.erb +1 -1
  35. data/config/muck_users_routes.rb +5 -2
  36. data/db/migrate/20100123035450_create_access_codes.rb +19 -0
  37. data/db/migrate/20100123233654_create_access_code_requests.rb +14 -0
  38. data/lib/action_controller/authentic_application.rb +1 -1
  39. data/lib/active_record/acts/muck_access_code.rb +75 -0
  40. data/lib/active_record/acts/muck_access_code_request.rb +33 -0
  41. data/lib/active_record/acts/muck_user.rb +13 -1
  42. data/lib/muck_users.rb +8 -1
  43. data/lib/muck_users/muck_custom_form_builder.rb +10 -0
  44. data/locales/en.yml +163 -102
  45. data/muck-users.gemspec +41 -2
  46. data/test/rails_root/app/models/access_code.rb +3 -0
  47. data/test/rails_root/app/models/access_code_request.rb +3 -0
  48. data/test/rails_root/app/models/user.rb +12 -9
  49. data/test/rails_root/config/environment.rb +1 -0
  50. data/test/rails_root/config/global_config.yml +1 -1
  51. data/test/rails_root/db/migrate/20100123035450_create_access_codes.rb +19 -0
  52. data/test/rails_root/db/migrate/20100123233654_create_access_code_requests.rb +14 -0
  53. data/test/rails_root/public/javascripts/jquery/jquery.jgrowl.js +9 -2
  54. data/test/rails_root/public/javascripts/muck.js +39 -13
  55. data/test/rails_root/public/stylesheets/admin.css +20 -3
  56. data/test/rails_root/public/stylesheets/jquery/cupertino/jquery-ui-1.7.2.custom.css +160 -0
  57. data/test/rails_root/public/stylesheets/jquery/redmond/jquery-ui-1.7.2.custom.css +160 -0
  58. data/test/rails_root/public/stylesheets/jquery/smoothness/jquery-ui-1.7.2.custom.css +160 -0
  59. data/test/rails_root/public/stylesheets/jquery/ui-lightness/jquery-ui-1.7.2.custom.css +160 -0
  60. data/test/rails_root/public/stylesheets/styles.css +9 -8
  61. data/test/rails_root/test/functional/access_code_requests_controller_test.rb +33 -0
  62. data/test/rails_root/test/functional/admin/access_codes_controller_test.rb +166 -0
  63. data/test/rails_root/test/unit/access_code_test.rb +100 -0
  64. data/test/rails_root/test/unit/role_test.rb +1 -0
  65. data/test/rails_root/test/unit/user_mailer_test.rb +13 -1
  66. data/test/rails_root/test/unit/user_test.rb +13 -9
  67. metadata +41 -2
data/app/models/role.rb CHANGED
@@ -11,10 +11,13 @@
11
11
  class Role < ActiveRecord::Base
12
12
  unloadable
13
13
 
14
- has_many :permissions
14
+ has_many :permissions, :dependent => :destroy
15
15
  has_many :users, :through => :permissions
16
-
16
+
17
17
  validates_presence_of :rolename
18
+ validates_uniqueness_of :rolename
19
+
20
+ named_scope :by_alpha, :order => 'roles.rolename ASC'
18
21
 
19
22
  # roles can be defined as symbols. We want to store them as strings in the database
20
23
  def rolename= val
@@ -43,4 +43,11 @@ class UserMailer < ActionMailer::Base
43
43
  :application_name => GlobalConfig.application_name
44
44
  end
45
45
 
46
+ def access_code(email, subject, message, code)
47
+ muck_setup_email(email)
48
+ subject subject
49
+ body :message => message, :code => code
50
+ content_type "text/html"
51
+ end
52
+
46
53
  end
@@ -0,0 +1,7 @@
1
+ <h3><%=translate('muck.users.request_access_code') %></h3>
2
+ <%= output_errors('Problem adding access code', {:class => 'help-box'}, @access_code_request) %>
3
+ <% custom_form_for :access_code_request, :url => access_code_requests_path do |f| -%>
4
+ <%= f.text_field :email, { :label => translate('muck.users.email_address'),
5
+ :tip => translate('muck.users.access_code_request_tip') } -%>
6
+ <%= f.submit translate('muck.users.submit') %>
7
+ <% end -%>
@@ -0,0 +1 @@
1
+ <p><%= translate('muck.users.access_code_request_thank_you') %></p>
@@ -0,0 +1,8 @@
1
+ <tr>
2
+ <td><%= link_to access_code.code, admin_access_code_path(access_code) %></td>
3
+ <td><%= access_code.uses %></td>
4
+ <td><%= access_code.use_limit %></td>
5
+ <td><%= access_code.unlimited %></td>
6
+ <td><%= format_date(access_code.expires_at) %></td>
7
+ <td><%= format_date(access_code.created_at) %></td>
8
+ </tr>
@@ -0,0 +1,15 @@
1
+ <%= f.text_field :code, { :label => translate('muck.users.access_code'),
2
+ :tip => translate('muck.users.access_code_tip') } -%>
3
+ <%= f.text_field :use_limit, { :label => translate('muck.users.use_limit'),
4
+ :tip => translate('muck.users.use_limit_tip') } -%>
5
+ <%= f.check_box :unlimited, { :label => translate('muck.users.unlimited'),
6
+ :tip => translate('muck.users.unlimited_tip') } -%>
7
+ <%= f.text_field :expires_at, { :label => translate('muck.users.expiration_date'),
8
+ :tip => translate('muck.users.expiration_date_tip'),
9
+ :class => 'date_pick' } -%>
10
+
11
+ <script type="text/javascript" language="JavaScript">
12
+ jQuery(document).ready(function(){
13
+ jQuery('.date_pick').datepicker();
14
+ });
15
+ </script>
@@ -0,0 +1,6 @@
1
+ <tr>
2
+ <td><%= link_to user.login, profile_path(user) %></td>
3
+ <td><%= user.email %></td>
4
+ <td><%= user.first_name %></td>
5
+ <td><%= user.last_name %></td>
6
+ </tr>
@@ -0,0 +1,12 @@
1
+ <h2><%=translate('muck.users.bulk_access_codes_title') %></h2>
2
+ <p><%=translate('muck.users.bulk_access_codes_description') %></p>
3
+
4
+ <%= output_errors(translate('muck.users.bulk_access_code_problem'), {:class => 'help-box'}, @access_code) %>
5
+
6
+ <% custom_form_for :access_code, :url => bulk_create_admin_access_codes_path, :html => {:class => "standard-form alt"} do |f| -%>
7
+ <%= render :partial => 'admin/access_codes/form', :locals => {:f => f} %>
8
+ <%= text_field_tag :subject, params[:subject], :label => {:text => "Subject"} %>
9
+ <%= text_area_tag :message, params[:message], :label => {:text => "Message"} %>
10
+ <%= text_area_tag :emails, params[:emails], :label => {:text =>"Emails"}, :tip => translate('muck.users.bulk_access_code_emails_tip') %>
11
+ <%= f.submit translate('muck.users.save') %>
12
+ <% end -%>
@@ -0,0 +1,6 @@
1
+ <h3><%=translate('muck.users.edit_access_code') %></h3>
2
+ <%= output_errors(translate('muck.users.access_code_edit_problem'), {:class => 'help-box'}, @access_code) %>
3
+ <% custom_form_for @access_code, :url => admin_access_code_path(@access_code), :html => { :method => :put } do |f| -%>
4
+ <%= render :partial => 'admin/access_codes/form', :locals => { :f => f } %>
5
+ <%= f.submit translate('muck.users.save') %>
6
+ <% end -%>
@@ -0,0 +1,18 @@
1
+ <h2><%=translate('muck.users.access_codes') %></h2>
2
+ <div>
3
+ <%= link_to translate('muck.users.access_code_new'), new_admin_access_code_path %>
4
+ </div>
5
+ <table class="adminTable" cellspacing="0" cellpadding="0">
6
+ <thead>
7
+ <tr>
8
+ <th><%=translate('muck.users.access_code') %></th>
9
+ <th><%=translate('muck.users.access_code_uses') %></th>
10
+ <th><%=translate('muck.users.access_code_use_limit') %></th>
11
+ <th><%=translate('muck.users.access_code_unlimited') %></th>
12
+ <th><%=translate('muck.users.access_code_expires') %></th>
13
+ <th><%=translate('muck.users.access_code_created') %></th>
14
+ </tr>
15
+ </thead>
16
+ <%= render :partial => 'admin/access_codes/access_code', :collection => @codes %>
17
+ </table>
18
+ <%= will_paginate @codes %>
@@ -0,0 +1,6 @@
1
+ <h3><%=translate('muck.users.add_access_code') %></h3>
2
+ <%= output_errors(translate('muck.users.access_code_add_problem'), {:class => 'help-box'}, @access_code) %>
3
+ <% custom_form_for :access_code, :url => admin_access_codes_path do |f| -%>
4
+ <%= render :partial => 'admin/access_codes/form', :locals => {:f => f} %>
5
+ <%= f.submit translate('muck.users.save') %>
6
+ <% end -%>
@@ -0,0 +1,30 @@
1
+ <h2><%=translate('muck.users.access_code') %></h2>
2
+ <%= link_to(translate('muck.users.access_code_edit_link'), edit_admin_access_code_path(@access_code.id)) %>
3
+ <%= link_to(translate('muck.users.access_code_delete_link'), admin_access_code_path(@access_code.id), :method => :delete, :confirm => translate('muck.users.access_code_delete_confirm')) %>
4
+
5
+ <table class="adminTable" cellspacing="0" cellpadding="0">
6
+ <thead>
7
+ <tr>
8
+ <th><%=translate('muck.users.access_code') %></th>
9
+ <th><%=translate('muck.users.access_code_uses') %></th>
10
+ <th><%=translate('muck.users.access_code_use_limit') %></th>
11
+ <th><%=translate('muck.users.access_code_unlimited') %></th>
12
+ <th><%=translate('muck.users.access_code_expires') %></th>
13
+ <th><%=translate('muck.users.access_code_created') %></th>
14
+ </tr>
15
+ </thead>
16
+ <%= render :partial => 'admin/access_codes/access_code', :object => @access_code %>
17
+ </table>
18
+
19
+ <h3><%=translate('muck.users.access_code_related_users') %></h3>
20
+ <table class="adminTable" cellspacing="0" cellpadding="0">
21
+ <thead>
22
+ <tr>
23
+ <th><%=translate('muck.users.login') %></th>
24
+ <th><%=translate('muck.users.email') %></th>
25
+ <th><%=translate('muck.users.first_name') %></th>
26
+ <th><%=translate('muck.users.last_name') %></th>
27
+ </tr>
28
+ </thead>
29
+ <%= render :partial => 'admin/access_codes/user', :collection => @access_code.users %>
30
+ </table>
@@ -0,0 +1,3 @@
1
+ <li id="<%=permission.dom_id%>">
2
+ <%= link_to(permission.role.rolename, admin_role_path(permission.role)) %>
3
+ </li>
@@ -1,9 +1,5 @@
1
- <li>
2
- <%= role.rolename %>
3
- <% if @user.has_role?(role.rolename) %>
4
- <%= link_to I18n.t('muck.roles.remove_role'), user_role_url(:id => role.id, :user_id => @user.id), :method => :delete %>
5
- <% else %>
6
- <%= link_to I18n.t('muck.roles.assign_role'), user_role_url(:id => role.id, :user_id => @user.id), :method => :put %>
7
- <% end %>
8
- </li>
9
-
1
+ <tr id="<%=role.dom_id%>">
2
+ <td><%= link_to(role.rolename, admin_role_path(role)) %></td>
3
+ <td><%= link_to(translate('muck.users.edit'), edit_admin_role_path(role), { :class => 'dialog-pop', :title => translate('muck.users.edit_role_dialog_title') } ) %></td>
4
+ <td><%= link_to(translate('muck.users.delete'), admin_role_path(role), { :class => 'ajax-delete', :confirm => translate('muck.users.role_delete_confirm') } ) %></td>
5
+ </tr>
@@ -1,17 +1,4 @@
1
- <h1><%= I18n.t('Editing role') %></h1>
2
-
3
- <%= error_messages_for :role %>
4
-
5
- <% form_for(admin_roles_path(@role)) do |f| %>
6
- <p>
7
- <b><%= I18n.t('Rolename') %></b><br />
8
- <%= f.text_field :rolename %>
9
- </p>
10
-
11
- <p>
12
- <%= f.submit I18n.t('Update') %>
13
- </p>
14
- <% end %>
15
-
16
- <%= link_to I18n.t('Show'), @role %> |
17
- <%= link_to I18n.t('Back'), admin_roles_path %>
1
+ <% custom_form_for @role, :url => admin_role_path(@role), :html => { :class => 'ajax', :method => :put } do |f| %>
2
+ <%= f.text_field :rolename %>
3
+ <%= f.submit translate('muck.users.update') %>
4
+ <% end %>
@@ -1,8 +1,16 @@
1
- <h2><%= I18n.t('Roles for %{user}') % {:user => h(@user.login.capitalize)} %></h2>
2
-
3
- <h3><%= I18n.t('Roles assigned:') %></h3>
4
- <ul><%= render :partial => 'role', :collection => @user.roles %></ul>
5
-
6
- <h3><%= I18n.t('Roles available:') %></h3>
7
- <ul><%= render :partial => 'role', :collection => (@all_roles - @user.roles) %></ul>
8
-
1
+ <h2><%=translate('muck.users.roles') %></h2>
2
+ <p>
3
+ <%= link_to translate('muck.users.add_role'), new_admin_role_path, { :class => 'dialog-pop', :title => translate('muck.users.add_role_dialog_title') } %>
4
+ </p>
5
+ <table class="adminTable">
6
+ <thead>
7
+ <tr>
8
+ <th><%=translate('muck.users.role') %></th>
9
+ <th></th>
10
+ <th></th>
11
+ </tr>
12
+ </thead>
13
+ <tbody id="current-roles">
14
+ <%= render :partial => 'admin/roles/role', :collection => @roles %>
15
+ </tbody>
16
+ </table>
@@ -1,16 +1,4 @@
1
- <h1><%= I18n.t('New role') %></h1>
2
-
3
- <%= error_messages_for :role %>
4
-
5
- <% form_for @role, :url => admin_role_path(@role) do |f| %>
6
- <p>
7
- <b><%= I18n.t('Rolename') %></b><br />
8
- <%= f.text_field :rolename %>
9
- </p>
10
-
11
- <p>
12
- <%= f.submit I18n.t('Create') %>
13
- </p>
14
- <% end %>
15
-
16
- <%= link_to I18n.t('Back'), admin_roles_path %>
1
+ <% custom_form_for @role, :url => admin_roles_path, :html => { :class => 'ajax' } do |f| %>
2
+ <%= f.text_field :rolename %>
3
+ <%= f.submit translate('muck.users.add') %>
4
+ <% end %>
@@ -1,7 +1,3 @@
1
- <p>
2
- <b><%= I18n.t('Rolename:') %></b>
3
- <%=h @role.rolename %>
4
- </p>
5
-
6
- <%= link_to I18n.t('Edit'), edit_role_path(@role) %> |
7
- <%= link_to I18n.t('Back'), admin_roles_path %>
1
+ <h2><%= @role.rolename %></h2>
2
+ <h3><%=translate('muck.users.users_in_role') %></h3>
3
+ <%= render :partial => 'admin/users/table' -%>
@@ -1,5 +1,5 @@
1
1
  <% if user.active? -%>
2
- <%= link_to_remote I18n.t('muck.general.deactivate'), { :url => admin_user_path(user, :format => 'js'), :method => :put } -%>
2
+ <%= link_to I18n.t('muck.general.deactivate'), admin_user_path(user, :deactivate => 'true'), :class => 'ajax-update' -%>
3
3
  <% else -%>
4
- <%= link_to_remote I18n.t('muck.general.activate'), { :url => admin_user_path(user, :format => 'js'), :method => :put } -%>
4
+ <%= link_to I18n.t('muck.general.activate'), admin_user_path(user, :activate => 'true'), :class => 'ajax-update' -%>
5
5
  <% end -%>
@@ -1,6 +1,12 @@
1
1
  <tr id="<%=user.dom_id('row')%>" class="<%= cycle('odd','even') %>">
2
2
  <td><%= link_to h(user.full_name), user %></td>
3
3
  <td><%= mail_to h(user.email), user.email %></td>
4
- <td id="<%=user.dom_id('link')%>"><%= render :partial => 'admin/users/activate', :locals => { :user => user } %></td>
5
- <td><%= link_to_remote t("muck.general.delete"), { :url => admin_user_path(user.id), :method => :delete }, { :title => t('muck.users.delete_this_user'), :class => 'delete-user' } -%></td>
4
+ <td>
5
+ <ul id="<%=user.dom_id('permissions')%>" class="permissions inline">
6
+ <%= render :partial => 'admin/permissions/permission', :collection => user.permissions, :locals => { :user => user } %>
7
+ </ul>
8
+ </td>
9
+ <td><%= link_to(translate('muck.users.change_permissions'), permissions_admin_user_path(user), { :title => translate('muck.users.change_permissions_for', :user => user.full_name), :class => 'dialog-pop' }) %></td>
10
+ <td id="<%=user.dom_id('link')%>"><%= render :partial => 'admin/users/activate', :locals => { :user => user } %></td>
11
+ <td><%= link_to(t("muck.general.delete"), { :url => admin_user_path(user.id) }, { :title => t('muck.users.delete_this_user'), :class => 'delete-user ajax-delete' }) -%></td>
6
12
  </tr>
@@ -1,21 +1,16 @@
1
- <table id="manage" class="manage">
1
+ <table class="adminTable">
2
2
  <thead>
3
- <tr>
4
- <th><%= t('muck.users.name') %></th>
5
- <th><%= t('muck.users.email_address') %></th>
6
- <th></th>
7
- <th></th>
8
- </tr>
3
+ <tr>
4
+ <th><%= t('muck.users.name') %></th>
5
+ <th><%= t('muck.users.email_address') %></th>
6
+ <th><%= t('muck.users.roles') %></th>
7
+ <th></th>
8
+ <th></th>
9
+ <th></th>
10
+ </tr>
9
11
  </thead>
10
12
  <tbody>
11
13
  <%= render :partial => 'admin/users/row', :collection => @users, :as => :user %>
12
14
  </tbody>
13
15
  </table>
14
- <%= will_paginate @users %>
15
- <script type="text/javascript" language="JavaScript">
16
- jQuery(document).ready(function() {
17
- jQuery(".delete-user").click(function() {
18
- jQuery(this).parent().html('deleting user...');
19
- });
20
- });
21
- </script>
16
+ <%= will_paginate @users %>
@@ -0,0 +1,8 @@
1
+ <% custom_form_for @user, :url => admin_user_path(@user), :html => { :class => 'ajax', :method => :put } do |f| %>
2
+ <ul class="checkbox-list">
3
+ <% Role.all.each do |role| -%>
4
+ <li><%= check_box_tag "user[role_ids][]", role.id, @user.has_role?(role.rolename) -%> <%= role.rolename -%></li>
5
+ <% end -%>
6
+ </ul>
7
+ <%= f.submit translate('muck.users.save') %>
8
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <p><%= @message %></p>
2
+ <p>Access Code: <%= @code %></p>
3
+ <p><%= link_to translate('muck.users.click_to_sign_up_now'), signup_url(:access_code => @code) %></p>
@@ -0,0 +1,5 @@
1
+ <%= @message %>
2
+
3
+ Access Code: <%= @code %>
4
+
5
+ <%= link_to translate('muck.users.click_to_sign_up_now'), signup_url(:access_code => @code) %>
@@ -2,6 +2,13 @@
2
2
 
3
3
  <%= output_errors(t('muck.users.problem_creating_account'), {:class => 'help-box'}, user) %>
4
4
 
5
+ <% if GlobalConfig.require_access_code -%>
6
+ <%= f.text_field :access_code_code, { :label => translate('muck.users.access_code'),
7
+ :extra_html => translate('muck.users.access_code_help',
8
+ :access_request_anchor => %Q{<a class="fancy-pop iframe" href="#{new_access_code_request_path}">},
9
+ :access_request_anchor_end => "</a>") } -%>
10
+ <% end -%>
11
+
5
12
  <%= f.text_field :login, { :label => t('muck.users.choose_member_name'),
6
13
  :extra_html => '<span id="username-availibility" class="availability"></span>',
7
14
  :tip => t('muck.users.username_help'),
@@ -1,5 +1,5 @@
1
1
  <div id="welcome" class="common-content">
2
2
  <%= output_errors('', {:class => 'help-box'}) %>
3
3
  <%= t('muck.users.welcome_message') %>
4
- <%= link_to 'View Your Account', user_path(current_user) %>
4
+ <%= link_to translate('muck.users.view_your_account'), user_path(current_user) %>
5
5
  </div>
@@ -45,14 +45,17 @@ ActionController::Routing::Routes.draw do |map|
45
45
  user_sessions.signup_complete_login_required '/signup_complete_login/:id', :action => 'new'
46
46
  end
47
47
 
48
+ # Access codes
49
+ map.resources :access_code_requests, :controller => 'muck/access_code_requests'
50
+
48
51
  # page a user is taken to when they log out
49
52
  map.logout_complete '/login', :controller => 'user_session', :action => 'new'
50
53
 
51
54
  # admin
52
55
  map.namespace :admin do |a|
53
- a.resources :users, :controller => 'muck/users', :collection => { :inactive => :get, :inactive_emails => :get, :activate_all => :get, :search => :post, :ajax_search => :post }
56
+ a.resources :users, :controller => 'muck/users', :member => { :permissions => :get }, :collection => { :inactive => :get, :inactive_emails => :get, :activate_all => :get, :search => :post, :ajax_search => :post }
54
57
  a.resources :roles, :controller => 'muck/roles'
55
- a.resources :permissions, :controller => 'muck/permissions'
58
+ a.resources :access_codes, :controller => 'muck/access_codes', :collection => {:bulk => :get, :bulk_create => :post}
56
59
  end
57
60
 
58
61
  end
@@ -0,0 +1,19 @@
1
+ class CreateAccessCodes < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :access_codes do |t|
4
+ t.string :code
5
+ t.integer :uses, :default => 0, :null => false
6
+ t.boolean :unlimited, :default => false, :null => false
7
+ t.datetime :expires_at
8
+ t.integer :use_limit, :default => 1, :null => false
9
+ t.timestamps
10
+ end
11
+ add_index :access_codes, :code
12
+ add_column :users, :access_code_id, :integer
13
+ end
14
+
15
+ def self.down
16
+ drop_table :access_codes
17
+ remove_column :users, :access_code_id
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ class CreateAccessCodeRequests < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :access_code_requests do |t|
4
+ t.string :email
5
+ t.datetime :code_sent_at
6
+ t.timestamps
7
+ end
8
+ add_index :access_code_requests, :email
9
+ end
10
+
11
+ def self.down
12
+ drop_table :access_code_requests
13
+ end
14
+ end
@@ -111,7 +111,7 @@ module ActionController
111
111
  end
112
112
 
113
113
  def can_access?(user, object, roles, &block)
114
- if logged_in? && user.is_in_role?(event, roles)
114
+ if logged_in? && user.is_in_role?(object, roles)
115
115
  content = capture(&block)
116
116
  concat(content, block.binding)
117
117
  end
@@ -0,0 +1,75 @@
1
+ module ActiveRecord
2
+ module Acts #:nodoc:
3
+ module MuckAccessCode #:nodoc:
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+
10
+ def acts_as_muck_access_code(options = {})
11
+
12
+ validates_presence_of :code, :uses, :use_limit, :expires_at
13
+ validates_uniqueness_of :code
14
+
15
+ has_many :users
16
+
17
+ named_scope :newest, :order => 'access_codes.created_at DESC'
18
+ named_scope :by_alpha, :order => 'access_codes.code ASC'
19
+ named_scope :active, :conditions => 'access_codes.expires_at > Now() AND access_codes.uses <= use_limit'
20
+
21
+ include ActiveRecord::Acts::MuckAccessCode::InstanceMethods
22
+ extend ActiveRecord::Acts::MuckAccessCode::SingletonMethods
23
+
24
+ end
25
+ end
26
+
27
+ # class methods
28
+ module SingletonMethods
29
+
30
+ def valid_code?(code)
31
+ access_code = find_by_code(code)
32
+ valid_code = access_code ? !access_code.overused? : false
33
+ [access_code, valid_code]
34
+ end
35
+
36
+ def random_code
37
+ code_length = 14 # will generate a code 15 chars long
38
+ letters = ['B', 'C', 'D', 'F', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z']
39
+ numbers = [2, 3, 4, 7, 9]
40
+ promo_set = letters | numbers # combine arrays
41
+ begin
42
+ promo_code = promo_set.sort_by{rand}[0..code_length].to_s # randomize array and take the first 15 elements and make them a string
43
+ end until !self.active_code?(promo_code)
44
+ promo_code
45
+ end
46
+
47
+ # Checks the database to ensure the specified code is not taken
48
+ def active_code?(code)
49
+ AccessCode.find_by_code(code)
50
+ end
51
+
52
+ end
53
+
54
+ module InstanceMethods
55
+
56
+ def use_code
57
+ self.update_attribute(:uses, self.uses + 1)
58
+ end
59
+
60
+ def invalid?
61
+ expired? || overused?
62
+ end
63
+
64
+ def overused?
65
+ (self.uses >= self.use_limit) && !self.unlimited
66
+ end
67
+
68
+ def expired?
69
+ self.expires_at? && self.expires_at < Time.now
70
+ end
71
+
72
+ end
73
+ end
74
+ end
75
+ end