class Vidibus::Service::ConnectorApp

Public Class Methods

call(env) click to toggle source
# File lib/vidibus/service/connector_app.rb, line 10
def self.call(env)
  self.new.call(env)
end

Public Instance Methods

call(env) click to toggle source
# File lib/vidibus/service/connector_app.rb, line 14
def call(env)
  @request = Rack::Request.new(env)
  unless @request.path == "/connector"
    return response(:error => "This app must be configured to respond to /connector path.")
  end
  method = @request.request_method.downcase
  if respond_to?(method, true)
    send(method)
  else
    response(:error => "Invalid request method: #{method}")
  end
end

Private Instance Methods

connector() click to toggle source

Returns data of the Connector. It will raise an error if this service is unconfigured.

# File lib/vidibus/service/connector_app.rb, line 144
def connector
  @connector ||= service.connector
end
content_type(type = nil) click to toggle source

Sets content type for response.

# File lib/vidibus/service/connector_app.rb, line 121
def content_type(type = nil)
  string = case type
  when :js
    "text/javascript; charset=utf-8"
  else
    "text/html; charset=utf-8"
  end
  { 'Content-Type' => string }
end
create_connector!() click to toggle source

Creates Connector service from params containing function “connector”.

# File lib/vidibus/service/connector_app.rb, line 149
def create_connector!
  uuid, data = @request.params.select {|k,v| v["function"] == "connector"}.first
  raise SetupError, "No Connector data given." unless data
  connector = service.new(data)
  unless connector.save
    raise SetupError, "Setting up the Connector failed: #{connector.errors.full_messages}"
  end
  connector
end
create_this!() click to toggle source

Creates this service from params containing “this”.

# File lib/vidibus/service/connector_app.rb, line 160
def create_this!
  uuid, data = @request.params.select {|k,v| v["this"] == "true"}.first
  raise SetupError, "No data given for this service." unless data

  this = service.new(data)
  this.valid?
  unless this.errors.messages.except(:secret).empty?
    raise ValidationError
  end
  set_secret!(this)
  this.save or raise ValidationError
rescue ValidationError
  raise SetupError, "Setting up this service failed: #{this.errors.full_messages}"
end
decrypt_secret!(secret, nonce, sign) click to toggle source

Decrypts secret with nonce.++

# File lib/vidibus/service/connector_app.rb, line 192
def decrypt_secret!(secret, nonce, sign)
  unless Vidibus::Secure.sign(secret, nonce) == sign
    raise SetupError, "Nonce is invalid."
  end
  Vidibus::Secure.decrypt(secret, nonce)
end
delete() click to toggle source

Deletes services by their UUID.

# File lib/vidibus/service/connector_app.rb, line 84
def delete
  verify_request!
  unless uuids = @request.params["uuids"]
    raise "Provide list of UUIDs of services to delete."
  end

  uuids.each do |uuid|
    obj = service.where(:uuid => uuid).first
    next unless obj
    unless obj.destroy
      errors = obj.errors.full_messages.join(',')
      raise "Deleting service #{uuid} failed: #{errors}"
    end
  end
  response(:success => "Services have been deleted.")
rescue => e
  response(:error => e.message)
end
fetch_secret(service) click to toggle source

Requests encrypted secret for given service from Connector.

# File lib/vidibus/service/connector_app.rb, line 186
def fetch_secret(service)
  uri = "#{connector.url}/services/#{service.uuid}/secret"
  HTTParty.get(uri, :format => :json)
end
get() click to toggle source

Returns settings of this and Connector. This action must only be called by Connector. Thus it is signed with the service's secret.

# File lib/vidibus/service/connector_app.rb, line 45
def get
  verify_request!
  out = {:this => this.public_data}
  if connector = service.local(:connector)
    out[:connector] = connector.public_data
  end
  response(out)
rescue => e
  response(:error => e.message)
end
post() click to toggle source

Creates this service and, unless it has already been set up, a Connector service. Once this service has been created, a secret will be traded for the given nonce.

# File lib/vidibus/service/connector_app.rb, line 31
def post
  if service.where(:this => true, :realm => nil).first
    raise SetupError, "This service has already been set up."
  end
  service.local(:connector) || create_connector!
  create_this!
  response({:success => "Setup successful"}, 201)
rescue SetupError => e
  response(:error => e.message)
end
put() click to toggle source

Updates data of given services.

# File lib/vidibus/service/connector_app.rb, line 57
def put
  verify_request!
  for uuid, attributes in @request.params.except("sign")
    unless Vidibus::Uuid.validate(uuid)
      raise "Updating failed: '#{uuid}' is not a valid UUID."
    end
    conditions = {:uuid => uuid}
    if realm_uuid = attributes.delete("realm_uuid")
      conditions[:realm_uuid] = realm_uuid
    end
    result = service.where(conditions)
    unless result.any?
      raise "Updating service #{uuid} failed: This service does not exist!"
    end
    for _service in result
      _service.attributes = attributes
      unless _service.save
        raise "Updating service #{uuid} failed: #{_service.errors.full_messages}"
      end
    end
  end
  response(:success => "Services updated.")
rescue => e
  response(:error => e.message)
end
response(data, status = nil, type = :js) click to toggle source

Renders response.

# File lib/vidibus/service/connector_app.rb, line 111
def response(data, status = nil, type = :js)
  if data[:error]
    status ||= 400
  else
    status ||= 200
  end
  Rack::Response.new([data.to_json], status, content_type(type)).finish
end
service() click to toggle source

Returns service class.

# File lib/vidibus/service/connector_app.rb, line 132
def service
  @service ||= ::Service
end
set_secret!(service) click to toggle source

Trades given nonce for secret.

# File lib/vidibus/service/connector_app.rb, line 176
def set_secret!(service)
  raise SetupError, "Setting a secret for this service is not allowed!" if service.secret
  nonce = service.nonce
  raise SetupError, "No nonce given." unless nonce and nonce != ""

  fetched = fetch_secret(service)
  service.secret = decrypt_secret!(fetched["secret"], nonce, fetched["sign"])
end
this() click to toggle source

Returns data of this service. It will raise an error if this service is unconfigured.

# File lib/vidibus/service/connector_app.rb, line 138
def this
  @this ||= service.this
end
verify_request!() click to toggle source

Verifies that the signature is valid.

# File lib/vidibus/service/connector_app.rb, line 104
def verify_request!
  unless Vidibus::Secure.verify_request(@request.request_method, @request.url, @request.params, this.secret)
    raise SignatureError.new("Invalid signature.")
  end
end