mirror of
https://github.com/TracksApp/tracks.git
synced 2026-02-03 06:21:49 +01:00
Made the Users Controller RESTful. This obviated the need for the currently functionality of the AdminController, so I removed it and consolidated tests.
git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@409 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
parent
707b8cdf86
commit
109a1847fb
21 changed files with 110 additions and 130 deletions
|
|
@ -1,49 +0,0 @@
|
|||
class AdminController < ApplicationController
|
||||
|
||||
before_filter :admin_login_required
|
||||
|
||||
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 home_path
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -62,6 +62,15 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def admin_login_required
|
||||
unless User.find_by_id_and_is_admin(session['user_id'], true)
|
||||
render :text => "401 Unauthorized: Only admin users are allowed access to this function.", :status => 401
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parse_date_per_user_prefs( s )
|
||||
|
|
|
|||
|
|
@ -1,19 +1,29 @@
|
|||
class UserController < ApplicationController
|
||||
class UsersController < ApplicationController
|
||||
|
||||
if Tracks::Config.auth_schemes.include?('open_id')
|
||||
open_id_consumer
|
||||
before_filter :begin_open_id_auth, :only => :update_auth_type
|
||||
end
|
||||
|
||||
before_filter :admin_login_required, :only => [ :index, :create, :destroy ]
|
||||
|
||||
verify :method => :post,
|
||||
:only => %w( create ),
|
||||
:render => { :text => '403 Forbidden: Only POST requests on this resource are allowed.',
|
||||
:status => 403 }
|
||||
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
|
||||
|
||||
# verify :method => :post,
|
||||
# :only => %w( create ),
|
||||
# :render => { :text => '403 Forbidden: Only POST requests on this resource are allowed.',
|
||||
# :status => 403 }
|
||||
|
||||
# Example usage: curl -H 'Accept: application/xml' -H 'Content-Type: application/xml'
|
||||
# -u admin:up2n0g00d
|
||||
# -d '<request><login>username</login><password>abc123</password></request>'
|
||||
# http://our.tracks.host/user/create
|
||||
# http://our.tracks.host/users
|
||||
#
|
||||
def create
|
||||
if params['exception']
|
||||
|
|
@ -38,6 +48,33 @@ class UserController < ApplicationController
|
|||
render_failure user.errors.to_xml
|
||||
end
|
||||
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
|
||||
|
||||
|
||||
def change_password
|
||||
@page_title = "TRACKS::Change password"
|
||||
|
|
@ -47,7 +84,7 @@ class UserController < ApplicationController
|
|||
if do_change_password_for(@user)
|
||||
redirect_to :controller => 'preferences'
|
||||
else
|
||||
redirect_to :controller => 'user', :action => 'change_password'
|
||||
redirect_to :action => 'change_password'
|
||||
notify :warning, "There was a problem saving the password. Please retry."
|
||||
end
|
||||
end
|
||||
|
|
@ -77,7 +114,7 @@ class UserController < ApplicationController
|
|||
redirect_to :controller => 'preferences'
|
||||
else
|
||||
notify :warning, "There was a problem updating your authentication type: #{ @user.errors.full_messages.join(', ')}"
|
||||
redirect_to :controller => 'user', :action => 'change_auth_type'
|
||||
redirect_to :action => 'change_auth_type'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -121,7 +158,7 @@ class UserController < ApplicationController
|
|||
@user.crypt_word
|
||||
@user.save
|
||||
notify :notice, "New token successfully generated"
|
||||
redirect_to :controller => 'user', :action => 'preferences'
|
||||
redirect_to :controller => 'preferences', :action => 'index'
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
module AdminHelper
|
||||
end
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
module TodosHelper
|
||||
|
||||
require 'user_controller'
|
||||
require 'users_controller'
|
||||
# Counts the number of uncompleted items in the specified context
|
||||
#
|
||||
def count_items(context)
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
<h1>Admin#create</h1>
|
||||
<p>Find me in app/views/admin/create.rhtml</p>
|
||||
|
|
@ -1 +0,0 @@
|
|||
page.notify :error, @error_message || "An error occurred on the server.", 8.0
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
<h1>Admin#update</h1>
|
||||
<p>Find me in app/views/admin/update.rhtml</p>
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
<li><%= navigation_link( "Preferences", {:controller => "preferences", :action => "index"}, {:accesskey => "u", :title => "Show my preferences"} ) %></li>
|
||||
<li><%= navigation_link( "Import/Export", {:controller => "data", :action => "index"}, {:accesskey => "i", :title => "Import and export data"} ) %></li>
|
||||
<% if @user.is_admin? -%>
|
||||
<li><%= navigation_link("Admin", {:controller => "admin", :action => "index"}, {:accesskey => "a", :title => "Add or delete users"} ) %></li>
|
||||
<li><%= navigation_link("Admin", users_path, {:accesskey => "a", :title => "Add or delete users"} ) %></li>
|
||||
<% end -%>
|
||||
<li><%= navigation_link(image_tag("feed-icon.png", :size => "16X16", :border => 0), {:controller => "feedlist", :action => "index"}, :title => "See a list of available feeds" ) %></li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
<div class="description">Token (for feeds and API use):</div>
|
||||
<div id="token><span class="highlight"><%= @user.word %></span></div>
|
||||
<div class="token_regenerate">
|
||||
<%= button_to "Generate a new token", { :controller => 'user', :action => 'refresh_token'},
|
||||
<%= button_to "Generate a new token", refresh_token_user_path(@user),
|
||||
:confirm => "Are you sure? Generating a new token will replace the existing one and break any external usages of this token." %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -44,18 +44,18 @@
|
|||
<% if Tracks::Config.auth_schemes.length > 1 %>
|
||||
<p>Your authentication type is <span class="highlight"><%= @user.auth_type %></span>.
|
||||
<div class="actions">
|
||||
<%= link_to "Change your authentication type »", { :controller => 'user', :action => 'change_auth_type'}, :class => 'edit_link' %>
|
||||
<%= link_to "Change your authentication type »", change_auth_type_user_path(@user), :class => 'edit_link' %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @user.auth_type == 'database' %>
|
||||
<div class="actions">
|
||||
<%= link_to 'Change your password »', :controller => 'user', :action => 'change_password' %>
|
||||
<%= link_to 'Change your password »', change_password_user_path(@user) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @user.auth_type == 'open_id' %>
|
||||
<p>Your Open ID URL is <span class="highlight"><%= @user.open_id_url %></span>.
|
||||
<div class="actions">
|
||||
<%= link_to 'Change Your Identity URL »', :controller => 'user', :action => 'change_auth_type' %></p>
|
||||
<%= link_to 'Change Your Identity URL »', change_auth_type_user_path(@user) %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
<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>
|
||||
<td><%= !user.is_admin? ? link_to_remote( image_tag("blank.png", :title =>"Destroy user", :class=>"delete_item"), {:url => user_path(user), :method => :delete, :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>
|
||||
|
|
@ -14,11 +14,6 @@ ActionController::Routing::Routes.draw do |map|
|
|||
# instead of a file named 'wsdl'
|
||||
#map.connect ':controller/service.wsdl', :action => 'wsdl'
|
||||
|
||||
|
||||
# Admin Routes
|
||||
map.connect 'admin', :controller => 'admin', :action => 'index'
|
||||
map.connect 'admin/destroy/:id', :controller => 'admin', :action => 'destroy', :requirements => {:id => /\d+/}
|
||||
|
||||
# Mobile/lite version
|
||||
map.connect 'mobile', :controller => 'mobile', :action => 'index'
|
||||
map.connect 'mobile/add_action', :controller => 'mobile', :action => 'show_add_form'
|
||||
|
|
@ -28,6 +23,11 @@ ActionController::Routing::Routes.draw do |map|
|
|||
map.connect 'logout', :controller => 'login', :action => 'logout'
|
||||
map.connect 'signup', :controller => 'login', :action => 'signup'
|
||||
|
||||
map.resources :users,
|
||||
:member => {:change_password => :get, :update_password => :post,
|
||||
:change_auth_type => :get, :update_auth_type => :post,
|
||||
:refresh_token => :post }
|
||||
|
||||
# ToDo Routes
|
||||
map.resources :todos,
|
||||
:member => {:toggle_check => :post},
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@
|
|||
<ul>
|
||||
<li>In a browser (if you haven't loaded the example data), go to <code>http://0.0.0.0:3000/signup</code>. This will allow you to choose a username and password for the admin user. Thereafter, anyone else trying to access <code>/signup</code> will get a message that they are not allowed to sign up, and are given your email address to contact for permission. When you are logged in as the admin user, you can visit <code>/signup</code> to sign up additional users (who will not be able to view any of your next actions, contexts, projects or notes, but can set up their own separate tasks), and visit <code>/login</code> to login yourself.</li>
|
||||
<li>Add some contexts at <code>http://0.0.0.0:3000/contexts</code> (you must do this before adding any next actions) and projects at <code>http://0.0.0.0:3000/projects</code> and then you're ready to add all your next actions.</li>
|
||||
<li>You can set various preferences by visiting <code>http://0.0.0.0:3000/user/preferences</code>. These are stored on a per-user basis in the database.</li>
|
||||
<li>You can set various preferences by visiting <code>http://0.0.0.0:3000/users/preferences</code>. These are stored on a per-user basis in the database.</li>
|
||||
<li>Have fun!</li>
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
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 home_path
|
||||
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
|
||||
|
|
@ -1,21 +1,46 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'user_controller'
|
||||
require 'users_controller'
|
||||
require 'user'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class UserController; def rescue_action(e) raise e end; end
|
||||
class UsersController; def rescue_action(e) raise e end; end
|
||||
|
||||
class UserControllerTest < Test::Unit::TestCase
|
||||
class UsersControllerTest < Test::Unit::TestCase
|
||||
fixtures :users
|
||||
|
||||
def setup
|
||||
assert_equal "test", ENV['RAILS_ENV']
|
||||
assert_equal "change-me", Tracks::Config.salt
|
||||
@controller = UserController.new
|
||||
@controller = UsersController.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 home_path
|
||||
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
|
||||
|
||||
def test_update_password_successful
|
||||
get :change_password # should fail because no login
|
||||
assert_redirected_to :controller => 'login', :action => 'login'
|
||||
|
|
@ -36,7 +61,7 @@ class UserControllerTest < Test::Unit::TestCase
|
|||
assert_redirected_to :controller => 'login', :action => 'login'
|
||||
@request.session['user_id'] = users(:admin_user).id # log in the admin user
|
||||
post :update_password, :updateuser => {:password => 'newpassword', :password_confirmation => 'wrong'}
|
||||
assert_redirected_to :controller => 'user', :action => 'change_password'
|
||||
assert_redirected_to :controller => 'users', :action => 'change_password'
|
||||
assert users(:admin_user).save, false
|
||||
assert_equal flash[:warning], 'There was a problem saving the password. Please retry.'
|
||||
end
|
||||
|
|
@ -46,7 +71,7 @@ class UserControllerTest < Test::Unit::TestCase
|
|||
assert_redirected_to :controller => 'login', :action => 'login'
|
||||
@request.session['user_id'] = users(:admin_user).id # log in the admin user
|
||||
post :update_password, :updateuser => {:password => 'ba', :password_confirmation => 'ba'}
|
||||
assert_redirected_to :controller => 'user', :action => 'change_password'
|
||||
assert_redirected_to :controller => 'users', :action => 'change_password'
|
||||
assert users(:admin_user).save, false
|
||||
# For some reason, no errors are being raised now.
|
||||
#assert_equal 1, users(:admin_user).errors.count
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'user_controller'
|
||||
require 'users_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class UserController; def rescue_action(e) raise e end; end
|
||||
class UsersController; def rescue_action(e) raise e end; end
|
||||
|
||||
class CreateUserControllerTest < ActionController::IntegrationTest
|
||||
fixtures :users
|
||||
|
|
@ -21,7 +21,7 @@ class CreateUserControllerTest < ActionController::IntegrationTest
|
|||
|
||||
def test_fails_with_401_if_not_admin_user
|
||||
authenticated_post_xml_to_user_create @@foobar_postdata, users(:other_user).login, 'sesame'
|
||||
assert_401_unauthorized
|
||||
assert_401_unauthorized_admin
|
||||
end
|
||||
|
||||
def test_content_type_must_be_xml
|
||||
|
|
@ -71,13 +71,13 @@ class CreateUserControllerTest < ActionController::IntegrationTest
|
|||
end
|
||||
|
||||
def test_fails_with_get_verb
|
||||
authenticated_get_xml "/user/create", users(:admin_user).login, 'abracadabra', {}
|
||||
authenticated_get_xml "/users", users(:admin_user).login, 'abracadabra', {}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authenticated_post_xml_to_user_create(postdata = @@foobar_postdata, user = users(:admin_user).login, password = 'abracadabra', headers = {})
|
||||
authenticated_post_xml "/user/create", user, password, postdata, headers
|
||||
authenticated_post_xml "/users", user, password, postdata, headers
|
||||
end
|
||||
|
||||
def assert_404_invalid_xml
|
||||
|
|
|
|||
|
|
@ -86,5 +86,11 @@ class ActionController::IntegrationTest
|
|||
def assert_401_unauthorized
|
||||
assert_response_and_body 401, "401 Unauthorized: You are not authorized to interact with Tracks."
|
||||
end
|
||||
|
||||
def assert_401_unauthorized_admin
|
||||
assert_response_and_body 401, "401 Unauthorized: Only admin users are allowed access to this function."
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue