Skip to content

Commit

Permalink
Created an admin controller that allows the admin user (only) to view…
Browse files Browse the repository at this point in the history
… the users on the system and destroy and signup new users. Destroying a user deletes all of their actions, contexts, projects and notes.

The link to the admin page only appears when an admin user is logged in, and the signup link is now on the admin page, rather than appearing in the mini-links at the top of the page.

The page also lists some statistics associated with each user (the number of actions, contexts, projects etc. each user has).

git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@371 a4c988fc-2ded-0310-b66e-134b36920a42
  • Loading branch information
bsag committed Dec 10, 2006
1 parent 74ad2b9 commit 26c7a1e
Show file tree
Hide file tree
Showing 13 changed files with 180 additions and 22 deletions.
51 changes: 51 additions & 0 deletions tracks/app/controllers/admin_controller.rb
@@ -0,0 +1,51 @@
class AdminController < ApplicationController

before_filter :login_required
before_filter :admin_login_required
layout 'standard'

def index
@user_pages, @users = paginate :users, :order => 'login ASC', :per_page => 10
@total_users = User.find(:all).size
# When we call login/signup from the admin page
# we store the URL so that we get returned here when signup is successful
store_location
end

def destroy
@deleted_user = User.find_by_id(params[:id])
@saved = @deleted_user.destroy
@total_users = User.find(:all).size

respond_to do |wants|

wants.html do
if @saved
notify :notice, "Successfully deleted user #{@deleted_user.login}", 2.0
redirect_to :action => 'index'
else
notify :error, "Failed to delete user #{@deleted_user.login}", 2.0
redirect_to :action => 'index'
end
end

wants.js do
render
end

wants.xml { render :text => '200 OK. User deleted.', :status => 200 }

end
end

protected

def admin_login_required
unless User.find_by_id_and_is_admin(session['user_id'], true)
notify :error, "Only admin users are allowed access to this function"
redirect_to :controller => 'todo', :action => 'index'
return false
end
end

end
2 changes: 2 additions & 0 deletions tracks/app/helpers/admin_helper.rb
@@ -0,0 +1,2 @@
module AdminHelper
end
8 changes: 4 additions & 4 deletions tracks/app/models/user.rb
@@ -1,10 +1,10 @@
require 'digest/sha1'

class User < ActiveRecord::Base
has_many :contexts, :order => "position ASC"
has_many :projects, :order => "position ASC"
has_many :todos, :order => "completed_at DESC, created_at DESC"
has_many :notes, :order => "created_at DESC"
has_many :contexts, :order => "position ASC", :dependent => :delete_all
has_many :projects, :order => "position ASC", :dependent => :delete_all
has_many :todos, :order => "completed_at DESC, created_at DESC", :dependent => :delete_all
has_many :notes, :order => "created_at DESC", :dependent => :delete_all
has_one :preference

attr_protected :is_admin
Expand Down
2 changes: 2 additions & 0 deletions tracks/app/views/admin/create.rhtml
@@ -0,0 +1,2 @@
<h1>Admin#create</h1>
<p>Find me in app/views/admin/create.rhtml</p>
7 changes: 7 additions & 0 deletions tracks/app/views/admin/destroy.rjs
@@ -0,0 +1,7 @@
if @saved
page["user-#{@deleted_user.id}"].remove
page['user_count'].replace_html @total_users.to_s
page.notify :notice, "User #{@deleted_user.login} was successfully destroyed", 2.0
else
page.notify :error, "There was an error deleting the user #{@deleted_user.login}", 8.0
end
1 change: 1 addition & 0 deletions tracks/app/views/admin/error.rjs
@@ -0,0 +1 @@
page.notify :error, @error_message || "An error occurred on the server.", 8.0
36 changes: 36 additions & 0 deletions tracks/app/views/admin/index.rhtml
@@ -0,0 +1,36 @@
<h1>Manage users</h1>

<p>You have a total of <span id="user_count"><%= @total_users %></span> users</p>

<table class="users_table">
<tr>
<th>Login</th>
<th>Full name</th>
<th>Authorization type</th>
<th>Open ID URL</th>
<th>Total actions</th>
<th>Total contexts</th>
<th>Total projects</th>
<th>Total notes</th>
<th>&nbsp;</th>
</tr>
<% for user in @users %>
<tr <%= "class=\"highlight\"" if user.is_admin? %> id="user-<%= user.id %>">
<td><%=h user.login %></td>
<td><%=h user.last_name? ? user.display_name : '-' %></td>
<td><%= h user.auth_type %></td>
<td><%= h user.open_id_url || '-' %></td>
<td><%= h user.todos.size %></td>
<td><%= h user.contexts.size %></td>
<td><%= h user.projects.size %></td>
<td><%= h user.notes.size %></td>
<td><%= !user.is_admin? ? link_to_remote( image_tag("blank.png", :title =>"Destroy user", :class=>"delete_item"), {:url => { :controller => 'admin', :action => 'destroy', :id => user.id }, :confirm => "Warning: this will delete user \'#{user.login}\', all their actions, contexts, project and notes. Are you sure that you want to continue?" }, { :class => "icon" } ) : "&nbsp;" %></td>
</tr>
<% end %>
</table>
<p>
<%= link_to "&laquo; Previous page", { :page => @user_pages.current.previous } if @user_pages.current.previous %> &nbsp;
<%= link_to "Next page &raquo;", { :page => @user_pages.current.next } if @user_pages.current.next %>
</p>

<p><%= link_to 'Signup new user', :controller => 'login', :action => 'signup' %></p>
2 changes: 2 additions & 0 deletions tracks/app/views/admin/update.rhtml
@@ -0,0 +1,2 @@
<h1>Admin#update</h1>
<p>Find me in app/views/admin/update.rhtml</p>
6 changes: 3 additions & 3 deletions tracks/app/views/layouts/standard.rhtml
Expand Up @@ -35,9 +35,6 @@
page.select('.notes').each { |e| e.toggle }
end
-%>&nbsp;|&nbsp;
<% if @user.is_admin? -%>
<%= link_to "Add users", :controller => "login", :action => "signup" %>&nbsp;|&nbsp;
<% end -%>
<%= link_to "Logout (#{@user.display_name}) »", :controller => "login", :action=>"logout"%>
</div>

Expand All @@ -50,6 +47,9 @@
<li><%= navigation_link( "Done", {:controller => "todo", :action => "completed"}, {:accesskey=>"d", :title=>"Completed"} ) %></li>
<li><%= navigation_link( "Notes", {:controller => "note", :action => "index"}, {:accesskey => "o", :title => "Show all notes"} ) %></li>
<li><%= navigation_link( "Preferences", {:controller => "user", :action => "preferences"}, {:accesskey => "u", :title => "Show my preferences"} ) %></li>
<% if @user.is_admin? -%>
<li><%= navigation_link("Admin", {:controller => "admin", :action => "index"}, {:accesskey => "a", :title => "Add or delete users"} ) %></li>
<% end -%>
<li><%= navigation_link(image_tag("feed-icon.png", :size => "16X16", :border => 0), {:controller => "feed", :action => "index"}, :title => "See a list of available feeds" ) %></li>
</ul>
</div>
Expand Down
5 changes: 5 additions & 0 deletions tracks/config/routes.rb
Expand Up @@ -16,6 +16,11 @@

# Index Route
map.connect '', :controller => 'todo', :action => 'index'

# Admin Routes
map.connect 'admin', :controller => 'admin', :action => 'index'
# map.connect 'admin/signup', :controller => 'admin', :action => 'create'
map.connect 'admin/destroy/:id', :controller => 'admin', :action => 'destroy', :requirements => {:id => /\d+/}

# Mobile/lite version
map.connect 'mobile', :controller => 'mobile', :action => 'index'
Expand Down
26 changes: 13 additions & 13 deletions tracks/db/schema.rb
Expand Up @@ -5,10 +5,10 @@
ActiveRecord::Schema.define(:version => 20) do

create_table "contexts", :force => true do |t|
t.column "name", :string, :default => "", :null => false
t.column "hide", :integer, :limit => 4, :default => 0, :null => false
t.column "position", :integer, :default => 0, :null => false
t.column "user_id", :integer, :default => 0, :null => false
t.column "name", :string, :default => "", :null => false
t.column "position", :integer, :default => 0, :null => false
t.column "hide", :boolean, :default => false
t.column "user_id", :integer, :default => 1
end

create_table "notes", :force => true do |t|
Expand Down Expand Up @@ -56,7 +56,7 @@
create_table "projects", :force => true do |t|
t.column "name", :string, :default => "", :null => false
t.column "position", :integer, :default => 0, :null => false
t.column "user_id", :integer, :default => 0, :null => false
t.column "user_id", :integer, :default => 1
t.column "description", :text
t.column "state", :string, :limit => 20, :default => "active", :null => false
end
Expand All @@ -70,23 +70,23 @@
add_index "sessions", ["session_id"], :name => "sessions_session_id_index"

create_table "todos", :force => true do |t|
t.column "context_id", :integer, :default => 0, :null => false
t.column "description", :string, :limit => 100, :default => "", :null => false
t.column "context_id", :integer, :default => 0, :null => false
t.column "project_id", :integer
t.column "description", :string, :default => "", :null => false
t.column "notes", :text
t.column "created_at", :datetime
t.column "due", :date
t.column "completed_at", :datetime
t.column "project_id", :integer
t.column "user_id", :integer, :default => 0, :null => false
t.column "user_id", :integer, :default => 1
t.column "show_from", :date
t.column "state", :string, :limit => 20, :default => "immediate", :null => false
t.column "state", :string, :limit => 20, :default => "immediate", :null => false
end

create_table "users", :force => true do |t|
t.column "login", :string, :limit => 80
t.column "password", :string, :limit => 40
t.column "login", :string, :limit => 80, :default => "", :null => false
t.column "password", :string, :limit => 40, :default => "", :null => false
t.column "word", :string
t.column "is_admin", :integer, :limit => 4, :default => 0, :null => false
t.column "is_admin", :boolean, :default => false, :null => false
t.column "first_name", :string
t.column "last_name", :string
t.column "auth_type", :string, :default => "database", :null => false
Expand Down
15 changes: 13 additions & 2 deletions tracks/public/stylesheets/standard.css
Expand Up @@ -206,7 +206,7 @@ h2 a:hover {
.item-container-drop-target {
border:2px inset black;
}
.container a.icon {
a.icon {
float: left;
vertical-align: middle;
background-color: transparent;
Expand Down Expand Up @@ -728,4 +728,15 @@ div.page_name_auto_complete ul strong.highlight {
color: #800;
margin: 0;
padding: 0;
}
}

table.users_table {
width: 100%;
text-align: center;
border: 1px solid #666;
background-color: #fff;
border-spacing: 0px;
}

.users_table th {color: #fff; background-color: #000;}
.users_table td {border: none;}
41 changes: 41 additions & 0 deletions tracks/test/functional/admin_controller_test.rb
@@ -0,0 +1,41 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'admin_controller'

# Re-raise errors caught by the controller.
class AdminController; def rescue_action(e) raise e end; end

class AdminControllerTest < Test::Unit::TestCase
fixtures :users, :preferences, :projects, :contexts, :todos

def setup
@controller = AdminController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end

def test_get_index_when_not_logged_in
get :index
assert_redirected_to :controller => 'login', :action => 'login'
end

def test_get_index_by_nonadmin
@request.session['user_id'] = users(:other_user).id
get :index
assert_redirected_to :controller => 'todo', :action => 'index'
end

def test_get_index_by_admin
@request.session['user_id'] = users(:admin_user).id
get :index
assert_response :success
end

def test_destroy_user
@no_users_before = User.find(:all).size
@request.session['user_id'] = users(:admin_user).id
xhr :post, :destroy, :id => 3
assert_rjs :page, "user-3", :remove
assert_equal @no_users_before-1, User.find(:all).size
end

end

0 comments on commit 26c7a1e

Please sign in to comment.