Module: Attache::API::V1

Extended by:
V1
Included in:
V1
Defined in:
lib/attache/api/v1.rb

Defined Under Namespace

Classes: HTTPClient

Constant Summary collapse

ATTACHE_URL =
ENV.fetch('ATTACHE_URL')             { "http://localhost:9292" }
ATTACHE_UPLOAD_URL =
ENV.fetch('ATTACHE_UPLOAD_URL')      { "#{ATTACHE_URL}/upload" }
ATTACHE_DOWNLOAD_URL =
ENV.fetch('ATTACHE_DOWNLOAD_URL')    { "#{ATTACHE_URL}/view" }
ATTACHE_DELETE_URL =
ENV.fetch('ATTACHE_DELETE_URL')      { "#{ATTACHE_URL}/delete" }
ATTACHE_BACKUP_URL =
ENV.fetch('ATTACHE_BACKUP_URL')      { "#{ATTACHE_URL}/backup" }
ATTACHE_UPLOAD_DURATION =

expires signed upload form

ENV.fetch('ATTACHE_UPLOAD_DURATION') { 3*3600 }.to_i
ATTACHE_SECRET_KEY =

unset to test password-less interaction

ENV['ATTACHE_SECRET_KEY']

Instance Method Summary collapse

Instance Method Details

#attache_auth_optionsObject



52
53
54
55
56
57
58
59
60
61
# File 'lib/attache/api/v1.rb', line 52

def attache_auth_options
  if ATTACHE_SECRET_KEY
    uuid = SecureRandom.uuid
    expiration = (Time.now + ATTACHE_UPLOAD_DURATION).to_i
    hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), ATTACHE_SECRET_KEY, "#{uuid}#{expiration}")
    { uuid: uuid, expiration: expiration, hmac: hmac }
  else
    {}
  end
end

#attache_backup(*paths) ⇒ Object



45
46
47
48
49
50
# File 'lib/attache/api/v1.rb', line 45

def attache_backup(*paths)
  HTTPClient.post_content(
    URI.parse(ATTACHE_BACKUP_URL),
    attache_auth_options.merge(paths: paths.join("\n"))
  )
end

#attache_delete(*paths) ⇒ Object



38
39
40
41
42
43
# File 'lib/attache/api/v1.rb', line 38

def attache_delete(*paths)
  HTTPClient.post_content(
    URI.parse(ATTACHE_DELETE_URL),
    attache_auth_options.merge(paths: paths.join("\n"))
  )
end

#attache_options(geometry, current_value, auth_options: true, placeholder: nil, data: {}) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/attache/api/v1.rb', line 63

def attache_options(geometry, current_value, auth_options: true, placeholder: nil, data: {})
  {
    data: {
      geometry: geometry,
      value: [*current_value],
      placeholder: [*placeholder],
      uploadurl: ATTACHE_UPLOAD_URL,
      downloadurl: ATTACHE_DOWNLOAD_URL,
    }.merge(data || {}).merge(auth_options == false ? {} : attache_auth_options),
  }
end

#attache_retry_doing(max_retries, retries = 0, exception_class = Exception) ⇒ Object



75
76
77
78
79
80
81
82
83
84
# File 'lib/attache/api/v1.rb', line 75

def attache_retry_doing(max_retries, retries = 0, exception_class = Exception)
  yield
rescue exception_class
  if (retries += 1) <= max_retries
    max_sleep_seconds = Float(2 ** retries)
    sleep rand(0..max_sleep_seconds)
    retry
  end
  raise
end

#attache_signature_for(hash) ⇒ Object



86
87
88
89
90
91
92
93
94
# File 'lib/attache/api/v1.rb', line 86

def attache_signature_for(hash)
  if ATTACHE_SECRET_KEY.to_s.strip != ""
    hash_without_signature = hash.reject {|k,v| k == 'signature' || k == 'multiple'}
    content = hash_without_signature.sort.collect {|k,v| "#{k}=#{v}" }.join('&')
    generated_signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), ATTACHE_SECRET_KEY, content)
    yield generated_signature if block_given?
    generated_signature
  end
end

#attache_upload(readable) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/attache/api/v1.rb', line 20

def attache_upload(readable)
  uri = URI.parse(ATTACHE_UPLOAD_URL)
  original_filename =
    readable.respond_to?(:original_filename) && readable.original_filename ||
    readable.respond_to?(:path) && File.basename(readable.path) ||
    'noname'
  uri.query = { file: original_filename, **attache_auth_options }.collect {|k,v|
    CGI.escape(k.to_s) + "=" + CGI.escape(v.to_s)
  }.join('&')
  res = attache_retry_doing(3) { HTTPClient.post(uri, readable, {'Content-Type' => 'binary/octet-stream'}) }
  res.body
end

#attache_url_for(path, geometry) ⇒ Object



33
34
35
36
# File 'lib/attache/api/v1.rb', line 33

def attache_url_for(path, geometry)
  prefix, basename = File.split(path)
  [ATTACHE_DOWNLOAD_URL, prefix, CGI.escape(geometry), CGI.escape(basename)].join('/')
end