Class: KStor::Store
- Inherits:
-
Object
- Object
- KStor::Store
- Defined in:
- lib/kstor/store.rb
Overview
Store and fetch objects in an SQLite database. rubocop:disable Metrics/MethodLength
Instance Method Summary collapse
- #group_create(name, pubk) ⇒ Object
- #groups ⇒ Object
- #groups_for_secret(secret_id) ⇒ Object
-
#initialize(file_path) ⇒ Store
constructor
A new instance of Store.
- #keychain_item_create(user_id, group_id, encrypted_privk) ⇒ Object
-
#secret_create(author_id, encrypted_data) ⇒ Object
in: - user ID - hash of: - group ID - array of: - ciphertext - encrypted metadata out: secret ID.
- #secret_delete(secret_id) ⇒ Object
-
#secret_fetch(secret_id, user_id) ⇒ Object
in: secret ID, user ID out: encrypted value.
-
#secret_setmeta(secret_id, user_id, group_encrypted_metadata) ⇒ Object
in: secret ID, author ID, array of [group ID, encrypted_metadata] out: nil.
- #secret_setvalue(secret_id, user_id, group_ciphertexts) ⇒ Object
-
#secrets_for_user(user_id) ⇒ Object
in: user ID out: array of: - secret ID - group ID common between user and secret - secret encrypted metadata - secret value and metadata author IDs.
- #transaction ⇒ Object
-
#user_by_id(user_id) ⇒ Object
in: user ID out: - ID - name - status - public key - key derivation function parameters - encrypted private key.
-
#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.
- #user_create(user) ⇒ Object
- #user_update(user) ⇒ Object
- #users ⇒ Object
- #users? ⇒ Boolean
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) |
#groups ⇒ Object
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(, 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", , ) |
#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_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 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) |
#transaction ⇒ Object
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 user_by_login(login) 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", login) |
#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.login, 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) |
#users ⇒ Object
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
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 |