p2p-db / test / ird / p2p / db / access_test.cljs
341 words
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
(ns ird.p2p.db.access-test
  "Write access is possession of the secret. With another secret a peer
  derives another identity: by name it lands in a different database, and
  by address — joining the very same log — OrbitDB's access controller
  refuses its appends while its own key cannot read anything."
  (:require [cljs.test :refer [deftest is testing]]
            [cljs.core.async :as async :refer [<!]]
            [ird.p2p.db.core :as db]
            [ird.p2p.db.errors :as err]
            [ird.p2p.db.test-util :as tu :refer [deftest-async]]))

(deftest-async wrong-secret-cannot-write
  {:timeout-ms 60000}
  (if (tu/skip-nodes?)
    (is true "IRD_P2P_DB_NO_NODE set — skipping the real-node access test")
    (let [secret (db/random-secret)
          wrong (db/random-secret)
          a (<! (db/open {:secret secret :app-salt "test/v1" :name "chat"}))
          _ (is (not (tu/error? a)) (some-> a ex-message))
          r1 (<! (db/append a {:text "only for holders" :n 1}))
          _ (is (not (tu/error? r1)))]
      (testing "by name: another secret is another database"
        (let [c1 (<! (db/open {:secret wrong :app-salt "test/v1" :name "chat"}))]
          (is (not (tu/error? c1)) (some-> c1 ex-message))
          (is (not= (db/address a) (db/address c1)))
          (is (not= (:identity a) (:identity c1)))
          (is (empty? (<! (db/entries c1))))
          (<! (db/close c1))))
      (testing "by address: the log can be joined, never written, never read"
        (let [c2 (<! (db/open {:secret wrong :app-salt "test/v1" :name "chat"
                               :address (db/address a) :dial (<! (db/multiaddrs a))}))]
          (is (not (tu/error? c2)) (some-> c2 ex-message))
          (is (= (db/address a) (db/address c2)))
          (is (= [(:orbit-id (:identity a))] (:write (:db c2))) "the manifest's write list names the secret's identity only")
          (is (not= (:orbit-id (:identity c2)) (first (:write (:db c2)))))
          (let [r (<! (db/append c2 {:text "forged" :n 99}))]
            (is (err/append-rejected? r) (pr-str r))
            (is (err/db-error? r)))
          ;; C receives A's entry through sync but cannot decrypt it: nothing on its stream
          (let [cc (tu/collector (db/entries-stream c2))
                pc (tu/collector (db/peers-stream c2))]
            (is (some? (<! (tu/wait-for pc #(= :peer-joined (:type %)) 20000))) "C synced with A")
            (<! (async/timeout 500))
            (is (empty? @cc) "A's record does not decrypt under C's key")
            (is (= 1 (count (<! ((:all (:db c2)))))) "…although C holds the ciphertext entry")
            (is (empty? (<! (db/entries c2)))))
          (<! (db/close c2))))
      (is (= 1 (count (<! (db/entries a)))) "A's log is untouched")
      (<! (db/close a)))))

static mirror of HEAD · about · clone: git clone https://ird.cod-sursa.ro/p2p-db.git