+ # Next, load the token's user record from the database (might be nil).
+ remote_user_prefix, remote_user_suffix = remote_token['owner_uuid'].split('-', 2)
+ if anonymous_user_uuid.end_with?(remote_user_suffix)
+ # Special case: map the remote anonymous user to local anonymous user
+ remote_user_uuid = anonymous_user_uuid
+ else
+ remote_user_uuid = remote_token['owner_uuid']
+ end
+ user = User.find_by_uuid(remote_user_uuid)
+
+ # Next, try to load the remote user. If this succeeds, we'll use this
+ # information to update/create the local database record as necessary.
+ # If this fails for any reason, but we successfully loaded a user record
+ # from the database, we'll just rely on that information.
+ remote_user = nil
+ begin
+ remote_user = SafeJSON.load(
+ clnt.get_content(
+ remote_url.merge("arvados/v1/users/current"),
+ remote_query, remote_headers,
+ ))
+ rescue HTTPClient::BadResponseError => e
+ # If user is defined, we will use that alone for auth, see below.
+ if user.nil?
+ # See rationale in the previous BadResponseError rescue.
+ def e.http_status
+ self.res.status_code
+ end
+ raise
+ end
+ # TODO #20927: Catch network exceptions and assign a 5xx status to them so
+ # the client knows they're a temporary problem.
+ rescue => e
+ Rails.logger.warn "getting remote user with token #{token.inspect} failed: #{e}"
+ else
+ # Check the response is well formed.
+ if !remote_user.is_a?(Hash) || !remote_user['uuid'].is_a?(String)
+ Rails.logger.warn "malformed remote user=#{remote_user.inspect}"
+ remote_user = nil
+ # Clusters can only authenticate for their own users.
+ elsif remote_user_prefix != upstream_cluster_id
+ Rails.logger.warn "remote user rejected: claimed remote user #{remote_user_prefix} but token was issued by #{upstream_cluster_id}"
+ remote_user = nil
+ # Force our local copy of a remote root to have a static name
+ elsif system_user_uuid.end_with?(remote_user_suffix)
+ remote_user.update(
+ "first_name" => "root",
+ "last_name" => "from cluster #{remote_user_prefix}",
+ )
+ end
+ end
+
+ if user.nil? and remote_user.nil?
+ Rails.logger.warn "remote token #{token.inspect} rejected: cannot get owner #{remote_user_uuid} from database or remote cluster"