Introduce a new setup method in the users controller
authorradhika chippada <radhika@radhika.curoverse>
Thu, 20 Mar 2014 20:07:48 +0000 (16:07 -0400)
committerradhika chippada <radhika@radhika.curoverse>
Thu, 20 Mar 2014 20:07:48 +0000 (16:07 -0400)
services/api/app/controllers/arvados/v1/users_controller.rb
services/api/config/routes.rb
services/api/script/setup-new-user.rb
services/api/test/functional/arvados/v1/users_controller_test.rb

index 367374abfef7f8e5289faf724e493df24508e5b9..1233e74e61283fc850f63bfc5af547dd5468a161 100644 (file)
@@ -1,8 +1,8 @@
 class Arvados::V1::UsersController < ApplicationController
   skip_before_filter :find_object_by_uuid, only:
-    [:activate, :event_stream, :current, :system]
+    [:activate, :event_stream, :current, :system, :setup]
   skip_before_filter :render_404_if_no_object, only:
-    [:activate, :event_stream, :current, :system]
+    [:activate, :event_stream, :current, :system, :setup]
 
   def current
     @object = current_user
@@ -88,6 +88,71 @@ class Arvados::V1::UsersController < ApplicationController
     show
   end
 
+  # create user object and all the needed links
+  def setup
+puts "\n*************PARAMS = #{params.inspect}"
+    if params[:openid_prefix]   # check if default openid_prefix needs to be overridden
+      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
+
+    # If user_param is passed, lookup for user. If exists, skip create and only create any missing links. 
+    if params[:user_param]
+      begin
+        @object_found = find_user_from_input params[:user_param], params[:user_param]
+      end
+      if !@object_found
+        @object = User.new    # when user_param is used, it will be used as user object
+        @object[:email] = params[:user_param]       
+        need_to_create = true
+      else
+        @object = @object_found
+      end
+    else    # need to create user for the given user data
+      @object_found = find_user_from_input @object[:uuid], @object[:email]
+      if !@object_found
+        need_to_create = true   # use the user object sent in to create with the user
+      else
+        @object = @object_found
+      end
+    end
+
+    # create if need be, and then create or update the links as needed 
+    if need_to_create
+      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"
+      end
+    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
+
   # create user object and all the needed links
   def create
     if params[:openid_prefix]   # check if default openid_prefix needs to be overridden
index dffae7fad1725768af1e00b1fbb37ac60da9f650..044f0dc90a4447bb611cbe211a5a7b9ca437b9cd 100644 (file)
@@ -90,6 +90,7 @@ Server::Application.routes.draw do
       post '/jobs/:uuid/cancel' => 'jobs#cancel'
       match '/users/:uuid/event_stream' => 'users#event_stream'
       post '/users/:uuid/activate' => 'users#activate'
+      post '/users/setup' => 'users#setup'
       match '/virtual_machines/get_all_logins' => 'virtual_machines#get_all_logins'
       match '/virtual_machines/:uuid/logins' => 'virtual_machines#logins'
       post '/api_client_authorizations/create_system_auth' => 'api_client_authorizations#create_system_auth'
index 38c9903483c2a90b0a596f1bc3785776ddeed574..ced32bc19f8e65ee4642031a44acd326ba5e91a6 100755 (executable)
@@ -4,6 +4,7 @@ abort 'Error: Ruby >= 1.9.3 required.' if RUBY_VERSION < '1.9.3'
 
 require 'logger'
 require 'trollop'
+
 log = Logger.new STDERR
 log.progname = $0.split('/').last
 
@@ -31,14 +32,35 @@ log.level = (ENV['DEBUG'] || opts.debug) ? Logger::DEBUG : Logger::WARN
 if ARGV.count != 3
   Trollop::die "required arguments are missing"
 end
+
 user_arg, user_repo_name, vm_uuid = ARGV
 
 require 'arvados'
 arv = Arvados.new(api_version: 'v1')
 
+# Look up the given user by uuid or, failing that, email address.
 begin
-  new_user = arv.user.create(user_param: user_arg, repo_name: user_repo_name, vm_uuid: vm_uuid, openid_prefix: opts.openid_prefix, user: {})
-  log.warn new_user
-rescue Exception => e #Arvados::TransactionFailedError
-  log.warn e.message
+  user = arv.user.get(uuid: user_arg)
+rescue Arvados::TransactionFailedError
+  found = arv.user.list(where: {email: ARGV[0]})[:items]
+         
+  if found.count == 0 
+    if !user_arg.match(/\w\@\w+\.\w+/)
+      abort "About to create new user, but #{user_arg.inspect} " +
+               "does not look like an email address. Stop."
+    end
+           
+    user = arv.user.setup(repo_name: user_repo_name, vm_uuid: vm_uuid, user: {email: user_arg})
+    log.info { "created user: " + user[:uuid] }
+  elsif found.count != 1
+    abort "Found #{found.count} users " +
+             "with uuid or email #{user_arg.inspect}. Stop."
+  else 
+    user = found.first
+    # Found user. Update ther user links
+    user = arv.user.setup(repo_name: user_repo_name, vm_uuid: vm_uuid, user: {email: user[:uuid]})
+  end
+    
+  puts "USER = #{user.inspect}"
+  log.info { "user uuid: " + user[:uuid] }
 end
index 748d28157434f5133334d415a4b637bd8e4d4f88..923949acf0aa2cb1c1d948dcd42a67f2512f7af2 100644 (file)
@@ -65,7 +65,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     authorize_with :admin
     repo_name = 'test_repo'
 
-    post :create, {
+    post :setup, {
       repo_name: repo_name,
       vm_uuid: 'no_such_vm',
       user: {
@@ -96,13 +96,12 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
   test "create user with user_param, vm and repo as input" do
     authorize_with :admin
 
-    post :create, {
+    post :setup, {
       user_param: 'not_an_existing_uuid_and_not_email_format',
       repo_name: 'test_repo',
       vm_uuid: 'no_such_vm',
       user: {}
     }
-
     response_body = JSON.parse(@response.body)
     response_errors = response_body['errors']
     assert_not_nil response_errors, 'Expected error in response'
@@ -118,7 +117,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     
     authorize_with :admin
 
-    post :create, {
+    post :setup, {
       user_param: inactive_user['uuid'],
       repo_name: 'test_repo',
       vm_uuid: 'no_such_vm',
@@ -135,7 +134,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
   test "create user with valid email user_param, vm and repo as input" do
     authorize_with :admin
 
-    post :create, {
+    post :setup, {
       user_param: 'abc@xyz.com',
       repo_name: 'test_repo',
       vm_uuid: 'no_such_vm',
@@ -151,7 +150,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
   test "create user with valid email user_param, no vm and repo as input" do
     authorize_with :admin
 
-    post :create, {
+    post :setup, {
       user_param: 'abc@xyz.com',
       user: {}
     }
@@ -165,7 +164,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
   test "create user with user_param and non-empty user which will be ignored" do
     authorize_with :admin
 
-    post :create, {
+    post :setup, {
       user_param: 'abc@xyz.com',
       repo_name: 'test_repo',
       vm_uuid: 'no_such_vm',
@@ -185,7 +184,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
   test "create user twice with user param and check links are not recreated" do
     authorize_with :admin
 
-    post :create, {
+    post :setup, {
       user_param: 'abc@xyz.com',
       repo_name: 'test_repo',
       vm_uuid: 'no_such_vm',
@@ -199,7 +198,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
     verify_num_links @all_links_at_start, 3   # openid, group, and repo links. no vm link
 
     # create again
-    post :create, {
+    post :setup, {
       user_param: 'abc@xyz.com',
       repo_name: 'test_repo',
       vm_uuid: 'no_such_vm',
@@ -216,7 +215,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
   test "create user twice with user object as input and check links are not recreated" do
     authorize_with :admin
 
-    post :create, {
+    post :setup, {
       repo_name: 'test_repo',
       user: {
         email: 'abc@xyz.com'
@@ -244,7 +243,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
   test "create user with openid prefix" do
     authorize_with :admin
 
-    post :create, {
+    post :setup, {
       repo_name: 'test_repo',
       vm_uuid: 'no_such_vm',
       openid_prefix: 'http://www.xyz.com/account',
@@ -275,7 +274,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase
   test "create user with user, vm and repo and verify links" do
     authorize_with :admin
 
-    post :create, {
+    post :setup, {
       repo_name: 'test_repo',
       vm_uuid: @vm_uuid,
       user: {