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(<<-EOSQL, name, pubk.to_s) INSERT INTO groups (name, pubk) VALUES (?, ?) EOSQL @db.last_insert_row_id end |
#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(<<-EOSQL) SELECT id, name, pubk FROM groups ORDER BY name EOSQL @cache[:groups] = rows.to_h do |r| a = [] a << r['id'] a << Model::Group.new( id: r['id'], name: r['name'], pubk: Crypto::PublicKey.new(r['pubk']) ) a end end |
#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(<<-EOSQL, secret_id) SELECT group_id FROM secret_values WHERE secret_id = ? EOSQL rows.map { |r| r['group_id'] } end |
#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(<<-EOSQL, user_id, group_id, encrypted_privk.to_s) INSERT INTO group_members (user_id, group_id, encrypted_privk) VALUES (?, ?, ?) EOSQL end |
#secret_create(author_id, encrypted_data) ⇒ Object
in:
- user ID
- hash of:
- group ID
- array of:
- ciphertext
- encrypted metadata
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 #{}") @db.execute(<<-EOSQL, , ) INSERT INTO secrets (value_author_id, meta_author_id) VALUES (?, ?) EOSQL secret_id = @db.last_insert_row_id encrypted_data.each do |group_id, (ciphertext, )| secret_value_create(secret_id, group_id, ciphertext, ) end secret_id end |
#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(<<-EOSQL, secret_id) DELETE FROM secrets WHERE id = ? EOSQL end |
#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(<<-EOSQL, user_id, secret_id) SELECT s.id, s.value_author_id, s.meta_author_id, sv.group_id, sv.ciphertext, sv.encrypted_metadata FROM secrets s, secret_values sv, group_members gm WHERE gm.user_id = ? AND gm.group_id = sv.group_id AND sv.secret_id = ? AND s.id = sv.secret_id EOSQL return nil if rows.empty? secret_from_row(rows.first) end |
#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(<<-EOSQL, user_id, secret_id) UPDATE secrets SET meta_author_id = ? WHERE id = ? EOSQL .each do |group_id, | @db.execute(<<-EOSQL, .to_s, secret_id, group_id) UPDATE secret_values SET encrypted_metadata = ? WHERE secret_id = ? AND group_id = ? EOSQL end end |
#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(<<-EOSQL, user_id, secret_id) UPDATE secrets SET value_author_id = ? WHERE id = ? EOSQL group_ciphertexts.each do |group_id, ciphertext| @db.execute(<<-EOSQL, ciphertext.to_s, secret_id, group_id) UPDATE secret_values SET ciphertext = ? WHERE secret_id = ? AND group_id = ? EOSQL end end |
#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
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(<<-EOSQL, user_id) SELECT s.id, s.value_author_id, s.meta_author_id, sv.group_id, sv.ciphertext, sv.encrypted_metadata FROM secrets s, secret_values sv, group_members gm WHERE gm.user_id = ? AND gm.group_id = sv.group_id AND sv.secret_id = s.id GROUP BY s.id ORDER BY s.id, sv.group_id EOSQL rows.map { |r| secret_from_row(r) } end |
#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(<<-EOSQL, user_id) SELECT u.id, u.login, u.name, u.status, c.kdf_params, c.pubk, c.encrypted_privk, FROM users u LEFT JOIN users_crypto_data c ON (c.user_id = u.id) WHERE u.id = ? EOSQL user_from_resultset(rows, include_crypto_data: true) end |
#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(<<-EOSQL, login) SELECT u.id, u.login, u.name, u.status, c.kdf_params, c.pubk, c.encrypted_privk FROM users u LEFT JOIN users_crypto_data c ON (c.user_id = u.id) WHERE u.login = ? EOSQL user_from_resultset(rows, include_crypto_data: true) end |
#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(<<-EOSQL, user.login, user.name, 'new') INSERT INTO users (login, name, status) VALUES (?, ?, ?) EOSQL user.id = @db.last_insert_row_id Log.debug("store: stored new user #{user.login}") params = [user.kdf_params, user.pubk, user.encrypted_privk].map(&:to_s) return user if params.any?(&:nil?) @db.execute(<<-EOSQL, user.id, *params) INSERT INTO users_crypto_data (user_id, kdf_params, pubk, encrypted_privk) VALUES (?, ?, ?, ?) EOSQL Log.debug("store: stored user crypto data for #{user.login}") user end |
#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(<<-EOSQL, user.name, user.status, user.id) UPDATE users SET name = ?, status = ? WHERE id = ? EOSQL params = [user.kdf_params, user.pubk, user.encrypted_privk, user.id] @db.execute(<<-EOSQL, *params) UPDATE users_crypto_data SET kdf_params = ?, pubk = ? encrypted_params = ? WHERE user_id = ? EOSQL end |
#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(<<-EOSQL) SELECT u.id, u.login, u.name, u.status, c.pubk FROM users u LEFT JOIN users_crypto_data c ON (c.user_id = u.id) ORDER BY u.login EOSQL @cache[:users] = users_from_resultset(rows) end |