s3.rb 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'aws-sdk-s3'
  3. module Store::Provider::S3
  4. class Store::Provider::S3::Error < StandardError; end
  5. class << self
  6. def add(data, sha)
  7. if data.bytesize > Store::Provider::S3::Config.max_chunk_size
  8. return upload(data, sha)
  9. end
  10. request(:put_object, key: sha, body: data)
  11. true
  12. end
  13. def client
  14. Certificate::ApplySSLCertificates.ensure_fresh_ssl_context
  15. @client.presence ||
  16. (Store::Provider::S3::Config.apply && @client = Aws::S3::Client.new)
  17. end
  18. def delete(sha)
  19. request(:delete_object, key: sha)
  20. true
  21. end
  22. def get(sha)
  23. object = request(:get_object, key: sha)
  24. object.body.binmode.read
  25. end
  26. def upload(data, sha)
  27. begin
  28. id = Store::Provider::S3::Upload.create(sha)
  29. parts = Store::Provider::S3::Upload.process(data, sha, id)
  30. Store::Provider::S3::Upload.complete(sha, parts, id)
  31. rescue => e
  32. log_and_raise(e)
  33. end
  34. true
  35. end
  36. def url(sha, expires_in: 3600)
  37. object = Aws::S3::Object.new(bucket_name: bucket, key: sha, client: client)
  38. object.presigned_url(:get, expires_in: expires_in)
  39. rescue => e
  40. log_and_raise(e)
  41. end
  42. def ping?
  43. return false if !client
  44. client.head_bucket(bucket: bucket)
  45. true
  46. rescue => e
  47. Rails.logger.error { "#{name}: #{e.message}" }
  48. false
  49. end
  50. def ping!
  51. raise Store::Provider::S3::Error, __('Simple Storage Service not reachable.') if !ping?
  52. end
  53. def reset
  54. @client = nil
  55. Store::Provider::S3::Config.reset
  56. true
  57. end
  58. private
  59. def bucket
  60. Store::Provider::S3::Config.bucket
  61. end
  62. def log_and_raise(error)
  63. Rails.logger.error { "#{name}: #{error.message}" }
  64. raise Store::Provider::S3::Error, __('Simple Storage Service malfunction. Please contact your Zammad administrator.')
  65. end
  66. def request(method, **)
  67. client.send(method, bucket: bucket, **)
  68. rescue => e
  69. log_and_raise(e)
  70. end
  71. end
  72. end