diff --git a/tests/unit/integrations/gitea/middlewares/signature/test_GiteaSignatureMiddleware.py b/tests/unit/integrations/gitea/middlewares/signature/test_GiteaSignatureMiddleware.py new file mode 100644 index 0000000..b8da923 --- /dev/null +++ b/tests/unit/integrations/gitea/middlewares/signature/test_GiteaSignatureMiddleware.py @@ -0,0 +1,118 @@ +# Copyright 2026 jCloud + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from src.jcloud_deployment_server.integrations.gitea.middlewares.signature import GiteaSignatureMiddleware +from starlette.requests import Request +from fastapi import HTTPException +import pytest +import hashlib +import hmac +import os + +class DummyResponse: + def __init__(self): + self.called = True + +async def call_next(request): + return DummyResponse() + +def make_request(body: bytes, headers = None) -> Request: + scope = { + 'type': 'http', + 'method': 'POST', + 'path': '/webhook/gitea/', + 'headers': [ + (k.lower().encode(), v.encode()) + for k, v in (headers or {}).items() + ] + } + + async def receive(): + return { + 'type': 'http.request', + 'body': body + } + + return Request(scope, receive) + +def make_signature(body: bytes, secret: bytes) -> str: + signature = hmac.new( + secret, + body, + hashlib.sha256 + ).hexdigest() + return f'sha256={signature}' + +@pytest.mark.asyncio +@pytest.mark.parametrize('body,secret,expected_exception', [ + ( + b'{"event":"push"}', + b'\xa1\xd6h\x0c\xe6\xc0\x99\x82yd\x14\xfew\xcc\x8e\xb0\xf9\x8f\xe6yM\xe5\xdd4\xdc\xb5M+\xef\xc8O\x94', + None + ), + ( + b'{"event":"push"}', + b'', + None + ), + ( + b'', + b'\xa1\xd6h\x0c\xe6\xc0\x99\x82yd\x14\xfew\xcc\x8e\xb0\xf9\x8f\xe6yM\xe5\xdd4\xdc\xb5M+\xef\xc8O\x94', + None + ), + ( + b'', + b'', + None + ), + ( + b'', + b'\x42', + None + ), + ( + b'', + b'\x42', + None + ), + ( + b'', + b'\x04\x02', + None + ), + ( + b'', + b'\x04\x02', + None + ), +]) +async def test_GiteaSignatureMiddleware_valid_signature(body, secret, expected_exception): + middleware = GiteaSignatureMiddleware(app = None, secret = secret) + + headers = { + 'X-Gitea-Signature': make_signature(body, secret) + } + + req = make_request( + body, + headers + ) + + if expected_exception is not None: + with pytest.raises(HTTPException): + await middleware.dispatch(req, call_next) + else: + res = await middleware.dispatch(req, call_next) + assert hasattr(res, 'called') + pass \ No newline at end of file