diff --git a/.forgejo/workflows/build-on-commit.yml b/.forgejo/workflows/build-on-commit.yml new file mode 100644 index 00000000..e8f0d2e3 --- /dev/null +++ b/.forgejo/workflows/build-on-commit.yml @@ -0,0 +1,40 @@ +name: Build Docker Image on Commit + +on: + push: + branches: + - main + tags: + - '!' # Exclude tags + +jobs: + build-and-publish: + runs-on: docker-builder + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set REPO_VARS + id: repo-url + run: | + echo "REPO_HOST=$(echo "${{ github.server_url }}" | sed 's~http[s]*://~~g')" >> $GITHUB_ENV + echo "REPO_PATH=${{ github.repository }}" >> $GITHUB_ENV + + - name: Login to OCI registry + run: | + echo "${{ secrets.OCI_TOKEN }}" | docker login $REPO_HOST -u "${{ secrets.OCI_USER }}" --password-stdin + + - name: Build and push Docker images + run: | + # Build Docker image with commit SHA + docker build -t $REPO_HOST/$REPO_PATH:${{ github.sha }} . + docker push $REPO_HOST/$REPO_PATH:${{ github.sha }} + + # Build Docker image with nightly tag + docker tag $REPO_HOST/$REPO_PATH:${{ github.sha }} $REPO_HOST/$REPO_PATH:nightly + docker push $REPO_HOST/$REPO_PATH:nightly + + # Remove local images to save storage + docker rmi $REPO_HOST/$REPO_PATH:${{ github.sha }} + docker rmi $REPO_HOST/$REPO_PATH:nightly diff --git a/.forgejo/workflows/build-on-tag.yml b/.forgejo/workflows/build-on-tag.yml new file mode 100644 index 00000000..888102b6 --- /dev/null +++ b/.forgejo/workflows/build-on-tag.yml @@ -0,0 +1,37 @@ +name: Build and Publish Docker Image on Tag + +on: + push: + tags: + - '*' + +jobs: + build-and-publish: + runs-on: docker-builder + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set REPO_VARS + id: repo-url + run: | + echo "REPO_HOST=$(echo "${{ github.server_url }}" | sed 's~http[s]*://~~g')" >> $GITHUB_ENV + echo "REPO_PATH=${{ github.repository }}" >> $GITHUB_ENV + + - name: Login to OCI registry + run: | + echo "${{ secrets.OCI_TOKEN }}" | docker login $REPO_HOST -u "${{ secrets.OCI_USER }}" --password-stdin + + - name: Build and push Docker image + run: | + TAG=${{ github.ref_name }} # Get the tag name from the context + # Build and push multi-platform Docker images + docker build -t $REPO_HOST/$REPO_PATH:$TAG --push . + # Tag and push latest + docker tag $REPO_HOST/$REPO_PATH:$TAG $REPO_HOST/$REPO_PATH:latest + docker push $REPO_HOST/$REPO_PATH:latest + + # Remove the local image to save storage + docker rmi $REPO_HOST/$REPO_PATH:$TAG + docker rmi $REPO_HOST/$REPO_PATH:latest \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6eaf3c6b..2bdcaf95 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,49 +4,48 @@ on: [push, pull_request] jobs: test: - - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 strategy: max-parallel: 16 matrix: - python-version: [3.6, 3.7, 3.8, 3.9] + python-version: ["3.7", "3.8", "3.9"] steps: - - name: Checkout ZeroNet - uses: actions/checkout@v2 - with: - submodules: 'true' + - name: Checkout ZeroNet + uses: actions/checkout@v2 + with: + submodules: "true" - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python-version }} - - name: Prepare for installation - run: | - python3 -m pip install setuptools - python3 -m pip install --upgrade pip wheel - python3 -m pip install --upgrade codecov coveralls flake8 mock pytest==4.6.3 pytest-cov selenium + - name: Prepare for installation + run: | + python3 -m pip install setuptools + python3 -m pip install --upgrade pip wheel + python3 -m pip install --upgrade codecov coveralls flake8 mock pytest==4.6.3 pytest-cov selenium - - name: Install - run: | - python3 -m pip install --upgrade -r requirements.txt - python3 -m pip list + - name: Install + run: | + python3 -m pip install --upgrade -r requirements.txt + python3 -m pip list - - name: Prepare for tests - run: | - openssl version -a - echo 0 | sudo tee /proc/sys/net/ipv6/conf/all/disable_ipv6 + - name: Prepare for tests + run: | + openssl version -a + echo 0 | sudo tee /proc/sys/net/ipv6/conf/all/disable_ipv6 - - name: Test - run: | - catchsegv python3 -m pytest src/Test --cov=src --cov-config src/Test/coverage.ini - export ZERONET_LOG_DIR="log/CryptMessage"; catchsegv python3 -m pytest -x plugins/CryptMessage/Test - export ZERONET_LOG_DIR="log/Bigfile"; catchsegv python3 -m pytest -x plugins/Bigfile/Test - export ZERONET_LOG_DIR="log/AnnounceLocal"; catchsegv python3 -m pytest -x plugins/AnnounceLocal/Test - export ZERONET_LOG_DIR="log/OptionalManager"; catchsegv python3 -m pytest -x plugins/OptionalManager/Test - export ZERONET_LOG_DIR="log/Multiuser"; mv plugins/disabled-Multiuser plugins/Multiuser && catchsegv python -m pytest -x plugins/Multiuser/Test - export ZERONET_LOG_DIR="log/Bootstrapper"; mv plugins/disabled-Bootstrapper plugins/Bootstrapper && catchsegv python -m pytest -x plugins/Bootstrapper/Test - find src -name "*.json" | xargs -n 1 python3 -c "import json, sys; print(sys.argv[1], end=' '); json.load(open(sys.argv[1])); print('[OK]')" - find plugins -name "*.json" | xargs -n 1 python3 -c "import json, sys; print(sys.argv[1], end=' '); json.load(open(sys.argv[1])); print('[OK]')" - flake8 . --count --select=E9,F63,F72,F82 --show-source --statistics --exclude=src/lib/pyaes/ + - name: Test + run: | + catchsegv python3 -m pytest src/Test --cov=src --cov-config src/Test/coverage.ini + export ZERONET_LOG_DIR="log/CryptMessage"; catchsegv python3 -m pytest -x plugins/CryptMessage/Test + export ZERONET_LOG_DIR="log/Bigfile"; catchsegv python3 -m pytest -x plugins/Bigfile/Test + export ZERONET_LOG_DIR="log/AnnounceLocal"; catchsegv python3 -m pytest -x plugins/AnnounceLocal/Test + export ZERONET_LOG_DIR="log/OptionalManager"; catchsegv python3 -m pytest -x plugins/OptionalManager/Test + export ZERONET_LOG_DIR="log/Multiuser"; mv plugins/disabled-Multiuser plugins/Multiuser && catchsegv python -m pytest -x plugins/Multiuser/Test + export ZERONET_LOG_DIR="log/Bootstrapper"; mv plugins/disabled-Bootstrapper plugins/Bootstrapper && catchsegv python -m pytest -x plugins/Bootstrapper/Test + find src -name "*.json" | xargs -n 1 python3 -c "import json, sys; print(sys.argv[1], end=' '); json.load(open(sys.argv[1])); print('[OK]')" + find plugins -name "*.json" | xargs -n 1 python3 -c "import json, sys; print(sys.argv[1], end=' '); json.load(open(sys.argv[1])); print('[OK]')" + flake8 . --count --select=E9,F63,F72,F82 --show-source --statistics --exclude=src/lib/pyaes/ diff --git a/.gitignore b/.gitignore index 38dd3a34..636cd115 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ __pycache__/ # Hidden files .* +!/.forgejo !/.github !/.gitignore !/.travis.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index a4365925..6974d18a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +### ZeroNet 0.9.0 (2023-07-12) Rev4630 + - Fix RDos Issue in Plugins https://github.com/ZeroNetX/ZeroNet-Plugins/pull/9 + - Add trackers to Config.py for failsafety incase missing trackers.txt + - Added Proxy links + - Fix pysha3 dep installation issue + - FileRequest -> Remove Unnecessary check, Fix error wording + - Fix Response when site is missing for `actionAs` + + ### ZeroNet 0.8.5 (2023-02-12) Rev4625 - Fix(https://github.com/ZeroNetX/ZeroNet/pull/202) for SSL cert gen failed on Windows. - default theme-class for missing value in `users.json`. diff --git a/README.md b/README.md index bc22c440..70b79adc 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,24 @@ Decentralized websites using Bitcoin crypto and the BitTorrent network - https:/ #### Docker There is an official image, built from source at: https://hub.docker.com/r/canewsin/zeronet/ +### Online Proxies +Proxies are like seed boxes for sites(i.e ZNX runs on a cloud vps), you can try zeronet experience from proxies. Add your proxy below if you have one. + +#### Official ZNX Proxy : + +https://proxy.zeronet.dev/ + +https://zeronet.dev/ + +#### From Community + +https://0net-preview.com/ + +https://portal.ngnoid.tv/ + +https://zeronet.ipfsscan.io/ + + ### Install from source - `wget https://github.com/ZeroNetX/ZeroNet/releases/latest/download/ZeroNet-src.zip` diff --git a/plugins b/plugins index 412d3703..689d9309 160000 --- a/plugins +++ b/plugins @@ -1 +1 @@ -Subproject commit 412d37030beca51244741e138b5f6d97f8f1a652 +Subproject commit 689d9309f73371f4681191b125ec3f2e14075eeb diff --git a/requirements.txt b/requirements.txt index b3df57ea..538a6dfc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ greenlet==0.4.16; python_version <= "3.6" gevent>=20.9.0; python_version >= "3.7" msgpack>=0.4.4 base58 -merkletools +merkletools @ git+https://github.com/ZeroNetX/pymerkletools.git@dev rsa PySocks>=1.6.8 pyasn1 diff --git a/src/Config.py b/src/Config.py index 96c3813e..a9208d55 100644 --- a/src/Config.py +++ b/src/Config.py @@ -13,8 +13,8 @@ import time class Config(object): def __init__(self, argv): - self.version = "0.8.5" - self.rev = 4625 + self.version = "0.9.0" + self.rev = 4630 self.argv = argv self.action = None self.test_parser = None @@ -81,7 +81,14 @@ class Config(object): def createArguments(self): from Crypt import CryptHash access_key_default = CryptHash.random(24, "base64") # Used to allow restrited plugins when multiuser plugin is enabled - trackers = [] + trackers = [ + "http://open.acgnxtracker.com:80/announce", # DE + "http://tracker.bt4g.com:2095/announce", # Cloudflare + "http://tracker.files.fm:6969/announce", + "http://t.publictracker.xyz:6969/announce", + "https://tracker.lilithraws.cf:443/announce", + "https://tracker.babico.name.tr:443/announce", + ] # Platform specific if sys.platform.startswith("win"): coffeescript = "type %s | tools\\coffee\\coffee.cmd" diff --git a/src/File/FileRequest.py b/src/File/FileRequest.py index afc26cb7..c082c378 100644 --- a/src/File/FileRequest.py +++ b/src/File/FileRequest.py @@ -128,7 +128,7 @@ class FileRequest(object): body = peer.getFile(site.address, inner_path).read() except Exception as err: site.log.debug("Can't download updated file %s: %s" % (inner_path, err)) - self.response({"error": "File invalid update: Can't download updaed file"}) + self.response({"error": "Invalid File update: Failed to download updated file content"}) self.connection.badAction(5) return @@ -165,21 +165,19 @@ class FileRequest(object): site.onFileDone(inner_path) # Trigger filedone - if inner_path.endswith("content.json"): # Download every changed file from peer - peer = site.addPeer(self.connection.ip, self.connection.port, return_peer=True, source="update") # Add or get peer - # On complete publish to other peers - diffs = params.get("diffs", {}) - site.onComplete.once(lambda: site.publish(inner_path=inner_path, diffs=diffs, limit=6), "publish_%s" % inner_path) + # Download every changed file from peer + peer = site.addPeer(self.connection.ip, self.connection.port, return_peer=True, source="update") # Add or get peer + # On complete publish to other peers + diffs = params.get("diffs", {}) + site.onComplete.once(lambda: site.publish(inner_path=inner_path, diffs=diffs, limit=6), "publish_%s" % inner_path) - # Load new content file and download changed files in new thread - def downloader(): - site.downloadContent(inner_path, peer=peer, diffs=params.get("diffs", {})) - del self.server.files_parsing[file_uri] - - gevent.spawn(downloader) - else: + # Load new content file and download changed files in new thread + def downloader(): + site.downloadContent(inner_path, peer=peer, diffs=params.get("diffs", {})) del self.server.files_parsing[file_uri] + gevent.spawn(downloader) + self.response({"ok": "Thanks, file %s updated!" % inner_path}) self.connection.goodAction() diff --git a/src/Ui/UiWebsocket.py b/src/Ui/UiWebsocket.py index 8514aa0c..2f982e1d 100644 --- a/src/Ui/UiWebsocket.py +++ b/src/Ui/UiWebsocket.py @@ -327,7 +327,10 @@ class UiWebsocket(object): def actionAs(self, to, address, cmd, params=[]): if not self.hasSitePermission(address, cmd=cmd): + #TODO! Return this as error ? return self.response(to, "No permission for site %s" % address) + if not self.server.sites.get(address): + return self.response(to, {"error": "Site Does Not Exist: %s" % address}) req_self = copy.copy(self) req_self.site = self.server.sites.get(address) req_self.hasCmdPermission = self.hasCmdPermission # Use the same permissions as current site diff --git a/src/User/User.py b/src/User/User.py index 0f366392..dbcfc56f 100644 --- a/src/User/User.py +++ b/src/User/User.py @@ -12,7 +12,7 @@ from Config import config from util import helper from Debug import Debug -# Fully Implemented in zeronet-rs::src::core::user.rs + @PluginManager.acceptPlugins class User(object): def __init__(self, master_address=None, master_seed=None, data={}): diff --git a/src/User/UserManager.py b/src/User/UserManager.py index bd17179c..067734a6 100644 --- a/src/User/UserManager.py +++ b/src/User/UserManager.py @@ -8,7 +8,7 @@ from .User import User from Plugin import PluginManager from Config import config -# Fully Implemented in zeronet-rs::src::io::utils.rs & zeronet-rs::src::io::user.rs + @PluginManager.acceptPlugins class UserManager(object): def __init__(self):