muck-users 0.2.23 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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