Refactor project membership and private repo functionality into generic protected...
[gitorious:mainline.git] / config / routes.rb
1 # encoding: utf-8
2 #--
3 #   Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
4 #   Copyright (C) 2007, 2008, 2009 Johan Sørensen <johan@johansorensen.com>
5 #
6 #   This program is free software: you can redistribute it and/or modify
7 #   it under the terms of the GNU Affero General Public License as published by
8 #   the Free Software Foundation, either version 3 of the License, or
9 #   (at your option) any later version.
10 #
11 #   This program is distributed in the hope that it will be useful,
12 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #   GNU Affero General Public License for more details.
15 #
16 #   You should have received a copy of the GNU Affero General Public License
17 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #++
19
20
21 # == ROUTING NOTE =========================================================
22 #
23 # Note that all routes are getting pre and post processed by the filter class
24 # in RAILS_ROOT/lib/route_filters/repository_owner_namespacing.rb and that
25 # you should be EXTRA CAREFUL when adding a route that doesn't map directly
26 # by name to an existing controller or action. In such case the same string
27 # should be added to Gitorious::Reservations::unaccounted_root_names
28 #
29 # =========================================================================
30
31 ActionController::Routing::Routes.draw do |map|
32   VALID_REF = /[a-zA-Z0-9~\{\}\+\^\.\-_\/]+/
33
34   # Builds up the common repository sub-routes that's shared between projects
35   # and user+team namespaced repositories
36   def build_repository_routes(repository, options = {})
37     repository.with_options(options) do |repo|
38       repo.resources :comments
39       repo.commit_comment "comments/commit/:sha", :controller => "comments",
40         :action => "commit", :conditions => { :method => :get }
41       repo.comments_preview 'comments/preview', :controller => 'comments',
42         :action => 'preview'#, :conditions => {:method => :put}
43       repo.resources :merge_requests, :member => {
44         :terms_accepted => :get,
45         :version => :get,
46         :commit_status => :get
47       }, :collection => {
48         :create => :post,
49         :commit_list => :post,
50         :target_branches => :post,
51       } do |merge_request|
52         merge_request.resources :comments, :collection => {:preview => :post}
53         merge_request.resources :merge_request_versions do |v|
54           v.resources :comments, :collection => {:preview => :post}
55         end
56       end
57
58       repo.resources :repository_memberships, :as => :memberships
59       repo.resources :committerships
60
61       repo.formatted_commits_feed("commits/*branch/feed.:format",
62                                   :controller => "commits", :action => "feed", :conditions => { :feed => :get })
63       repo.commits         "commits", :controller => "commits", :action => "index"
64       repo.commits_in_ref  "commits/*branch", :controller => "commits", :action => "index"
65       repo.graph           "graph", :controller => "graphs", :action => "index"
66       repo.graph_in_ref    "graph/*branch", :controller => "graphs", :action => "index"
67       repo.commit_comments "commit/:id/comments", :controller => "commit_comments", :action => "index", :id => /[^\/]+/
68       repo.commit_diffs    "commit/:id/diffs", :controller => "commit_diffs", :action => "index", :id => /[^\/]+/
69       repo.commit_compare  "commit/:from_id/diffs/:id", :controller => "commit_diffs", :action => "compare"
70       repo.commit          "commit/:id", :controller => "commits", :action => "show", :id => /.*/
71       repo.trees           "trees/", :controller => "trees", :action => "index"
72       repo.tree            "trees/*branch_and_path", :controller => "trees", :action => "show"
73       repo.formatted_tree  "trees/*branch_and_path.:format", :controller => "trees", :action => "show"
74       repo.archive_tar     "archive-tarball/*branch", :controller => "trees", :action => "archive", :archive_format => "tar.gz"
75       #repo.archive_zip    "archive-zip/*branch", :controller => "trees", :action => "archive", :archive_format => "zip"
76       repo.raw_blob        "blobs/raw/*branch_and_path", :controller => "blobs", :action => "raw"
77       repo.blob_history    "blobs/history/*branch_and_path", :controller => "blobs", :action => "history"
78       repo.blame           "blobs/blame/*branch_and_path", :controller => "blobs", :action => "blame"
79       repo.blob            "blobs/*branch_and_path", :controller => "blobs", :action => "show"
80     end
81   end
82
83   repository_options = {
84     :member => {
85       :clone => :get, :create_clone => :post,
86       :writable_by => :get,
87       :config => :get,
88       :confirm_delete => :get,
89       :committers => :get,
90       :search_clones => :get
91     }
92   }
93
94   map.root :controller => "site", :action => "index"
95
96   map.connect "users/activate/:activation_code", :controller => "users", :action => "activate"
97   map.connect "users/pending_activation", :controller => "users", :action => "pending_activation"
98   map.reset_password "users/reset_password/:token", :controller => "users", :action => "reset_password"
99   map.resources(:users, :requirements => {:id => /#{User::USERNAME_FORMAT}/i }, :collection => {
100     :forgot_password => :get,
101     :forgot_password_create => :post,
102     :openid_build => :get,
103     :openid_create => :post
104   }, :member => {
105     :feed => :get,
106     :password => :get,
107     :update_password => :put,
108     :avatar => :delete,
109     :watchlist => :get
110   }) do |user|
111     user.with_options({:requirements => {:user_id => /#{User::USERNAME_FORMAT}/i}}) do |user_req|
112       user_req.resources :keys
113       user_req.resources :aliases, :member => { :confirm => :get }
114       user_req.resource :license
115       user_req.resources(:repositories, repository_options){|r| build_repository_routes(r) }
116       user_req.resources :projects do |p|
117         p.resources(:repositories, repository_options.merge({
118           :requirements => {:user_id => /#{User::USERNAME_FORMAT}/i}
119         })) do |repo|
120           build_repository_routes(repo, {:requirements => {:user_id => /#{User::USERNAME_FORMAT}/i}})
121         end
122       end
123     end
124   end
125
126   map.resources :events, :member => {:commits => :get}
127   map.resources :user_auto_completions, :only => [:index]
128   map.resources :group_auto_completions, :only => [:index]
129
130   map.open_id_complete '/sessions', :controller => "sessions", :action=> "create",:requirements => { :method => :get }
131
132   map.resource  :sessions
133
134   map.resources :groups, :as => "teams", :member => {:avatar => :delete}  do |grp|
135     grp.resources :memberships
136     grp.resources(:repositories, repository_options){|r| build_repository_routes(r) }
137     grp.resources :projects do |p|
138       p.resources(:repositories, repository_options){|r| build_repository_routes(r) }
139     end
140   end
141
142   map.site_wiki_git_access_connect 'wiki/:site_id/config', :controller => 'site_wiki_pages', :action => 'config'
143   map.site_wiki_git_writable_by 'wiki/:site_id/writable_by', :controller => 'site_wiki_pages', :action => 'writable_by'
144
145   map.resources :site_wiki_pages, :as => "wiki", :member => { :history => :get,:preview => :put},
146   :collection => { :git_access => :get }
147
148   map.resources :projects, :member => {
149     :confirm_delete => :get,
150     :preview => :put,
151     :edit_slug => :any,
152     :clones => :get
153   } do |projects|
154     projects.resources :project_memberships, :as => :memberships
155     projects.resources :pages, :member => { :history => :get,:preview => :put}, :collection => { :git_access => :get }
156     projects.resources(:repositories, repository_options){|r| build_repository_routes(r) }
157   end
158
159   map.resource :search
160
161   map.resources :messages,
162     :member => {:reply => :post, :read => :put},
163     :collection => {:auto_complete_for_message_recipients => :get, :sent => :get, :bulk_update => :put, :all => :get}
164
165   map.with_options :controller => 'sessions' do |session|
166     session.login    '/login',  :action => 'new'
167     session.logout   '/logout', :action => 'destroy'
168   end
169
170   map.dashboard "dashboard", :controller => "site", :action => "dashboard"
171   map.about "about", :controller => "site", :action => "about"
172   map.about_page "about/:action", :controller => "site"
173   map.contact "contact", :controller => "site", :action => "contact"
174
175   map.namespace :api do |api|
176     api.connect ':project_id/:repository_id/log/graph', :controller => 'graphs', :action => 'show', :branch => 'master'
177     api.connect ':project_id/:repository_id/log/graph/*branch', :controller => 'graphs', :action => 'show'
178   end
179
180   map.namespace :admin do |admin|
181     admin.resources :users, :member => { :suspend => :put, :unsuspend => :put, :reset_password => :put }
182     admin.resource :oauth_settings, :path_prefix => "/admin/projects/:project_id"
183     admin.resources :repositories, :member => {:recreate => :put}
184   end
185
186   map.resources :favorites
187
188   map.activity "/activities", :controller => "site", :action => "public_timeline"
189
190   map.merge_request_landing_page '/merge_request_landing_page', :controller => 'merge_requests', :action => 'oauth_return'
191
192   map.merge_request_direct_access '/merge_requests/:id', :controller => 'merge_requests', :action => 'direct_access'
193
194   # Install the default route as the lowest priority.
195   map.connect ':controller/:action/:id.:format'
196   map.connect ':controller/:action/:id'
197
198   # See the routing_filter plugin and lib/route_filters/*
199   map.filter "repository_owner_namespacing", :file => "route_filters/repository_owner_namespacing"
200 end