aion-s3 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/aion-s3.rb +1 -0
- data/lib/aion_s3.rb +8 -0
- data/lib/aion_s3/packer.rb +120 -0
- data/lib/aion_s3/uploader.rb +64 -0
- data/lib/aion_s3/version.rb +3 -0
- metadata +103 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0e2a5f113d1729577f5f289cd6d96acd4d530833fd6deffd840f0c54eae00ce7
|
4
|
+
data.tar.gz: 29fbc5075544c42f8269533ec46fcac2e38358bd3e524e11813d1ea59a96f5b1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 00cd42ac47c8339fcc2f4d1b640c42f055dc19ee95f30191cda8333843cc62797f82662600cbe2e65021e54b4cc201b6f69350e04b4ed709da97a0518843158a
|
7
|
+
data.tar.gz: dab3192475cc6c6e8cff389953b613ee0e2c2b03c06e7d1bd7f429cd6887325e99988e9d93a99f6f110a421672a7408e32c556b9281370662890a8fc22c01a3b
|
data/lib/aion-s3.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'aion_s3'
|
data/lib/aion_s3.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'zlib'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
module AionS3
|
6
|
+
|
7
|
+
# A <code>Packer</code> is a utility for packing and unpacking data.
|
8
|
+
# Packing applies compression and encryption to provided data.
|
9
|
+
# Unpacking applies decryption and decompression to provided data.
|
10
|
+
#
|
11
|
+
# Encryption uses cipher +AES-256-CBC+. The key is generated via a password provided when the <code>Packer</code> is initialized.
|
12
|
+
# The password must be a string at least 20 chars long.
|
13
|
+
#
|
14
|
+
# It is *very* important that the password is randomly generated.
|
15
|
+
class Packer
|
16
|
+
|
17
|
+
# @return [String]
|
18
|
+
attr_reader :password
|
19
|
+
|
20
|
+
# Returns a new Packer object with a key based on the given +password+.
|
21
|
+
# If no password is provided, a random password will be generated
|
22
|
+
# The password can later be read via #password.
|
23
|
+
#
|
24
|
+
# @param [String] password
|
25
|
+
def initialize(password = nil)
|
26
|
+
password ||= Packer.random_password
|
27
|
+
if password and password.size < 32
|
28
|
+
raise ArgumentError, 'Provided password must be at least 32 characters'
|
29
|
+
end
|
30
|
+
@key = OpenSSL::Digest.digest('sha256', password)
|
31
|
+
@password = password.freeze
|
32
|
+
end
|
33
|
+
|
34
|
+
# Encrypts data with +AES-256-CBC+ and returns it as a binary encoded string.
|
35
|
+
#
|
36
|
+
# @param [String] data
|
37
|
+
# @return [String] a binary encoded string
|
38
|
+
def encrypt(data)
|
39
|
+
_data = data
|
40
|
+
cipher = OpenSSL::Cipher::AES.new(256, :cbc).encrypt
|
41
|
+
cipher.key = @key
|
42
|
+
cipher.random_iv + cipher.update(_data) + cipher.final
|
43
|
+
end
|
44
|
+
|
45
|
+
# Decrypts data that have been encrypted using #encrypt(data) and returns it as a binary encoded string.
|
46
|
+
#
|
47
|
+
# @param [String] data
|
48
|
+
# @return [String] a binary encoded string
|
49
|
+
def decrypt(data)
|
50
|
+
_data = data
|
51
|
+
decipher = OpenSSL::Cipher::AES.new(256, :cbc).decrypt
|
52
|
+
decipher.key = @key
|
53
|
+
decipher.iv = _data.byteslice(0,16)
|
54
|
+
decipher.update(_data.byteslice(16, _data.bytesize - 16)) + decipher.final
|
55
|
+
end
|
56
|
+
|
57
|
+
# Decompresses data with zlib and returns it a binary encoded string.
|
58
|
+
#
|
59
|
+
# @param [String] data
|
60
|
+
# @return [String] a binary encoded string
|
61
|
+
def deflate(data)
|
62
|
+
Zlib::Deflate.deflate(data, Zlib::BEST_COMPRESSION)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Compresses data with zlib and returns it a binary encoded string.
|
66
|
+
#
|
67
|
+
# @param [String] data
|
68
|
+
# @return [String] a binary encoded string
|
69
|
+
def inflate(data)
|
70
|
+
Zlib::Inflate.inflate(data)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Compresses and encrypts given data.
|
74
|
+
#
|
75
|
+
# *Note*
|
76
|
+
# The ruby string's local encoding will be lost when packed.
|
77
|
+
# unpack(data) will always return a string with binary encoding.
|
78
|
+
#
|
79
|
+
# Example:
|
80
|
+
#
|
81
|
+
# data = 'æøå' # utf8 encoded string
|
82
|
+
# str = unpack(pack(data))
|
83
|
+
#
|
84
|
+
# puts str.bytes == data.bytes
|
85
|
+
# puts str == data
|
86
|
+
# puts str.encoding == data.encoding
|
87
|
+
#
|
88
|
+
# Produces:
|
89
|
+
#
|
90
|
+
# true
|
91
|
+
# false
|
92
|
+
# false
|
93
|
+
#
|
94
|
+
# @param [String] data
|
95
|
+
# @return [String] a binary encoded string
|
96
|
+
def pack(data)
|
97
|
+
encrypt(deflate(data))
|
98
|
+
end
|
99
|
+
|
100
|
+
# Decrypts and decompresses given data.
|
101
|
+
#
|
102
|
+
# @param [Object] data
|
103
|
+
# @return [String] a binary encoded string
|
104
|
+
def unpack(data)
|
105
|
+
inflate(decrypt(data))
|
106
|
+
end
|
107
|
+
|
108
|
+
# Returns a base64 encoded string based on random bytes.
|
109
|
+
# The length will be <code>n * 2</code> characters.
|
110
|
+
#
|
111
|
+
# If +n+ is not defined, it will default to 24, which will generate a 32 character base64 encoded string.
|
112
|
+
#
|
113
|
+
# @param [Integer] n
|
114
|
+
# @return [String] a base64 encoded string
|
115
|
+
def self.random_password(n = 24)
|
116
|
+
SecureRandom.base64(n)
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'aws-sdk-s3'
|
2
|
+
|
3
|
+
module AionS3
|
4
|
+
|
5
|
+
# An <code>Uploader</code> is a utility for uploading data to s3.
|
6
|
+
# The Uploader supports compliance locking, where files are locked for update/deletion for a configured amount of time.
|
7
|
+
#
|
8
|
+
# The utility is a wrapper around <code>Aws::S3::Client</code>.
|
9
|
+
class Uploader
|
10
|
+
|
11
|
+
# @return [Aws::S3::Client]
|
12
|
+
attr_reader :client
|
13
|
+
|
14
|
+
# @param [String] bucket
|
15
|
+
# @param [Integer] lock_days
|
16
|
+
# @param [Hash] s3_options
|
17
|
+
def initialize(bucket, lock_days: 0, s3_options: {})
|
18
|
+
@client = Aws::S3::Client.new(s3_options)
|
19
|
+
@bucket = bucket
|
20
|
+
@lock_seconds = lock_days.to_i * 24 * 60 * 60
|
21
|
+
end
|
22
|
+
|
23
|
+
# Gets metadata from an object in s3.
|
24
|
+
#
|
25
|
+
# If a target is provided, the object data will be downloaded as well.
|
26
|
+
# +target+ must be a string with file path or an <code>IO</code> object.
|
27
|
+
#
|
28
|
+
# @param [String] key
|
29
|
+
# @param [String, IO] target
|
30
|
+
# @return [Aws::S3::Types::GetObjectOutput]
|
31
|
+
def get(key, target = nil)
|
32
|
+
@client.get_object(
|
33
|
+
bucket: @bucket,
|
34
|
+
key: key,
|
35
|
+
response_target: target
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Puts an object to s3.
|
40
|
+
#
|
41
|
+
# If <code>Uploader</code> was configured with lock_days > 0 a compliance lock will be put on the object.
|
42
|
+
#
|
43
|
+
# @param [String] key an urlsafe string
|
44
|
+
# @param [String, IO] body
|
45
|
+
# @return [Aws::S3::Types::PutObjectOutput]
|
46
|
+
def put(key, body)
|
47
|
+
options = {
|
48
|
+
bucket: @bucket,
|
49
|
+
key: key,
|
50
|
+
body: body,
|
51
|
+
}
|
52
|
+
|
53
|
+
if @lock_seconds > 0
|
54
|
+
options.reverse_merge!(
|
55
|
+
object_lock_mode: 'COMPLIANCE',
|
56
|
+
object_lock_retain_until_date: Time.now + @lock_seconds
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
@client.put_object(options)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aion-s3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Andersen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-11-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk-s3
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.17.3
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.17.3
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 12.3.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 12.3.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 5.11.3
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 5.11.3
|
69
|
+
description: A tool for compressing, encrypting and uploading files to AWS S3
|
70
|
+
email: michael@aion.dk
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- lib/aion-s3.rb
|
76
|
+
- lib/aion_s3.rb
|
77
|
+
- lib/aion_s3/packer.rb
|
78
|
+
- lib/aion_s3/uploader.rb
|
79
|
+
- lib/aion_s3/version.rb
|
80
|
+
homepage: https://github.com/aion-dk/aion-s3
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubygems_version: 3.0.3
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
102
|
+
summary: Aion S3
|
103
|
+
test_files: []
|