411296c127a25764ae3f931793ffd384678df112
[arvados.git] / app / models / orvos_model.rb
1 class OrvosModel < ActiveRecord::Base
2   self.abstract_class = true
3
4   include CurrentApiClient      # current_user, current_api_client, etc.
5
6   attr_protected :created_at
7   attr_protected :modified_by_user
8   attr_protected :modified_by_client
9   attr_protected :modified_at
10   before_update :permission_to_update
11   before_create :update_modified_by_fields
12   before_update :update_modified_by_fields
13
14   def self.kind_class(kind)
15     kind.match(/^orvos\#(.+?)(_list|List)?$/)[1].pluralize.classify.constantize rescue nil
16   end
17
18   def eager_load_associations
19     self.class.columns.each do |col|
20       re = col.name.match /^(.*)_kind$/
21       if (re and
22           self.respond_to? re[1].to_sym and
23           (auuid = self.send((re[1] + '_uuid').to_sym)) and
24           (aclass = self.class.kind_class(self.send(col.name.to_sym))) and
25           (aobject = aclass.where('uuid=?', auuid).first))
26         self.instance_variable_set('@'+re[1], aobject)
27       end
28     end
29   end
30
31   protected
32
33   def permission_to_update
34     if !current_user
35       logger.warn "Anonymous user tried to update #{self.class.to_s} #{self.uuid_was}"
36       return false
37     end
38     if self.uuid_changed?
39       logger.warn "User #{current_user.uuid} tried to change uuid of #{self.class.to_s} #{self.uuid_was} to #{self.uuid}"
40       return false
41     end
42     return true if current_user.is_admin
43     if self.owner_changed? and
44         self.owner_was != current_user.uuid and
45         0 == Link.where(link_class: 'permission',
46                         name: 'can_pillage',
47                         tail_uuid: self.owner,
48                         head_uuid: current_user.uuid).count
49       logger.warn "User #{current_user.uuid} tried to change owner of #{self.class.to_s} #{self.uuid} to #{self.owner}"
50       return false
51     end
52     self.owner == current_user.uuid or
53       current_user.is_admin or
54       current_user.uuid == self.uuid or
55       Link.where(link_class: 'permission',
56                  name: 'can_write',
57                  tail_uuid: self.owner,
58                  head_uuid: current_user.uuid).count > 0
59   end
60
61   def update_modified_by_fields
62     if self.changed?
63       self.created_at ||= Time.now
64       self.owner ||= current_user.uuid
65       self.modified_at = Time.now
66       self.modified_by_user = current_user.uuid
67       self.modified_by_client = current_api_client ? current_api_client.uuid : nil
68     end
69   end
70 end