Expose user unsetup method from the API server. Added functional tests.
[arvados.git] / services / api / app / models / user.rb
index 218f1da59f20665f5e3845f61774edca1aa5bc3f..b86ac6c9756fe5f72c937dbcab1985888be5f79c 100644 (file)
@@ -111,63 +111,82 @@ class User < ArvadosModel
 
   def self.setup(user, openid_prefix, repo_name=nil, vm_uuid=nil)
     login_perm_props = {identity_url_prefix: openid_prefix}
-    if user[:uuid]
-      found = User.find_by_uuid user[:uuid]
-    end
-
-    if !found
-      if !user[:email]
-        raise "No email found in the input. Aborting user creation."
-      end
 
-      if user.save
-        oid_login_perm = Link.where(tail_uuid: user[:email],
-                                    head_kind: 'arvados#user',
-                                    link_class: 'permission',
-                                    name: 'can_login')
-
-        if !oid_login_perm.any?
-          # create openid login permission
-          oid_login_perm = Link.create(link_class: 'permission',
-                                       name: 'can_login',
-                                       tail_kind: 'email',
-                                       tail_uuid: user[:email],
-                                       head_kind: 'arvados#user',
-                                       head_uuid: user[:uuid],
-                                       properties: login_perm_props
-                                      )
-          logger.info { "openid login permission: " + oid_login_perm[:uuid] }
-        end
-      else
-        raise "Save failed"
-      end
+    # Check oid_login_perm
+    oid_login_perms = Link.where(tail_uuid: user.email,
+                                   head_kind: 'arvados#user',
+                                   link_class: 'permission',
+                                   name: 'can_login')
+
+    if !oid_login_perms.any?
+      # create openid login permission
+      oid_login_perm = Link.create(link_class: 'permission',
+                                   name: 'can_login',
+                                   tail_kind: 'email',
+                                   tail_uuid: user.email,
+                                   head_kind: 'arvados#user',
+                                   head_uuid: user.uuid,
+                                   properties: login_perm_props
+                                  )
+      logger.info { "openid login permission: " + oid_login_perm[:uuid] }
     else
-      user = found
+      oid_login_perm = oid_login_perms.first
     end
 
-    response = {user: user, oid_login_perm: oid_login_perm}
-
-    user.setup_links(repo_name, vm_uuid, openid_prefix, response)
-
-    return response
+    return [oid_login_perm] + user.setup_repo_vm_links(repo_name, vm_uuid)
   end 
 
   # create links
-  def setup_links(repo_name, vm_uuid, openid_prefix, response)
+  def setup_repo_vm_links(repo_name, vm_uuid)
     repo_perm = create_user_repo_link repo_name
-    if repo_perm
-      response[:repo_perm] = repo_perm
+    vm_login_perm = create_vm_login_permission_link vm_uuid, repo_name
+    group_perm = create_user_group_link
+
+    return [repo_perm, vm_login_perm, group_perm, self].compact
+  end 
+
+  # delete user signatures, login, repo, and vm perms, and mark as inactive
+  def unsetup
+    # delete oid_login_perms for this user
+    oid_login_perms = Link.where(tail_uuid: self.email,
+                                 head_kind: 'arvados#user',
+                                 link_class: 'permission',
+                                 name: 'can_login')
+    oid_login_perms.each do |perm|
+      Link.delete perm
     end
 
-    vm_login_perm = create_vm_login_permission_link vm_uuid, repo_name
-    if vm_login_perm
-      response[:vm_login_perm] = vm_login_perm
+    # delete repo_perms for this user
+    repo_perms = Link.where(tail_uuid: self.uuid,
+                            head_kind: 'arvados#repository',
+                            link_class: 'permission',
+                            name: 'can_write')
+    repo_perms.each do |perm|
+      Link.delete perm
     end
 
-    group_perm = create_user_group_links
-    if group_perm
-      response[:group_perm] = group_perm
+    # delete vm_login_perms for this user
+    vm_login_perms = Link.where(tail_uuid: self.uuid,
+                                head_kind: 'arvados#virtualMachine',
+                                link_class: 'permission',
+                                name: 'can_login')
+    vm_login_perms.each do |perm|
+      Link.delete perm
     end
+
+    # delete any signatures by this user
+    signed_uuids = Link.where(link_class: 'signature',
+                              tail_kind: 'arvados#user',
+                              tail_uuid: self.uuid)
+    signed_uuids.each do |sign|
+      Link.delete sign
+    end
+
+    # mark the user as inactive
+    self.is_active = false
+    self.save!
+
+    return self
   end 
 
   protected
@@ -240,6 +259,7 @@ class User < ArvadosModel
   end
 
   def create_user_repo_link(repo_name)
+    # repo_name is optional
     if not repo_name
       logger.warn ("Repository name not given for #{self.uuid}.")
       return
@@ -280,23 +300,28 @@ class User < ArvadosModel
 
   # create login permission for the given vm_uuid, if it does not already exist
   def create_vm_login_permission_link(vm_uuid, repo_name)
-    # Look up the given virtual machine just to make sure it really exists.
     begin
-      vm = VirtualMachine.where(uuid: vm_uuid).first
-
-      if not vm
-        logger.warn "Could not find virtual machine for #{vm_uuid.inspect}"
-        return
+              
+      # vm uuid is optional
+      if vm_uuid 
+        vm = VirtualMachine.where(uuid: vm_uuid).first
+
+        if not vm
+          logger.warn "Could not find virtual machine for #{vm_uuid.inspect}"
+          raise "No vm found for #{vm_uuid}"
+        end
+      else
+        return 
       end
 
       logger.info { "vm uuid: " + vm[:uuid] }
 
-      login_perm = Link.where(tail_uuid: self.uuid,
+      login_perms = Link.where(tail_uuid: self.uuid,
                               head_uuid: vm[:uuid],
                               head_kind: 'arvados#virtualMachine',
                               link_class: 'permission',
                               name: 'can_login')
-      if !login_perm.any?
+      if !login_perms.any?
         login_perm = Link.create(tail_kind: 'arvados#user',
                                  tail_uuid: self.uuid,
                                  head_kind: 'arvados#virtualMachine',
@@ -305,6 +330,8 @@ class User < ArvadosModel
                                  name: 'can_login',
                                  properties: {username: repo_name})
         logger.info { "login permission: " + login_perm[:uuid] }
+      else
+        login_perm = login_perms.first
       end
 
       return login_perm
@@ -312,7 +339,7 @@ class User < ArvadosModel
   end
 
   # add the user to the 'All users' group
-  def create_user_group_links
+  def create_user_group_link
     # Look up the "All users" group (we expect uuid *-*-fffffffffffffff).
     group = Group.where(name: 'All users').select do |g|
       g[:uuid].match /-f+$/
@@ -320,17 +347,17 @@ class User < ArvadosModel
 
     if not group
       logger.warn "No 'All users' group with uuid '*-*-fffffffffffffff'."
-      return
+      raise "No 'All users' group with uuid '*-*-fffffffffffffff' is found"
     else
       logger.info { "\"All users\" group uuid: " + group[:uuid] }
 
-      group_perm = Link.where(tail_uuid: self.uuid,
+      group_perms = Link.where(tail_uuid: self.uuid,
                               head_uuid: group[:uuid],
                               head_kind: 'arvados#group',
                               link_class: 'permission',
                               name: 'can_read')
 
-      if !group_perm.any?
+      if !group_perms.any?
         group_perm = Link.create(tail_kind: 'arvados#user',
                                  tail_uuid: self.uuid,
                                  head_kind: 'arvados#group',
@@ -338,6 +365,8 @@ class User < ArvadosModel
                                  link_class: 'permission',
                                  name: 'can_read')
         logger.info { "group permission: " + group_perm[:uuid] }
+      else 
+        group_perm = group_perms.first
       end
 
       return group_perm