cdamian-admin 0.0.0 → 0.0.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 (60) hide show
  1. data/README.rdoc +1 -1
  2. data/Rakefile +3 -2
  3. data/VERSION +1 -1
  4. data/app/controllers/admin/base_controller.rb +59 -0
  5. data/app/controllers/admin/dashboard_controller.rb +4 -0
  6. data/app/controllers/admin/moderator_sessions_controller.rb +26 -0
  7. data/app/controllers/admin/moderators_controller.rb +67 -0
  8. data/app/helpers/admin/base_helper.rb +24 -0
  9. data/app/helpers/admin/dashboard_helper.rb +2 -0
  10. data/app/helpers/admin/moderator_sessions_helper.rb +2 -0
  11. data/app/helpers/admin/moderators_helper.rb +2 -0
  12. data/app/models/moderator.rb +6 -0
  13. data/app/models/moderator_session.rb +3 -0
  14. data/app/views/admin/dashboard/index.html.erb +3 -0
  15. data/app/views/admin/moderator_sessions/new.html.erb +57 -0
  16. data/app/views/admin/moderators/_form.erb +42 -0
  17. data/app/views/admin/moderators/edit.html.erb +25 -0
  18. data/app/views/admin/moderators/index.html.erb +35 -0
  19. data/app/views/admin/moderators/new.html.erb +25 -0
  20. data/app/views/layouts/admin.html.erb +45 -0
  21. data/config/routes.rb +9 -0
  22. data/db/migrate/20090810030104_create_moderators.rb +39 -0
  23. data/lib/admin.rb +29 -0
  24. data/public/images/admin/background.png +0 -0
  25. data/public/images/admin/button_back.png +0 -0
  26. data/public/images/admin/button_backup.png +0 -0
  27. data/public/images/admin/button_cancel.png +0 -0
  28. data/public/images/admin/button_delete.png +0 -0
  29. data/public/images/admin/button_insert.png +0 -0
  30. data/public/images/admin/button_login.png +0 -0
  31. data/public/images/admin/button_middle.png +0 -0
  32. data/public/images/admin/button_print.png +0 -0
  33. data/public/images/admin/button_restore.png +0 -0
  34. data/public/images/admin/button_right.png +0 -0
  35. data/public/images/admin/button_save.png +0 -0
  36. data/public/images/admin/button_send.png +0 -0
  37. data/public/images/admin/column_left.png +0 -0
  38. data/public/images/admin/column_right.png +0 -0
  39. data/public/images/admin/footer.png +0 -0
  40. data/public/images/admin/header.png +0 -0
  41. data/public/images/admin/login.png +0 -0
  42. data/public/images/admin/login_bottom.png +0 -0
  43. data/public/images/admin/login_top.png +0 -0
  44. data/public/images/admin/tab_1.png +0 -0
  45. data/public/images/admin/tab_2.png +0 -0
  46. data/public/images/admin/tab_3.png +0 -0
  47. data/public/images/admin/top_1.png +0 -0
  48. data/public/stylesheets/admin/application.css +430 -0
  49. data/tasks/admin_tasks.rake +7 -0
  50. data/test/fixtures/moderators.yml +7 -0
  51. data/test/functional/admin/base_controller_test.rb +8 -0
  52. data/test/functional/admin/dashboard_controller_test.rb +8 -0
  53. data/test/functional/admin/moderator_sessions_controller_test.rb +8 -0
  54. data/test/functional/admin/moderators_controller_test.rb +8 -0
  55. data/test/unit/helpers/admin/base_helper_test.rb +4 -0
  56. data/test/unit/helpers/admin/dashboard_helper_test.rb +4 -0
  57. data/test/unit/helpers/admin/moderator_sessions_helper_test.rb +4 -0
  58. data/test/unit/helpers/admin/moderators_helper_test.rb +4 -0
  59. data/test/unit/moderator_test.rb +8 -0
  60. metadata +68 -4
data/README.rdoc CHANGED
@@ -1,6 +1,6 @@
1
1
  = admin
2
2
 
3
- Description goes here.
3
+ A drop-in admin interface for existing rails applications.
4
4
 
5
5
  == Copyright
6
6
 
data/Rakefile CHANGED
@@ -5,11 +5,12 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "admin"
8
- gem.summary = %Q{Core admin interface with user authentication and authorization}
8
+ gem.summary = %Q{A drop-in admin interface for existing rails applications}
9
+ gem.description = %Q{A drop-in admin interface for existing rails applications}
9
10
  gem.email = "damian.caruso@gmail.com"
10
11
  gem.homepage = "http://github.com/cdamian/admin"
11
12
  gem.authors = ["Damian Caruso"]
12
- gem.files = FileList['lib/**/*.rb', '[A-Z]*', 'test/**/*'].to_a
13
+ gem.files = FileList['app/**/*', 'config/**/*', 'db/**/*', 'lib/**/*.rb', 'public/**/*', 'tasks/**/*.rake', '[A-Z]*', 'test/**/*'].to_a
13
14
  gem.add_dependency("binarylogic-authlogic", ">= 2.1.1")
14
15
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
16
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.0.1
@@ -0,0 +1,59 @@
1
+ class Admin::BaseController < ApplicationController
2
+ helper :all
3
+ helper_method :current_moderator_session, :current_moderator
4
+ protect_from_forgery
5
+ filter_parameter_logging :password, :password_confirmation
6
+ before_filter :require_moderator
7
+ layout "admin"
8
+
9
+ def admin_index
10
+ redirect_to admin_dashboard_path
11
+ end
12
+
13
+ private
14
+ def current_moderator_session
15
+ return @current_moderator_session if defined?(@current_moderator_session)
16
+ @current_moderator_session = ModeratorSession.find
17
+ end
18
+
19
+ def current_moderator
20
+ return @current_moderator if defined?(@current_moderator)
21
+ @current_moderator = current_moderator_session && current_moderator_session.record
22
+ end
23
+
24
+ def require_moderator
25
+ unless current_moderator
26
+ store_location
27
+ flash[:notice] = "You must be logged in to access this page"
28
+ redirect_to new_admin_moderator_session_url
29
+ return false
30
+ end
31
+ end
32
+
33
+ def require_no_moderator
34
+ if current_moderator
35
+ store_location
36
+ flash[:notice] = "You must be logged out to access this page"
37
+ redirect_to admin_account_url
38
+ return false
39
+ end
40
+ end
41
+
42
+ def require_admin
43
+ unless current_moderator && current_moderator.admin?
44
+ store_location
45
+ flash[:notice] = "You must be an administrator to access this page"
46
+ redirect_to admin_account_url
47
+ return false
48
+ end
49
+ end
50
+
51
+ def store_location
52
+ session[:return_to] = request.request_uri
53
+ end
54
+
55
+ def redirect_back_or_default(default)
56
+ redirect_to(session[:return_to] || default)
57
+ session[:return_to] = nil
58
+ end
59
+ end
@@ -0,0 +1,4 @@
1
+ class Admin::DashboardController < Admin::BaseController
2
+ def index
3
+ end
4
+ end
@@ -0,0 +1,26 @@
1
+ class Admin::ModeratorSessionsController < Admin::BaseController
2
+ skip_before_filter :require_moderator, :only => [:new, :create]
3
+ before_filter :require_no_moderator, :only => [:new, :create]
4
+ layout false
5
+
6
+ def new
7
+ @moderator_session = ModeratorSession.new
8
+ end
9
+
10
+ def create
11
+ @moderator_session = ModeratorSession.new(params[:moderator_session])
12
+ if @moderator_session.save
13
+ flash[:notice] = "Login successful!"
14
+ redirect_back_or_default admin_dashboard_url
15
+ else
16
+ flash.now[:error] = "Invalid credentials!"
17
+ render :action => :new
18
+ end
19
+ end
20
+
21
+ def destroy
22
+ current_moderator_session.destroy
23
+ flash[:notice] = "Logout successful!"
24
+ redirect_back_or_default new_admin_moderator_session_url
25
+ end
26
+ end
@@ -0,0 +1,67 @@
1
+ class Admin::ModeratorsController < Admin::BaseController
2
+ before_filter :require_admin, :except => [:edit, :update, :show]
3
+ before_filter :set_moderator, :only => [:edit, :update]
4
+
5
+ def index
6
+ @moderators = Moderator.find(:all, :conditions => ["id != ?", current_moderator.id])
7
+ end
8
+
9
+ def new
10
+ @moderator = Moderator.new
11
+ end
12
+
13
+ def create
14
+ @moderator = Moderator.new(params[:moderator])
15
+ if @moderator.save
16
+ flash[:notice] = "Account created!"
17
+ redirect_to admin_moderators_url
18
+ else
19
+ render :action => :new
20
+ end
21
+ end
22
+
23
+ def show
24
+ @moderator = @current_moderator
25
+ end
26
+
27
+ def edit
28
+ if current_moderator != @moderator
29
+ @title = "Moderators"
30
+ @cancel_url = admin_moderators_path
31
+ else
32
+ @title = "Edit Account"
33
+ @cancel_url = admin_dashboard_path
34
+ end
35
+ end
36
+
37
+ def update
38
+ if @moderator.update_attributes(params[:moderator])
39
+ flash[:notice] = "Account updated!"
40
+ if current_moderator != @moderator
41
+ redirect_to admin_moderators_url
42
+ else
43
+ redirect_to admin_dashboard_path
44
+ end
45
+ else
46
+ render :action => :edit
47
+ end
48
+ end
49
+
50
+ def destroy
51
+ @moderator = Moderator.find(params[:id])
52
+ @moderator.destroy
53
+ flash[:notice] = "Account deleted!"
54
+ redirect_to admin_moderators_url
55
+ end
56
+
57
+ protected
58
+ def set_moderator
59
+ if params[:id] && !current_moderator.admin?
60
+ redirect_to admin_account_url
61
+ elsif params[:id].blank?
62
+ @moderator = @current_moderator
63
+ else
64
+ @moderator = Moderator.find(params[:id])
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,24 @@
1
+ module Admin::BaseHelper
2
+ def current_url?(options)
3
+ url = case options
4
+ when Hash
5
+ url_for options
6
+ else
7
+ options.to_s
8
+ end
9
+ request.request_uri =~ Regexp.new('^' + Regexp.quote(clean(url)))
10
+ end
11
+
12
+ def clean(url)
13
+ uri = URI.parse(url)
14
+ uri.path.gsub(%r{/+}, '/').gsub(%r{/$}, '')
15
+ end
16
+
17
+ def nav_link_to(name, options)
18
+ if current_url?(options)
19
+ %{<strong>#{ link_to name, options }</strong>}
20
+ else
21
+ link_to name, options
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::DashboardHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::ModeratorSessionsHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::ModeratorsHelper
2
+ end
@@ -0,0 +1,6 @@
1
+ class Moderator < ActiveRecord::Base
2
+ acts_as_authentic do |c|
3
+ c.logged_in_timeout = 1.minute
4
+ end
5
+ validates_presence_of :name
6
+ end
@@ -0,0 +1,3 @@
1
+ class ModeratorSession < Authlogic::Session::Base
2
+ logout_on_timeout true
3
+ end
@@ -0,0 +1,3 @@
1
+ <div class="heading">
2
+ <h1>Dashboard</h1>
3
+ </div>
@@ -0,0 +1,57 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html>
4
+ <head>
5
+ <title>Login</title>
6
+ <%= javascript_include_tag :defaults %>
7
+ <%= stylesheet_link_tag "admin/application" %>
8
+ </head>
9
+ <body>
10
+ <div id="header">
11
+ <div class="div1">
12
+ <div class="div2">Admin UI</div>
13
+ </div>
14
+ </div>
15
+ <div id="menu"></div>
16
+ <div id="loginbox">
17
+ <div class="div1">Please enter your login details.</div>
18
+ <div class="div2">
19
+ <% flash.each do |name, msg| %>
20
+ <%= content_tag :div, msg, :class => "flash_#{name}" %>
21
+ <% end %>
22
+ <% form_for @moderator_session, :url => admin_moderator_session_path, :html => { :id => "loginfrm" } do |f| %>
23
+ <table>
24
+ <tbody>
25
+ <tr>
26
+ <td align="center" rowspan="3">
27
+ <%= image_tag "/images/admin/login.png", :alt => "Please enter your login details." %>
28
+ </td>
29
+ </tr>
30
+ <tr>
31
+ <td>
32
+ <%= f.label :email %>:<br/>
33
+ <%= f.text_field :email, :size => 20 %>
34
+ <br/>
35
+ <br/>
36
+ <%= f.label :password %>:<br/>
37
+ <%= f.password_field :password, :size => 20 %>
38
+ </td>
39
+ </tr>
40
+ <tr>
41
+ <td align="right">
42
+ <a class="button" onclick="$('loginfrm').submit();">
43
+ <span class="button_left button_login"></span>
44
+ <span class="button_middle">Login</span>
45
+ <span class="button_right"></span>
46
+ </a>
47
+ <%= f.submit "Login", :class => "nodisp" %>
48
+ </td>
49
+ </tr>
50
+ </tbody>
51
+ </table>
52
+ <% end %>
53
+ </div>
54
+ <div class="div3"></div>
55
+ </div>
56
+ </body>
57
+ </html>
@@ -0,0 +1,42 @@
1
+ <table class="form">
2
+ <tbody>
3
+ <tr>
4
+ <td width="25%">
5
+ <span class="required">*</span>
6
+ <%= form.label :name %>
7
+ </td>
8
+ <td><%= form.text_field :name %></td>
9
+ </tr>
10
+ <tr>
11
+ <td width="25%">
12
+ <span class="required">*</span>
13
+ <%= form.label :email %>
14
+ </td>
15
+ <td><%= form.text_field :email %></td>
16
+ </tr>
17
+ <tr>
18
+ <td width="25%">
19
+ <% if form.object.new_record? %>
20
+ <span class="required">*</span>
21
+ <% end %>
22
+ <%= form.label :password, form.object.new_record? ? nil : "Change password" %>
23
+ </td>
24
+ <td><%= form.password_field :password %></td>
25
+ </tr>
26
+ <tr>
27
+ <td width="25%">
28
+ <% if form.object.new_record? %>
29
+ <span class="required">*</span>
30
+ <% end %>
31
+ <%= form.label :password_confirmation %>
32
+ </td>
33
+ <td><%= form.password_field :password_confirmation %></td>
34
+ </tr>
35
+ <% if current_moderator.admin? %>
36
+ <tr>
37
+ <td width="25%"><%= form.label "Administrator" %></td>
38
+ <td><%= form.check_box :admin %></td>
39
+ </tr>
40
+ <% end %>
41
+ </tbody>
42
+ </table>
@@ -0,0 +1,25 @@
1
+ <div class="heading">
2
+ <h1><%=h @title %></h1>
3
+ <div class="buttons">
4
+ <a class="button" onclick="$('moderatorfrm').submit();">
5
+ <span class="button_left button_save"></span>
6
+ <span class="button_middle">Save</span>
7
+ <span class="button_right"></span>
8
+ </a>
9
+ <a class="button" href="<%= @cancel_url %>">
10
+ <span class="button_left button_cancel"></span>
11
+ <span class="button_middle">Cancel</span>
12
+ <span class="button_right"></span>
13
+ </a>
14
+ </div>
15
+ </div>
16
+ <div class="tabs">
17
+ <a class="selected" href="#">General</a>
18
+ </div>
19
+ <% form_for @moderator, :url => admin_moderator_path(@moderator), :html => { :id => "moderatorfrm" } do |f| %>
20
+ <div class="page">
21
+ <%= f.error_messages %>
22
+ <%= render :partial => "form", :object => f %>
23
+ <%= f.submit "Save", :class => "nodisp" %>
24
+ </div>
25
+ <% end %>
@@ -0,0 +1,35 @@
1
+ <div class="heading">
2
+ <h1>Moderators</h1>
3
+ <div class="buttons">
4
+ <a class="button" href="<%= new_admin_moderator_path %>">
5
+ <span class="button_left button_insert"></span>
6
+ <span class="button_middle">Add</span>
7
+ <span class="button_right"></span>
8
+ </a>
9
+ </div>
10
+ </div>
11
+ <table class="list">
12
+ <thead>
13
+ <tr>
14
+ <td class="left">Name</td>
15
+ <td class="left">Email</td>
16
+ <td class="right">Admin</td>
17
+ <td class="right">Last Login</td>
18
+ <td class="right">Action</td>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <% for moderator in @moderators %>
23
+ <tr class="<%= cycle('even','odd') %>">
24
+ <td class="left"><%=h moderator.name %></td>
25
+ <td class="left"><%=h moderator.email %></td>
26
+ <td class="right"><%= moderator.admin? ? "X" : "" %></td>
27
+ <td class="right"><%= distance_of_time_in_words_to_now(moderator.last_login_at) %> ago</td>
28
+ <td class="right">
29
+ [ <%= link_to "Edit", edit_admin_moderator_path(moderator) %> ]
30
+ [ <%= link_to "Destroy", admin_moderator_path(moderator), :confirm => "Are you sure?", :method => :delete %> ]
31
+ </td>
32
+ </tr>
33
+ <% end %>
34
+ </tbody>
35
+ </table>
@@ -0,0 +1,25 @@
1
+ <div class="heading">
2
+ <h1>Moderators</h1>
3
+ <div class="buttons">
4
+ <a class="button" onclick="$('moderatorfrm').submit();">
5
+ <span class="button_left button_save"></span>
6
+ <span class="button_middle">Save</span>
7
+ <span class="button_right"></span>
8
+ </a>
9
+ <a class="button" href="<%= admin_moderators_path %>">
10
+ <span class="button_left button_cancel"></span>
11
+ <span class="button_middle">Cancel</span>
12
+ <span class="button_right"></span>
13
+ </a>
14
+ </div>
15
+ </div>
16
+ <div class="tabs">
17
+ <a class="selected" href="#">General</a>
18
+ </div>
19
+ <% form_for @moderator, :url => admin_moderators_path, :html => { :id => "moderatorfrm" } do |f| %>
20
+ <div class="page">
21
+ <%= f.error_messages %>
22
+ <%= render :partial => "form", :object => f %>
23
+ <%= f.submit "Save", :class => "nodisp" %>
24
+ </div>
25
+ <% end %>
@@ -0,0 +1,45 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html>
4
+ <head>
5
+ <title><%= h(yield(:title) || "Administration") %></title>
6
+ <%= javascript_include_tag :defaults %>
7
+ <%= stylesheet_link_tag 'admin/application' %>
8
+ <%= yield(:head) %>
9
+ </head>
10
+ <body>
11
+ <div id="header">
12
+ <div class="div1">
13
+ <div class="div2">Admin UI</div>
14
+ <div class="div3">
15
+ Welcome
16
+ <b><%=h current_moderator.name %></b>
17
+ |
18
+ <%= link_to "My Account", edit_admin_account_path %>
19
+ |
20
+ <%= link_to "Logout", admin_moderator_session_path, :method => :delete %><br/>
21
+ </div>
22
+ </div>
23
+ </div>
24
+ <div id="menu">
25
+ <ul id="nav">
26
+ <% Admin.tabs.each do |tab| %>
27
+ <% if tab.display_for?(current_moderator) %>
28
+ <li><%= nav_link_to h(tab.name), tab.path %></li>
29
+ <% end %>
30
+ <% end %>
31
+ </ul>
32
+ </div>
33
+ <div id="container">
34
+ <div id="column_left"></div>
35
+ <div id="content">
36
+ <% flash.each do |name, msg| %>
37
+ <%= content_tag :div, msg, :class => "flash_#{name}" %>
38
+ <% end %>
39
+ <%= yield %>
40
+ </div>
41
+ <div id="column_right"></div>
42
+ </div>
43
+ <div id="footer"></div>
44
+ </body>
45
+ </html>