Class: Apertur::Resources::Upload

Inherits:
Object
  • Object
show all
Defined in:
lib/apertur/resources/upload.rb

Overview

Upload images to a session.

Supports both plaintext multipart uploads and client-side encrypted uploads using AES-256-GCM with RSA-OAEP key wrapping.

Instance Method Summary collapse

Constructor Details

#initialize(http) ⇒ Upload

Returns a new instance of Upload.

Parameters:



11
12
13
# File 'lib/apertur/resources/upload.rb', line 11

def initialize(http)
  @http = http
end

Instance Method Details

#image(uuid, file, filename: "image.jpg", mime_type: "image/jpeg", source: nil, password: nil) ⇒ Hash

Upload an image to a session via multipart/form-data.

Parameters:

  • uuid (String)

    the session UUID

  • file (String, IO)

    a file path (String), an IO-like object responding to read, or raw image bytes (binary String)

  • filename (String) (defaults to: "image.jpg")

    the filename to send (default: “image.jpg”)

  • mime_type (String) (defaults to: "image/jpeg")

    the MIME type of the image (default: “image/jpeg”)

  • source (String, nil) (defaults to: nil)

    an optional source identifier

  • password (String, nil) (defaults to: nil)

    session password if the session is protected

Returns:

  • (Hash)

    upload result



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/apertur/resources/upload.rb', line 25

def image(uuid, file, filename: "image.jpg", mime_type: "image/jpeg", source: nil, password: nil)
  file_data = read_file(file)

  fields = {}
  fields["source"] = source if source

  headers = {}
  headers["x-session-password"] = password if password

  @http.request_multipart(
    "/api/v1/upload/#{uuid}/images",
    file_data,
    filename: filename,
    mime_type: mime_type,
    fields: fields,
    headers: headers
  )
end

#image_encrypted(uuid, file, public_key, filename: "image.jpg", mime_type: "image/jpeg", source: nil, password: nil) ⇒ Hash

Upload an encrypted image to a session.

The image is encrypted client-side using AES-256-GCM, with the AES key wrapped by the server’s RSA public key. The encrypted payload is sent as JSON with the X-Aptr-Encrypted: default header.

Parameters:

  • uuid (String)

    the session UUID

  • file (String, IO)

    a file path, IO, or raw bytes

  • public_key (String)

    the RSA public key in PEM format

  • filename (String) (defaults to: "image.jpg")

    the filename (default: “image.jpg”)

  • mime_type (String) (defaults to: "image/jpeg")

    the MIME type (default: “image/jpeg”)

  • source (String, nil) (defaults to: nil)

    optional source identifier

  • password (String, nil) (defaults to: nil)

    session password if the session is protected

Returns:

  • (Hash)

    upload result



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/apertur/resources/upload.rb', line 58

def image_encrypted(uuid, file, public_key, filename: "image.jpg", mime_type: "image/jpeg", source: nil, password: nil)
  file_data = read_file(file)
  encrypted = Apertur::Crypto.encrypt_image(file_data, public_key)

  # The server's "default" encryption mode expects a multipart file
  # upload whose body is the JSON-serialized EncryptedPayload (camelCase
  # keys), which it then decrypts with its private key. Sending a JSON
  # request body instead yields a 500 ("No file uploaded").
  payload_json = JSON.generate(
    "encryptedKey" => encrypted["encrypted_key"],
    "iv" => encrypted["iv"],
    "encryptedData" => encrypted["encrypted_data"],
    "algorithm" => encrypted["algorithm"]
  )

  fields = {}
  fields["source"] = source if source

  headers = { "X-Aptr-Encrypted" => "default" }
  headers["x-session-password"] = password if password

  @http.request_multipart(
    "/api/v1/upload/#{uuid}/images",
    payload_json,
    filename: "#{filename}.enc",
    mime_type: "application/octet-stream",
    fields: fields,
    headers: headers
  )
end