Further repo browser/Dolt integration work
[gitorious:mainline.git] / config / routes.rb
1 # encoding: utf-8
2 #--
3 #   Copyright (C) 2012 Gitorious AS
4 #
5 #   This program is free software: you can redistribute it and/or modify
6 #   it under the terms of the GNU Affero General Public License as published by
7 #   the Free Software Foundation, either version 3 of the License, or
8 #   (at your option) any later version.
9 #
10 #   This program is distributed in the hope that it will be useful,
11 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #   GNU Affero General Public License for more details.
14 #
15 #   You should have received a copy of the GNU Affero General Public License
16 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #++
18
19 require (Rails.root + "app/racks/git_http_cloner.rb").realpath
20 require (Rails.root + "app/racks/repository_browser.rb").realpath
21
22 Gitorious::Application.routes.draw do
23   ### R0. Site index
24   root :to => "site#index"
25
26   ### R1. Rack endpoints
27   match "/:project_id/:repository_id.git/*slug" => Gitorious::GitHttpCloner
28   # The repository browser instance is configured in an initializer
29   match "/:project_id/:repository_id/:action/*slug" => Gitorious::RepositoryBrowser.instance, :action => /(source)|(tree_history|raw|blame|history)/
30   match "/:project_id/:repository_id/refs" => Gitorious::RepositoryBrowser.instance
31
32   ### R2. User routes
33   resources :users, :only => [:new, :create] do
34     collection do
35       get  "/reset_password/:token" => "users#reset_password", :as => :reset_password
36       get  "/activate/:activation_code" => "users#activate"
37       post "/forgot_password" => "users#forgot_password_create", :as => :forgot_password_create
38       get :forgot_password
39       get :pending_activation
40       get :openid_build
41       post :openid_create
42       get "/new" => "users#new"
43
44       # Used to be we supported things like /users/~zmalltalker/mainline
45       # No more, ~<user_name> is the canonical user URL namespace
46       get "/*slug" => (redirect do |params, request|
47                          request.fullpath.sub("users/", "~")
48                        end), :slug => /.*/
49     end
50   end
51
52   # `resources :users` can't do the ~<user> ids
53   get "/~:id(.:format)" => "users#show", :as => "user", :id => /[^\/]+/
54   get "/~:id/edit(.:format)" => "users#edit", :as => "edit_user", :id => /[^\/]+/
55   put "/~:id(.:format)" => "users#update", :id => /[^\/]+/
56   delete "/~:id(.:format)" => "users#destroy", :id => /[^\/]+/
57
58   # Additional user actions
59   scope "/~:id", :id => /[^\/]+/, :as => :user do
60     get "/delete_current" => "users#delete_current", :as => :delete_current
61     delete "/avatar" => "users#avatar"
62     get "/watchlist" => "users#watchlist", :as => :watchlist
63     get "/password" => "users#password", :as => :password
64     get "/feed" => "users#feed", :as => :feed
65     put "/update_password" => "users#update_password", :as => :update_password
66   end
67
68   # Nested user resources. This is in a separate scope because the
69   # controllers expect params[:user_id] to contain the user, not
70   # params[:id] as in the scope above
71   scope "/~:user_id", :user_id => /[^\/]+/, :as => :user do
72     resources :keys
73
74     resources :aliases do
75       member do
76         get :confirm
77       end
78     end
79
80     get "/repositories" => "repositories#index"
81     resource :license, :only => [:show, :edit, :update]
82     match "/*slug" => "owner_redirections#show"
83   end
84
85   ### R3. Sessions
86   resource :sessions
87   get "/sessions" => "sessions#create", :as => :open_id_complete
88   get "/login" => "sessions#new", :as => :login
89   get "/logout" => "sessions#destroy", :as => :logout
90
91   ### R4. Groups
92   resources :groups, :only => [:index, :new, :create]
93   # `resource :groups` can't do the +<group> ids
94   get "/+:id(.:format)" => "groups#show", :as => "group", :id => /[^\/]+/
95   get "/+:id/edit(.:format)" => "groups#edit", :as => "edit_group", :id => /[^\/]+/
96   put "/+:id(.:format)" => "groups#update", :id => /[^\/]+/
97   delete "/+:id(.:format)" => "groups#destroy", :id => /[^\/]+/
98
99   # Additional group actions
100   scope "/+:id", :id => /[^\/]+/, :as => :group do
101     delete "avatar" => "groups#avatar"
102   end
103
104   # Nested group resources. This is in a separate scope because the
105   # controllers expect params[:group_id] to contain the group, not
106   # params[:id] as in the scope above
107   scope "/+:group_id", :id => /[^\/]+/, :as => :group do
108     resources :memberships
109     get "/repositories" => "repositories#index"
110     match "/*slug" => "owner_redirections#show"
111   end
112
113   ### R5. Site-wide wiki
114   get "/wiki/:site_id/config" => "site_wiki_pages#repository_config", :as => :site_wiki_git_access_connect
115   get "/wiki/:site_id/writable_by" => "site_wiki_pages#writable_by", :as => :site_wiki_git_writable_by
116
117   resources :site_wiki_pages, :path => "/wiki" do
118     collection do
119       get :git_access
120     end
121
122     member do
123       put :preview
124       get :history
125     end
126   end
127
128   ### R6. Direct merge request access
129   match "/merge_request_landing_page" => "merge_requests#oauth_return", :as => :merge_request_landing_page
130   get "/merge_requests/:id" => "merge_requests#direct_access", :as => :merge_request_direct_access
131
132   ### R7. Site controller, various loose pages
133   get "/activities" => "site#public_timeline", :as => :activity
134   get "/dashboard" => "site#dashboard", :as => :dashboard
135   get "/about" => "site#about", :as => :about
136   get "/about/:action" => "site#index", :as => :about_page
137   get "/contact" => "site#contact", :as => :contact
138
139   ### R8. Administration
140   namespace :admin do
141     resources :users, :only => [:index, :new, :create] do
142       member do
143         put :suspend
144         put :flip_admin_status
145         put :unsuspend
146         put :reset_password
147       end
148     end
149
150     resource :oauth_settings
151
152     resources :repositories, :only => [:index] do
153       member do
154         put :recreate
155       end
156     end
157
158     resources :diagnostics, :only => [:index] do
159       collection { get :summary }
160     end
161
162     resources :project_proposals, :only => [:index, :new, :create]
163     post "/project_proposals/:id/reject" => "project_proposals#reject"
164     post "/project_proposals/:id/approve" => "project_proposals#approve"
165   end
166
167   ### R9. API
168   namespace :api do
169     get ":project_id/:repository_id/log/graph(.:format)" => "graphs#show"
170     get ":project_id/:repository_id/log/graph/*branch(.:format)" => "graphs#show"
171   end
172
173   ### R10. Events
174   resources :events do
175     collection do
176       get :commits
177     end
178   end
179
180   ### R11. Additional logged in user resources
181   resources :messages do
182     collection do
183       get :sent
184       put :bulk_update
185       get :all
186       get :auto_complete_for_message_recipients
187     end
188
189     member do
190       post :reply
191       put :read
192     end
193   end
194
195   resources :favorites, :only => [:index, :create, :update, :destroy]
196
197   ### R12. Search
198   resource :search
199
200   ### R13. Auto-completion
201   resources :user_auto_completions, :only => [:index]
202   resources :group_auto_completions, :only => [:index]
203
204   ### R14. Projects
205   resources :projects, :only => [:index, :create]
206   get "/:id/edit(.:format)" => "projects#edit"
207
208   resources :projects, :path => "/" do
209     member do
210       put :preview
211       get :edit_slug
212       put :edit_slug
213       get :clones
214       get :confirm_delete
215     end
216
217     resources :project_memberships, :only => [:index, :new, :create, :destroy]
218
219     resources :pages do
220       collection do
221         get :git_access
222       end
223
224       member do
225         put :preview
226         get :history
227       end
228     end
229
230     ### R14.2. Repositories
231
232     # Listing repositories and creating new ones happens over
233     # /<project>/repositories/, e.g:
234     #   /gitorious/repositories/new
235     resources :repositories, :only => [:index, :new, :create]
236
237     # Browsing, editing and destroying existing repositories happens over
238     # /<project>/<repository_name>/, e.g.:
239     #   /gitorious/mainline
240     #   /gitorious/mainline/edit
241     resources(:repositories, {
242                 :path => "/",
243                 :only => [:show, :edit, :update, :destroy]
244               }) do
245       member do
246         post :create_clone
247         get :clone
248         get :search_clones
249         get :committers
250         get :confirm_delete
251         get :writable_by
252         get "/config" => "repositories#repository_config"
253       end
254
255       resources :comments
256
257       get "/comments/commit/:sha" => "comments#commit", :as => :commit_comment
258       match "/comments/preview" => "comments#preview", :as => :comments_preview, :via => [:get, :post]
259
260       resources :merge_requests do
261         collection do
262           post :create
263           post :commit_list
264           post :target_branches
265         end
266
267         member do
268           get :commit_status
269           get :version
270           get :terms_accepted
271         end
272
273         resources :comments do
274           collection do
275             post :preview
276           end
277         end
278
279         resources :merge_request_versions do
280           resources :comments do
281             collection do
282               post :preview
283             end
284           end
285         end
286       end
287
288       resources :repository_memberships, :only => [:index, :new, :create, :destroy]
289       resources :committerships
290
291       match "/commits/*id/feed(.:format)" => "commits#feed", :as => :formatted_commits_feed
292       match "/commits" => "commits#index", :as => :commits
293       match "/commits/*branch" => "commits#index", :as => :commits_in_ref
294
295       match "/commit/:id/comments" => "commit_comments#index", :as => :commit_comments, :id => /[^\/]+/
296       match "/commit/:id/diffs" => "commit_diffs#index", :as => :commit_diffs, :id => /[^\/]+/
297       match "/commit/:from_id/diffs/:id" => "commit_diffs#compare", :as => :commit_compare
298       match "/commit/:format/:id" => "commits#show", :as => :commit, :id => /.*/
299       match "/commit/:id" => "commits#show", :as => :commit, :id => /.*/
300
301       match "/graph" => "graphs#index", :as => :graph
302       match "/graph/*branch" => "graphs#index", :as => :graph_in_ref
303
304       match "/trees/" => "trees#index", :as => :trees
305       match "/trees/*branch_and_path" => "trees#show", :as => :tree
306       match "/trees/*branch_and_path.:format" => "trees#show", :as => :formatted_tree
307
308       # These URLs were introduced as a work-around for a Rails bug that
309       # prevented URLs like /archive/:branch.:format. Now we can use the
310       # "real" URLs, redirect these temps to the proper ones.
311       get "/archive-tarball/*branch" => (redirect do |params, request|
312         prefix = request.fullpath.split("/archive-tarball").first
313         "#{prefix}/archive/#{params[:branch]}.tar.gz"
314       end)
315
316       match "/archive/*branch.tar.gz" => "trees#archive", :as => :archive_tar
317       match "/archive/*branch.:archive_format" => "trees#archive", :as => :archive
318
319       match "/blobs/raw/*branch_and_path" => "blobs#raw", :as => :raw_blob
320       match "/blobs/history/*branch_and_path" => "blobs#history", :as => :blob_history
321       match "/blobs/blame/*branch_and_path" => "blobs#blame", :as => :blame
322       match "/blobs/*branch_and_path" => "blobs#show", :as => :blob, :branch_and_path => /.*/
323     end
324   end
325 end