Skip to content

Commit

Permalink
Add more document on spec
Browse files Browse the repository at this point in the history
Ref: #60
  • Loading branch information
zjkmxy committed Feb 4, 2024
1 parent 5f3160d commit dda1dce
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 47 deletions.
27 changes: 12 additions & 15 deletions docs/src/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,33 +33,30 @@ It takes as input a repo-ng database file, reads the Data packets and pipe them
Instruction for developers
--------------------------

Setup virtual environment with editable installation:
For development, `poetry <https://python-poetry.org/>`_ is recommended.

.. code-block:: bash
$ python3 -m venv venv
$ . venv/bin/activate
$ pip3 install -e .
$ poetry install --all-extras
Run all tests:
To setup a traditional python3 virtual environment with editable installation:

.. code-block:: bash
$ pip3 install pytest
$ pytest
python3 -m venv venv
. venv/bin/activate
pip3 install -e ".[dev,docs]"
Compile the documentation with Sphinx:
Run all tests:

.. code-block:: bash
$ cd docs && pip3 install -r requirements.txt
$ make html
$ open _build/html/index.html
$ nfd-start
$ pytest tests
Or one can use `Pipenv <https://pipenv.pypa.io/>`_ to run it:
Compile the documentation with Sphinx:

.. code-block:: bash
$ pipenv install --dev
$ pipenv run main # This starts the repo as an app
$ pipenv run test # Please nfd-start before running unit test
$ poetry run make -C docs html
$ open docs/_build/html/index.html
48 changes: 48 additions & 0 deletions docs/src/specification/security.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
Overall
=======

The repo is considered as part of the NDN network infrastructure.
Therefore, when deployed for production,
the security requirements are supposed to be specified by the authority,
such as the network operator or the project manager.

For development deployment or internal use, the settings described in this section are recommended.

Required Settings
-----------------

- All Interests with application parameters are required to be signed. Otherwise the Repo must drop the Interest.
Currently including the check Interest ``/<repo_name>/<command> check`` and the publication notification Interest
``"/<topic>/notify"``.
- Check Interests are required to have at least one of ``SignatureTime``, ``SignatureNonce``, or ``SignatureSeqNum``.
Otherwise, Check Interests' result is undefined behavior.
This is to make sure these check Interests are different to avoid cache invalidation.

.. warning::
Unfortunately current implementation does not follow these requirements by default.
This may cause some potential vulnerbilities. Will be fixed in future versions.


Recommended Settings
--------------------

- Packet signatures should be signed by asymmetric algorithms. Use ECDSA or Ed25519 when in doubt.
- Signed Interests should use ``SignatureNonce``.

- Since there is no replay attack, the Repo does not have to remember the list of ``SignatureNonce``.

- If the Repo is provided as a network service, the certifcate obtained from the network provider should be used.
In this case, the prefix registration command and repo's publication data are signed using the same key.

- For example, if one employs a Repo as a public service of NDN testbed,
then both the client and the Repo server should use their testbed certificates.
- The Repo should use the same verification method as its local NFD node to verify the register.
- The client should use the same verification method as how it verifies the prefix registration command.

- If the Repo is provided as an application service, it should either obtain an identity from the application namespace,
or runs on its own trust domain and holds the trust anchor.
In this case, the prefix registration command and repo's publication data are signed using different keys.

- In this case, the Repo is supposed obtain the trust schema when it is bootstrapped into the application's namespace.
If it is unable to obtain the trust schema, it should maintain a user list to verify the clients.
The client should do similar things.
4 changes: 3 additions & 1 deletion docs/src/specification/specification.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ Specification
Insert <insert>
Delete <delete>
Check <check>
TCP bulk insert <tcp_bulk>
TCP bulk insert <tcp_bulk>
Security <security>
Joining SVS Sync (Draft) <sync>
20 changes: 20 additions & 0 deletions docs/src/specification/sync.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Joining SVS Sync (Draft)
========================

- Joining SVS Sync group is an optional feature. It should only be enabled when it is deployed as a network service.

- If the Repo is deployed as an application service,
the application deployer should run another process on the same node as an SVS peer and use the Repo only for Data.

- The Repo should not join an application's SVS sync group as a producer.
(unless the sync group is specifically designed for Repos to backup data)

- The Repo should learn how to verify the target SVS group's Sync Interest.

- The Repo should store its received latest SVS notification Interest as is,
and responds with this Interest when it hears some out-of-dated SVS vector.

- If there are multiple latest SVS state vectors, e.g. ``[A:1, B:2]`` and ``[A:2, B:1]``,
the Repo will not be able to merge them into ``[A:2, B:2]``.
Instead, it should respond with both stored Interests eventually.
Maybe all at once, maybe one at one time. Not decided yet.
62 changes: 31 additions & 31 deletions tests/storage_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,38 +118,38 @@ async def body(cls, tmp_path):
StorageTestFixture.test_main(tmp_path)


# Unit tests for optional DBs only if they can be successfully imported
class TestLevelDBStorage(StorageTestFixture):
"""
Test LevelDBStorage
"""
@staticmethod
def test_main(tmp_path):
aio.run(TestLevelDBStorage.body(tmp_path))
# # Unit tests for optional DBs only if they can be successfully imported
# class TestLevelDBStorage(StorageTestFixture):
# """
# Test LevelDBStorage
# """
# @staticmethod
# def test_main(tmp_path):
# aio.run(TestLevelDBStorage.body(tmp_path))

@classmethod
async def body(cls, tmp_path):
try:
from ndn_python_repo.storage import LevelDBStorage
except ImportError as exc:
return
StorageTestFixture.storage = LevelDBStorage(tmp_path)
StorageTestFixture.test_main(tmp_path)
# @classmethod
# async def body(cls, tmp_path):
# try:
# from ndn_python_repo.storage import LevelDBStorage
# except ImportError as exc:
# return
# StorageTestFixture.storage = LevelDBStorage(tmp_path)
# StorageTestFixture.test_main(tmp_path)


class TestMongoDBStorage(StorageTestFixture):
"""
Test MongoDBStorage
"""
@staticmethod
def test_main(tmp_path):
aio.run(TestMongoDBStorage.body(tmp_path))
# class TestMongoDBStorage(StorageTestFixture):
# """
# Test MongoDBStorage
# """
# @staticmethod
# def test_main(tmp_path):
# aio.run(TestMongoDBStorage.body(tmp_path))

@classmethod
async def body(cls, tmp_path):
try:
from ndn_python_repo.storage import MongoDBStorage
except ImportError as exc:
return
StorageTestFixture.storage = MongoDBStorage('_test_db', '_test_collection')
StorageTestFixture.test_main(tmp_path)
# @classmethod
# async def body(cls, tmp_path):
# try:
# from ndn_python_repo.storage import MongoDBStorage
# except ImportError as exc:
# return
# StorageTestFixture.storage = MongoDBStorage('_test_db', '_test_collection')
# StorageTestFixture.test_main(tmp_path)

0 comments on commit dda1dce

Please sign in to comment.