X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/1f5561a43693243ad3b6737dcd1020cbe0cc809f..c2aeaa729c350a33ec47ae1b012e50a6685ac2d2:/services/api/app/controllers/arvados/v1/users_controller.rb diff --git a/services/api/app/controllers/arvados/v1/users_controller.rb b/services/api/app/controllers/arvados/v1/users_controller.rb index 367374abfe..08368cb5ef 100644 --- a/services/api/app/controllers/arvados/v1/users_controller.rb +++ b/services/api/app/controllers/arvados/v1/users_controller.rb @@ -1,8 +1,9 @@ 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] + 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,18 +60,17 @@ 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 @@ -89,197 +89,68 @@ class Arvados::V1::UsersController < ApplicationController end # create user object and all the needed links - def create - 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 + def setup + @object = nil + if params[:uuid] + @object = User.find_by_uuid params[:uuid] + if !@object + return render_404_if_no_object 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 + object_found = true + else + if !params[:user] + raise ArgumentError.new "Required uuid or 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] } + if params[:user]['uuid'] + @object = User.find_by_uuid params[:user]['uuid'] + if @object + object_found = true + end 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 - - protected - - # find the user from the given user parameters - def find_user_from_input(user_uuid, user_email) - if user_uuid - found_object = User.find_by_uuid user_uuid - end - if !found_object - begin - if !user_email - return - end + if !@object + if !params[:user]['email'] + raise ArgumentError.new "Require user email" + end - if !user_email.match(/\w\@\w+\.\w+/) - logger.warn ("Given user param is not valid email format: #{user_email}") - raise ArgumentError.new "User param is not of valid email format. Stop" - else - found_objects = User.where('email=?', user_email) - if found_objects.size > 1 - logger.warn ("Found #{found_objects.size} users with email #{user_email}. Stop.") - raise ArgumentError.new "Found #{found_objects.size} users with email #{user_email}. Stop." - elsif found_objects.size == 1 - found_object = found_objects.first + if !params[:openid_prefix] + raise ArgumentError.new "Required openid_prefix parameter is missing." end + + @object = model_class.create! resource_attrs end end 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]}. Skip creating the link") - 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 = (repositories = Repository.where(name: repo_name)) != nil ? repositories.first : nil - if repo - logger.warn "Repository already exists with name #{repo_name}: #{repo[:uuid]}. Will link to user." - - # Look for existing repository access (perhaps using a different repository/user name). - 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 - repo ||= Repository.create(name: repo_name) # create repo, if does not already exist - 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 look up virtual machine with uuid #{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 + protected - if not group - logger.warn "Could not look up the 'All users' group with uuid '*-*-fffffffffffffff'. Skip." - 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') - - 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