##// END OF EJS Templates
Expose roles details via REST API (#11502)....
Jean-Philippe Lang -
r10409:ad94777d9c24
parent child
Show More
@@ -0,0 +1,9
1 api.role do
2 api.id @role.id
3 api.name @role.name
4 api.array :permissions do
5 @role.permissions.each do |perm|
6 api.permission(perm.to_s)
7 end
8 end
9 end
@@ -1,102 +1,107
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class RolesController < ApplicationController
18 class RolesController < ApplicationController
19 layout 'admin'
19 layout 'admin'
20
20
21 before_filter :require_admin, :except => :index
21 before_filter :require_admin, :except => [:index, :show]
22 before_filter :require_admin_or_api_request, :only => :index
22 before_filter :require_admin_or_api_request, :only => [:index, :show]
23 before_filter :find_role, :only => [:edit, :update, :destroy]
23 before_filter :find_role, :only => [:show, :edit, :update, :destroy]
24 accept_api_auth :index
25
24
26 def index
25 def index
27 respond_to do |format|
26 respond_to do |format|
28 format.html {
27 format.html {
29 @role_pages, @roles = paginate :roles, :per_page => 25, :order => 'builtin, position'
28 @role_pages, @roles = paginate :roles, :per_page => 25, :order => 'builtin, position'
30 render :action => "index", :layout => false if request.xhr?
29 render :action => "index", :layout => false if request.xhr?
31 }
30 }
32 format.api {
31 format.api {
33 @roles = Role.givable.all
32 @roles = Role.givable.all
34 }
33 }
35 end
34 end
36 end
35 end
37
36
37 def show
38 respond_to do |format|
39 format.api
40 end
41 end
42
38 def new
43 def new
39 # Prefills the form with 'Non member' role permissions by default
44 # Prefills the form with 'Non member' role permissions by default
40 @role = Role.new(params[:role] || {:permissions => Role.non_member.permissions})
45 @role = Role.new(params[:role] || {:permissions => Role.non_member.permissions})
41 if params[:copy].present? && @copy_from = Role.find_by_id(params[:copy])
46 if params[:copy].present? && @copy_from = Role.find_by_id(params[:copy])
42 @role.copy_from(@copy_from)
47 @role.copy_from(@copy_from)
43 end
48 end
44 @roles = Role.sorted.all
49 @roles = Role.sorted.all
45 end
50 end
46
51
47 def create
52 def create
48 @role = Role.new(params[:role])
53 @role = Role.new(params[:role])
49 if request.post? && @role.save
54 if request.post? && @role.save
50 # workflow copy
55 # workflow copy
51 if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from]))
56 if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from]))
52 @role.workflow_rules.copy(copy_from)
57 @role.workflow_rules.copy(copy_from)
53 end
58 end
54 flash[:notice] = l(:notice_successful_create)
59 flash[:notice] = l(:notice_successful_create)
55 redirect_to :action => 'index'
60 redirect_to :action => 'index'
56 else
61 else
57 @roles = Role.sorted.all
62 @roles = Role.sorted.all
58 render :action => 'new'
63 render :action => 'new'
59 end
64 end
60 end
65 end
61
66
62 def edit
67 def edit
63 end
68 end
64
69
65 def update
70 def update
66 if request.put? and @role.update_attributes(params[:role])
71 if request.put? and @role.update_attributes(params[:role])
67 flash[:notice] = l(:notice_successful_update)
72 flash[:notice] = l(:notice_successful_update)
68 redirect_to :action => 'index'
73 redirect_to :action => 'index'
69 else
74 else
70 render :action => 'edit'
75 render :action => 'edit'
71 end
76 end
72 end
77 end
73
78
74 def destroy
79 def destroy
75 @role.destroy
80 @role.destroy
76 redirect_to :action => 'index'
81 redirect_to :action => 'index'
77 rescue
82 rescue
78 flash[:error] = l(:error_can_not_remove_role)
83 flash[:error] = l(:error_can_not_remove_role)
79 redirect_to :action => 'index'
84 redirect_to :action => 'index'
80 end
85 end
81
86
82 def permissions
87 def permissions
83 @roles = Role.sorted.all
88 @roles = Role.sorted.all
84 @permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
89 @permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
85 if request.post?
90 if request.post?
86 @roles.each do |role|
91 @roles.each do |role|
87 role.permissions = params[:permissions][role.id.to_s]
92 role.permissions = params[:permissions][role.id.to_s]
88 role.save
93 role.save
89 end
94 end
90 flash[:notice] = l(:notice_successful_update)
95 flash[:notice] = l(:notice_successful_update)
91 redirect_to :action => 'index'
96 redirect_to :action => 'index'
92 end
97 end
93 end
98 end
94
99
95 private
100 private
96
101
97 def find_role
102 def find_role
98 @role = Role.find(params[:id])
103 @role = Role.find(params[:id])
99 rescue ActiveRecord::RecordNotFound
104 rescue ActiveRecord::RecordNotFound
100 render_404
105 render_404
101 end
106 end
102 end
107 end
@@ -1,344 +1,344
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 RedmineApp::Application.routes.draw do
18 RedmineApp::Application.routes.draw do
19 root :to => 'welcome#index', :as => 'home'
19 root :to => 'welcome#index', :as => 'home'
20
20
21 match 'login', :to => 'account#login', :as => 'signin'
21 match 'login', :to => 'account#login', :as => 'signin'
22 match 'logout', :to => 'account#logout', :as => 'signout'
22 match 'logout', :to => 'account#logout', :as => 'signout'
23 match 'account/register', :to => 'account#register', :via => [:get, :post], :as => 'register'
23 match 'account/register', :to => 'account#register', :via => [:get, :post], :as => 'register'
24 match 'account/lost_password', :to => 'account#lost_password', :via => [:get, :post], :as => 'lost_password'
24 match 'account/lost_password', :to => 'account#lost_password', :via => [:get, :post], :as => 'lost_password'
25 match 'account/activate', :to => 'account#activate', :via => :get
25 match 'account/activate', :to => 'account#activate', :via => :get
26
26
27 match '/news/preview', :controller => 'previews', :action => 'news', :as => 'preview_news'
27 match '/news/preview', :controller => 'previews', :action => 'news', :as => 'preview_news'
28 match '/issues/preview/new/:project_id', :to => 'previews#issue', :as => 'preview_new_issue'
28 match '/issues/preview/new/:project_id', :to => 'previews#issue', :as => 'preview_new_issue'
29 match '/issues/preview/edit/:id', :to => 'previews#issue', :as => 'preview_edit_issue'
29 match '/issues/preview/edit/:id', :to => 'previews#issue', :as => 'preview_edit_issue'
30 match '/issues/preview', :to => 'previews#issue', :as => 'preview_issue'
30 match '/issues/preview', :to => 'previews#issue', :as => 'preview_issue'
31
31
32 match 'projects/:id/wiki', :to => 'wikis#edit', :via => :post
32 match 'projects/:id/wiki', :to => 'wikis#edit', :via => :post
33 match 'projects/:id/wiki/destroy', :to => 'wikis#destroy', :via => [:get, :post]
33 match 'projects/:id/wiki/destroy', :to => 'wikis#destroy', :via => [:get, :post]
34
34
35 match 'boards/:board_id/topics/new', :to => 'messages#new', :via => [:get, :post]
35 match 'boards/:board_id/topics/new', :to => 'messages#new', :via => [:get, :post]
36 get 'boards/:board_id/topics/:id', :to => 'messages#show', :as => 'board_message'
36 get 'boards/:board_id/topics/:id', :to => 'messages#show', :as => 'board_message'
37 match 'boards/:board_id/topics/quote/:id', :to => 'messages#quote', :via => [:get, :post]
37 match 'boards/:board_id/topics/quote/:id', :to => 'messages#quote', :via => [:get, :post]
38 get 'boards/:board_id/topics/:id/edit', :to => 'messages#edit'
38 get 'boards/:board_id/topics/:id/edit', :to => 'messages#edit'
39
39
40 post 'boards/:board_id/topics/preview', :to => 'messages#preview'
40 post 'boards/:board_id/topics/preview', :to => 'messages#preview'
41 post 'boards/:board_id/topics/:id/replies', :to => 'messages#reply'
41 post 'boards/:board_id/topics/:id/replies', :to => 'messages#reply'
42 post 'boards/:board_id/topics/:id/edit', :to => 'messages#edit'
42 post 'boards/:board_id/topics/:id/edit', :to => 'messages#edit'
43 post 'boards/:board_id/topics/:id/destroy', :to => 'messages#destroy'
43 post 'boards/:board_id/topics/:id/destroy', :to => 'messages#destroy'
44
44
45 # Misc issue routes. TODO: move into resources
45 # Misc issue routes. TODO: move into resources
46 match '/issues/auto_complete', :to => 'auto_completes#issues', :via => :get, :as => 'auto_complete_issues'
46 match '/issues/auto_complete', :to => 'auto_completes#issues', :via => :get, :as => 'auto_complete_issues'
47 match '/issues/context_menu', :to => 'context_menus#issues', :as => 'issues_context_menu'
47 match '/issues/context_menu', :to => 'context_menus#issues', :as => 'issues_context_menu'
48 match '/issues/changes', :to => 'journals#index', :as => 'issue_changes'
48 match '/issues/changes', :to => 'journals#index', :as => 'issue_changes'
49 match '/issues/:id/quoted', :to => 'journals#new', :id => /\d+/, :via => :post, :as => 'quoted_issue'
49 match '/issues/:id/quoted', :to => 'journals#new', :id => /\d+/, :via => :post, :as => 'quoted_issue'
50
50
51 match '/journals/diff/:id', :to => 'journals#diff', :id => /\d+/, :via => :get
51 match '/journals/diff/:id', :to => 'journals#diff', :id => /\d+/, :via => :get
52 match '/journals/edit/:id', :to => 'journals#edit', :id => /\d+/, :via => [:get, :post]
52 match '/journals/edit/:id', :to => 'journals#edit', :id => /\d+/, :via => [:get, :post]
53
53
54 match '/projects/:project_id/issues/gantt', :to => 'gantts#show'
54 match '/projects/:project_id/issues/gantt', :to => 'gantts#show'
55 match '/issues/gantt', :to => 'gantts#show'
55 match '/issues/gantt', :to => 'gantts#show'
56
56
57 match '/projects/:project_id/issues/calendar', :to => 'calendars#show'
57 match '/projects/:project_id/issues/calendar', :to => 'calendars#show'
58 match '/issues/calendar', :to => 'calendars#show'
58 match '/issues/calendar', :to => 'calendars#show'
59
59
60 match 'projects/:id/issues/report', :to => 'reports#issue_report', :via => :get
60 match 'projects/:id/issues/report', :to => 'reports#issue_report', :via => :get
61 match 'projects/:id/issues/report/:detail', :to => 'reports#issue_report_details', :via => :get
61 match 'projects/:id/issues/report/:detail', :to => 'reports#issue_report_details', :via => :get
62
62
63 match 'my/account', :controller => 'my', :action => 'account', :via => [:get, :post]
63 match 'my/account', :controller => 'my', :action => 'account', :via => [:get, :post]
64 match 'my/account/destroy', :controller => 'my', :action => 'destroy', :via => [:get, :post]
64 match 'my/account/destroy', :controller => 'my', :action => 'destroy', :via => [:get, :post]
65 match 'my/page', :controller => 'my', :action => 'page', :via => :get
65 match 'my/page', :controller => 'my', :action => 'page', :via => :get
66 match 'my', :controller => 'my', :action => 'index', :via => :get # Redirects to my/page
66 match 'my', :controller => 'my', :action => 'index', :via => :get # Redirects to my/page
67 match 'my/reset_rss_key', :controller => 'my', :action => 'reset_rss_key', :via => :post
67 match 'my/reset_rss_key', :controller => 'my', :action => 'reset_rss_key', :via => :post
68 match 'my/reset_api_key', :controller => 'my', :action => 'reset_api_key', :via => :post
68 match 'my/reset_api_key', :controller => 'my', :action => 'reset_api_key', :via => :post
69 match 'my/password', :controller => 'my', :action => 'password', :via => [:get, :post]
69 match 'my/password', :controller => 'my', :action => 'password', :via => [:get, :post]
70 match 'my/page_layout', :controller => 'my', :action => 'page_layout', :via => :get
70 match 'my/page_layout', :controller => 'my', :action => 'page_layout', :via => :get
71 match 'my/add_block', :controller => 'my', :action => 'add_block', :via => :post
71 match 'my/add_block', :controller => 'my', :action => 'add_block', :via => :post
72 match 'my/remove_block', :controller => 'my', :action => 'remove_block', :via => :post
72 match 'my/remove_block', :controller => 'my', :action => 'remove_block', :via => :post
73 match 'my/order_blocks', :controller => 'my', :action => 'order_blocks', :via => :post
73 match 'my/order_blocks', :controller => 'my', :action => 'order_blocks', :via => :post
74
74
75 resources :users
75 resources :users
76 match 'users/:id/memberships/:membership_id', :to => 'users#edit_membership', :via => :put, :as => 'user_membership'
76 match 'users/:id/memberships/:membership_id', :to => 'users#edit_membership', :via => :put, :as => 'user_membership'
77 match 'users/:id/memberships/:membership_id', :to => 'users#destroy_membership', :via => :delete
77 match 'users/:id/memberships/:membership_id', :to => 'users#destroy_membership', :via => :delete
78 match 'users/:id/memberships', :to => 'users#edit_membership', :via => :post, :as => 'user_memberships'
78 match 'users/:id/memberships', :to => 'users#edit_membership', :via => :post, :as => 'user_memberships'
79
79
80 match 'watchers/new', :controller=> 'watchers', :action => 'new', :via => :get
80 match 'watchers/new', :controller=> 'watchers', :action => 'new', :via => :get
81 match 'watchers', :controller=> 'watchers', :action => 'create', :via => :post
81 match 'watchers', :controller=> 'watchers', :action => 'create', :via => :post
82 match 'watchers/append', :controller=> 'watchers', :action => 'append', :via => :post
82 match 'watchers/append', :controller=> 'watchers', :action => 'append', :via => :post
83 match 'watchers/destroy', :controller=> 'watchers', :action => 'destroy', :via => :post
83 match 'watchers/destroy', :controller=> 'watchers', :action => 'destroy', :via => :post
84 match 'watchers/watch', :controller=> 'watchers', :action => 'watch', :via => :post
84 match 'watchers/watch', :controller=> 'watchers', :action => 'watch', :via => :post
85 match 'watchers/unwatch', :controller=> 'watchers', :action => 'unwatch', :via => :post
85 match 'watchers/unwatch', :controller=> 'watchers', :action => 'unwatch', :via => :post
86 match 'watchers/autocomplete_for_user', :controller=> 'watchers', :action => 'autocomplete_for_user', :via => :get
86 match 'watchers/autocomplete_for_user', :controller=> 'watchers', :action => 'autocomplete_for_user', :via => :get
87
87
88 match 'projects/:id/settings/:tab', :to => "projects#settings"
88 match 'projects/:id/settings/:tab', :to => "projects#settings"
89
89
90 resources :projects do
90 resources :projects do
91 member do
91 member do
92 get 'settings'
92 get 'settings'
93 post 'modules'
93 post 'modules'
94 post 'archive'
94 post 'archive'
95 post 'unarchive'
95 post 'unarchive'
96 post 'close'
96 post 'close'
97 post 'reopen'
97 post 'reopen'
98 match 'copy', :via => [:get, :post]
98 match 'copy', :via => [:get, :post]
99 end
99 end
100
100
101 resources :memberships, :shallow => true, :controller => 'members', :only => [:index, :show, :create, :update, :destroy] do
101 resources :memberships, :shallow => true, :controller => 'members', :only => [:index, :show, :create, :update, :destroy] do
102 collection do
102 collection do
103 get 'autocomplete'
103 get 'autocomplete'
104 end
104 end
105 end
105 end
106
106
107 resource :enumerations, :controller => 'project_enumerations', :only => [:update, :destroy]
107 resource :enumerations, :controller => 'project_enumerations', :only => [:update, :destroy]
108
108
109 match 'issues/:copy_from/copy', :to => 'issues#new'
109 match 'issues/:copy_from/copy', :to => 'issues#new'
110 resources :issues, :only => [:index, :new, :create] do
110 resources :issues, :only => [:index, :new, :create] do
111 resources :time_entries, :controller => 'timelog' do
111 resources :time_entries, :controller => 'timelog' do
112 collection do
112 collection do
113 get 'report'
113 get 'report'
114 end
114 end
115 end
115 end
116 end
116 end
117 # issue form update
117 # issue form update
118 match 'issues/new', :controller => 'issues', :action => 'new', :via => [:put, :post], :as => 'issue_form'
118 match 'issues/new', :controller => 'issues', :action => 'new', :via => [:put, :post], :as => 'issue_form'
119
119
120 resources :files, :only => [:index, :new, :create]
120 resources :files, :only => [:index, :new, :create]
121
121
122 resources :versions, :except => [:index, :show, :edit, :update, :destroy] do
122 resources :versions, :except => [:index, :show, :edit, :update, :destroy] do
123 collection do
123 collection do
124 put 'close_completed'
124 put 'close_completed'
125 end
125 end
126 end
126 end
127 match 'versions.:format', :to => 'versions#index'
127 match 'versions.:format', :to => 'versions#index'
128 match 'roadmap', :to => 'versions#index', :format => false
128 match 'roadmap', :to => 'versions#index', :format => false
129 match 'versions', :to => 'versions#index'
129 match 'versions', :to => 'versions#index'
130
130
131 resources :news, :except => [:show, :edit, :update, :destroy]
131 resources :news, :except => [:show, :edit, :update, :destroy]
132 resources :time_entries, :controller => 'timelog' do
132 resources :time_entries, :controller => 'timelog' do
133 get 'report', :on => :collection
133 get 'report', :on => :collection
134 end
134 end
135 resources :queries, :only => [:new, :create]
135 resources :queries, :only => [:new, :create]
136 resources :issue_categories, :shallow => true
136 resources :issue_categories, :shallow => true
137 resources :documents, :except => [:show, :edit, :update, :destroy]
137 resources :documents, :except => [:show, :edit, :update, :destroy]
138 resources :boards
138 resources :boards
139 resources :repositories, :shallow => true, :except => [:index, :show] do
139 resources :repositories, :shallow => true, :except => [:index, :show] do
140 member do
140 member do
141 match 'committers', :via => [:get, :post]
141 match 'committers', :via => [:get, :post]
142 end
142 end
143 end
143 end
144
144
145 match 'wiki/index', :controller => 'wiki', :action => 'index', :via => :get
145 match 'wiki/index', :controller => 'wiki', :action => 'index', :via => :get
146 match 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
146 match 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
147 match 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff'
147 match 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff'
148 resources :wiki, :except => [:index, :new, :create] do
148 resources :wiki, :except => [:index, :new, :create] do
149 member do
149 member do
150 get 'rename'
150 get 'rename'
151 post 'rename'
151 post 'rename'
152 get 'history'
152 get 'history'
153 get 'diff'
153 get 'diff'
154 match 'preview', :via => [:post, :put]
154 match 'preview', :via => [:post, :put]
155 post 'protect'
155 post 'protect'
156 post 'add_attachment'
156 post 'add_attachment'
157 end
157 end
158 collection do
158 collection do
159 get 'export'
159 get 'export'
160 get 'date_index'
160 get 'date_index'
161 end
161 end
162 end
162 end
163 match 'wiki', :controller => 'wiki', :action => 'show', :via => :get
163 match 'wiki', :controller => 'wiki', :action => 'show', :via => :get
164 match 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
164 match 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
165 end
165 end
166
166
167 resources :issues do
167 resources :issues do
168 collection do
168 collection do
169 match 'bulk_edit', :via => [:get, :post]
169 match 'bulk_edit', :via => [:get, :post]
170 post 'bulk_update'
170 post 'bulk_update'
171 end
171 end
172 resources :time_entries, :controller => 'timelog' do
172 resources :time_entries, :controller => 'timelog' do
173 collection do
173 collection do
174 get 'report'
174 get 'report'
175 end
175 end
176 end
176 end
177 resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
177 resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
178 end
178 end
179 match '/issues', :controller => 'issues', :action => 'destroy', :via => :delete
179 match '/issues', :controller => 'issues', :action => 'destroy', :via => :delete
180
180
181 resources :queries, :except => [:show]
181 resources :queries, :except => [:show]
182
182
183 resources :news, :only => [:index, :show, :edit, :update, :destroy]
183 resources :news, :only => [:index, :show, :edit, :update, :destroy]
184 match '/news/:id/comments', :to => 'comments#create', :via => :post
184 match '/news/:id/comments', :to => 'comments#create', :via => :post
185 match '/news/:id/comments/:comment_id', :to => 'comments#destroy', :via => :delete
185 match '/news/:id/comments/:comment_id', :to => 'comments#destroy', :via => :delete
186
186
187 resources :versions, :only => [:show, :edit, :update, :destroy] do
187 resources :versions, :only => [:show, :edit, :update, :destroy] do
188 post 'status_by', :on => :member
188 post 'status_by', :on => :member
189 end
189 end
190
190
191 resources :documents, :only => [:show, :edit, :update, :destroy] do
191 resources :documents, :only => [:show, :edit, :update, :destroy] do
192 post 'add_attachment', :on => :member
192 post 'add_attachment', :on => :member
193 end
193 end
194
194
195 match '/time_entries/context_menu', :to => 'context_menus#time_entries', :as => :time_entries_context_menu
195 match '/time_entries/context_menu', :to => 'context_menus#time_entries', :as => :time_entries_context_menu
196
196
197 resources :time_entries, :controller => 'timelog', :except => :destroy do
197 resources :time_entries, :controller => 'timelog', :except => :destroy do
198 collection do
198 collection do
199 get 'report'
199 get 'report'
200 get 'bulk_edit'
200 get 'bulk_edit'
201 post 'bulk_update'
201 post 'bulk_update'
202 end
202 end
203 end
203 end
204 match '/time_entries/:id', :to => 'timelog#destroy', :via => :delete, :id => /\d+/
204 match '/time_entries/:id', :to => 'timelog#destroy', :via => :delete, :id => /\d+/
205 # TODO: delete /time_entries for bulk deletion
205 # TODO: delete /time_entries for bulk deletion
206 match '/time_entries/destroy', :to => 'timelog#destroy', :via => :delete
206 match '/time_entries/destroy', :to => 'timelog#destroy', :via => :delete
207
207
208 # TODO: port to be part of the resources route(s)
208 # TODO: port to be part of the resources route(s)
209 match 'projects/:id/settings/:tab', :to => 'projects#settings', :via => :get
209 match 'projects/:id/settings/:tab', :to => 'projects#settings', :via => :get
210
210
211 get 'projects/:id/activity', :to => 'activities#index'
211 get 'projects/:id/activity', :to => 'activities#index'
212 get 'projects/:id/activity.:format', :to => 'activities#index'
212 get 'projects/:id/activity.:format', :to => 'activities#index'
213 get 'activity', :to => 'activities#index'
213 get 'activity', :to => 'activities#index'
214
214
215 # repositories routes
215 # repositories routes
216 get 'projects/:id/repository/:repository_id/statistics', :to => 'repositories#stats'
216 get 'projects/:id/repository/:repository_id/statistics', :to => 'repositories#stats'
217 get 'projects/:id/repository/:repository_id/graph', :to => 'repositories#graph'
217 get 'projects/:id/repository/:repository_id/graph', :to => 'repositories#graph'
218
218
219 get 'projects/:id/repository/:repository_id/changes(/*path(.:ext))',
219 get 'projects/:id/repository/:repository_id/changes(/*path(.:ext))',
220 :to => 'repositories#changes'
220 :to => 'repositories#changes'
221
221
222 get 'projects/:id/repository/:repository_id/revisions/:rev', :to => 'repositories#revision'
222 get 'projects/:id/repository/:repository_id/revisions/:rev', :to => 'repositories#revision'
223 get 'projects/:id/repository/:repository_id/revision', :to => 'repositories#revision'
223 get 'projects/:id/repository/:repository_id/revision', :to => 'repositories#revision'
224 post 'projects/:id/repository/:repository_id/revisions/:rev/issues', :to => 'repositories#add_related_issue'
224 post 'projects/:id/repository/:repository_id/revisions/:rev/issues', :to => 'repositories#add_related_issue'
225 delete 'projects/:id/repository/:repository_id/revisions/:rev/issues/:issue_id', :to => 'repositories#remove_related_issue'
225 delete 'projects/:id/repository/:repository_id/revisions/:rev/issues/:issue_id', :to => 'repositories#remove_related_issue'
226 get 'projects/:id/repository/:repository_id/revisions', :to => 'repositories#revisions'
226 get 'projects/:id/repository/:repository_id/revisions', :to => 'repositories#revisions'
227 get 'projects/:id/repository/:repository_id/revisions/:rev/:action(/*path(.:ext))',
227 get 'projects/:id/repository/:repository_id/revisions/:rev/:action(/*path(.:ext))',
228 :controller => 'repositories',
228 :controller => 'repositories',
229 :format => false,
229 :format => false,
230 :constraints => {
230 :constraints => {
231 :action => /(browse|show|entry|raw|annotate|diff)/,
231 :action => /(browse|show|entry|raw|annotate|diff)/,
232 :rev => /[a-z0-9\.\-_]+/
232 :rev => /[a-z0-9\.\-_]+/
233 }
233 }
234
234
235 get 'projects/:id/repository/statistics', :to => 'repositories#stats'
235 get 'projects/:id/repository/statistics', :to => 'repositories#stats'
236 get 'projects/:id/repository/graph', :to => 'repositories#graph'
236 get 'projects/:id/repository/graph', :to => 'repositories#graph'
237
237
238 get 'projects/:id/repository/changes(/*path(.:ext))',
238 get 'projects/:id/repository/changes(/*path(.:ext))',
239 :to => 'repositories#changes'
239 :to => 'repositories#changes'
240
240
241 get 'projects/:id/repository/revisions', :to => 'repositories#revisions'
241 get 'projects/:id/repository/revisions', :to => 'repositories#revisions'
242 get 'projects/:id/repository/revisions/:rev', :to => 'repositories#revision'
242 get 'projects/:id/repository/revisions/:rev', :to => 'repositories#revision'
243 get 'projects/:id/repository/revision', :to => 'repositories#revision'
243 get 'projects/:id/repository/revision', :to => 'repositories#revision'
244 post 'projects/:id/repository/revisions/:rev/issues', :to => 'repositories#add_related_issue'
244 post 'projects/:id/repository/revisions/:rev/issues', :to => 'repositories#add_related_issue'
245 delete 'projects/:id/repository/revisions/:rev/issues/:issue_id', :to => 'repositories#remove_related_issue'
245 delete 'projects/:id/repository/revisions/:rev/issues/:issue_id', :to => 'repositories#remove_related_issue'
246 get 'projects/:id/repository/revisions/:rev/:action(/*path(.:ext))',
246 get 'projects/:id/repository/revisions/:rev/:action(/*path(.:ext))',
247 :controller => 'repositories',
247 :controller => 'repositories',
248 :format => false,
248 :format => false,
249 :constraints => {
249 :constraints => {
250 :action => /(browse|show|entry|raw|annotate|diff)/,
250 :action => /(browse|show|entry|raw|annotate|diff)/,
251 :rev => /[a-z0-9\.\-_]+/
251 :rev => /[a-z0-9\.\-_]+/
252 }
252 }
253 get 'projects/:id/repository/:repository_id/:action(/*path(.:ext))',
253 get 'projects/:id/repository/:repository_id/:action(/*path(.:ext))',
254 :controller => 'repositories',
254 :controller => 'repositories',
255 :action => /(browse|show|entry|raw|changes|annotate|diff)/
255 :action => /(browse|show|entry|raw|changes|annotate|diff)/
256 get 'projects/:id/repository/:action(/*path(.:ext))',
256 get 'projects/:id/repository/:action(/*path(.:ext))',
257 :controller => 'repositories',
257 :controller => 'repositories',
258 :action => /(browse|show|entry|raw|changes|annotate|diff)/
258 :action => /(browse|show|entry|raw|changes|annotate|diff)/
259
259
260 get 'projects/:id/repository/:repository_id', :to => 'repositories#show', :path => nil
260 get 'projects/:id/repository/:repository_id', :to => 'repositories#show', :path => nil
261 get 'projects/:id/repository', :to => 'repositories#show', :path => nil
261 get 'projects/:id/repository', :to => 'repositories#show', :path => nil
262
262
263 # additional routes for having the file name at the end of url
263 # additional routes for having the file name at the end of url
264 match 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/, :via => :get
264 match 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/, :via => :get
265 match 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/, :via => :get
265 match 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/, :via => :get
266 match 'attachments/download/:id', :controller => 'attachments', :action => 'download', :id => /\d+/, :via => :get
266 match 'attachments/download/:id', :controller => 'attachments', :action => 'download', :id => /\d+/, :via => :get
267 match 'attachments/thumbnail/:id(/:size)', :controller => 'attachments', :action => 'thumbnail', :id => /\d+/, :via => :get, :size => /\d+/
267 match 'attachments/thumbnail/:id(/:size)', :controller => 'attachments', :action => 'thumbnail', :id => /\d+/, :via => :get, :size => /\d+/
268 resources :attachments, :only => [:show, :destroy]
268 resources :attachments, :only => [:show, :destroy]
269
269
270 resources :groups do
270 resources :groups do
271 member do
271 member do
272 get 'autocomplete_for_user'
272 get 'autocomplete_for_user'
273 end
273 end
274 end
274 end
275
275
276 match 'groups/:id/users', :controller => 'groups', :action => 'add_users', :id => /\d+/, :via => :post, :as => 'group_users'
276 match 'groups/:id/users', :controller => 'groups', :action => 'add_users', :id => /\d+/, :via => :post, :as => 'group_users'
277 match 'groups/:id/users/:user_id', :controller => 'groups', :action => 'remove_user', :id => /\d+/, :via => :delete, :as => 'group_user'
277 match 'groups/:id/users/:user_id', :controller => 'groups', :action => 'remove_user', :id => /\d+/, :via => :delete, :as => 'group_user'
278 match 'groups/destroy_membership/:id', :controller => 'groups', :action => 'destroy_membership', :id => /\d+/, :via => :post
278 match 'groups/destroy_membership/:id', :controller => 'groups', :action => 'destroy_membership', :id => /\d+/, :via => :post
279 match 'groups/edit_membership/:id', :controller => 'groups', :action => 'edit_membership', :id => /\d+/, :via => :post
279 match 'groups/edit_membership/:id', :controller => 'groups', :action => 'edit_membership', :id => /\d+/, :via => :post
280
280
281 resources :trackers, :except => :show do
281 resources :trackers, :except => :show do
282 collection do
282 collection do
283 match 'fields', :via => [:get, :post]
283 match 'fields', :via => [:get, :post]
284 end
284 end
285 end
285 end
286 resources :issue_statuses, :except => :show do
286 resources :issue_statuses, :except => :show do
287 collection do
287 collection do
288 post 'update_issue_done_ratio'
288 post 'update_issue_done_ratio'
289 end
289 end
290 end
290 end
291 resources :custom_fields, :except => :show
291 resources :custom_fields, :except => :show
292 resources :roles, :except => :show do
292 resources :roles do
293 collection do
293 collection do
294 match 'permissions', :via => [:get, :post]
294 match 'permissions', :via => [:get, :post]
295 end
295 end
296 end
296 end
297 resources :enumerations, :except => :show
297 resources :enumerations, :except => :show
298
298
299 get 'projects/:id/search', :controller => 'search', :action => 'index'
299 get 'projects/:id/search', :controller => 'search', :action => 'index'
300 get 'search', :controller => 'search', :action => 'index'
300 get 'search', :controller => 'search', :action => 'index'
301
301
302 match 'mail_handler', :controller => 'mail_handler', :action => 'index', :via => :post
302 match 'mail_handler', :controller => 'mail_handler', :action => 'index', :via => :post
303
303
304 match 'admin', :controller => 'admin', :action => 'index', :via => :get
304 match 'admin', :controller => 'admin', :action => 'index', :via => :get
305 match 'admin/projects', :controller => 'admin', :action => 'projects', :via => :get
305 match 'admin/projects', :controller => 'admin', :action => 'projects', :via => :get
306 match 'admin/plugins', :controller => 'admin', :action => 'plugins', :via => :get
306 match 'admin/plugins', :controller => 'admin', :action => 'plugins', :via => :get
307 match 'admin/info', :controller => 'admin', :action => 'info', :via => :get
307 match 'admin/info', :controller => 'admin', :action => 'info', :via => :get
308 match 'admin/test_email', :controller => 'admin', :action => 'test_email', :via => :get
308 match 'admin/test_email', :controller => 'admin', :action => 'test_email', :via => :get
309 match 'admin/default_configuration', :controller => 'admin', :action => 'default_configuration', :via => :post
309 match 'admin/default_configuration', :controller => 'admin', :action => 'default_configuration', :via => :post
310
310
311 resources :auth_sources do
311 resources :auth_sources do
312 member do
312 member do
313 get 'test_connection'
313 get 'test_connection'
314 end
314 end
315 end
315 end
316
316
317 match 'workflows', :controller => 'workflows', :action => 'index', :via => :get
317 match 'workflows', :controller => 'workflows', :action => 'index', :via => :get
318 match 'workflows/edit', :controller => 'workflows', :action => 'edit', :via => [:get, :post]
318 match 'workflows/edit', :controller => 'workflows', :action => 'edit', :via => [:get, :post]
319 match 'workflows/permissions', :controller => 'workflows', :action => 'permissions', :via => [:get, :post]
319 match 'workflows/permissions', :controller => 'workflows', :action => 'permissions', :via => [:get, :post]
320 match 'workflows/copy', :controller => 'workflows', :action => 'copy', :via => [:get, :post]
320 match 'workflows/copy', :controller => 'workflows', :action => 'copy', :via => [:get, :post]
321 match 'settings', :controller => 'settings', :action => 'index', :via => :get
321 match 'settings', :controller => 'settings', :action => 'index', :via => :get
322 match 'settings/edit', :controller => 'settings', :action => 'edit', :via => [:get, :post]
322 match 'settings/edit', :controller => 'settings', :action => 'edit', :via => [:get, :post]
323 match 'settings/plugin/:id', :controller => 'settings', :action => 'plugin', :via => [:get, :post]
323 match 'settings/plugin/:id', :controller => 'settings', :action => 'plugin', :via => [:get, :post]
324
324
325 match 'sys/projects', :to => 'sys#projects', :via => :get
325 match 'sys/projects', :to => 'sys#projects', :via => :get
326 match 'sys/projects/:id/repository', :to => 'sys#create_project_repository', :via => :post
326 match 'sys/projects/:id/repository', :to => 'sys#create_project_repository', :via => :post
327 match 'sys/fetch_changesets', :to => 'sys#fetch_changesets', :via => :get
327 match 'sys/fetch_changesets', :to => 'sys#fetch_changesets', :via => :get
328
328
329 match 'uploads', :to => 'attachments#upload', :via => :post
329 match 'uploads', :to => 'attachments#upload', :via => :post
330
330
331 get 'robots.txt', :to => 'welcome#robots'
331 get 'robots.txt', :to => 'welcome#robots'
332
332
333 Dir.glob File.expand_path("plugins/*", Rails.root) do |plugin_dir|
333 Dir.glob File.expand_path("plugins/*", Rails.root) do |plugin_dir|
334 file = File.join(plugin_dir, "config/routes.rb")
334 file = File.join(plugin_dir, "config/routes.rb")
335 if File.exists?(file)
335 if File.exists?(file)
336 begin
336 begin
337 instance_eval File.read(file)
337 instance_eval File.read(file)
338 rescue Exception => e
338 rescue Exception => e
339 puts "An error occurred while loading the routes definition of #{File.basename(plugin_dir)} plugin (#{file}): #{e.message}."
339 puts "An error occurred while loading the routes definition of #{File.basename(plugin_dir)} plugin (#{file}): #{e.message}."
340 exit 1
340 exit 1
341 end
341 end
342 end
342 end
343 end
343 end
344 end
344 end
@@ -1,69 +1,90
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../../test_helper', __FILE__)
18 require File.expand_path('../../../test_helper', __FILE__)
19
19
20 class ApiTest::RolesTest < ActionController::IntegrationTest
20 class ApiTest::RolesTest < ActionController::IntegrationTest
21 fixtures :roles
21 fixtures :roles
22
22
23 def setup
23 def setup
24 Setting.rest_api_enabled = '1'
24 Setting.rest_api_enabled = '1'
25 end
25 end
26
26
27 context "/roles" do
27 context "/roles" do
28 context "GET" do
28 context "GET" do
29 context "xml" do
29 context "xml" do
30 should "return the roles" do
30 should "return the roles" do
31 get '/roles.xml'
31 get '/roles.xml'
32
32
33 assert_response :success
33 assert_response :success
34 assert_equal 'application/xml', @response.content_type
34 assert_equal 'application/xml', @response.content_type
35 assert_equal 3, assigns(:roles).size
35 assert_equal 3, assigns(:roles).size
36
36
37 assert_tag :tag => 'roles',
37 assert_tag :tag => 'roles',
38 :attributes => {:type => 'array'},
38 :attributes => {:type => 'array'},
39 :child => {
39 :child => {
40 :tag => 'role',
40 :tag => 'role',
41 :child => {
41 :child => {
42 :tag => 'id',
42 :tag => 'id',
43 :content => '2',
43 :content => '2',
44 :sibling => {
44 :sibling => {
45 :tag => 'name',
45 :tag => 'name',
46 :content => 'Developer'
46 :content => 'Developer'
47 }
47 }
48 }
48 }
49 }
49 }
50 end
50 end
51 end
51 end
52
52
53 context "json" do
53 context "json" do
54 should "return the roles" do
54 should "return the roles" do
55 get '/roles.json'
55 get '/roles.json'
56
56
57 assert_response :success
57 assert_response :success
58 assert_equal 'application/json', @response.content_type
58 assert_equal 'application/json', @response.content_type
59 assert_equal 3, assigns(:roles).size
59 assert_equal 3, assigns(:roles).size
60
60
61 json = ActiveSupport::JSON.decode(response.body)
61 json = ActiveSupport::JSON.decode(response.body)
62 assert_kind_of Hash, json
62 assert_kind_of Hash, json
63 assert_kind_of Array, json['roles']
63 assert_kind_of Array, json['roles']
64 assert_include({'id' => 2, 'name' => 'Developer'}, json['roles'])
64 assert_include({'id' => 2, 'name' => 'Developer'}, json['roles'])
65 end
65 end
66 end
66 end
67 end
67 end
68 end
68 end
69
70 context "/roles/:id" do
71 context "GET" do
72 context "xml" do
73 should "return the role" do
74 get '/roles/1.xml'
75
76 assert_response :success
77 assert_equal 'application/xml', @response.content_type
78
79 assert_select 'role' do
80 assert_select 'name', :text => 'Manager'
81 assert_select 'role permissions[type=array]' do
82 assert_select 'permission', Role.find(1).permissions.size
83 assert_select 'permission', :text => 'view_issues'
84 end
85 end
86 end
87 end
88 end
89 end
69 end
90 end
@@ -1,57 +1,61
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../../test_helper', __FILE__)
18 require File.expand_path('../../../test_helper', __FILE__)
19
19
20 class RoutingRolesTest < ActionController::IntegrationTest
20 class RoutingRolesTest < ActionController::IntegrationTest
21 def test_roles
21 def test_roles
22 assert_routing(
22 assert_routing(
23 { :method => 'get', :path => "/roles" },
23 { :method => 'get', :path => "/roles" },
24 { :controller => 'roles', :action => 'index' }
24 { :controller => 'roles', :action => 'index' }
25 )
25 )
26 assert_routing(
26 assert_routing(
27 { :method => 'get', :path => "/roles.xml" },
27 { :method => 'get', :path => "/roles.xml" },
28 { :controller => 'roles', :action => 'index', :format => 'xml' }
28 { :controller => 'roles', :action => 'index', :format => 'xml' }
29 )
29 )
30 assert_routing(
30 assert_routing(
31 { :method => 'get', :path => "/roles/2.xml" },
32 { :controller => 'roles', :action => 'show', :id => '2', :format => 'xml' }
33 )
34 assert_routing(
31 { :method => 'get', :path => "/roles/new" },
35 { :method => 'get', :path => "/roles/new" },
32 { :controller => 'roles', :action => 'new' }
36 { :controller => 'roles', :action => 'new' }
33 )
37 )
34 assert_routing(
38 assert_routing(
35 { :method => 'post', :path => "/roles" },
39 { :method => 'post', :path => "/roles" },
36 { :controller => 'roles', :action => 'create' }
40 { :controller => 'roles', :action => 'create' }
37 )
41 )
38 assert_routing(
42 assert_routing(
39 { :method => 'get', :path => "/roles/2/edit" },
43 { :method => 'get', :path => "/roles/2/edit" },
40 { :controller => 'roles', :action => 'edit', :id => '2' }
44 { :controller => 'roles', :action => 'edit', :id => '2' }
41 )
45 )
42 assert_routing(
46 assert_routing(
43 { :method => 'put', :path => "/roles/2" },
47 { :method => 'put', :path => "/roles/2" },
44 { :controller => 'roles', :action => 'update', :id => '2' }
48 { :controller => 'roles', :action => 'update', :id => '2' }
45 )
49 )
46 assert_routing(
50 assert_routing(
47 { :method => 'delete', :path => "/roles/2" },
51 { :method => 'delete', :path => "/roles/2" },
48 { :controller => 'roles', :action => 'destroy', :id => '2' }
52 { :controller => 'roles', :action => 'destroy', :id => '2' }
49 )
53 )
50 ["get", "post"].each do |method|
54 ["get", "post"].each do |method|
51 assert_routing(
55 assert_routing(
52 { :method => method, :path => "/roles/permissions" },
56 { :method => method, :path => "/roles/permissions" },
53 { :controller => 'roles', :action => 'permissions' }
57 { :controller => 'roles', :action => 'permissions' }
54 )
58 )
55 end
59 end
56 end
60 end
57 end
61 end
General Comments 0
You need to be logged in to leave comments. Login now