e3db 2.0.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,6 +41,7 @@ module E3DB
41
41
  attribute :client_id, Types::String
42
42
  attribute :api_key_id, Types::String
43
43
  attribute :api_secret, Types::String
44
+ attribute :client_email, Types::String
44
45
  attribute :public_key, Types::String
45
46
  attribute :private_key, Types::String
46
47
  attribute :api_url, Types::String.default(DEFAULT_API_URL)
@@ -57,6 +58,7 @@ module E3DB
57
58
  # "client_id": "UUID",
58
59
  # "api_key_id": "API_KEY",
59
60
  # "api_secret": "API_SECRET",
61
+ # "client_email": "CLIENT_EMAIL",
60
62
  # "public_key": "PUBLIC_KEY",
61
63
  # "private_key": "PRIVATE_KEY",
62
64
  # "api_url": "URL",
@@ -5,142 +5,66 @@
5
5
  # All Rights Reserved.
6
6
  #
7
7
 
8
-
9
8
  module E3DB
10
- class Client
9
+ module Crypto
11
10
  private
12
- def decrypt_record(record)
13
- writer_id = record.meta.writer_id
14
- user_id = record.meta.user_id
15
- type = record.meta.type
16
- ak = get_access_key(writer_id, user_id, @config.client_id, type)
17
- decrypt_record_with_key(record, ak)
18
- end
19
-
20
- def decrypt_record_with_key(encrypted_record, ak)
21
- record = Record.new(meta: encrypted_record.meta.clone, data: Hash.new)
22
-
23
- encrypted_record.data.each do |k, v|
24
- fields = v.split('.', 4)
25
-
26
- edk = Crypto.base64decode(fields[0])
27
- edkN = Crypto.base64decode(fields[1])
28
- ef = Crypto.base64decode(fields[2])
29
- efN = Crypto.base64decode(fields[3])
30
-
31
- dk = RbNaCl::SecretBox.new(ak).decrypt(edkN, edk)
32
- pv = RbNaCl::SecretBox.new(dk).decrypt(efN, ef)
33
-
34
- record.data[k] = pv
35
- end
36
-
37
- record
38
- end
39
-
40
- def encrypt_record(plaintext_record)
41
- record = Record.new(meta: plaintext_record.meta.clone, data: Hash.new)
42
-
43
- writer_id = record.meta.writer_id
44
- user_id = record.meta.user_id
45
- type = record.meta.type
46
-
47
- begin
48
- ak = get_access_key(writer_id, user_id, @config.client_id, type)
49
- rescue Faraday::ResourceNotFound
50
- ak = RbNaCl::Random.random_bytes(RbNaCl::SecretBox.key_bytes)
51
- put_access_key(writer_id, user_id, @config.client_id, type, ak)
52
- end
53
-
54
- plaintext_record.data.each do |k, v|
55
- dk = Crypto.secret_box_random_key
56
- efN = Crypto.secret_box_random_nonce
57
- ef = RbNaCl::SecretBox.new(dk).encrypt(efN, v)
58
- edkN = Crypto.secret_box_random_nonce
59
- edk = RbNaCl::SecretBox.new(ak).encrypt(edkN, dk)
60
-
61
- record.data[k] = sprintf('%s.%s.%s.%s',
62
- Crypto.base64encode(edk), Crypto.base64encode(edkN),
63
- Crypto.base64encode(ef), Crypto.base64encode(efN))
64
- end
65
-
66
- record
67
- end
68
-
69
- def decrypt_eak(json)
70
- k = json[:authorizer_public_key][:curve25519]
71
- authorizer_pubkey = Crypto.decode_public_key(k)
72
-
73
- fields = json[:eak].split('.', 2)
74
- ciphertext = Crypto.base64decode(fields[0])
75
- nonce = Crypto.base64decode(fields[1])
76
- box = RbNaCl::Box.new(authorizer_pubkey, @private_key)
77
-
78
- box.decrypt(nonce, ciphertext)
79
- end
80
-
81
- def get_access_key(writer_id, user_id, reader_id, type)
82
- ak_cache_key = [writer_id, user_id, type]
83
- if @ak_cache.key? ak_cache_key
84
- return @ak_cache[ak_cache_key]
85
- end
86
11
 
87
- url = get_url('v1', 'storage', 'access_keys', writer_id, user_id, reader_id, type)
88
- resp = @conn.get(url)
89
- json = JSON.parse(resp.body, symbolize_names: true)
90
-
91
- ak = decrypt_eak(json)
92
- @ak_cache[ak_cache_key] = ak
93
- ak
94
- end
95
-
96
- def put_access_key(writer_id, user_id, reader_id, type, ak)
97
- ak_cache_key = [writer_id, user_id, type]
98
- @ak_cache[ak_cache_key] = ak
99
-
100
- reader_key = client_key(reader_id)
101
- nonce = RbNaCl::Random.random_bytes(RbNaCl::Box.nonce_bytes)
102
- eak = RbNaCl::Box.new(reader_key, @private_key).encrypt(nonce, ak)
103
-
104
- encoded_eak = sprintf('%s.%s', Crypto.base64encode(eak), Crypto.base64encode(nonce))
105
-
106
- url = get_url('v1', 'storage', 'access_keys', writer_id, user_id, reader_id, type)
107
- @conn.put(url, { :eak => encoded_eak })
12
+ # Create a new, random access key. Returns a
13
+ # string of bytes representing the key.
14
+ def new_access_key
15
+ RbNaCl::Random.random_bytes(RbNaCl::SecretBox.key_bytes)
108
16
  end
109
17
 
110
- end
18
+ alias :new_data_key :new_access_key
111
19
 
112
- class Crypto
113
- def self.decode_public_key(s)
20
+ def decode_public_key(s)
114
21
  RbNaCl::PublicKey.new(base64decode(s))
115
22
  end
116
23
 
117
- def self.encode_public_key(k)
24
+ def encode_public_key(k)
118
25
  base64encode(k.to_bytes)
119
26
  end
120
27
 
121
- def self.decode_private_key(s)
28
+ def decode_private_key(s)
122
29
  RbNaCl::PrivateKey.new(base64decode(s))
123
30
  end
124
31
 
125
- def self.encode_private_key(k)
32
+ def encode_private_key(k)
126
33
  base64encode(k.to_bytes)
127
34
  end
128
35
 
129
- def self.secret_box_random_key
130
- RbNaCl::Random.random_bytes(RbNaCl::SecretBox.key_bytes)
36
+ def box_random_nonce
37
+ RbNaCl::Random.random_bytes(RbNaCl::Box.nonce_bytes)
131
38
  end
132
39
 
133
- def self.secret_box_random_nonce
40
+ def secret_box_random_nonce
134
41
  RbNaCl::Random.random_bytes(RbNaCl::SecretBox.nonce_bytes)
135
42
  end
136
43
 
137
- def self.base64encode(x)
44
+ def base64encode(x)
138
45
  Base64.urlsafe_encode64(x, padding: false)
139
46
  end
140
47
 
141
- def self.base64decode(x)
48
+ def base64decode(x)
142
49
  Base64.urlsafe_decode64(x)
143
50
  end
51
+
52
+ def decrypt_box(encrypted, pub, priv)
53
+ pub = decode_public_key(pub) unless pub.is_a? RbNaCl::PublicKey
54
+ priv = decode_private_key(priv) unless priv.is_a? RbNaCl::PrivateKey
55
+
56
+ ciphertext, nonce = encrypted.split('.', 2).map { |f| base64decode(f) }
57
+ RbNaCl::Box.new(pub, priv).decrypt(nonce, ciphertext)
58
+ end
59
+
60
+ def encrypt_box(plain, pub, priv)
61
+ pub = decode_public_key(pub) unless pub.is_a? RbNaCl::PublicKey
62
+ priv = decode_private_key(priv) unless priv.is_a? RbNaCl::PrivateKey
63
+
64
+ nonce = box_random_nonce
65
+ encrypted = RbNaCl::Box.new(pub, priv).encrypt(nonce, plain)
66
+ [encrypted, nonce].map { |f| base64encode(f) }.join(".")
67
+ end
144
68
  end
145
69
 
146
70
  private_constant :Crypto
@@ -1,3 +1,3 @@
1
1
  module E3DB
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.1"
3
3
  end
@@ -21,4 +21,22 @@ cat > "$HOME/.tozny/integration-test/e3db.json" <<EOT
21
21
  "public_key":"${PUBLIC_KEY}",
22
22
  "private_key":"${PRIVATE_KEY}"
23
23
  }
24
+ EOT
25
+
26
+ # Check if the config is already set
27
+ if [ ! -d "$HOME/.tozny/integration-test-share" ]; then
28
+ mkdir -p "$HOME/.tozny/integration-test-share"
29
+ fi
30
+
31
+ cat > "$HOME/.tozny/integration-test-share/e3db.json" <<EOT
32
+ {
33
+ "version":1,
34
+ "api_url":"${API_URL_2}",
35
+ "api_key_id":"${API_KEY_ID_2}",
36
+ "api_secret":"${API_SECRET_2}",
37
+ "client_id":"${CLIENT_ID_2}",
38
+ "client_email":"${CLIENT_EMAIL_2}",
39
+ "public_key":"${PUBLIC_KEY_2}",
40
+ "private_key":"${PRIVATE_KEY_2}"
41
+ }
24
42
  EOT
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: e3db
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tozny, LLC
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-07-11 00:00:00.000000000 Z
11
+ date: 2017-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -188,12 +188,13 @@ files:
188
188
  - ".travis.yml"
189
189
  - ".yardopts"
190
190
  - Gemfile
191
- - LICENSE.txt
191
+ - LICENSE.md
192
192
  - README.md
193
193
  - Rakefile
194
194
  - bin/console
195
195
  - bin/setup
196
196
  - e3db.gemspec
197
+ - examples/registration.rb
197
198
  - examples/simple.rb
198
199
  - lib/e3db.rb
199
200
  - lib/e3db/client.rb
@@ -223,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
224
  version: '0'
224
225
  requirements: []
225
226
  rubyforge_project:
226
- rubygems_version: 2.6.8
227
+ rubygems_version: 2.6.13
227
228
  signing_key:
228
229
  specification_version: 4
229
230
  summary: e3db client SDK
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (C) 2017, Tozny, LLC.
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.