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.
- data/README.rdoc +3 -1
- data/VERSION +1 -1
- data/app/controllers/admin/muck/access_codes_controller.rb +78 -0
- data/app/controllers/admin/muck/roles_controller.rb +34 -24
- data/app/controllers/admin/muck/users_controller.rb +56 -21
- data/app/controllers/muck/access_code_requests_controller.rb +27 -0
- data/app/controllers/muck/activations_controller.rb +0 -1
- data/app/controllers/muck/users_controller.rb +122 -110
- data/app/models/role.rb +5 -2
- data/app/models/user_mailer.rb +7 -0
- data/app/views/access_code_requests/new.html.erb +7 -0
- data/app/views/access_code_requests/show.html.erb +1 -0
- data/app/views/admin/access_codes/_access_code.html.erb +8 -0
- data/app/views/admin/access_codes/_form.html.erb +15 -0
- data/app/views/admin/access_codes/_user.html.erb +6 -0
- data/app/views/admin/access_codes/bulk.html.erb +12 -0
- data/app/views/admin/access_codes/edit.html.erb +6 -0
- data/app/views/admin/access_codes/index.html.erb +18 -0
- data/app/views/admin/access_codes/new.html.erb +6 -0
- data/app/views/admin/access_codes/show.html.erb +30 -0
- data/app/views/admin/permissions/_permission.html.erb +3 -0
- data/app/views/admin/roles/_role.html.erb +5 -9
- data/app/views/admin/roles/edit.html.erb +4 -17
- data/app/views/admin/roles/index.html.erb +16 -8
- data/app/views/admin/roles/new.html.erb +4 -16
- data/app/views/admin/roles/show.html.erb +3 -7
- data/app/views/admin/users/_activate.html.erb +2 -2
- data/app/views/admin/users/_row.html.erb +8 -2
- data/app/views/admin/users/_table.html.erb +10 -15
- data/app/views/admin/users/permissions.html.erb +8 -0
- data/app/views/user_mailer/access_code.text.html.erb +3 -0
- data/app/views/user_mailer/access_code.text.plain.erb +5 -0
- data/app/views/users/_signup_form.html.erb +7 -0
- data/app/views/users/welcome.html.erb +1 -1
- data/config/muck_users_routes.rb +5 -2
- data/db/migrate/20100123035450_create_access_codes.rb +19 -0
- data/db/migrate/20100123233654_create_access_code_requests.rb +14 -0
- data/lib/action_controller/authentic_application.rb +1 -1
- data/lib/active_record/acts/muck_access_code.rb +75 -0
- data/lib/active_record/acts/muck_access_code_request.rb +33 -0
- data/lib/active_record/acts/muck_user.rb +13 -1
- data/lib/muck_users.rb +8 -1
- data/lib/muck_users/muck_custom_form_builder.rb +10 -0
- data/locales/en.yml +163 -102
- data/muck-users.gemspec +41 -2
- data/test/rails_root/app/models/access_code.rb +3 -0
- data/test/rails_root/app/models/access_code_request.rb +3 -0
- data/test/rails_root/app/models/user.rb +12 -9
- data/test/rails_root/config/environment.rb +1 -0
- data/test/rails_root/config/global_config.yml +1 -1
- data/test/rails_root/db/migrate/20100123035450_create_access_codes.rb +19 -0
- data/test/rails_root/db/migrate/20100123233654_create_access_code_requests.rb +14 -0
- data/test/rails_root/public/javascripts/jquery/jquery.jgrowl.js +9 -2
- data/test/rails_root/public/javascripts/muck.js +39 -13
- data/test/rails_root/public/stylesheets/admin.css +20 -3
- data/test/rails_root/public/stylesheets/jquery/cupertino/jquery-ui-1.7.2.custom.css +160 -0
- data/test/rails_root/public/stylesheets/jquery/redmond/jquery-ui-1.7.2.custom.css +160 -0
- data/test/rails_root/public/stylesheets/jquery/smoothness/jquery-ui-1.7.2.custom.css +160 -0
- data/test/rails_root/public/stylesheets/jquery/ui-lightness/jquery-ui-1.7.2.custom.css +160 -0
- data/test/rails_root/public/stylesheets/styles.css +9 -8
- data/test/rails_root/test/functional/access_code_requests_controller_test.rb +33 -0
- data/test/rails_root/test/functional/admin/access_codes_controller_test.rb +166 -0
- data/test/rails_root/test/unit/access_code_test.rb +100 -0
- data/test/rails_root/test/unit/role_test.rb +1 -0
- data/test/rails_root/test/unit/user_mailer_test.rb +13 -1
- data/test/rails_root/test/unit/user_test.rb +13 -9
- 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
|
data/app/models/user_mailer.rb
CHANGED
@@ -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,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>
|
@@ -1,9 +1,5 @@
|
|
1
|
-
<
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
-
|
2
|
-
|
3
|
-
<%=
|
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><%=
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
<
|
7
|
-
<
|
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
|
-
|
2
|
-
|
3
|
-
<%=
|
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
|
-
<
|
2
|
-
|
3
|
-
|
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
|
-
<%=
|
2
|
+
<%= link_to I18n.t('muck.general.deactivate'), admin_user_path(user, :deactivate => 'true'), :class => 'ajax-update' -%>
|
3
3
|
<% else -%>
|
4
|
-
<%=
|
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
|
5
|
-
|
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
|
1
|
+
<table class="adminTable">
|
2
2
|
<thead>
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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 %>
|
@@ -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 '
|
4
|
+
<%= link_to translate('muck.users.view_your_account'), user_path(current_user) %>
|
5
5
|
</div>
|
data/config/muck_users_routes.rb
CHANGED
@@ -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 :
|
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?(
|
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
|