Make our dynamic dns update system for compute nodes more generic.
[arvados.git] / services / api / app / models / authorized_key.rb
1 class AuthorizedKey < ArvadosModel
2   include HasUuid
3   include KindAndEtag
4   include CommonApiTemplate
5   before_create :permission_to_set_authorized_user_uuid
6   before_update :permission_to_set_authorized_user_uuid
7
8   belongs_to :authorized_user, :foreign_key => :authorized_user_uuid, :class_name => 'User', :primary_key => :uuid
9
10   validate :public_key_must_be_unique
11
12   api_accessible :user, extend: :common do |t|
13     t.add :name
14     t.add :key_type
15     t.add :authorized_user_uuid
16     t.add :public_key
17     t.add :expires_at
18   end
19
20   def permission_to_set_authorized_user_uuid
21     # Anonymous users cannot do anything here
22     return false if !current_user
23
24     # Administrators can attach a key to any user account
25     return true if current_user.is_admin
26
27     # All users can attach keys to their own accounts
28     return true if current_user.uuid == authorized_user_uuid
29
30     # Default = deny.
31     false
32   end
33
34   def public_key_must_be_unique
35     if self.public_key
36       #key = /^ssh-(rsa|dss) [A-Za-z0-9+\/=\+]+\b/.match(self.public_key)
37       valid_key = SSHKey.valid_ssh_public_key? self.public_key
38
39       if not valid_key
40         errors.add(:public_key, "does not appear to be a valid ssh-rsa or dsa public key")
41       else
42         # Valid if no other rows have this public key
43         if self.class.where('public_key like ?', "%#{self.public_key}%").any?
44           errors.add(:public_key, "already exists in the database, use a different key.")
45           return false
46         end
47       end
48     end
49     return true
50   end
51 end