Rev467, requirements.txt accept newer dependecies, Boost dbschema.json, Move getDirname getFilename to helper, Verify optional files, Includes not allowed in user files, Optional files rules, Peer hashfield functions, Test optional files signing, Test file info, Test verify file, Test helpers
This commit is contained in:
parent
a7d8d488da
commit
9d7d4f1552
22 changed files with 486 additions and 220 deletions
17
src/Test/Spy.py
Normal file
17
src/Test/Spy.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
class Spy:
|
||||
def __init__(self, obj, func_name):
|
||||
self.obj = obj
|
||||
self.func_name = func_name
|
||||
self.func_original = getattr(self.obj, func_name)
|
||||
self.calls = []
|
||||
|
||||
def __enter__(self, *args, **kwargs):
|
||||
def loggedFunc(cls, *args, **kwags):
|
||||
print "Logging", self, args, kwargs
|
||||
self.calls.append(args)
|
||||
return self.func_original(cls, *args, **kwargs)
|
||||
setattr(self.obj, self.func_name, loggedFunc)
|
||||
return self.calls
|
||||
|
||||
def __exit__(self, *args, **kwargs):
|
||||
setattr(self.obj, self.func_name, self.func_original)
|
|
@ -9,7 +9,7 @@ from Crypt import CryptBitcoin
|
|||
|
||||
@pytest.mark.usefixtures("resetSettings")
|
||||
class TestContent:
|
||||
def testIncludes(self, site):
|
||||
def testInclude(self, site):
|
||||
# Rules defined in parent content.json
|
||||
rules = site.content_manager.getRules("data/test_include/content.json")
|
||||
|
||||
|
@ -34,7 +34,7 @@ class TestContent:
|
|||
# Valid signers for root content.json
|
||||
assert site.content_manager.getValidSigners("content.json") == ["1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT"]
|
||||
|
||||
def testLimits(self, site):
|
||||
def testInlcudeLimits(self, site):
|
||||
privatekey = "5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv"
|
||||
# Data validation
|
||||
data_dict = {
|
||||
|
@ -48,7 +48,7 @@ class TestContent:
|
|||
}
|
||||
|
||||
# Normal data
|
||||
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict), privatekey) }
|
||||
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict), privatekey)}
|
||||
data = StringIO(json.dumps(data_dict))
|
||||
assert site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False)
|
||||
# Reset
|
||||
|
@ -56,7 +56,7 @@ class TestContent:
|
|||
|
||||
# Too large
|
||||
data_dict["files"]["data.json"]["size"] = 200000 # Emulate 2MB sized data.json
|
||||
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict), privatekey) }
|
||||
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict), privatekey)}
|
||||
data = StringIO(json.dumps(data_dict))
|
||||
assert not site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False)
|
||||
# Reset
|
||||
|
@ -65,7 +65,7 @@ class TestContent:
|
|||
|
||||
# Not allowed file
|
||||
data_dict["files"]["notallowed.exe"] = data_dict["files"]["data.json"]
|
||||
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict), privatekey) }
|
||||
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict), privatekey)}
|
||||
data = StringIO(json.dumps(data_dict))
|
||||
assert not site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False)
|
||||
# Reset
|
||||
|
@ -73,6 +73,58 @@ class TestContent:
|
|||
del data_dict["signs"]
|
||||
|
||||
# Should work again
|
||||
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict), privatekey) }
|
||||
data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict), privatekey)}
|
||||
data = StringIO(json.dumps(data_dict))
|
||||
assert site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False)
|
||||
|
||||
@pytest.mark.parametrize("inner_path", ["content.json", "data/test_include/content.json", "data/users/content.json"])
|
||||
def testSign(self, site, inner_path):
|
||||
# Bad privatekey
|
||||
assert not site.content_manager.sign(inner_path, privatekey="5aaa3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMnaa", filewrite=False)
|
||||
|
||||
# Good privatekey
|
||||
content = site.content_manager.sign(inner_path, privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv", filewrite=False)
|
||||
content_old = site.content_manager.contents[inner_path] # Content before the sign
|
||||
assert not content_old == content # Timestamp changed
|
||||
assert site.address in content["signs"] # Used the site's private key to sign
|
||||
if inner_path == "content.json":
|
||||
assert len(content["files"]) == 17
|
||||
elif inner_path == "data/test-include/content.json":
|
||||
assert len(content["files"]) == 1
|
||||
elif inner_path == "data/users/content.json":
|
||||
assert len(content["files"]) == 0
|
||||
|
||||
# Everything should be same as before except the modified timestamp and the signs
|
||||
assert (
|
||||
{key: val for key, val in content_old.items() if key not in ["modified", "signs", "sign"]}
|
||||
==
|
||||
{key: val for key, val in content.items() if key not in ["modified", "signs", "sign"]}
|
||||
)
|
||||
|
||||
def testSignOptionalFiles(self, site):
|
||||
site.content_manager.contents["content.json"]["optional"] = "((data/img/zero.*))"
|
||||
content_optional = site.content_manager.sign(privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv", filewrite=False)
|
||||
|
||||
del site.content_manager.contents["content.json"]["optional"]
|
||||
content_nooptional = site.content_manager.sign(privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv", filewrite=False)
|
||||
|
||||
assert len(content_nooptional.get("files_optional", {})) == 0
|
||||
assert len(content_optional["files_optional"]) > 0
|
||||
assert len(content_nooptional["files"]) > len(content_optional["files"])
|
||||
|
||||
def testFileInfo(self, site):
|
||||
assert "sha512" in site.content_manager.getFileInfo("index.html")
|
||||
assert not site.content_manager.getFileInfo("notexist")
|
||||
|
||||
# Optional file
|
||||
file_info_optional = site.content_manager.getFileInfo("data/optional.txt")
|
||||
assert "sha512" in file_info_optional
|
||||
assert file_info_optional["optional"] is True
|
||||
|
||||
# Not exists yet user content.json
|
||||
assert "cert_signers" in site.content_manager.getFileInfo("data/users/unknown/content.json")
|
||||
|
||||
# Optional user file
|
||||
file_info_optional = site.content_manager.getFileInfo("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif")
|
||||
assert "sha512" in file_info_optional
|
||||
assert file_info_optional["optional"] is True
|
||||
|
|
|
@ -50,6 +50,66 @@ class TestUserContent:
|
|||
rules = site.content_manager.getRules("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_content)
|
||||
assert rules is False
|
||||
|
||||
def testVerify(self, site):
|
||||
privatekey = "5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv" # For 1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT
|
||||
user_inner_path = "data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json"
|
||||
data_dict = site.content_manager.contents[user_inner_path]
|
||||
users_content = site.content_manager.contents["data/users/content.json"]
|
||||
|
||||
data = StringIO(json.dumps(data_dict))
|
||||
assert site.content_manager.verifyFile(user_inner_path, data, ignore_same=False)
|
||||
|
||||
# Test max size exception by setting allowed to 0
|
||||
rules = site.content_manager.getRules(user_inner_path, data_dict)
|
||||
assert rules["max_size"] == 10000
|
||||
assert users_content["user_contents"]["permission_rules"][".*"]["max_size"] == 10000
|
||||
|
||||
users_content["user_contents"]["permission_rules"][".*"]["max_size"] = 0
|
||||
rules = site.content_manager.getRules(user_inner_path, data_dict)
|
||||
assert rules["max_size"] == 0
|
||||
data = StringIO(json.dumps(data_dict))
|
||||
assert not site.content_manager.verifyFile(user_inner_path, data, ignore_same=False)
|
||||
users_content["user_contents"]["permission_rules"][".*"]["max_size"] = 10000 # Reset
|
||||
|
||||
# Test max optional size exception
|
||||
# 1 MB gif = Allowed
|
||||
data_dict["files_optional"]["peanut-butter-jelly-time.gif"]["size"] = 1024 * 1024
|
||||
del data_dict["signs"] # Remove signs before signing
|
||||
data_dict["signs"] = {
|
||||
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), privatekey)
|
||||
}
|
||||
data = StringIO(json.dumps(data_dict))
|
||||
assert site.content_manager.verifyFile(user_inner_path, data, ignore_same=False)
|
||||
|
||||
# 100 MB gif = Not allowed
|
||||
data_dict["files_optional"]["peanut-butter-jelly-time.gif"]["size"] = 100 * 1024 * 1024
|
||||
del data_dict["signs"] # Remove signs before signing
|
||||
data_dict["signs"] = {
|
||||
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), privatekey)
|
||||
}
|
||||
data = StringIO(json.dumps(data_dict))
|
||||
assert not site.content_manager.verifyFile(user_inner_path, data, ignore_same=False)
|
||||
data_dict["files_optional"]["peanut-butter-jelly-time.gif"]["size"] = 1024 * 1024 # Reset
|
||||
|
||||
# hello.exe = Not allowed
|
||||
data_dict["files_optional"]["hello.exe"] = data_dict["files_optional"]["peanut-butter-jelly-time.gif"]
|
||||
del data_dict["signs"] # Remove signs before signing
|
||||
data_dict["signs"] = {
|
||||
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), privatekey)
|
||||
}
|
||||
data = StringIO(json.dumps(data_dict))
|
||||
assert not site.content_manager.verifyFile(user_inner_path, data, ignore_same=False)
|
||||
del data_dict["files_optional"]["hello.exe"] # Reset
|
||||
|
||||
# Includes not allowed in user content
|
||||
data_dict["includes"] = { "other.json": { } }
|
||||
del data_dict["signs"] # Remove signs before signing
|
||||
data_dict["signs"] = {
|
||||
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), privatekey)
|
||||
}
|
||||
data = StringIO(json.dumps(data_dict))
|
||||
assert not site.content_manager.verifyFile(user_inner_path, data, ignore_same=False)
|
||||
|
||||
def testCert(self, site):
|
||||
# user_addr = "1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C"
|
||||
user_priv = "5Kk7FSA63FC2ViKmKLuBxk9gQkaQ5713hKq8LmFAf4cVeXh6K6A"
|
||||
|
|
|
@ -1,17 +1,39 @@
|
|||
class Spy:
|
||||
def __init__(self, obj, func_name):
|
||||
self.obj = obj
|
||||
self.func_name = func_name
|
||||
self.func_original = getattr(self.obj, func_name)
|
||||
self.calls = []
|
||||
import socket
|
||||
|
||||
def __enter__(self, *args, **kwargs):
|
||||
def loggedFunc(cls, *args, **kwags):
|
||||
print "Logging", self, args, kwargs
|
||||
self.calls.append(args)
|
||||
return self.func_original(cls, *args, **kwargs)
|
||||
setattr(self.obj, self.func_name, loggedFunc)
|
||||
return self.calls
|
||||
import pytest
|
||||
from util import helper
|
||||
|
||||
def __exit__(self, *args, **kwargs):
|
||||
setattr(self.obj, self.func_name, self.func_original)
|
||||
|
||||
@pytest.mark.usefixtures("resetSettings")
|
||||
class TestHelper:
|
||||
def testShellquote(self):
|
||||
assert helper.shellquote("hel'lo") == "\"hel'lo\"" # Allow '
|
||||
assert helper.shellquote('hel"lo') == '"hello"' # Remove "
|
||||
assert helper.shellquote("hel'lo", 'hel"lo') == ('"hel\'lo"', '"hello"')
|
||||
|
||||
def testPackAddress(self):
|
||||
assert len(helper.packAddress("1.1.1.1", 1)) == 6
|
||||
assert helper.unpackAddress(helper.packAddress("1.1.1.1", 1)) == ("1.1.1.1", 1)
|
||||
|
||||
with pytest.raises(socket.error):
|
||||
helper.packAddress("999.1.1.1", 1)
|
||||
|
||||
with pytest.raises(socket.error):
|
||||
helper.unpackAddress("X")
|
||||
|
||||
def testGetDirname(self):
|
||||
assert helper.getDirname("data/users/content.json") == "data/users/"
|
||||
assert helper.getDirname("data/users") == "data/"
|
||||
assert helper.getDirname("") == ""
|
||||
assert helper.getDirname("content.json") == ""
|
||||
assert helper.getDirname("data/users/") == "data/users/"
|
||||
assert helper.getDirname("/data/users/content.json") == "/data/users/"
|
||||
|
||||
|
||||
def testGetFilename(self):
|
||||
assert helper.getFilename("data/users/content.json") == "content.json"
|
||||
assert helper.getFilename("data/users") == "users"
|
||||
assert helper.getFilename("") == ""
|
||||
assert helper.getFilename("content.json") == "content.json"
|
||||
assert helper.getFilename("data/users/") == ""
|
||||
assert helper.getFilename("/data/users/content.json") == "content.json"
|
|
@ -62,36 +62,3 @@ class TestSite:
|
|||
assert new_site.address in SiteManager.site_manager.sites
|
||||
SiteManager.site_manager.delete(new_site.address)
|
||||
assert new_site.address not in SiteManager.site_manager.sites
|
||||
|
||||
@pytest.mark.parametrize("inner_path", ["content.json", "data/test_include/content.json", "data/users/content.json"])
|
||||
def testSign(self, site, inner_path):
|
||||
# Bad privatekey
|
||||
assert not site.content_manager.sign(inner_path, privatekey="5aaa3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMnaa", filewrite=False)
|
||||
|
||||
# Good privatekey
|
||||
content = site.content_manager.sign(inner_path, privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv", filewrite=False)
|
||||
content_old = site.content_manager.contents[inner_path] # Content before the sign
|
||||
assert not content_old == content # Timestamp changed
|
||||
assert site.address in content["signs"] # Used the site's private key to sign
|
||||
if inner_path == "content.json":
|
||||
assert len(content["files"]) == 24
|
||||
elif inner_path == "data/test-include/content.json":
|
||||
assert len(content["files"]) == 1
|
||||
elif inner_path == "data/users/content.json":
|
||||
assert len(content["files"]) == 0
|
||||
|
||||
# Everything should be same as before except the modified timestamp and the signs
|
||||
assert (
|
||||
{key: val for key, val in content_old.items() if key not in ["modified", "signs", "sign"]}
|
||||
==
|
||||
{key: val for key, val in content.items() if key not in ["modified", "signs", "sign"]}
|
||||
)
|
||||
|
||||
def testSignOptionalFiles(self, site):
|
||||
site.content_manager.contents["content.json"]["optional"] = "((data/img/zero.*))"
|
||||
content_optional = site.content_manager.sign(privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv", filewrite=False)
|
||||
|
||||
del site.content_manager.contents["content.json"]["optional"]
|
||||
content_nooptional = site.content_manager.sign(privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv", filewrite=False)
|
||||
|
||||
assert len(content_nooptional["files"]) > len(content_optional["files"])
|
||||
|
|
63
src/Test/TestSiteDownload.py
Normal file
63
src/Test/TestSiteDownload.py
Normal file
|
@ -0,0 +1,63 @@
|
|||
import pytest
|
||||
import mock
|
||||
import time
|
||||
|
||||
from Connection import ConnectionServer
|
||||
from Config import config
|
||||
from Site import Site
|
||||
from File import FileRequest
|
||||
import Spy
|
||||
|
||||
@pytest.mark.usefixtures("resetTempSettings")
|
||||
@pytest.mark.usefixtures("resetSettings")
|
||||
class TestWorker:
|
||||
def testDownload(self, file_server, site, site_temp):
|
||||
client = ConnectionServer("127.0.0.1", 1545)
|
||||
assert site.storage.directory == config.data_dir + "/" + site.address
|
||||
assert site_temp.storage.directory == config.data_dir + "-temp/" + site.address
|
||||
|
||||
# Init source server
|
||||
site.connection_server = file_server
|
||||
file_server.sites[site.address] = site
|
||||
|
||||
# Init client server
|
||||
site_temp.connection_server = client
|
||||
site_temp.announce = mock.MagicMock(return_value=True) # Don't try to find peers from the net
|
||||
|
||||
site_temp.addPeer("127.0.0.1", 1544)
|
||||
with Spy.Spy(FileRequest, "route") as requests:
|
||||
def boostRequest(inner_path):
|
||||
# I really want these file
|
||||
if inner_path == "index.html":
|
||||
print "needFile"
|
||||
site_temp.needFile("data/img/multiuser.png", priority=9, blocking=False)
|
||||
site_temp.needFile("data/img/direct_domains.png", priority=10, blocking=False)
|
||||
site_temp.onFileDone.append(boostRequest)
|
||||
site_temp.download(blind_includes=True).join(timeout=5)
|
||||
file_requests = [request[2]["inner_path"] for request in requests if request[0] in ("getFile", "streamFile")]
|
||||
# Test priority
|
||||
assert file_requests[0:2] == ["content.json", "index.html"] # Must-have files
|
||||
assert file_requests[2:4] == ["data/img/direct_domains.png", "data/img/multiuser.png"] # Directly requested files
|
||||
assert file_requests[4:6] == ["css/all.css", "js/all.js"] # Important assets
|
||||
assert file_requests[6] == "dbschema.json" # Database map
|
||||
assert "-default" in file_requests[-1] # Put default files for cloning to the end
|
||||
|
||||
# Check files
|
||||
bad_files = site_temp.storage.verifyFiles(quick_check=True)
|
||||
|
||||
# -1 because data/users/1J6... user has invalid cert
|
||||
assert len(site_temp.content_manager.contents) == len(site.content_manager.contents) - 1
|
||||
assert not bad_files
|
||||
|
||||
# Optional file
|
||||
assert not site_temp.storage.isFile("data/optional.txt")
|
||||
assert site.storage.isFile("data/optional.txt")
|
||||
site_temp.needFile("data/optional.txt")
|
||||
assert site_temp.storage.isFile("data/optional.txt")
|
||||
|
||||
# Optional user file
|
||||
assert not site_temp.storage.isFile("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif")
|
||||
site_temp.needFile("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif")
|
||||
assert site_temp.storage.isFile("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif")
|
||||
|
||||
assert site_temp.storage.deleteFiles()
|
|
@ -1,15 +1,13 @@
|
|||
import shutil
|
||||
import os
|
||||
|
||||
import pytest
|
||||
from Site import SiteManager
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("resetSettings")
|
||||
class TestSiteStorage:
|
||||
def testList(self, site):
|
||||
list_root = list(site.storage.list(""))
|
||||
assert "content.json" in list_root
|
||||
assert "css/all.css" in list_root
|
||||
# Rootdir
|
||||
list_root = list(site.storage.list(""))
|
||||
assert "content.json" in list_root
|
||||
assert "css/all.css" in list_root
|
||||
|
||||
# Subdir
|
||||
assert list(site.storage.list("data-default")) == ["data.json", "users/content-default.json"]
|
||||
|
|
|
@ -22,6 +22,7 @@ from Config import config
|
|||
config.argv = ["none"] # Dont pass any argv to config parser
|
||||
config.parse()
|
||||
config.data_dir = "src/Test/testdata" # Use test data for unittests
|
||||
config.debug_socket = True # Use test data for unittests
|
||||
logging.basicConfig(level=logging.DEBUG, stream=sys.stdout)
|
||||
|
||||
from Site import Site
|
||||
|
@ -76,7 +77,7 @@ def resetTempSettings(request):
|
|||
request.addfinalizer(cleanup)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
@pytest.fixture()
|
||||
def site():
|
||||
site = Site("1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT")
|
||||
return site
|
||||
|
|
|
@ -1,133 +1,136 @@
|
|||
{
|
||||
"address": "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT",
|
||||
"background-color": "white",
|
||||
"description": "Blogging platform Demo",
|
||||
"domain": "Blog.ZeroNetwork.bit",
|
||||
"address": "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT",
|
||||
"background-color": "white",
|
||||
"description": "Blogging platform Demo",
|
||||
"domain": "Blog.ZeroNetwork.bit",
|
||||
"files": {
|
||||
"css/all.css": {
|
||||
"sha512": "65ddd3a2071a0f48c34783aa3b1bde4424bdea344630af05a237557a62bd55dc",
|
||||
"sha512": "65ddd3a2071a0f48c34783aa3b1bde4424bdea344630af05a237557a62bd55dc",
|
||||
"size": 112710
|
||||
},
|
||||
},
|
||||
"data-default/data.json": {
|
||||
"sha512": "3f5c5a220bde41b464ab116cce0bd670dd0b4ff5fe4a73d1dffc4719140038f2",
|
||||
"sha512": "3f5c5a220bde41b464ab116cce0bd670dd0b4ff5fe4a73d1dffc4719140038f2",
|
||||
"size": 196
|
||||
},
|
||||
},
|
||||
"data-default/users/content-default.json": {
|
||||
"sha512": "0603ce08f7abb92b3840ad0cf40e95ea0b3ed3511b31524d4d70e88adba83daa",
|
||||
"sha512": "0603ce08f7abb92b3840ad0cf40e95ea0b3ed3511b31524d4d70e88adba83daa",
|
||||
"size": 679
|
||||
},
|
||||
},
|
||||
"data/data.json": {
|
||||
"sha512": "0f2321c905b761a05c360a389e1de149d952b16097c4ccf8310158356e85fb52",
|
||||
"sha512": "0f2321c905b761a05c360a389e1de149d952b16097c4ccf8310158356e85fb52",
|
||||
"size": 31126
|
||||
},
|
||||
},
|
||||
"data/img/autoupdate.png": {
|
||||
"sha512": "d2b4dc8e0da2861ea051c0c13490a4eccf8933d77383a5b43de447c49d816e71",
|
||||
"sha512": "d2b4dc8e0da2861ea051c0c13490a4eccf8933d77383a5b43de447c49d816e71",
|
||||
"size": 24460
|
||||
},
|
||||
},
|
||||
"data/img/direct_domains.png": {
|
||||
"sha512": "5f14b30c1852735ab329b22496b1e2ea751cb04704789443ad73a70587c59719",
|
||||
"sha512": "5f14b30c1852735ab329b22496b1e2ea751cb04704789443ad73a70587c59719",
|
||||
"size": 16185
|
||||
},
|
||||
},
|
||||
"data/img/domain.png": {
|
||||
"sha512": "ce87e0831f4d1e95a95d7120ca4d33f8273c6fce9f5bbedf7209396ea0b57b6a",
|
||||
"sha512": "ce87e0831f4d1e95a95d7120ca4d33f8273c6fce9f5bbedf7209396ea0b57b6a",
|
||||
"size": 11881
|
||||
},
|
||||
},
|
||||
"data/img/memory.png": {
|
||||
"sha512": "dd56515085b4a79b5809716f76f267ec3a204be3ee0d215591a77bf0f390fa4e",
|
||||
"sha512": "dd56515085b4a79b5809716f76f267ec3a204be3ee0d215591a77bf0f390fa4e",
|
||||
"size": 12775
|
||||
},
|
||||
},
|
||||
"data/img/multiuser.png": {
|
||||
"sha512": "88e3f795f9b86583640867897de6efc14e1aa42f93e848ed1645213e6cc210c6",
|
||||
"sha512": "88e3f795f9b86583640867897de6efc14e1aa42f93e848ed1645213e6cc210c6",
|
||||
"size": 29480
|
||||
},
|
||||
},
|
||||
"data/img/progressbar.png": {
|
||||
"sha512": "23d592ae386ce14158cec34d32a3556771725e331c14d5a4905c59e0fe980ebf",
|
||||
"sha512": "23d592ae386ce14158cec34d32a3556771725e331c14d5a4905c59e0fe980ebf",
|
||||
"size": 13294
|
||||
},
|
||||
},
|
||||
"data/img/slides.png": {
|
||||
"sha512": "1933db3b90ab93465befa1bd0843babe38173975e306286e08151be9992f767e",
|
||||
"sha512": "1933db3b90ab93465befa1bd0843babe38173975e306286e08151be9992f767e",
|
||||
"size": 14439
|
||||
},
|
||||
},
|
||||
"data/img/slots_memory.png": {
|
||||
"sha512": "82a250e6da909d7f66341e5b5c443353958f86728cd3f06e988b6441e6847c29",
|
||||
"sha512": "82a250e6da909d7f66341e5b5c443353958f86728cd3f06e988b6441e6847c29",
|
||||
"size": 9488
|
||||
},
|
||||
},
|
||||
"data/img/trayicon.png": {
|
||||
"sha512": "e7ae65bf280f13fb7175c1293dad7d18f1fcb186ebc9e1e33850cdaccb897b8f",
|
||||
"sha512": "e7ae65bf280f13fb7175c1293dad7d18f1fcb186ebc9e1e33850cdaccb897b8f",
|
||||
"size": 19040
|
||||
},
|
||||
"data/img/zeroblog-comments.png": {
|
||||
"sha512": "efe4e815a260e555303e5c49e550a689d27a8361f64667bd4a91dbcccb83d2b4",
|
||||
"size": 24001
|
||||
},
|
||||
"data/img/zeroid.png": {
|
||||
"sha512": "b46d541a9e51ba2ddc8a49955b7debbc3b45fd13467d3c20ef104e9d938d052b",
|
||||
"size": 18875
|
||||
},
|
||||
"data/img/zeroname.png": {
|
||||
"sha512": "bab45a1bb2087b64e4f69f756b2ffa5ad39b7fdc48c83609cdde44028a7a155d",
|
||||
"size": 36031
|
||||
},
|
||||
"data/img/zerotalk-mark.png": {
|
||||
"sha512": "a335b2fedeb8d291ca68d3091f567c180628e80f41de4331a5feb19601d078af",
|
||||
"size": 44862
|
||||
},
|
||||
"data/img/zerotalk-upvote.png": {
|
||||
"sha512": "b1ffd7f948b4f99248dde7efe256c2efdfd997f7e876fb9734f986ef2b561732",
|
||||
"size": 41092
|
||||
},
|
||||
"data/img/zerotalk.png": {
|
||||
"sha512": "54d10497a1ffca9a4780092fd1bd158c15f639856d654d2eb33a42f9d8e33cd8",
|
||||
"size": 26606
|
||||
},
|
||||
"data/test_include/data.json": {
|
||||
"sha512": "369d4e780cc80504285f13774ca327fe725eed2d813aad229e62356b07365906",
|
||||
"size": 505
|
||||
},
|
||||
},
|
||||
"dbschema.json": {
|
||||
"sha512": "7b756e8e475d4d6b345a24e2ae14254f5c6f4aa67391a94491a026550fe00df8",
|
||||
"sha512": "7b756e8e475d4d6b345a24e2ae14254f5c6f4aa67391a94491a026550fe00df8",
|
||||
"size": 1529
|
||||
},
|
||||
},
|
||||
"img/loading.gif": {
|
||||
"sha512": "8a42b98962faea74618113166886be488c09dad10ca47fe97005edc5fb40cc00",
|
||||
"sha512": "8a42b98962faea74618113166886be488c09dad10ca47fe97005edc5fb40cc00",
|
||||
"size": 723
|
||||
},
|
||||
},
|
||||
"index.html": {
|
||||
"sha512": "c4039ebfc4cb6f116cac05e803a18644ed70404474a572f0d8473f4572f05df3",
|
||||
"sha512": "c4039ebfc4cb6f116cac05e803a18644ed70404474a572f0d8473f4572f05df3",
|
||||
"size": 4667
|
||||
},
|
||||
},
|
||||
"js/all.js": {
|
||||
"sha512": "034c97535f3c9b3fbebf2dcf61a38711dae762acf1a99168ae7ddc7e265f582c",
|
||||
"sha512": "034c97535f3c9b3fbebf2dcf61a38711dae762acf1a99168ae7ddc7e265f582c",
|
||||
"size": 201178
|
||||
}
|
||||
},
|
||||
"ignore": "((js|css)/(?!all.(js|css))|data/.*db|data/users/.*/.*)",
|
||||
},
|
||||
"files_optional": {
|
||||
"data/img/zeroblog-comments.png": {
|
||||
"sha512": "efe4e815a260e555303e5c49e550a689d27a8361f64667bd4a91dbcccb83d2b4",
|
||||
"size": 24001
|
||||
},
|
||||
"data/img/zeroid.png": {
|
||||
"sha512": "b46d541a9e51ba2ddc8a49955b7debbc3b45fd13467d3c20ef104e9d938d052b",
|
||||
"size": 18875
|
||||
},
|
||||
"data/img/zeroname.png": {
|
||||
"sha512": "bab45a1bb2087b64e4f69f756b2ffa5ad39b7fdc48c83609cdde44028a7a155d",
|
||||
"size": 36031
|
||||
},
|
||||
"data/img/zerotalk-mark.png": {
|
||||
"sha512": "a335b2fedeb8d291ca68d3091f567c180628e80f41de4331a5feb19601d078af",
|
||||
"size": 44862
|
||||
},
|
||||
"data/img/zerotalk-upvote.png": {
|
||||
"sha512": "b1ffd7f948b4f99248dde7efe256c2efdfd997f7e876fb9734f986ef2b561732",
|
||||
"size": 41092
|
||||
},
|
||||
"data/img/zerotalk.png": {
|
||||
"sha512": "54d10497a1ffca9a4780092fd1bd158c15f639856d654d2eb33a42f9d8e33cd8",
|
||||
"size": 26606
|
||||
},
|
||||
"data/optional.txt": {
|
||||
"sha512": "c6f81db0e9f8206c971c9e5826e3ba823ffbb1a3a900f8047652a8bf78ea98fd",
|
||||
"size": 6
|
||||
}
|
||||
},
|
||||
"ignore": "((js|css)/(?!all.(js|css))|data/.*db|data/users/.*/.*|data/test_include/.*)",
|
||||
"includes": {
|
||||
"data/test_include/content.json": {
|
||||
"added": 1424976057,
|
||||
"files_allowed": "data.json",
|
||||
"includes_allowed": false,
|
||||
"max_size": 20000,
|
||||
"signers": [ "15ik6LeBWnACWfaika1xqGapRZ1zh3JpCo" ],
|
||||
"signers_required": 1,
|
||||
"user_id": 47,
|
||||
"added": 1424976057,
|
||||
"files_allowed": "data.json",
|
||||
"includes_allowed": false,
|
||||
"max_size": 20000,
|
||||
"signers": [ "15ik6LeBWnACWfaika1xqGapRZ1zh3JpCo" ],
|
||||
"signers_required": 1,
|
||||
"user_id": 47,
|
||||
"user_name": "test"
|
||||
},
|
||||
},
|
||||
"data/users/content.json": {
|
||||
"signers": [ "1LSxsKfC9S9TVXGGNSM3vPHjyW82jgCX5f" ],
|
||||
"signers": [ "1LSxsKfC9S9TVXGGNSM3vPHjyW82jgCX5f" ],
|
||||
"signers_required": 1
|
||||
}
|
||||
},
|
||||
"modified": 1443393859.801,
|
||||
},
|
||||
"modified": 1443645832.748,
|
||||
"optional": "(data/img/zero.*|data/optional.txt)",
|
||||
"sign": [
|
||||
30041653970398729892154852118727733790145614202537425646336077462070348808967,
|
||||
96823925597554846684463773054016176426938620086211253074026312396122955360853
|
||||
],
|
||||
"signers_sign": "HDNmWJHM2diYln4pkdL+qYOvgE7MdwayzeG+xEUZBgp1HtOjBJS+knDEVQsBkjcOPicDG2it1r6R1eQrmogqSP0=",
|
||||
33155653220731268227776289017011639520872180216646876377169089096034035969487,
|
||||
36744504416132878244552522451563313660303086381031784548929582417244124447603
|
||||
],
|
||||
"signers_sign": "HDNmWJHM2diYln4pkdL+qYOvgE7MdwayzeG+xEUZBgp1HtOjBJS+knDEVQsBkjcOPicDG2it1r6R1eQrmogqSP0=",
|
||||
"signs": {
|
||||
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": "HKBBvaOi1v20ZuSVORtD4bBRRgf/85QDVy4HaaPX3fFDAKYmvUWK+Jbp3yIGElMmPoO2+YljFLyromAoEwWd6Eg="
|
||||
},
|
||||
"signs_required": 1,
|
||||
"title": "ZeroBlog",
|
||||
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": "HP+qomOGy0hTFX1HjHv8iQIL6E22qNynb+IijEblL2lm8SgsyiOxKGaVkD6/eE6xYGeYHSnhSii2Gw/04z3okNM="
|
||||
},
|
||||
"signs_required": 1,
|
||||
"title": "ZeroBlog",
|
||||
"zeronet_version": "0.3.2"
|
||||
}
|
1
src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/optional.txt
vendored
Normal file
1
src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/optional.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
hello!
|
|
@ -1,15 +1,22 @@
|
|||
{
|
||||
"cert_auth_type": "web",
|
||||
"cert_sign": "HBsTrjTmv+zD1iY93tSci8n9DqdEtYwzxJmRppn4/b+RYktcANGm5tXPOb+Duw3AJcgWDcGUvQVgN1D9QAwIlCw=",
|
||||
"cert_user_id": "toruser@zeroid.bit",
|
||||
"files": {
|
||||
"data.json": {
|
||||
"sha512": "4868b5e6d70a55d137db71c2e276bda80437e0235ac670962acc238071296b45",
|
||||
"size": 168
|
||||
}
|
||||
},
|
||||
"modified": 1432491109.11,
|
||||
"signs": {
|
||||
"1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9": "HMy7ZwwqE0Sk8O+5hTx/ejFW6KtIDbID6fGblCodUTpz4mJZ5GwApBHSVLMYL43vvGT/vKZOiQoJ5tQTeFVbbkk="
|
||||
"cert_auth_type": "web",
|
||||
"cert_sign": "HBsTrjTmv+zD1iY93tSci8n9DqdEtYwzxJmRppn4/b+RYktcANGm5tXPOb+Duw3AJcgWDcGUvQVgN1D9QAwIlCw=",
|
||||
"cert_user_id": "toruser@zeroid.bit",
|
||||
"files": {
|
||||
"data.json": {
|
||||
"sha512": "4868b5e6d70a55d137db71c2e276bda80437e0235ac670962acc238071296b45",
|
||||
"size": 168
|
||||
}
|
||||
},
|
||||
"files_optional": {
|
||||
"peanut-butter-jelly-time.gif": {
|
||||
"sha512": "a238fd27bda2a06f07f9f246954b34dcf82e6472aebdecc2c5dc1f01a50721ef",
|
||||
"size": 1606
|
||||
}
|
||||
},
|
||||
"modified": 1443645834.763,
|
||||
"optional": ".*\\.(jpg|png|gif)",
|
||||
"signs": {
|
||||
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": "HD+/5Jmew6BotfeWsfpTFKXUVIY5MyjKQx5KRnT6WO0nMBLxaI6/sTb+6ZXq0tXjXNkmlt36/UICYQcYQjCRhkY="
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"cert_auth_type": "web",
|
||||
"cert_sign": "HBsTrjTmv+zD1iY93tSci8n9DqdEtYwzxJmRppn4/b+RYktcANGm5tXPOb+Duw3AJcgWDcGUvQVgN1D9QAwIlCw=",
|
||||
"cert_user_id": "toruser@zeroid.bit",
|
||||
"files": {
|
||||
"data.json": {
|
||||
"sha512": "4868b5e6d70a55d137db71c2e276bda80437e0235ac670962acc238071296b45",
|
||||
"size": 168
|
||||
}
|
||||
},
|
||||
"modified": 1432491109.11,
|
||||
"signs": {
|
||||
"1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9": "HMy7ZwwqE0Sk8O+5hTx/ejFW6KtIDbID6fGblCodUTpz4mJZ5GwApBHSVLMYL43vvGT/vKZOiQoJ5tQTeFVbbkk="
|
||||
"cert_auth_type": "web",
|
||||
"cert_sign": "HBsTrjTmv+zD1iY93tSci8n9DqdEtYwzxJmRppn4/b+RYktcANGm5tXPOb+Duw3AJcgWDcGUvQVgN1D9QAwIlCw=",
|
||||
"cert_user_id": "toruser@zeroid.bit",
|
||||
"files": {
|
||||
"data.json": {
|
||||
"sha512": "4868b5e6d70a55d137db71c2e276bda80437e0235ac670962acc238071296b45",
|
||||
"size": 168
|
||||
}
|
||||
},
|
||||
"modified": 1443645835.157,
|
||||
"signs": {
|
||||
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": "HNIXDWV1kpqKtsJ+yrNKLvks/FDYIpVmx7xgkXPJ6NZiajCMHrgEwLH9QRiq6rs3nOCs0P08eRhlgZLvC+3U6ps="
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"files": {},
|
||||
"ignore": ".*",
|
||||
"modified": 1443088330.941,
|
||||
"modified": 1443645833.247,
|
||||
"signs": {
|
||||
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": "G/YCfchtojDA7EjXk5Xa6af5EaEME14LDAvVE9P8PCDb2ncWN79ZTMsczAx7N3HYyM9Vdqn+8or4hh28z4ITKqU="
|
||||
"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": "G2EcaEKdzzfbpRITDcaBajNwjaIIJW3zp1YQGIMJcxfw3tLnn6uv/goImvbzvuTXKkl5fQKmBowK2Bg1xXJ3078="
|
||||
},
|
||||
"user_contents": {
|
||||
"cert_signers": {
|
||||
|
@ -12,7 +12,9 @@
|
|||
"permission_rules": {
|
||||
".*": {
|
||||
"files_allowed": "data.json",
|
||||
"files_allowed_optional": ".*\\.(png|jpg|gif)",
|
||||
"max_size": 10000,
|
||||
"max_size_optional": 10000000,
|
||||
"signers": [ "14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet" ]
|
||||
},
|
||||
"bitid/.*@zeroid.bit": { "max_size": 40000 },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue