fix pending messages with symmetric keys

This commit is contained in:
Roman Volosovskyi 2017-10-26 17:51:48 +02:00
parent bdf962a140
commit 88d368e970
6 changed files with 119 additions and 37 deletions

View File

@ -25,13 +25,13 @@
(defn save
[{:keys [id to group-id message] :as pending-message}]
(let [{:keys [sig symKeyID pubKey topic payload]} message
(let [{:keys [sig sym-key-password pubKey topic payload]} message
id' (get-id id to)
chat-id (or group-id to)
message' (-> pending-message
(assoc :id id'
:sig sig
:sym-key-id symKeyID
:sym-key-password sym-key-password
:pub-key pubKey
:message-id id
:chat-id chat-id

View File

@ -14,7 +14,8 @@
[status-im.data-store.realm.schemas.account.v13.core :as v13]
[status-im.data-store.realm.schemas.account.v14.core :as v14]
[status-im.data-store.realm.schemas.account.v15.core :as v15]
[status-im.data-store.realm.schemas.account.v16.core :as v16]))
[status-im.data-store.realm.schemas.account.v16.core :as v16]
[status-im.data-store.realm.schemas.account.v17.core :as v17]))
;; TODO(oskarth): Add failing test if directory vXX exists but isn't in schemas.
@ -67,4 +68,6 @@
{:schema v16/schema
:schemaVersion 16
:migration v16/migration}
])
{:schema v17/schema
:schemaVersion 17
:migration v17/migration}])

View File

@ -0,0 +1,41 @@
(ns status-im.data-store.realm.schemas.account.v17.core
(:require [status-im.data-store.realm.schemas.account.v11.chat :as chat]
[status-im.data-store.realm.schemas.account.v1.chat-contact :as chat-contact]
[status-im.data-store.realm.schemas.account.v6.command :as command]
[status-im.data-store.realm.schemas.account.v9.command-parameter :as command-parameter]
[status-im.data-store.realm.schemas.account.v16.contact :as contact]
[status-im.data-store.realm.schemas.account.v1.discover :as discover]
[status-im.data-store.realm.schemas.account.v1.kv-store :as kv-store]
[status-im.data-store.realm.schemas.account.v10.message :as message]
[status-im.data-store.realm.schemas.account.v17.pending-message :as pending-message]
[status-im.data-store.realm.schemas.account.v1.processed-message :as processed-message]
[status-im.data-store.realm.schemas.account.v15.request :as request]
[status-im.data-store.realm.schemas.account.v1.tag :as tag]
[status-im.data-store.realm.schemas.account.v1.user-status :as user-status]
[status-im.data-store.realm.schemas.account.v5.contact-group :as contact-group]
[status-im.data-store.realm.schemas.account.v5.group-contact :as group-contact]
[status-im.data-store.realm.schemas.account.v8.local-storage :as local-storage]
[status-im.data-store.realm.schemas.account.v13.handler-data :as handler-data]
[taoensso.timbre :as log]
[cljs.reader :as reader]))
(def schema [chat/schema
chat-contact/schema
command/schema
command-parameter/schema
contact/schema
discover/schema
kv-store/schema
message/schema
pending-message/schema
processed-message/schema
request/schema
tag/schema
user-status/schema
contact-group/schema
group-contact/schema
local-storage/schema
handler-data/schema])
(defn migration [old-realm new-realm]
(log/debug "migrating v17 account database: " old-realm new-realm))

View File

@ -0,0 +1,26 @@
(ns status-im.data-store.realm.schemas.account.v17.pending-message
(:require [taoensso.timbre :as log]))
(def schema {:name :pending-message
:primaryKey :id
:properties {:id :string
:message-id :string
:chat-id {:type :string
:optional true}
:ack? :bool
:requires-ack? :bool
:sig :string
:pub-key {:type :string
:optional true}
:sym-key-password {:type :string
:optional true}
:to {:type :string
:optional true}
:payload :string
:type :string
:topic :string
:attempts :int
:was-sent? :bool}})
(defn migration [old-realm new-realm]
(log/debug "migrating pending-message schema v12"))

View File

@ -6,7 +6,7 @@
(s/def :message/sig :message/from)
(s/def :message/privateKeyID (s/nilable string?))
(s/def :message/pub-key (s/nilable string?))
(s/def :message/sym-key-id (s/nilable string?))
(s/def :message/sym-key-password (s/nilable string?))
(s/def :message/topic string?)
(s/def :message/to (s/nilable string?))
(s/def :message/message-id string?)

View File

@ -19,30 +19,32 @@
callback]
(let [{:keys [public]} keypair
content (:content payload)
content' (if (and (not to) public content)
(e/encrypt public (prn-str content))
content)
content (:content payload)
content' (if (and (not to) public content)
(e/encrypt public (prn-str content))
content)
payload' (-> message
(select-keys [:message-id :requires-ack? :type :clock-value])
(merge payload)
(assoc :content content')
prn-str
u/from-utf8)]
payload' (-> message
(select-keys [:message-id :requires-ack? :type :clock-value])
(merge payload)
(assoc :content content')
prn-str
u/from-utf8)
sym-key-password (or key-password shh-keys/status-key-password)]
(shh-keys/get-sym-key
web3
(or key-password shh-keys/status-key-password)
(fn [status-key-id]
(callback
(merge
(select-keys message [:ttl])
(let [type (if to :asym :sym)]
(cond-> {:sig from
:topic (first topics)
:payload payload'}
to (assoc :pubKey to)
(not to) (assoc :symKeyID status-key-id)))))))))
web3
sym-key-password
(fn [status-key-id]
(callback
(merge
(select-keys message [:ttl])
(let [type (if to :asym :sym)]
(cond-> {:sig from
:topic (first topics)
:payload payload'}
to (assoc :pubKey to)
(not to) (assoc :symKeyID status-key-id
:sym-key-password sym-key-password)))))))))
(s/def :shh/pending-message
(s/keys :req-un [:message/sig :shh/payload :message/topic]
@ -85,23 +87,33 @@
(s/def :delivery/pending-message
(s/keys :req-un [:message/sig :message/to :shh/payload :payload/ack? ::id
:message/requires-ack? :message/topic ::attempts ::was-sent?]
:opt-un [:message/pubKey :message/symKeyID]))
:opt-un [:message/pub-key :message/sym-key-password]))
(defn add-prepared-pending-message!
[web3 {:keys [message-id to sym-key-id pub-key] :as pending-message}]
{:pre [(valid? :delivery/pending-message pending-message)]}
(debug :add-prepared-pending-message!)
(let [message (assoc
(select-keys pending-message [:sig :topic :payload])
:symKeyID sym-key-id
:pubKey pub-key)
pending-message' (assoc pending-message :message message
(defn- do-add-pending-message!
[web3 {:keys [message-id to pub-key sym-key-id] :as pending-message}]
(let [message (select-keys pending-message [:sig :topic :payload])
message' (if sym-key-id
(assoc message :symKeyId sym-key-id)
(assoc message :pubKey pub-key))
pending-message' (assoc pending-message :message message'
:id message-id)]
(swap! messages assoc-in [web3 message-id to] pending-message')
(when to
(swap! recipient->pending-message
update to set/union #{[web3 message-id to]}))))
(defn add-prepared-pending-message!
[web3 {:keys [sym-key-password] :as pending-message}]
{:pre [(valid? :delivery/pending-message pending-message)]}
(debug :add-prepared-pending-message!)
(if sym-key-password
(shh-keys/get-sym-key
web3
sym-key-password
(fn [sym-key-id]
(do-add-pending-message! web3 (assoc pending-message :sym-key-id sym-key-id))))
(do-add-pending-message! web3 pending-message)))
(defn remove-pending-message! [web3 id to]
(swap! messages update web3
(fn [messages]