Class: KStor::Store

Inherits:
Object
  • Object
show all
Defined in:
lib/kstor/store.rb

Overview

Store and fetch objects in an SQLite database. rubocop:disable Metrics/MethodLength

Instance Method Summary collapse

Constructor Details

#initialize(file_path) ⇒ Store

Returns a new instance of Store.



11
12
13
14
15
# File 'lib/kstor/store.rb', line 11

def initialize(file_path)
  @file_path = file_path
  @db = SQLConnection.new(file_path)
  @cache = {}
end

Instance Method Details

#group_create(name, pubk) ⇒ Object



70
71
72
73
74
75
76
# File 'lib/kstor/store.rb', line 70

def group_create(name, pubk)
  @db.execute("    INSERT INTO groups (name, pubk)\n         VALUES (?, ?)\n  EOSQL\n  @db.last_insert_row_id\nend\n", name, pubk.to_s)

#groupsObject



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/kstor/store.rb', line 78

def groups
  return @cache[:groups] if @cache.key?(:groups)

  Log.debug('store: loading groups')
  rows = @db.execute("      SELECT id,\n             name,\n             pubk\n        FROM groups\n    ORDER BY name\n  EOSQL\n  @cache[:groups] = rows.to_h do |r|\n    a = []\n    a << r['id']\n    a << Model::Group.new(\n      id: r['id'], name: r['name'], pubk: Crypto::PublicKey.new(r['pubk'])\n    )\n    a\n  end\nend\n")

#groups_for_secret(secret_id) ⇒ Object



245
246
247
248
249
250
251
252
253
# File 'lib/kstor/store.rb', line 245

def groups_for_secret(secret_id)
  Log.debug("store: loading group IDs for secret #{secret_id}")
  rows = @db.execute("      SELECT group_id\n        FROM secret_values\n       WHERE secret_id = ?\n  EOSQL\n  rows.map { |r| r['group_id'] }\nend\n", secret_id)

#keychain_item_create(user_id, group_id, encrypted_privk) ⇒ Object



63
64
65
66
67
68
# File 'lib/kstor/store.rb', line 63

def keychain_item_create(user_id, group_id, encrypted_privk)
  @db.execute("    INSERT INTO group_members (user_id, group_id, encrypted_privk)\n         VALUES (?, ?, ?)\n  EOSQL\nend\n", user_id, group_id, encrypted_privk.to_s)

#secret_create(author_id, encrypted_data) ⇒ Object

in:

- user ID
- hash of:
  - group ID
  - array of:
    - ciphertext
    - encrypted 

out: secret ID



232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/kstor/store.rb', line 232

def secret_create(author_id, encrypted_data)
  Log.debug("store: creating secret for user #{author_id}")
  @db.execute("    INSERT INTO secrets (value_author_id, meta_author_id) VALUES (?, ?)\n  EOSQL\n  secret_id = @db.last_insert_row_id\n  encrypted_data.each do |group_id, (ciphertext, encrypted_metadata)|\n    secret_value_create(secret_id, group_id, ciphertext, encrypted_metadata)\n  end\n\n  secret_id\nend\n", author_id, author_id)

#secret_delete(secret_id) ⇒ Object



287
288
289
290
291
292
293
# File 'lib/kstor/store.rb', line 287

def secret_delete(secret_id)
  Log.debug("store: delete secret ##{secret_id}")
  # Will cascade to secret_values:
  @db.execute("    DELETE FROM secrets WHERE id = ?\n  EOSQL\nend\n", secret_id)

#secret_fetch(secret_id, user_id) ⇒ Object

in: secret ID, user ID out: encrypted value



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/kstor/store.rb', line 200

def secret_fetch(secret_id, user_id)
  Log.debug(
    "store: loading secret value ##{secret_id} for user ##{user_id}"
  )
  rows = @db.execute("       SELECT s.id,\n              s.value_author_id,\n              s.meta_author_id,\n              sv.group_id,\n              sv.ciphertext,\n              sv.encrypted_metadata\n         FROM secrets s,\n              secret_values sv,\n              group_members gm\n        WHERE gm.user_id = ?\n          AND gm.group_id = sv.group_id\n          AND sv.secret_id = ?\n          AND s.id = sv.secret_id\n  EOSQL\n  return nil if rows.empty?\n\n  secret_from_row(rows.first)\nend\n", user_id, secret_id)

#secret_setmeta(secret_id, user_id, group_encrypted_metadata) ⇒ Object

in: secret ID, author ID, array of [group ID, encrypted_metadata] out: nil



257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/kstor/store.rb', line 257

def secret_setmeta(secret_id, user_id, )
  Log.debug("store: set metadata for secret ##{secret_id}")
  @db.execute("    UPDATE secrets SET meta_author_id = ? WHERE id = ?\n  EOSQL\n  group_encrypted_metadata.each do |group_id, encrypted_metadata|\n    @db.execute(<<-EOSQL, encrypted_metadata.to_s, secret_id, group_id)\n      UPDATE secret_values\n         SET encrypted_metadata = ?\n       WHERE secret_id = ?\n         AND group_id = ?\n    EOSQL\n  end\nend\n", user_id, secret_id)

#secret_setvalue(secret_id, user_id, group_ciphertexts) ⇒ Object



272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/kstor/store.rb', line 272

def secret_setvalue(secret_id, user_id, group_ciphertexts)
  Log.debug("store: set value for secret ##{secret_id}")
  @db.execute("    UPDATE secrets SET value_author_id = ? WHERE id = ?\n  EOSQL\n  group_ciphertexts.each do |group_id, ciphertext|\n    @db.execute(<<-EOSQL, ciphertext.to_s, secret_id, group_id)\n      UPDATE secret_values\n         SET ciphertext = ?\n       WHERE secret_id = ?\n         AND group_id = ?\n    EOSQL\n  end\nend\n", user_id, secret_id)

#secrets_for_user(user_id) ⇒ Object

in: user ID out: array of:

- secret ID
- group ID common between user and secret
- secret encrypted 
- secret value and  author IDs


176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/kstor/store.rb', line 176

def secrets_for_user(user_id)
  Log.debug("store: loading secrets for user ##{user_id}")
  rows = @db.execute("       SELECT s.id,\n              s.value_author_id,\n              s.meta_author_id,\n              sv.group_id,\n              sv.ciphertext,\n              sv.encrypted_metadata\n         FROM secrets s,\n              secret_values sv,\n              group_members gm\n        WHERE gm.user_id = ?\n          AND gm.group_id = sv.group_id\n          AND sv.secret_id = s.id\n     GROUP BY s.id\n     ORDER BY s.id, sv.group_id\n  EOSQL\n\n  rows.map { |r| secret_from_row(r) }\nend\n", user_id)

#transactionObject



17
18
19
# File 'lib/kstor/store.rb', line 17

def transaction(&)
  @db.transaction(&)
end

#user_by_id(user_id) ⇒ Object

in: user ID out:

- ID
- name
- status
- public key
- key derivation function parameters
- encrypted private key


153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/kstor/store.rb', line 153

def user_by_id(user_id)
  Log.debug("store: loading user by ID ##{user_id}")
  rows = @db.execute("       SELECT u.id,\n              u.login,\n              u.name,\n              u.status,\n              c.kdf_params,\n              c.pubk,\n              c.encrypted_privk,\n         FROM users u\n    LEFT JOIN users_crypto_data c ON (c.user_id = u.id)\n        WHERE u.id = ?\n  EOSQL\n  user_from_resultset(rows, include_crypto_data: true)\nend\n", user_id)

#user_by_login(login) ⇒ Object

in: login out:

- ID
- name
- status
- public key
- key derivation function parameters
- encrypted private key
- keychain: hash of:
  - group ID
  - encrypted group private key


128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/kstor/store.rb', line 128

def ()
  Log.debug("store: loading user by login #{login.inspect}")
  rows = @db.execute("       SELECT u.id,\n              u.login,\n              u.name,\n              u.status,\n              c.kdf_params,\n              c.pubk,\n              c.encrypted_privk\n         FROM users u\n    LEFT JOIN users_crypto_data c ON (c.user_id = u.id)\n        WHERE u.login = ?\n  EOSQL\n  user_from_resultset(rows, include_crypto_data: true)\nend\n", )

#user_create(user) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/kstor/store.rb', line 29

def user_create(user)
  @db.execute("    INSERT INTO users (login, name, status)\n         VALUES (?, ?, ?)\n  EOSQL\n  user.id = @db.last_insert_row_id\n  Log.debug(\"store: stored new user \#{user.login}\")\n  params = [user.kdf_params, user.pubk, user.encrypted_privk].map(&:to_s)\n  return user if params.any?(&:nil?)\n\n  @db.execute(<<-EOSQL, user.id, *params)\n    INSERT INTO users_crypto_data (user_id, kdf_params, pubk, encrypted_privk)\n         VALUES (?, ?, ?, ?)\n  EOSQL\n  Log.debug(\"store: stored user crypto data for \#{user.login}\")\n\n  user\nend\n", user., user.name, 'new')

#user_update(user) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/kstor/store.rb', line 48

def user_update(user)
  @db.execute("    UPDATE users SET name = ?, status = ?\n     WHERE id = ?\n  EOSQL\n  params = [user.kdf_params, user.pubk, user.encrypted_privk, user.id]\n  @db.execute(<<-EOSQL, *params)\n    UPDATE users_crypto_data SET\n           kdf_params = ?,\n           pubk = ?\n           encrypted_params = ?\n     WHERE user_id = ?\n  EOSQL\nend\n", user.name, user.status, user.id)

#usersObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/kstor/store.rb', line 99

def users
  return @cache[:users] if @cache.key?(:users)

  Log.debug('store: loading users')
  rows = @db.execute("       SELECT u.id,\n              u.login,\n              u.name,\n              u.status,\n              c.pubk\n         FROM users u\n    LEFT JOIN users_crypto_data c ON (c.user_id = u.id)\n     ORDER BY u.login\n  EOSQL\n\n  @cache[:users] = users_from_resultset(rows)\nend\n")

#users?Boolean

Returns:

  • (Boolean)


21
22
23
24
25
26
27
# File 'lib/kstor/store.rb', line 21

def users?
  rows = @db.execute('SELECT count(*) AS n FROM users')
  count = Integer(rows.first['n'])
  Log.debug("store: count of users is #{count}")

  count.positive?
end