summaryrefslogtreecommitdiff
path: root/lib/ci/api/helpers.rb
blob: 3f58670fb498bda1663451059b944e94d2f5436c (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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
module Ci
  module API
    module Helpers
      PRIVATE_TOKEN_PARAM = :private_token
      PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN"
      ACCESS_TOKEN_PARAM = :access_token
      ACCESS_TOKEN_HEADER = "HTTP_ACCESS_TOKEN"
      UPDATE_RUNNER_EVERY = 60

      def current_user
        @current_user ||= begin
          options = {
            access_token: (params[ACCESS_TOKEN_PARAM] || env[ACCESS_TOKEN_HEADER]),
            private_token: (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]),
          }
          Ci::UserSession.new.authenticate(options.compact)
        end
      end

      def current_runner
        @runner ||= Ci::Runner.find_by_token(params[:token].to_s)
      end

      def authenticate!
        forbidden! unless current_user
      end

      def authenticate_runners!
        forbidden! unless params[:token] == GitlabCi::REGISTRATION_TOKEN
      end

      def authenticate_runner!
        forbidden! unless current_runner
      end

      def authenticate_project_token!(project)
        forbidden! unless project.valid_token?(params[:project_token])
      end

      def update_runner_last_contact
        if current_runner.contacted_at.nil? || Time.now - current_runner.contacted_at >= UPDATE_RUNNER_EVERY
          current_runner.update_attributes(contacted_at: Time.now)
        end
      end

      def update_runner_info
        return unless params["info"].present?
        info = attributes_for_keys(["name", "version", "revision", "platform", "architecture"], params["info"])
        current_runner.update(info)
      end

      # Checks the occurrences of required attributes, each attribute must be present in the params hash
      # or a Bad Request error is invoked.
      #
      # Parameters:
      #   keys (required) - A hash consisting of keys that must be present
      def required_attributes!(keys)
        keys.each do |key|
          bad_request!(key) unless params[key].present?
        end
      end

      def attributes_for_keys(keys, custom_params = nil)
        params_hash = custom_params || params
        attrs = {}
        keys.each do |key|
          attrs[key] = params_hash[key] if params_hash[key].present?
        end
        attrs
      end

      # error helpers

      def forbidden!
        render_api_error!('403 Forbidden', 403)
      end

      def bad_request!(attribute)
        message = ["400 (Bad request)"]
        message << "\"" + attribute.to_s + "\" not given"
        render_api_error!(message.join(' '), 400)
      end

      def not_found!(resource = nil)
        message = ["404"]
        message << resource if resource
        message << "Not Found"
        render_api_error!(message.join(' '), 404)
      end

      def unauthorized!
        render_api_error!('401 Unauthorized', 401)
      end

      def not_allowed!
        render_api_error!('Method Not Allowed', 405)
      end

      def render_api_error!(message, status)
        error!({ 'message' => message }, status)
      end

      private

      def abilities
        @abilities ||= begin
                         abilities = Six.new
                         abilities << Ability
                         abilities
                       end
      end
    end
  end
end