summaryrefslogtreecommitdiff
path: root/app/helpers/lfs_helper.rb
blob: 95b60aeab5f8139a406e48efaf248021ebbce7c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
module LfsHelper
  include Gitlab::Routing.url_helpers
  
  def require_lfs_enabled!
    return if Gitlab.config.lfs.enabled

    render(
      json: {
        message: 'Git LFS is not enabled on this GitLab server, contact your admin.',
        documentation_url: help_url,
      },
      status: 501
    )
  end

  def lfs_check_access!
    return if download_request? && lfs_download_access?
    return if upload_request? && lfs_upload_access?

    if project.public? || (user && user.can?(:read_project, project))
      render_lfs_forbidden
    else
      render_lfs_not_found
    end
  end

  def lfs_download_access?
    return false unless project.lfs_enabled?

    project.public? || ci? || lfs_deploy_token? || user_can_download_code? || build_can_download_code?
  end

  def user_can_download_code?
    has_authentication_ability?(:download_code) && can?(user, :download_code, project)
  end

  def build_can_download_code?
    has_authentication_ability?(:build_download_code) && can?(user, :build_download_code, project)
  end

  def lfs_upload_access?
    return false unless project.lfs_enabled?

    has_authentication_ability?(:push_code) && can?(user, :push_code, project)
  end

  def render_lfs_forbidden
    render(
      json: {
        message: 'Access forbidden. Check your access level.',
        documentation_url: help_url,
      },
      content_type: "application/vnd.git-lfs+json",
      status: 403
    )
  end

  def render_lfs_not_found
    render(
      json: {
        message: 'Not found.',
        documentation_url: help_url,
      },
      content_type: "application/vnd.git-lfs+json",
      status: 404
    )
  end

  def storage_project
    @storage_project ||= begin
      result = project

      loop do
        break unless result.forked?
        result = result.forked_from_project
      end

      result
    end
  end
end