Merge branch '1968-monitor-disk-usage'
[arvados.git] / services / api / app / controllers / arvados / v1 / users_controller.rb
index adad309fda9e0ca27b6edff3aa59b567ecbfce47..c2a32f02f1b7e0e68bd8da293e34a0269308b4c0 100644 (file)
@@ -3,6 +3,7 @@ class Arvados::V1::UsersController < ApplicationController
     [:activate, :event_stream, :current, :system, :setup]
   skip_before_filter :render_404_if_no_object, only:
     [:activate, :event_stream, :current, :system, :setup]
+  before_filter :admin_required, only: [:setup, :unsetup]
 
   def current
     @object = current_user
@@ -28,7 +29,7 @@ class Arvados::V1::UsersController < ApplicationController
       end
     end
   end
-      
+
   def event_stream
     channel = current_user.andand.uuid
     if current_user.andand.is_admin
@@ -59,22 +60,21 @@ class Arvados::V1::UsersController < ApplicationController
         raise ArgumentError.new "Cannot activate without being invited."
       end
       act_as_system_user do
-        required_uuids = Link.where(owner_uuid: system_user_uuid,
-                                    link_class: 'signature',
-                                    name: 'require',
-                                    tail_uuid: system_user_uuid,
-                                    head_kind: 'arvados#collection').
+        required_uuids = Link.where("owner_uuid = ? and link_class = ? and name = ? and tail_uuid = ? and head_uuid like ?",
+                                    system_user_uuid,
+                                    'signature',
+                                    'require',
+                                    system_user_uuid,
+                                    Collection.uuid_like_pattern).
           collect(&:head_uuid)
         signed_uuids = Link.where(owner_uuid: system_user_uuid,
                                   link_class: 'signature',
                                   name: 'click',
-                                  tail_kind: 'arvados#user',
                                   tail_uuid: @object.uuid,
-                                  head_kind: 'arvados#collection',
                                   head_uuid: required_uuids).
           collect(&:head_uuid)
         todo_uuids = required_uuids - signed_uuids
-        if todo_uuids == []
+        if todo_uuids.empty?
           @object.update_attributes is_active: true
           logger.info "User #{@object.uuid} activated"
         else
@@ -90,174 +90,67 @@ class Arvados::V1::UsersController < ApplicationController
 
   # create user object and all the needed links
   def setup
-    # check if default openid_prefix needs to be overridden
-    if params[:openid_prefix]
-      openid_prefix = params[:openid_prefix]
-    else 
-      openid_prefix = Rails.configuration.openid_prefix
-    end
-    login_perm_props = {identity_url_prefix: openid_prefix}
-
-    @object = model_class.new resource_attrs
-
-    # Lookup for user. If exists, only create any missing links
-    @object_found = find_user_from_input 
-
-    if !@object_found
-      if !@object[:email]
-        raise "No email found in the input. Aborting user creation."
-      end
-
-      if @object.save
-        oid_login_perm = Link.where(tail_uuid: @object[:email],
-                                    head_kind: 'arvados#user',
-                                    link_class: 'permission',
-                                    name: 'can_login')
-
-        if [] == oid_login_perm
-          # create openid login permission
-          oid_login_perm = Link.create(link_class: 'permission',
-                                       name: 'can_login',
-                                       tail_kind: 'email',
-                                       tail_uuid: @object[:email],
-                                       head_kind: 'arvados#user',
-                                       head_uuid: @object[:uuid],
-                                       properties: login_perm_props
-                                      )
-          logger.info { "openid login permission: " + oid_login_perm[:uuid] }
-        end
-      else
-        raise "Save failed"
+    @object = nil
+    if params[:uuid]
+      @object = User.find_by_uuid params[:uuid]
+      if !@object
+        return render_404_if_no_object
       end
+      object_found = true
     else
-      @object = @object_found
-    end
-    
-    # create links
-    create_user_repo_link params[:repo_name]
-    create_vm_login_permission_link params[:vm_uuid], params[:repo_name]
-    create_user_group_link 
-
-    show  
-  end
+      if !params[:user]
+        raise ArgumentError.new "Required uuid or user"
+      else
+        if params[:user]['uuid']
+          @object = User.find_by_uuid params[:user]['uuid']
+          if @object
+            object_found = true
+          end
+        end
 
-  protected 
+        if !@object
+          if !params[:user]['email']
+            raise ArgumentError.new "Require user email"
+          end
 
-  # find the user from the given user parameters
-  def find_user_from_input
-    if @object[:uuid]
-      found_object = User.find_by_uuid @object[:uuid]
-    end
+          if !params[:openid_prefix]
+            raise ArgumentError.new "Required openid_prefix parameter is missing."
+          end
 
-    if !found_object
-      if !@object[:email]
-        return
+          @object = model_class.create! resource_attrs
+        end
       end
-
-      found_objects = User.where('email=?', @object[:email])  
-      found_object = found_objects.first
     end
 
-    return found_object
-  end
-  
-  # link the repo_name passed
-  def create_user_repo_link(repo_name)
-    if not repo_name
-      logger.warn ("Repository name not given for #{@object[:uuid]}.")
-      return
+    if object_found
+      @response = @object.setup_repo_vm_links params[:repo_name],
+                    params[:vm_uuid], params[:openid_prefix]
+    else
+      @response = User.setup @object, params[:openid_prefix],
+                    params[:repo_name], params[:vm_uuid]
     end
 
-    # Check for an existing repository with the same name we're about to use.
-    repo = (repos = Repository.where(name: repo_name)) != nil ? repos.first : nil
-    if repo
-      logger.warn "Repository exists for #{repo_name}: #{repo[:uuid]}."
-
-      # Look for existing repository access for this repo
-      repo_perms = Link.where(tail_uuid: @object[:uuid],
-                              head_kind: 'arvados#repository',
-                              head_uuid: repo[:uuid],
-                              link_class: 'permission',
-                              name: 'can_write')
-      if [] != repo_perms
-        logger.warn "User already has repository access " + 
-            repo_perms.collect { |p| p[:uuid] }.inspect
-        return
-      end
+    # setup succeeded. send email to user
+    if params[:send_notification_email] == true || params[:send_notification_email] == 'true'
+      UserNotifier.account_is_setup(@object).deliver
     end
 
-    # create repo, if does not already exist
-    repo ||= Repository.create(name: repo_name)
-    logger.info { "repo uuid: " + repo[:uuid] }
-
-    repo_perm = Link.create(tail_kind: 'arvados#user',
-                            tail_uuid: @object[:uuid],
-                            head_kind: 'arvados#repository',
-                            head_uuid: repo[:uuid],
-                            link_class: 'permission',
-                            name: 'can_write')
-    logger.info { "repo permission: " + repo_perm[:uuid] }
+    render json: { kind: "arvados#HashList", items: @response.as_api_response(nil) }
   end
 
-  # 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 = (vms = VirtualMachine.where(uuid: vm_uuid)) != nil ? vms.first : nil
-      if not vm
-        logger.warn "Could not find virtual machine for #{vm_uuid.inspect}"
-        return
-      end
-
-      logger.info { "vm uuid: " + vm[:uuid] }
-
-      login_perm = Link.where(tail_uuid: @object[:uuid],
-                              head_uuid: vm[:uuid],
-                              head_kind: 'arvados#virtualMachine',
-                              link_class: 'permission',
-                              name: 'can_login')
-      if [] == login_perm
-        login_perm = Link.create(tail_kind: 'arvados#user',
-                                 tail_uuid: @object[:uuid],
-                                 head_kind: 'arvados#virtualMachine',
-                                 head_uuid: vm[:uuid],
-                                 link_class: 'permission',
-                                 name: 'can_login',
-                                 properties: {username: repo_name})
-        logger.info { "login permission: " + login_perm[:uuid] }
-      end
-    end
+  # delete user agreements, vm, repository, login links; set state to inactive
+  def unsetup
+    reload_object_before_update
+    @object.unsetup
+    show
   end
 
-  # add the user to the 'All users' group
-  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+$/
-    end.first
-
-    if not group
-      logger.warn "No 'All users' group with uuid '*-*-fffffffffffffff'."
-      return
-    else
-      logger.info { "\"All users\" group uuid: " + group[:uuid] }
-
-      group_perm = Link.where(tail_uuid: @object[:uuid],
-                              head_uuid: group[:uuid],
-                              head_kind: 'arvados#group',
-                              link_class: 'permission',
-                              name: 'can_read')
+  protected
 
-      if [] == group_perm
-        group_perm = Link.create(tail_kind: 'arvados#user',
-                                 tail_uuid: @object[:uuid],
-                                 head_kind: 'arvados#group',
-                                 head_uuid: group[:uuid],
-                                 link_class: 'permission',
-                                 name: 'can_read')
-        logger.info { "group permission: " + group_perm[:uuid] }
-      end
-    end
+  def self._setup_requires_parameters
+    {
+      send_notification_email: { type: 'boolean', required: true },
+    }
   end
 
 end