def index
expires_in 24.hours, public: true
- discovery = Rails.cache.fetch 'arvados_v1_rest_discovery' do
+ send_json discovery_doc
+ end
+
+ protected
+
+ def discovery_doc
+ Rails.cache.fetch 'arvados_v1_rest_discovery' do
Rails.application.eager_load!
discovery = {
kind: "discovery#restDescription",
crunchLogThrottleLines: Rails.application.config.crunch_log_throttle_lines,
crunchLimitLogBytesPerJob: Rails.application.config.crunch_limit_log_bytes_per_job,
crunchLogPartialLineThrottlePeriod: Rails.application.config.crunch_log_partial_line_throttle_period,
+ remoteHosts: Rails.configuration.remote_hosts,
+ remoteHostsViaDNS: Rails.configuration.remote_hosts_via_dns,
websocketUrl: Rails.application.config.websocket_address,
parameters: {
alt: {
end
discovery
end
- send_json discovery
end
end
auth = ApiClientAuthorization.
validate(token: Thread.current[:supplied_token], remote: false)
- if auth
- auth.last_used_at = Time.now
- auth.last_used_by_ip_address = remote_ip.to_s
- auth.save validate: false
- end
-
Thread.current[:api_client_ip_address] = remote_ip
Thread.current[:api_client_authorization] = auth
Thread.current[:api_client_uuid] = auth.andand.api_client.andand.uuid
Thread.current[:api_client] = auth.andand.api_client
Thread.current[:user] = auth.andand.user
+ if auth
+ auth.last_used_at = Time.now
+ auth.last_used_by_ip_address = remote_ip.to_s
+ auth.save validate: false
+ end
+
@app.call env if @app
end
end
include HasUuid
include KindAndEtag
include CommonApiTemplate
+ extend CurrentApiClient
belongs_to :api_client
belongs_to :user
["#{table_name}.id desc"]
end
+ def self.remote_host(uuid:)
+ Rails.configuration.remote_hosts[uuid[0..4]] ||
+ (Rails.configuration.remote_hosts_via_dns &&
+ uuid[0..4]+".arvadosapi.com")
+ end
+
def self.validate(token:, remote:)
return nil if !token
remote ||= Rails.configuration.uuid_prefix
(secret == auth.api_token ||
secret == OpenSSL::HMAC.hexdigest('sha1', auth.api_token, remote))
return auth
+ elsif uuid[0..4] != Rails.configuration.uuid_prefix
+ # Token was issued by a different cluster. If it's expired or
+ # missing in our database, ask the originating cluster to
+ # [re]validate it.
+ arv = Arvados.new(api_host: remote_host(uuid: uuid),
+ api_token: token)
+ remote_user = arv.user.current(remote_id: Rails.configuration.uuid_prefix)
+ if remote_user && remote_user[:uuid][0..4] == uuid[0..4]
+ act_as_system_user do
+ # Add/update user and token in our database so we can
+ # validate subsequent requests faster.
+ user = User.find_or_create_by(uuid: remote_user[:uuid])
+ user.update_attributes!(remote_user)
+ auth = ApiClientAuthorization.
+ includes(:user).
+ find_or_create_by(uuid: uuid,
+ api_token: token,
+ user: user,
+ api_client_id: 0)
+ # Accept this token (and don't reload the user record) for
+ # 5 minutes. TODO: Request the actual api_client_auth
+ # record from the remote server in case it wants the token
+ # to expire sooner.
+ auth.update_attributes!(expires_at: Time.now + 5.minutes)
+ end
+ return auth
+ end
end
else
auth = ApiClientAuthorization.
# original job reuse behavior, and is still the default).
reuse_job_if_outputs_differ: false
+ ###
+ ### Federation support.
+ ###
+
+ # Map known prefixes to hosts. Example:
+ # remote_hosts:
+ # zzzzz: zzzzz.example.com
+ remote_hosts: {}
+
+ # Use {prefix}.arvadosapi.com for any prefix not given in
+ # remote_hosts above.
+ remote_hosts_via_dns: true
+
###
### Remaining assorted configuration options.
###