PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/app/controllers/application_controller.rb

https://gitlab.com/celadevra/gitlab-ce
Ruby | 346 lines | 264 code | 62 blank | 20 comment | 42 complexity | db803bc7d2ffb54020ae0f3098ea2861 MD5 | raw file
Possible License(s): CC-BY-3.0
  1. require 'gon'
  2. require 'fogbugz'
  3. class ApplicationController < ActionController::Base
  4. include Gitlab::CurrentSettings
  5. include GitlabRoutingHelper
  6. include PageLayoutHelper
  7. PER_PAGE = 20
  8. before_action :authenticate_user_from_token!
  9. before_action :authenticate_user!
  10. before_action :reject_blocked!
  11. before_action :check_password_expiration
  12. before_action :ldap_security_check
  13. before_action :default_headers
  14. before_action :add_gon_variables
  15. before_action :configure_permitted_parameters, if: :devise_controller?
  16. before_action :require_email, unless: :devise_controller?
  17. protect_from_forgery with: :exception
  18. helper_method :abilities, :can?, :current_application_settings
  19. helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled?
  20. rescue_from Encoding::CompatibilityError do |exception|
  21. log_exception(exception)
  22. render "errors/encoding", layout: "errors", status: 500
  23. end
  24. rescue_from ActiveRecord::RecordNotFound do |exception|
  25. log_exception(exception)
  26. render_404
  27. end
  28. protected
  29. # From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example
  30. # https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
  31. def authenticate_user_from_token!
  32. user_token = if params[:authenticity_token].presence
  33. params[:authenticity_token].presence
  34. elsif params[:private_token].presence
  35. params[:private_token].presence
  36. end
  37. user = user_token && User.find_by_authentication_token(user_token.to_s)
  38. if user
  39. # Notice we are passing store false, so the user is not
  40. # actually stored in the session and a token is needed
  41. # for every request. If you want the token to work as a
  42. # sign in token, you can simply remove store: false.
  43. sign_in user, store: false
  44. end
  45. end
  46. def authenticate_user!(*args)
  47. # If user is not signed-in and tries to access root_path - redirect him to landing page
  48. # Don't redirect to the default URL to prevent endless redirections
  49. if current_application_settings.home_page_url.present? &&
  50. current_application_settings.home_page_url.chomp('/') != Gitlab.config.gitlab['url'].chomp('/')
  51. if current_user.nil? && root_path == request.path
  52. redirect_to current_application_settings.home_page_url and return
  53. end
  54. end
  55. super(*args)
  56. end
  57. def log_exception(exception)
  58. application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace
  59. application_trace.map!{ |t| " #{t}\n" }
  60. logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}"
  61. end
  62. def reject_blocked!
  63. if current_user && current_user.blocked?
  64. sign_out current_user
  65. flash[:alert] = "Your account is blocked. Retry when an admin has unblocked it."
  66. redirect_to new_user_session_path
  67. end
  68. end
  69. def after_sign_in_path_for(resource)
  70. if resource.is_a?(User) && resource.respond_to?(:blocked?) && resource.blocked?
  71. sign_out resource
  72. flash[:alert] = "Your account is blocked. Retry when an admin has unblocked it."
  73. new_user_session_path
  74. else
  75. stored_location_for(:redirect) || stored_location_for(resource) || root_path
  76. end
  77. end
  78. def after_sign_out_path_for(resource)
  79. current_application_settings.after_sign_out_path || new_user_session_path
  80. end
  81. def abilities
  82. Ability.abilities
  83. end
  84. def can?(object, action, subject)
  85. abilities.allowed?(object, action, subject)
  86. end
  87. def project
  88. unless @project
  89. namespace = params[:namespace_id]
  90. id = params[:project_id] || params[:id]
  91. # Redirect from
  92. # localhost/group/project.git
  93. # to
  94. # localhost/group/project
  95. #
  96. if id =~ /\.git\Z/
  97. redirect_to request.original_url.gsub(/\.git\Z/, '') and return
  98. end
  99. project_path = "#{namespace}/#{id}"
  100. @project = Project.find_with_namespace(project_path)
  101. if @project and can?(current_user, :read_project, @project)
  102. if @project.path_with_namespace != project_path
  103. redirect_to request.original_url.gsub(project_path, @project.path_with_namespace) and return
  104. end
  105. @project
  106. elsif current_user.nil?
  107. @project = nil
  108. authenticate_user!
  109. else
  110. @project = nil
  111. render_404 and return
  112. end
  113. end
  114. @project
  115. end
  116. def repository
  117. @repository ||= project.repository
  118. end
  119. def authorize_project!(action)
  120. return access_denied! unless can?(current_user, action, project)
  121. end
  122. def access_denied!
  123. render "errors/access_denied", layout: "errors", status: 404
  124. end
  125. def git_not_found!
  126. render "errors/git_not_found", layout: "errors", status: 404
  127. end
  128. def method_missing(method_sym, *arguments, &block)
  129. if method_sym.to_s =~ /\Aauthorize_(.*)!\z/
  130. authorize_project!($1.to_sym)
  131. else
  132. super
  133. end
  134. end
  135. def render_403
  136. head :forbidden
  137. end
  138. def render_404
  139. render file: Rails.root.join("public", "404"), layout: false, status: "404"
  140. end
  141. def require_non_empty_project
  142. redirect_to @project if @project.empty_repo?
  143. end
  144. def no_cache_headers
  145. response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
  146. response.headers["Pragma"] = "no-cache"
  147. response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
  148. end
  149. def default_headers
  150. headers['X-Frame-Options'] = 'DENY'
  151. headers['X-XSS-Protection'] = '1; mode=block'
  152. headers['X-UA-Compatible'] = 'IE=edge'
  153. headers['X-Content-Type-Options'] = 'nosniff'
  154. # Enabling HSTS for non-standard ports would send clients to the wrong port
  155. if Gitlab.config.gitlab.https and Gitlab.config.gitlab.port == 443
  156. headers['Strict-Transport-Security'] = 'max-age=31536000'
  157. end
  158. end
  159. def add_gon_variables
  160. gon.api_version = API::API.version
  161. gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s
  162. gon.default_issues_tracker = Project.new.default_issue_tracker.to_param
  163. gon.max_file_size = current_application_settings.max_attachment_size
  164. gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
  165. gon.user_color_scheme = Gitlab::ColorSchemes.for_user(current_user).css_class
  166. if current_user
  167. gon.current_user_id = current_user.id
  168. gon.api_token = current_user.private_token
  169. end
  170. end
  171. def check_password_expiration
  172. if current_user && current_user.password_expires_at && current_user.password_expires_at < Time.now && !current_user.ldap_user?
  173. redirect_to new_profile_password_path and return
  174. end
  175. end
  176. def ldap_security_check
  177. if current_user && current_user.requires_ldap_check?
  178. unless Gitlab::LDAP::Access.allowed?(current_user)
  179. sign_out current_user
  180. flash[:alert] = "Access denied for your LDAP account."
  181. redirect_to new_user_session_path
  182. end
  183. end
  184. end
  185. def event_filter
  186. filters = cookies['event_filter'].split(',') if cookies['event_filter'].present?
  187. @event_filter ||= EventFilter.new(filters)
  188. end
  189. def gitlab_ldap_access(&block)
  190. Gitlab::LDAP::Access.open { |access| block.call(access) }
  191. end
  192. # JSON for infinite scroll via Pager object
  193. def pager_json(partial, count)
  194. html = render_to_string(
  195. partial,
  196. layout: false,
  197. formats: [:html]
  198. )
  199. render json: {
  200. html: html,
  201. count: count
  202. }
  203. end
  204. def view_to_html_string(partial)
  205. render_to_string(
  206. partial,
  207. layout: false,
  208. formats: [:html]
  209. )
  210. end
  211. def configure_permitted_parameters
  212. devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email, :password, :login, :remember_me, :otp_attempt) }
  213. end
  214. def hexdigest(string)
  215. Digest::SHA1.hexdigest string
  216. end
  217. def require_email
  218. if current_user && current_user.temp_oauth_email?
  219. redirect_to profile_path, notice: 'Please complete your profile with email address' and return
  220. end
  221. end
  222. def set_filters_params
  223. params[:sort] ||= 'created_desc'
  224. params[:scope] = 'all' if params[:scope].blank?
  225. params[:state] = 'opened' if params[:state].blank?
  226. @sort = params[:sort]
  227. @filter_params = params.dup
  228. if @project
  229. @filter_params[:project_id] = @project.id
  230. elsif @group
  231. @filter_params[:group_id] = @group.id
  232. else
  233. # TODO: this filter ignore issues/mr created in public or
  234. # internal repos where you are not a member. Enable this filter
  235. # or improve current implementation to filter only issues you
  236. # created or assigned or mentioned
  237. #@filter_params[:authorized_only] = true
  238. end
  239. @filter_params
  240. end
  241. def get_issues_collection
  242. set_filters_params
  243. @issuable_finder = IssuesFinder.new(current_user, @filter_params)
  244. @issuable_finder.execute
  245. end
  246. def get_merge_requests_collection
  247. set_filters_params
  248. @issuable_finder = MergeRequestsFinder.new(current_user, @filter_params)
  249. @issuable_finder.execute
  250. end
  251. def import_sources_enabled?
  252. !current_application_settings.import_sources.empty?
  253. end
  254. def github_import_enabled?
  255. current_application_settings.import_sources.include?('github')
  256. end
  257. def github_import_configured?
  258. Gitlab::OAuth::Provider.enabled?(:github)
  259. end
  260. def gitlab_import_enabled?
  261. request.host != 'gitlab.com' && current_application_settings.import_sources.include?('gitlab')
  262. end
  263. def gitlab_import_configured?
  264. Gitlab::OAuth::Provider.enabled?(:gitlab)
  265. end
  266. def bitbucket_import_enabled?
  267. current_application_settings.import_sources.include?('bitbucket')
  268. end
  269. def bitbucket_import_configured?
  270. Gitlab::OAuth::Provider.enabled?(:bitbucket) && Gitlab::BitbucketImport.public_key.present?
  271. end
  272. def gitorious_import_enabled?
  273. current_application_settings.import_sources.include?('gitorious')
  274. end
  275. def google_code_import_enabled?
  276. current_application_settings.import_sources.include?('google_code')
  277. end
  278. def fogbugz_import_enabled?
  279. current_application_settings.import_sources.include?('fogbugz')
  280. end
  281. def git_import_enabled?
  282. current_application_settings.import_sources.include?('git')
  283. end
  284. end