mirror of
https://github.com/TracksApp/tracks.git
synced 2026-02-03 06:21:49 +01:00
Created an admin controller that allows the admin user (only) to view 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
This commit is contained in:
parent
74ad2b9cc7
commit
26c7a1e6f1
13 changed files with 180 additions and 22 deletions
51
tracks/app/controllers/admin_controller.rb
Normal file
51
tracks/app/controllers/admin_controller.rb
Normal file
|
|
@ -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
tracks/app/helpers/admin_helper.rb
Normal file
2
tracks/app/helpers/admin_helper.rb
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
module AdminHelper
|
||||
end
|
||||
|
|
@ -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
|
||||
|
|
|
|||
2
tracks/app/views/admin/create.rhtml
Normal file
2
tracks/app/views/admin/create.rhtml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<h1>Admin#create</h1>
|
||||
<p>Find me in app/views/admin/create.rhtml</p>
|
||||
7
tracks/app/views/admin/destroy.rjs
Normal file
7
tracks/app/views/admin/destroy.rjs
Normal file
|
|
@ -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
tracks/app/views/admin/error.rjs
Normal file
1
tracks/app/views/admin/error.rjs
Normal file
|
|
@ -0,0 +1 @@
|
|||
page.notify :error, @error_message || "An error occurred on the server.", 8.0
|
||||
36
tracks/app/views/admin/index.rhtml
Normal file
36
tracks/app/views/admin/index.rhtml
Normal file
|
|
@ -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> </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" } ) : " " %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<p>
|
||||
<%= link_to "« Previous page", { :page => @user_pages.current.previous } if @user_pages.current.previous %>
|
||||
<%= link_to "Next page »", { :page => @user_pages.current.next } if @user_pages.current.next %>
|
||||
</p>
|
||||
|
||||
<p><%= link_to 'Signup new user', :controller => 'login', :action => 'signup' %></p>
|
||||
2
tracks/app/views/admin/update.rhtml
Normal file
2
tracks/app/views/admin/update.rhtml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<h1>Admin#update</h1>
|
||||
<p>Find me in app/views/admin/update.rhtml</p>
|
||||
|
|
@ -35,9 +35,6 @@
|
|||
page.select('.notes').each { |e| e.toggle }
|
||||
end
|
||||
-%> |
|
||||
<% if @user.is_admin? -%>
|
||||
<%= link_to "Add users", :controller => "login", :action => "signup" %> |
|
||||
<% end -%>
|
||||
<%= link_to "Logout (#{@user.display_name}) »", :controller => "login", :action=>"logout"%>
|
||||
</div>
|
||||
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@ ActionController::Routing::Routes.draw do |map|
|
|||
|
||||
# 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'
|
||||
|
|
|
|||
|
|
@ -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|
|
||||
|
|
@ -56,7 +56,7 @@ ActiveRecord::Schema.define(:version => 20) do
|
|||
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
|
||||
|
|
@ -70,23 +70,23 @@ ActiveRecord::Schema.define(:version => 20) do
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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
tracks/test/functional/admin_controller_test.rb
Normal file
41
tracks/test/functional/admin_controller_test.rb
Normal file
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue