Separate out the repository ownership from the namespacing
[gitorious:taladars-gitorious-saltation.git] / app / controllers / application_controller.rb
1 #--
2 #   Copyright (C) 2007, 2008 Johan Sørensen <johan@johansorensen.com>
3 #
4 #   This program is free software: you can redistribute it and/or modify
5 #   it under the terms of the GNU Affero General Public License as published by
6 #   the Free Software Foundation, either version 3 of the License, or
7 #   (at your option) any later version.
8 #
9 #   This program is distributed in the hope that it will be useful,
10 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 #   GNU Affero General Public License for more details.
13 #
14 #   You should have received a copy of the GNU Affero General Public License
15 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 #++
17
18 # Filters added to this controller apply to all controllers in the application.
19 # Likewise, all the methods added will be available for all controllers.
20
21 class ApplicationController < ActionController::Base
22   include AuthenticatedSystem
23   include ExceptionNotifiable
24   
25   before_filter :public_and_logged_in
26   
27   rescue_from ActiveRecord::RecordNotFound, :with => :render_not_found
28   rescue_from ActionController::UnknownController, :with => :render_not_found
29   rescue_from ActionController::UnknownAction, :with => :render_not_found
30   rescue_from Grit::GitRuby::Repository::NoSuchPath, :with => :render_not_found
31   rescue_from Grit::Git::GitTimeout, :with => :render_git_timeout
32   
33   def rescue_action(exception)
34     return super if RAILS_ENV != "production"
35     
36     case exception
37       # Can't catch RoutingError with rescue_from it seems, 
38       # so do it the old-fashioned way
39     when ActionController::RoutingError
40       render_not_found
41     else
42       super
43     end
44   end
45   
46   protected
47     def require_user_has_ssh_keys
48       unless current_user.ssh_keys.count > 0
49         flash[:error] = I18n.t "application.require_ssh_keys_error"
50         redirect_to new_account_key_path
51         return 
52       end
53     end
54     
55     def require_current_eula
56       unless current_user.current_license_agreement_accepted?
57         store_location
58         flash[:error] = I18n.t "views.license.terms_not_accepted"
59         redirect_to account_license_path
60         return
61       end
62     end
63     
64     def find_repository_owner
65       if params[:project_id]
66         @owner = Project.find_by_slug!(params[:project_id])
67         @project = @owner
68       elsif params[:user_id]
69         @owner = User.find_by_login!(params[:user_id])
70       elsif params[:group_id]
71         @owner = Group.find_by_name!(params[:group_id])
72       else
73         raise ActiveRecord::RecordNotFound
74       end
75     end
76     
77     def find_repository_owner_and_repository
78       find_repository_owner
79       @owner.repositories.find_by_name!(params[:id])
80     end
81     
82     def find_project
83       @project = Project.find_by_slug!(params[:project_id])
84     end
85     
86     def find_project_and_repository
87       @project = Project.find_by_slug!(params[:project_id])
88       # We want to look in all repositories that's somehow within this project
89       # realm, not just @project.repositories
90       @repository = Repository.find_by_name_and_project_id!(params[:repository_id], @project.id)
91     end
92     
93     def check_repository_for_commits
94       unless @repository.has_commits?
95         flash[:notice] = I18n.t "application.no_commits_notice"
96         redirect_to project_repository_path(@project, @repository) and return
97       end
98     end
99     
100     def render_not_found
101       render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
102     end
103     
104     def render_git_timeout
105       render :partial => "/projects/git_timeout", :layout => "application" and return
106     end
107     
108     def public_and_logged_in
109       login_required unless GitoriousConfig['public_mode']
110     end
111     
112     # turns ["foo", "bar"] route globbing parameters into "foo/bar"
113     def desplat_path(*paths)
114       paths.join("/")
115     end
116     helper_method :desplat_path
117     
118     # turns "foo/bar" into ["foo", "bar"] for route globbing
119     def ensplat_path(path)
120       path.split("/").select{|p| !p.blank? }
121     end
122     helper_method :ensplat_path
123     
124     # Returns an array like [branch_ref, *tree_path]
125     def branch_with_tree(branch_ref, tree_path)
126       tree_path = tree_path.is_a?(Array) ? tree_path : ensplat_path(tree_path)
127       ensplat_path(branch_ref) + tree_path
128     end
129     helper_method :branch_with_tree
130     
131     def branch_and_path(branch_and_path, git)
132       branch_and_path = desplat_path(branch_and_path)
133       branch_ref = path = nil
134       heads = Array(git.heads).map{|h| h.name }
135       heads.each do |head|
136         if branch_and_path.starts_with?(head)
137           branch_ref = head
138           path = ensplat_path(branch_and_path.sub(head, "")) || []
139         end
140       end
141       unless path # fallback
142         path = ensplat_path(branch_and_path)[1..-1]
143         branch_ref = ensplat_path(branch_and_path)[0]
144       end
145       [branch_ref, path]
146     end
147 end