Merge branch '12863-wb-cr-status'
[arvados.git] / services / api / app / controllers / arvados / v1 / users_controller.rb
index 131ee5236bc08e26afb096912505594db0755f67..dc7e62f3e340741bec37e1d72bbb99c7ccf797d4 100644 (file)
@@ -1,3 +1,7 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
 class Arvados::V1::UsersController < ApplicationController
   accept_attribute_as_json :prefs, Hash
 
@@ -5,7 +9,7 @@ class Arvados::V1::UsersController < ApplicationController
     [:activate, :current, :system, :setup]
   skip_before_filter :render_404_if_no_object, only:
     [:activate, :current, :system, :setup]
-  before_filter :admin_required, only: [:setup, :unsetup]
+  before_filter :admin_required, only: [:setup, :unsetup, :update_uuid]
 
   def current
     if current_user
@@ -64,49 +68,44 @@ class Arvados::V1::UsersController < ApplicationController
 
   # create user object and all the needed links
   def setup
-    @object = nil
     if params[:uuid]
-      @object = User.find_by_uuid params[:uuid]
+      @object = User.find_by_uuid(params[:uuid])
       if !@object
         return render_404_if_no_object
       end
-      object_found = true
+    elsif !params[:user]
+      raise ArgumentError.new "Required uuid or user"
+    elsif !params[:user]['email']
+      raise ArgumentError.new "Require user email"
+    elsif !params[:openid_prefix]
+      raise ArgumentError.new "Required openid_prefix parameter is missing."
     else
-      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
-
-        if !@object
-          if !params[:user]['email']
-            raise ArgumentError.new "Require user email"
-          end
-
-          if !params[:openid_prefix]
-            raise ArgumentError.new "Required openid_prefix parameter is missing."
-          end
-
-          @object = model_class.create! resource_attrs
-        end
-      end
+      @object = model_class.create! resource_attrs
     end
 
-    if object_found
-      @response = @object.setup_repo_vm_links params[:repo_name],
-                    params[:vm_uuid], params[:openid_prefix]
+    # It's not always possible for the client to know the user's
+    # username when submitting this request: the username might have
+    # been assigned automatically in create!() above. If client
+    # provided a plain repository name, prefix it with the username
+    # now that we know what it is.
+    if params[:repo_name].nil?
+      full_repo_name = nil
+    elsif @object.username.nil?
+      raise ArgumentError.
+        new("cannot setup a repository because user has no username")
+    elsif params[:repo_name].index("/")
+      full_repo_name = params[:repo_name]
     else
-      @response = User.setup @object, params[:openid_prefix],
-                    params[:repo_name], params[:vm_uuid]
+      full_repo_name = "#{@object.username}/#{params[:repo_name]}"
     end
 
+    @response = @object.setup(repo_name: full_repo_name,
+                              vm_uuid: params[:vm_uuid],
+                              openid_prefix: params[:openid_prefix])
+
     # setup succeeded. send email to user
-    if params[:send_notification_email] == true || params[:send_notification_email] == 'true'
-      UserNotifier.account_is_setup(@object).deliver
+    if params[:send_notification_email]
+      UserNotifier.account_is_setup(@object).deliver_now
     end
 
     send_json kind: "arvados#HashList", items: @response.as_api_response(nil)
@@ -119,6 +118,13 @@ class Arvados::V1::UsersController < ApplicationController
     show
   end
 
+  # Change UUID to a new (unused) uuid and transfer all owned/linked
+  # objects accordingly.
+  def update_uuid
+    @object.update_uuid(new_uuid: params[:new_uuid])
+    show
+  end
+
   protected
 
   def self._setup_requires_parameters
@@ -141,8 +147,16 @@ class Arvados::V1::UsersController < ApplicationController
     }
   end
 
+  def self._update_uuid_requires_parameters
+    {
+      new_uuid: {
+        type: 'string', required: true,
+      },
+    }
+  end
+
   def apply_filters(model_class=nil)
-    return super if @read_users.any? &:is_admin
+    return super if @read_users.any?(&:is_admin)
     if params[:uuid] != current_user.andand.uuid
       # Non-admin index/show returns very basic information about readable users.
       safe_attrs = ["uuid", "is_active", "email", "first_name", "last_name"]