Merge branch '2873-permission-links-ownership'
[arvados.git] / services / api / app / controllers / arvados / v1 / links_controller.rb
1 class Arvados::V1::LinksController < ApplicationController
2
3   def check_uuid_kind uuid, kind
4     if kind and ArvadosModel::resource_class_for_uuid(uuid).andand.kind != kind
5       send_error("'#{kind}' does not match uuid '#{uuid}', expected '#{ArvadosModel::resource_class_for_uuid(uuid).andand.kind}'",
6                  status: 422)
7       nil
8     else
9       true
10     end
11   end
12
13   def create
14     return if ! check_uuid_kind resource_attrs[:head_uuid], resource_attrs[:head_kind]
15     return if ! check_uuid_kind resource_attrs[:tail_uuid], resource_attrs[:tail_kind]
16
17     resource_attrs.delete :head_kind
18     resource_attrs.delete :tail_kind
19     super
20   end
21
22   def get_permissions
23     if current_user.can?(manage: @object)
24       # find all links and return them
25       @objects = Link.where(link_class: "permission",
26                             head_uuid: params[:uuid])
27       @offset = 0
28       @limit = @objects.count
29       render_list
30     else
31       render :json => { errors: ['Forbidden'] }.to_json, status: 403
32     end
33   end
34
35   protected
36
37   # Override find_object_by_uuid: the get_permissions method may be
38   # called on a uuid belonging to any class.
39   def find_object_by_uuid
40     if action_name == 'get_permissions'
41       @object = ArvadosModel::resource_class_for_uuid(params[:uuid])
42         .readable_by(*@read_users)
43         .where(uuid: params[:uuid])
44         .first
45     else
46       super
47     end
48   end
49
50   # Overrides ApplicationController load_where_param
51   def load_where_param
52     super
53
54     # head_kind and tail_kind columns are now virtual,
55     # equivilent functionality is now provided by
56     # 'is_a', so fix up any old-style 'where' clauses.
57     if @where
58       @filters ||= []
59       if @where[:head_kind]
60         @filters << ['head_uuid', 'is_a', @where[:head_kind]]
61         @where.delete :head_kind
62       end
63       if @where[:tail_kind]
64         @filters << ['tail_uuid', 'is_a', @where[:tail_kind]]
65         @where.delete :tail_kind
66       end
67     end
68   end
69
70   # Overrides ApplicationController load_filters_param
71   def load_filters_param
72     super
73
74     # head_kind and tail_kind columns are now virtual,
75     # equivilent functionality is now provided by
76     # 'is_a', so fix up any old-style 'filter' clauses.
77     @filters = @filters.map do |k|
78       if k[0] == 'head_kind' and k[1] == '='
79         ['head_uuid', 'is_a', k[2]]
80       elsif k[0] == 'tail_kind' and k[1] == '='
81         ['tail_uuid', 'is_a', k[2]]
82       else
83         k
84       end
85     end
86   end
87
88 end