Sha256: 711292e6404f9867c97adc9bc109fb4c32afcfc92a4f5ebcf9c16fe1ab76805d

Contents?: true

Size: 1.94 KB

Versions: 2

Compression:

Stored size: 1.94 KB

Contents

module SWD
  class Resource
    include AttrRequired, AttrOptional
    attr_required :principal, :service, :host, :path
    attr_optional :port

    class Expired < Exception; end

    def initialize(attributes = {})
      (optional_attributes + required_attributes).each do |key|
        self.send "#{key}=", attributes[key]
      end
      @path ||= '/.well-known/simple-web-discovery'
      attr_missing!
    end

    def discover!(cache_options = {})
      SWD.cache.fetch(cache_key, cache_options) do
        handle_response do
          SWD.http_client.get endpoint.to_s
        end
      end
    end

    def endpoint
      SWD.url_builder.build [nil, host, port, path, {
        :principal => principal,
        :service => service
      }.to_query, nil]
    rescue URI::Error => e
      raise Exception.new(e.message)
    end

    private

    def handle_response
      json = yield.body.with_indifferent_access
      if redirect = json[:SWD_service_redirect]
        redirect_to redirect[:location], redirect[:expires]
      else
        Response.new json
      end
    rescue Faraday::Error => e
      case e.response_status
      when nil
        raise e
      when 400
        raise BadRequest.new('Bad Request', e.response_body)
      when 401
        raise Unauthorized.new('Unauthorized', e.response_body)
      when 403
        raise Forbidden.new('Forbidden', e.response_body)
      when 404
        raise NotFound.new('Not Found', e.response_body)
      else
        raise HttpError.new(e.response_status, e.response_body, e.response_body)
      end
    end

    def redirect_to(location, expires)
      uri = URI.parse(location)
      @host, @path, @port = uri.host, uri.path, uri.port
      raise Expired if expires && expires.to_i < Time.now.utc.to_i
      discover!
    end

    def cache_key
      sha256 = OpenSSL::Digest::SHA256.hexdigest [
        principal,
        service,
        host
      ].join(' ')
      "swd:resource:#{sha256}"
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
swd-2.0.1 lib/swd/resource.rb
swd-2.0.0 lib/swd/resource.rb