pyrelukko 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyrelukko might be problematic. Click here for more details.

Files changed (39) hide show
  1. pyrelukko-0.3.0/.gitlab-ci.yml +137 -0
  2. {pyrelukko-0.2.0 → pyrelukko-0.3.0}/PKG-INFO +2 -1
  3. pyrelukko-0.3.0/cicd/build-py-rf-image.sh +48 -0
  4. pyrelukko-0.3.0/cicd/run_docs_pages.sh +17 -0
  5. pyrelukko-0.3.0/cicd/run_pylint.sh +24 -0
  6. pyrelukko-0.3.0/cicd/run_pytest.sh +14 -0
  7. pyrelukko-0.3.0/cicd/run_shellcheck.sh +14 -0
  8. pyrelukko-0.3.0/container/Containerfile +5 -0
  9. pyrelukko-0.3.0/container/requirements.txt +3 -0
  10. {pyrelukko-0.2.0 → pyrelukko-0.3.0}/pyproject.toml +23 -1
  11. {pyrelukko-0.2.0 → pyrelukko-0.3.0}/src/pyrelukko/pyrelukko.py +1 -1
  12. pyrelukko-0.2.0/tests/conftest.py → pyrelukko-0.3.0/src/pyrelukko/testcontainers.py +29 -68
  13. {pyrelukko-0.2.0 → pyrelukko-0.3.0}/src/pyrelukko/version.py +1 -1
  14. pyrelukko-0.3.0/tests/cert/README.md +11 -0
  15. pyrelukko-0.3.0/tests/cert/relukko.crt +18 -0
  16. pyrelukko-0.3.0/tests/cert/relukko.csr +16 -0
  17. pyrelukko-0.3.0/tests/cert/relukko.key +28 -0
  18. pyrelukko-0.3.0/tests/cert/rootCA.crt +19 -0
  19. pyrelukko-0.3.0/tests/cert/rootCA.der +0 -0
  20. pyrelukko-0.3.0/tests/cert/rootCA.key +28 -0
  21. pyrelukko-0.3.0/tests/cert/rootCA.srl +1 -0
  22. pyrelukko-0.3.0/tests/conftest.py +70 -0
  23. {pyrelukko-0.2.0 → pyrelukko-0.3.0}/tests/test_relukko.py +4 -4
  24. pyrelukko-0.2.0/.pylintrc.toml +0 -9
  25. pyrelukko-0.2.0/tests/cert/README.md +0 -8
  26. pyrelukko-0.2.0/tests/cert/relukko.crt +0 -21
  27. pyrelukko-0.2.0/tests/cert/relukko.csr +0 -16
  28. pyrelukko-0.2.0/tests/cert/relukko.der +0 -0
  29. pyrelukko-0.2.0/tests/cert/relukko.key +0 -28
  30. pyrelukko-0.2.0/tests/cert/rootCA.crt +0 -21
  31. pyrelukko-0.2.0/tests/cert/rootCA.der +0 -0
  32. pyrelukko-0.2.0/tests/cert/rootCA.key +0 -28
  33. pyrelukko-0.2.0/tests/cert/rootCA.srl +0 -1
  34. {pyrelukko-0.2.0 → pyrelukko-0.3.0}/LICENSE +0 -0
  35. {pyrelukko-0.2.0 → pyrelukko-0.3.0}/README.md +0 -0
  36. {pyrelukko-0.2.0 → pyrelukko-0.3.0}/src/pyrelukko/__init__.py +0 -0
  37. {pyrelukko-0.2.0 → pyrelukko-0.3.0}/src/pyrelukko/retry.py +0 -0
  38. /pyrelukko-0.2.0/tests/cert/47615cfb.0 → /pyrelukko-0.3.0/tests/cert/5d868fca.0 +0 -0
  39. {pyrelukko-0.2.0 → pyrelukko-0.3.0}/tests/initdb.d/20240930160154_init.up.sql +0 -0
@@ -0,0 +1,137 @@
1
+ variables:
2
+ FF_TIMESTAMPS: true
3
+ BUILD_IMAGE:
4
+ description: Used in rules, if "true" and web triggered it builds the image!
5
+ value: "false"
6
+ options:
7
+ - "false"
8
+ - "true"
9
+ IMAGE_NAME: py-rf-image
10
+ IMAGE_TAG:
11
+ description: >-
12
+ The "tag" added to the image name for the test / lint image.
13
+ Remove this when you trigger by hand an image build and want it to use
14
+ the new built image with Git short sha tag (X icon on the right)!
15
+ value: "latest"
16
+ # RUN_DOCS_PUBLISH:
17
+ # description: >-
18
+ # Used in rules, if "true" and web triggered it generates the docs and
19
+ # publishes them!
20
+ # value: "false"
21
+ # options:
22
+ # - "false"
23
+ # - "true"
24
+
25
+ build-py-rf-image:
26
+ stage: build
27
+ image: docker:25
28
+ services:
29
+ - name: docker:25-dind
30
+ alias: docker
31
+ before_script:
32
+ - docker info
33
+ before_script:
34
+ - echo "Login to Gitlab container registry"
35
+ - echo "$CI_REGISTRY_PASSWORD" | docker login --username $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
36
+ script:
37
+ - echo "Build container image..."
38
+ - ./cicd/build-py-rf-image.sh
39
+ - echo "Export IMAGE_TAG var to next stage!"
40
+ - echo "IMAGE_TAG=${CI_COMMIT_SHORT_SHA}" > image_tag.env
41
+ - echo "Build complete."
42
+ artifacts:
43
+ reports:
44
+ dotenv: image_tag.env
45
+ rules:
46
+ - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
47
+ changes:
48
+ - .gitlab-ci.yml
49
+ - cicd/build-py-rf-image.sh
50
+ - container/**/*
51
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
52
+ changes:
53
+ - .gitlab-ci.yml
54
+ - cicd/build-py-rf-image.sh
55
+ - container/**/*
56
+ - if: $CI_PIPELINE_SOURCE == "web" && $BUILD_IMAGE == "true"
57
+ when: always
58
+
59
+ run-pylint:
60
+ stage: test
61
+ image: "${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG}"
62
+ rules:
63
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
64
+ changes:
65
+ - src/**/*.py
66
+ - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
67
+ changes:
68
+ - src/**/*.py
69
+ before_script:
70
+ - echo "Running PyLint."
71
+ script:
72
+ - ./cicd/run_pylint.sh
73
+ artifacts:
74
+ when: always
75
+ expire_in: 2 week
76
+ paths:
77
+ - pylint.out.*
78
+
79
+
80
+ run-pytest:
81
+ stage: test
82
+ image: "${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG}"
83
+ rules:
84
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
85
+ changes:
86
+ - src/**/*.py
87
+ - tests/test_*.py
88
+ - tests/conftest.py
89
+ - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
90
+ changes:
91
+ - src/**/*.py
92
+ - tests/test_*.py
93
+ - tests/conftest.py
94
+ before_script:
95
+ - echo "Running PyTest."
96
+ script:
97
+ - ./cicd/run_pytest.sh
98
+ artifacts:
99
+ when: always
100
+ expire_in: 2 week
101
+ paths:
102
+ - pytest-junit.xml
103
+ reports:
104
+ junit: pytest-junit.xml
105
+
106
+
107
+ run-shellcheck:
108
+ stage: test
109
+ image: "${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG}"
110
+ rules:
111
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
112
+ changes:
113
+ - cicd/*.sh
114
+ - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
115
+ changes:
116
+ - cicd/*.sh
117
+ before_script:
118
+ - echo "Running ShellCheck."
119
+ script:
120
+ - ./cicd/run_shellcheck.sh
121
+
122
+ # pages:
123
+ # stage: deploy
124
+ # image: "${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG}"
125
+ # rules:
126
+ # - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
127
+ # changes:
128
+ # - src/**/*.py
129
+ # - if: $CI_PIPELINE_SOURCE == "web" && $RUN_DOCS_PUBLISH == "true"
130
+ # when: always
131
+ # before_script:
132
+ # - echo "Running Docs generation and publishing..."
133
+ # script:
134
+ # - ./cicd/run_docs_pages.sh
135
+ # artifacts:
136
+ # paths:
137
+ # - public
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyrelukko
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Relukko client.
5
5
  Author-email: Reto Zingg <g.d0b3rm4n@gmail.com>
6
6
  Requires-Python: >=3.12
@@ -11,6 +11,7 @@ Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Topic :: Internet :: WWW/HTTP
12
12
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
13
  Requires-Dist: requests >=2.32.3
14
+ Requires-Dist: websockets >= 13.1
14
15
  Project-URL: Homepage, https://gitlab.com/relukko/pyrelukko
15
16
  Project-URL: Issues, https://gitlab.com/relukko/pyrelukko/-/issues
16
17
 
@@ -0,0 +1,48 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
6
+ REPO_DIR="${SCRIPT_DIR}/.."
7
+ CONTAINER_DIR="${REPO_DIR}/container"
8
+ CONTAINER_CMD="docker"
9
+
10
+ # IMAGE_NAME should normally come from .gitlab-ci.yml file,
11
+ # set default for local usage.
12
+ if [ -z "${IMAGE_NAME+x}" ]; then
13
+ IMAGE_NAME=py-rf-image-local
14
+ fi
15
+
16
+ cd "${CONTAINER_DIR}" || exit
17
+
18
+ ${CONTAINER_CMD} build -t "${IMAGE_NAME}:latest" --file Containerfile .
19
+
20
+ ${CONTAINER_CMD} images
21
+
22
+ if [ -n "${CI_REGISTRY_IMAGE}" ]; then
23
+ # In Gitlab
24
+
25
+ # Tag with Git commit short sha and push
26
+ IMAGE_WITH_GIT_SHA="${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}"
27
+ echo "IMAGE_WITH_GIT_SHA: ${IMAGE_WITH_GIT_SHA}"
28
+
29
+ ${CONTAINER_CMD} tag "${IMAGE_NAME}:latest" "${IMAGE_WITH_GIT_SHA}"
30
+ ${CONTAINER_CMD} push "${IMAGE_WITH_GIT_SHA}"
31
+
32
+ if [ "${CI_COMMIT_BRANCH}" = "${CI_DEFAULT_BRANCH}" ]; then
33
+ # We run in default branch, also tag with latest
34
+ # Tag with "latest" (overwrites last 'latest' in registry) and push
35
+ IMAGE_WITH_LATEST="${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:latest"
36
+
37
+ echo "Tag image with as 'latest': ${IMAGE_WITH_LATEST}"
38
+
39
+ ${CONTAINER_CMD} tag "${IMAGE_NAME}:latest" "${IMAGE_WITH_LATEST}"
40
+ ${CONTAINER_CMD} push "${IMAGE_WITH_LATEST}"
41
+ fi
42
+ else
43
+ echo "Runs locally, no pushing!"
44
+ fi
45
+
46
+ cd -
47
+
48
+ # vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+
3
+ SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
4
+ REPO_DIR="${SCRIPT_DIR}/.."
5
+ PUBLIC_DIR="${REPO_DIR}/public"
6
+
7
+ # Main script execution
8
+ main() {
9
+ mkdir -p "${PUBLIC_DIR}"
10
+ # libdoc --pythonpath ./src Relukko "${PUBLIC_DIR}/index.html"
11
+ echo "Not Implemented yet"
12
+ }
13
+
14
+ # Execute the main function
15
+ main
16
+
17
+ # vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
@@ -0,0 +1,24 @@
1
+ #!/bin/bash
2
+
3
+ SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
4
+ REPO_DIR="${SCRIPT_DIR}/.."
5
+
6
+ # Main script execution
7
+ main() {
8
+ pylint --verbose \
9
+ --rcfile "${REPO_DIR}/pyproject.toml" \
10
+ --output-format=json:pylint.out.json,parseable:pylint.out.txt,text \
11
+ "${REPO_DIR}"
12
+ pylint_exit_code=$?
13
+
14
+ pylint-json2html \
15
+ -o "${REPO_DIR}/pylint.out.html" \
16
+ "${REPO_DIR}/pylint.out.json"
17
+
18
+ return ${pylint_exit_code}
19
+ }
20
+
21
+ # Execute the main function
22
+ main
23
+
24
+ # vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+
3
+ SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
4
+ REPO_DIR="${SCRIPT_DIR}/.."
5
+
6
+ # Main script execution
7
+ main() {
8
+ pytest --junit-xml "${REPO_DIR}/pytest-junit.xml"
9
+ }
10
+
11
+ # Execute the main function
12
+ main
13
+
14
+ # vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+
3
+ SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
4
+ REPO_DIR="${SCRIPT_DIR}/.."
5
+
6
+ # Main script execution
7
+ main() {
8
+ shellcheck "${REPO_DIR}"/cicd/*.sh
9
+ }
10
+
11
+ # Execute the main function
12
+ main
13
+
14
+ # vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
@@ -0,0 +1,5 @@
1
+ FROM python:3.13-alpine
2
+
3
+ RUN apk add --no-cache bash shellcheck
4
+ COPY requirements.txt /opt/requirements.txt
5
+ RUN pip install --no-cache-dir -r /opt/requirements.txt
@@ -0,0 +1,3 @@
1
+ pylint==3.3.1
2
+ pylint-json2html==0.5.0
3
+ pytest==8.3.3
@@ -17,6 +17,7 @@ requires-python = ">=3.12"
17
17
  dynamic = ["version", "description"]
18
18
  dependencies = [
19
19
  "requests >=2.32.3",
20
+ "websockets >= 13.1",
20
21
  ]
21
22
 
22
23
  [tool.flit.sdist]
@@ -36,4 +37,25 @@ testpaths = [
36
37
  ]
37
38
  pythonpath = [
38
39
  "src",
39
- ]
40
+ ]
41
+
42
+ [tool.tox]
43
+ requires = ["tox>=4.23"]
44
+ env_list = ["3.13", "3.12"]
45
+
46
+ [tool.tox.env_run_base]
47
+ description = "Run test under {base_python}"
48
+ commands = [["pytest"]]
49
+ deps = ["httpx", "pytest", "testcontainers"]
50
+ set_env = { VIRTUALENV_DISCOVERY = "pyenv" }
51
+ pass_env = [ "TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "DOCKER_HOST" ]
52
+
53
+ [tool.pylint.main]
54
+ # Files or directories to be skipped. They should be base names, not paths.
55
+ ignore = ["LICENSE", "pyproject.toml", "version.py",
56
+ "README.md", "demo.py", "conftest.py", ".tox"]
57
+
58
+ # Files or directories matching the regular expression patterns are skipped. The
59
+ # regex matches against base names, not paths. The default value ignores Emacs
60
+ # file locks
61
+ ignore-patterns = ["^\\.#", "^test_"]
@@ -151,7 +151,7 @@ class RelukkoClient:
151
151
 
152
152
  def _setup_ws_url(self, ws_url: str) -> Url:
153
153
  url = ws_url.replace("http", "ws", 1)
154
- return parse_url(f"{url}/deletions")
154
+ return parse_url(f"{url}/ws/broadcast")
155
155
 
156
156
  def _setup_base_url(self, base_url: Union[Url, str]) -> Url:
157
157
  if isinstance(base_url, str):
@@ -1,24 +1,31 @@
1
+ # pylint: skip-file
2
+ """
3
+ Testcontainers to be used in PyTests, for a fixture see tests/conftest.py
4
+ (relukko_backend):
5
+
6
+ @pytest.fixture(scope="session")
7
+ def relukko_backend():
8
+ with Network() as rl_net:
9
+ with RelukkoDbContainer(net=rl_net, initdb_dir=INITDB_DIR,
10
+ image="postgres:16", hostname="relukkodb") as _db:
11
+ db_url = "postgresql://relukko:relukko@relukkodb/relukko"
12
+ with RelukkoContainer(rl_net, db_url=db_url) as backend:
13
+ relukko = RelukkoClient(
14
+ base_url=backend.get_api_url(), api_key="somekey")
15
+ yield relukko, backend
16
+ """
1
17
  import socket
2
- import ssl
3
- import threading
4
18
  from pathlib import Path
5
- from typing import List
6
19
 
7
- import pytest
8
20
  from testcontainers.core.network import Network
9
21
  from testcontainers.core.waiting_utils import wait_container_is_ready
10
22
  from testcontainers.generic import ServerContainer
11
23
  from testcontainers.postgres import PostgresContainer
12
24
 
13
- from pyrelukko import RelukkoClient
14
-
15
- SCRIPT_DIR = Path(__file__).parent.absolute()
16
- INITDB_DIR = SCRIPT_DIR / "initdb.d"
17
-
18
25
 
19
26
  class RelukkoContainer(ServerContainer):
20
27
  def __init__(self, net: Network,
21
- image="registry.gitlab.com/relukko/relukko:0.9.0", db_url=None):
28
+ image="registry.gitlab.com/relukko/relukko:0.10.0", db_url=None):
22
29
  self.db_url = db_url
23
30
  self.net = net
24
31
  super(RelukkoContainer, self).__init__(image=image, port=3000)
@@ -39,12 +46,22 @@ class RelukkoContainer(ServerContainer):
39
46
 
40
47
 
41
48
  class RelukkoDbContainer(PostgresContainer):
42
- def __init__(self, net: Network, image: str = "postgres:latest", port: int = 5432, username: str | None = None, password: str | None = None, dbname: str | None = None, driver: str | None = "psycopg2", **kwargs) -> None:
49
+ def __init__(
50
+ self, net: Network,
51
+ initdb_dir: Path,
52
+ image: str = "postgres:latest",
53
+ port: int = 5432,
54
+ username: str | None = None,
55
+ password: str | None = None,
56
+ dbname: str | None = None,
57
+ driver: str | None = "psycopg2",
58
+ **kwargs) -> None:
43
59
  self.net = net
60
+ self.initdb_dir = initdb_dir
44
61
  super().__init__(image, port, username, password, dbname, driver, **kwargs)
45
62
 
46
63
  def _configure(self) -> None:
47
- self.with_volume_mapping(INITDB_DIR, "/docker-entrypoint-initdb.d", "Z")
64
+ self.with_volume_mapping(self.initdb_dir, "/docker-entrypoint-initdb.d", "Z")
48
65
  self.with_env("POSTGRES_USER", "relukko")
49
66
  self.with_env("POSTGRES_PASSWORD", "relukko")
50
67
  self.with_env("POSTGRES_DB", "relukko")
@@ -71,59 +88,3 @@ class RelukkoDbContainer(PostgresContainer):
71
88
  buf = sock.recv(40)
72
89
  if len(buf) == 0 and "SCRAM-SHA" not in buf:
73
90
  raise ConnectionError
74
-
75
-
76
- @pytest.fixture(scope="session")
77
- def relukko_backend():
78
- with Network() as rl_net:
79
- with RelukkoDbContainer(net=rl_net,
80
- image="postgres:16", hostname="relukkodb") as _db:
81
- db_url = "postgresql://relukko:relukko@relukkodb/relukko"
82
- with RelukkoContainer(rl_net, db_url=db_url) as backend:
83
- relukko = RelukkoClient(
84
- base_url=backend.get_api_url(), api_key="somekey")
85
- yield relukko, backend
86
-
87
- @pytest.fixture(scope="function")
88
- def tls_listener():
89
-
90
- certfile = SCRIPT_DIR / "cert" / "relukko.crt"
91
- keyfile = SCRIPT_DIR / "cert" / "relukko.key"
92
-
93
- def run_server(port_info: List, keep_running: threading.Event):
94
- # Create a TCP socket
95
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
96
- sock.bind(("127.0.0.1", 0))
97
- sock.listen(5) # Listen for incoming connections
98
-
99
- _, assigned_port = sock.getsockname()
100
- port_info.append(assigned_port)
101
-
102
- # Wrap the socket with TLS
103
- context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
104
- context.load_cert_chain(certfile=certfile, keyfile=keyfile)
105
- with context.wrap_socket(sock, server_side=True) as ssock:
106
-
107
- ssock.settimeout(1)
108
-
109
- while keep_running.is_set():
110
- try:
111
- client_socket, _ = ssock.accept()
112
- client_socket.sendall(b"Hello, TLS Client!")
113
- client_socket.close()
114
- except Exception as _:
115
- continue
116
-
117
- port_info = []
118
- keep_running = threading.Event()
119
- keep_running.set()
120
- thread = threading.Thread(target=run_server, args=(port_info, keep_running))
121
- thread.start()
122
-
123
- while not port_info:
124
- pass
125
-
126
- yield thread, port_info[0]
127
-
128
- keep_running.clear()
129
- thread.join()
@@ -1,2 +1,2 @@
1
1
  # pylint: disable=all
2
- __version__ = "0.2.0"
2
+ __version__ = "0.3.0"
@@ -0,0 +1,11 @@
1
+ # How To
2
+ ```
3
+ openssl req -subj '/CN=Relukko CA' -x509 -sha256 -days 7300 -noenc -newkey rsa:2048 -keyout rootCA.key -out rootCA.crt -addext keyUsage=critical,cRLSign,digitalSignature,keyCertSign
4
+
5
+ ln -s rootCA.crt "$(openssl x509 -hash -noout -in rootCA.crt).0"
6
+
7
+ openssl req -subj '/CN=relukko' -newkey rsa:2048 -noenc -keyout relukko.key -out relukko.csr -addext keyUsage=critical,digitalSignature,keyEncipherment,keyAgreement -addext extendedKeyUsage=critical,serverAuth
8
+
9
+ openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in relukko.csr -out relukko.crt -days 7299 -CAcreateserial
10
+ openssl x509 -inform PEM -in rootCA.crt -outform DER -out rootCA.der
11
+ ```
@@ -0,0 +1,18 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIC9zCCAd+gAwIBAgIUXFQN+AOO7KFdiVNVFman8BLkRfkwDQYJKoZIhvcNAQEL
3
+ BQAwFTETMBEGA1UEAwwKUmVsdWtrbyBDQTAeFw0yNDExMTYyMTM5MTNaFw00NDEx
4
+ MTAyMTM5MTNaMBIxEDAOBgNVBAMMB3JlbHVra28wggEiMA0GCSqGSIb3DQEBAQUA
5
+ A4IBDwAwggEKAoIBAQCljry3blOWFJRdinzcH4XzRnvKlhhofBhtRsPH+pvjmrHO
6
+ v52rXj1XeHqXaEBevhNiN7lP5eg2UgOrs0KAVXYR2Na9Mxrh8ACX+IqeEJF9BKgO
7
+ 4t2RvItDU3SWxV3dIYMasBhe/iDXDKKZd/jVOiluL9zuxo9ltDagZxc72jWMnvrO
8
+ lvlnZVEtH4n9i+hnx1daWRZG87DjO6d8I8F8nX6NTqJgBlrRm8jlcq2N/G8eHTFq
9
+ OrLY4xk4CF+aVExpJrEGprfhNkbE025tJIbGNM9Xv+W0sI/nhEwJdv4ifEP/b+44
10
+ n+KHrAurOboFYmRcoZ9Vn4C1KuYBvDOpgkwOs1wtAgMBAAGjQjBAMB0GA1UdDgQW
11
+ BBSy6DZz/N1PW1mkQY7HUj3Fz6yZOjAfBgNVHSMEGDAWgBT+sHazfmyczKb0BV6r
12
+ Z1JQ8Sfx9zANBgkqhkiG9w0BAQsFAAOCAQEAL1c1l3Azna1mh86haErurYk3EsiH
13
+ KDGprRubdB5qfpa2GdAkhitp9juKYdKGdw877eOl5z7AMeMWAA8WXQ3z7jkQkUhU
14
+ 9wsZxNyHQajq6Lo9KsRxZiRKZX/fxagcnDem+4xTvzSlJoAT5p/CO5E31odwWkZN
15
+ bg79I36nk87opISXzNAbMBcbQEV5R8l4PzNGs/DcrLzTC66FKxHHzyih4mlBF5mS
16
+ /sMY5l9QNaJHKPK7fKZ5yxohkda7tDwtb5p0bbEUQlMeZIQ8r/go1b7/ppXXM5ei
17
+ mTDcwKgeOBgVujqhvgGXOKtcHVfkrqcID+qgDMxYd7XXE/icGF3zmnHwDQ==
18
+ -----END CERTIFICATE-----
@@ -0,0 +1,16 @@
1
+ -----BEGIN CERTIFICATE REQUEST-----
2
+ MIICkDCCAXgCAQAwEjEQMA4GA1UEAwwHcmVsdWtrbzCCASIwDQYJKoZIhvcNAQEB
3
+ BQADggEPADCCAQoCggEBAKWOvLduU5YUlF2KfNwfhfNGe8qWGGh8GG1Gw8f6m+Oa
4
+ sc6/natePVd4epdoQF6+E2I3uU/l6DZSA6uzQoBVdhHY1r0zGuHwAJf4ip4QkX0E
5
+ qA7i3ZG8i0NTdJbFXd0hgxqwGF7+INcMopl3+NU6KW4v3O7Gj2W0NqBnFzvaNYye
6
+ +s6W+WdlUS0fif2L6GfHV1pZFkbzsOM7p3wjwXydfo1OomAGWtGbyOVyrY38bx4d
7
+ MWo6stjjGTgIX5pUTGkmsQamt+E2RsTTbm0khsY0z1e/5bSwj+eETAl2/iJ8Q/9v
8
+ 7jif4oesC6s5ugViZFyhn1WfgLUq5gG8M6mCTA6zXC0CAwEAAaA5MDcGCSqGSIb3
9
+ DQEJDjEqMCgwDgYDVR0PAQH/BAQDAgOoMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMB
10
+ MA0GCSqGSIb3DQEBCwUAA4IBAQBfEyjmGQtITqSsmoAQXEb11Cm/olsL5w6kEzgr
11
+ /0K8ASvDvW+3yJ3U9OBngvgh6iQCJjYaixb8NtQS7yVWYEqJoaA0Hp1q0QDmRS/l
12
+ MDLe2cILgbLQUKOf1jLtYsLG93Lb74HSGztjIIEoi3Wgrm5LLGc/cd28q8yw5c/j
13
+ s1EntUHeNWCYAUIRvwmt+1UPcc8EBHH2DugGz2verzARdvLWAajL5r9ZIJkkU0kY
14
+ fh5gnmVb6I6RtIXhWcXMUL9nBwzPCyJMd4cC/fueC+HxzLNhGldvVxj3cg7W57vR
15
+ QnbG/qcJYN5WGhoHrWIiI90GufG4jifVvyQeBC/vQcymRlAL
16
+ -----END CERTIFICATE REQUEST-----
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCljry3blOWFJRd
3
+ inzcH4XzRnvKlhhofBhtRsPH+pvjmrHOv52rXj1XeHqXaEBevhNiN7lP5eg2UgOr
4
+ s0KAVXYR2Na9Mxrh8ACX+IqeEJF9BKgO4t2RvItDU3SWxV3dIYMasBhe/iDXDKKZ
5
+ d/jVOiluL9zuxo9ltDagZxc72jWMnvrOlvlnZVEtH4n9i+hnx1daWRZG87DjO6d8
6
+ I8F8nX6NTqJgBlrRm8jlcq2N/G8eHTFqOrLY4xk4CF+aVExpJrEGprfhNkbE025t
7
+ JIbGNM9Xv+W0sI/nhEwJdv4ifEP/b+44n+KHrAurOboFYmRcoZ9Vn4C1KuYBvDOp
8
+ gkwOs1wtAgMBAAECggEAAlGzzikAoqYfc7wywBDXLkXjClhpN2t6zYStTbhlvyQ4
9
+ 9rgdJA9CC9JI+1gVqlrkyB5j0IOPg27i+y1PBblMwF0mf7t+/KiOEl+3R2J2VODZ
10
+ q6Dp110KB8bCdLGg/TqqZld02/D/S98ZY83eezqUZbH/cqVu6rVbaSQdWyeh7Bow
11
+ 0rfnMV2537JpZVXzmVDGhlhKcgKjJFkzdW4Zv34lMSOCAAeByrIJtPEoQrJ7MQOj
12
+ 9WpwYN+JN4YeP1FWXIG3Ah7ivFsCMZN9MEvXWMcEnAqSHhXXyRzJnJh4jBrigfM1
13
+ JeqDWgiMlCLP5Z2CwA8ahTnJZAYBJUfeFiNHBYC1sQKBgQDjoTCIlCr7UyLkxaJr
14
+ +IY65tl0jjWiEEvSZ9E+fqqesAsABGE8Po1ZEA7VZNViFf+4ttuBZLngmm/YVBvV
15
+ Ok+hf1HSDsvNhon7oIIa7cxlYGKH2Lf6tq8ovtt7IXRknInbbxh6+CoMm5Yc1KXp
16
+ XRCApfeBEoQdM2N2TRLUL+pPkQKBgQC6MQ9L3zMEr2yXrkyi2wmqBMMaSHCM5Zuh
17
+ ifQSFjJfkarh2y0KN7I73HR6KJVMVRVSmARi/QgN8tEvaXjCvVN67re4mDiZ5rC+
18
+ uIx903tkuKR4ruC1DE96NtsM1VNh1mUa2ndPULztpqPXhMCPspMltH4KbJHLo/iv
19
+ MaRHu2Ps3QKBgDGluIYxeuZyDYxEJtbRz8UNEKTBV6VPVJpBlnvA+Mm/r8aDLgoL
20
+ wpyIShP0+C16itno2Btysq/wPzC5t5BcNX4N3PSp0X20OGgva/EfqJL74MGsXQRL
21
+ 0AxdBFXoyBAhrFe19WrssY8qaCVFpCIv8Cd/C2qVdUdBLBJjYRXylXJhAoGBAIPX
22
+ z5QTReYwbj3uD5hWcD5zRtBqsUAkKpM1w523GA5ycMWj1P3iOJSI4/XInQfDS+kD
23
+ ej+6GyT9Z0Eid3+2XtGzDmdpatMX9tnmhp1mzn6g/N30P2wUfob1JyGsQXILRebB
24
+ AjEo48+I64XmHBDlC6tsZr/s50SDJMqx5TliKT0FAoGAeqqC57jD2bj8Srs1Xa9p
25
+ JDZdS1DU/HthIngHTlud/rvOs2koVbIKRAHqxoBn2TCii6srFf7nHgLZ4iDOiyHF
26
+ eOb52GaYYKQNiSF77LUV0wdxmwwhm3h6hRYgt52nT1JVHH6rilZ64e2mevPX5H1T
27
+ CVvlmUZTRqXOidoSGMkO3sQ=
28
+ -----END PRIVATE KEY-----
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDGzCCAgOgAwIBAgIURXOBbBP+BSnq15fqso3+0Wkwt2swDQYJKoZIhvcNAQEL
3
+ BQAwFTETMBEGA1UEAwwKUmVsdWtrbyBDQTAeFw0yNDExMTYyMTM4MDVaFw00NDEx
4
+ MTEyMTM4MDVaMBUxEzARBgNVBAMMClJlbHVra28gQ0EwggEiMA0GCSqGSIb3DQEB
5
+ AQUAA4IBDwAwggEKAoIBAQDSDxl9hWmwLjTwJTHTH55HwNFKDMHXjiMmig2SMVCE
6
+ Y9fRYNms46CU+ulGGr8TMqXExb3J1ywE/HB8PBYoPKvAmPBHrquXT03A64fXl30q
7
+ IcnRHsJymxmUQV7yQxyfIXHT57NGUBauRhYSG8enbTNPbwByAdDAK6z0/41mMPbz
8
+ NFSXR89+ZkYf0CfKkvi/lPGdC80rS9LokLvDniVT50ir4CurhzndBP/U82nTMxvr
9
+ +Q2/TQmxbzeHOpa4ZCD2OBAHNXAGgV1qltnhvmbn+zYEK+vt9ZSb6lRUXWBWUvkn
10
+ TRCy3lMHu27q5h8Gzzxvi0Ct2lJ02poZG98QlXoAto+RAgMBAAGjYzBhMB0GA1Ud
11
+ DgQWBBT+sHazfmyczKb0BV6rZ1JQ8Sfx9zAfBgNVHSMEGDAWgBT+sHazfmyczKb0
12
+ BV6rZ1JQ8Sfx9zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkq
13
+ hkiG9w0BAQsFAAOCAQEAASuRdyC8zk+FD3DO8vO3bpxiewqjSjQ0cE/t2XU3floV
14
+ r6Lp1bS+IjpeKIYzTg3+DdIMGub8piCh7JcU5ru1Ef0/xwtmCCUB/rOcYwfa2nHj
15
+ w7sc+njSnmdpISCyUV9Yxsqs+b2eQOMj/D28R5c2vf7QIYQMJivqa44TrMy57mJP
16
+ Tu+Y4stHZnfrnlggScfjn+dKjT58awyI0UVPr80YWZuSIDx26CREP41X8SJ5qRMN
17
+ K6KFXxN/PJhl/Y5axV/k/omRXd1FusUaC8yGk5E4zCs7cvbhG830FVIM19zbVSKg
18
+ SF6Dvx3mEWraHyBls9e+FYQIxB5FEJz9KGZdsOSjcQ==
19
+ -----END CERTIFICATE-----
Binary file
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDSDxl9hWmwLjTw
3
+ JTHTH55HwNFKDMHXjiMmig2SMVCEY9fRYNms46CU+ulGGr8TMqXExb3J1ywE/HB8
4
+ PBYoPKvAmPBHrquXT03A64fXl30qIcnRHsJymxmUQV7yQxyfIXHT57NGUBauRhYS
5
+ G8enbTNPbwByAdDAK6z0/41mMPbzNFSXR89+ZkYf0CfKkvi/lPGdC80rS9LokLvD
6
+ niVT50ir4CurhzndBP/U82nTMxvr+Q2/TQmxbzeHOpa4ZCD2OBAHNXAGgV1qltnh
7
+ vmbn+zYEK+vt9ZSb6lRUXWBWUvknTRCy3lMHu27q5h8Gzzxvi0Ct2lJ02poZG98Q
8
+ lXoAto+RAgMBAAECggEAMnh7TOv5xWGMyah+LLZ7nszm3G5tQr/9lRx1f0tHB9A/
9
+ gijNlFtK8ZDJ7NSvVUsFhl5mp/EBvB71XfxH7JoLQGbe0LJYuy3MRk6xIG1fHvjo
10
+ V00XNlcq0bLVP8s9PMTZ5yrUKdBDatMfKXGwSnuT6QGIL1xdTlcQIvul+0hHhY58
11
+ +QGhB1HJASChg13OjLFwDhjiUqH1rkr8WjFspZZIm+SrwXUZTr6PYkF4E1cBcsWT
12
+ 4PLCYKTZTKKr3D0UVa5ipOkp/ZIgWqRk1SACn84G1/AkmBpgv+0XgZz8kZ0Ju+9W
13
+ sPQV/fxXYpvnM/cvkHBAnvWDp4N3VX648zez7t+f2wKBgQD7guX7G5LdtLB/Crlx
14
+ uyAhkJyvc8Ttt11HCf2T/k6oqhATt9014NlJYQY2pVlyoyEQEb1Pe919ei+UpVVt
15
+ Ahaanw5xveOeGdjc2YJIqQV4mqc/daEXFfyLU+3dCzTKB4AXaIT09If5mna46Ou/
16
+ q1UW96cH/SqLC5Z3CyUhqwIvfwKBgQDVztB2P1KBH45lOT1oP/vPxYklUSokA/g+
17
+ VRw3pB8Wmm86fSxQ1lEvMViVf/tyrc+dpvNS+7quNzc0U/2+vpMcLjBkS9EpxAMy
18
+ hPDwZPnPXHKHnC/ET9WWO+wVaCTienGSVaTDTToeKo71Oesi1etHkLl0aWEMp8vo
19
+ gYGPM+/I7wKBgF0dNhXEPJhWF+3Aw60mcRvcFRYjzymO9DqjqTzMLsTkyTTzojMb
20
+ PnabNBixGK+HU2tGlgbCPdsBjHIEz96eok22Szuy6H0U5qPE5yYNZVgkMX0eCHiq
21
+ jCfs96gZSP7uze5cpLSnf1vaYs/Mc9MvFD5/i1g60zBNJvSFrMaNMC7zAoGBANNp
22
+ y+GQ3aEGNgRLZDgIRJN/DQyURCoWrsnb2KoAJClyjZd1HHPWZ7JVhfVV9qm/yjJm
23
+ WeXtOft4Z6LbhmWtBcPwvDMAcRNuWYcDw0bBYe6zyB/lxanFEzqZh+jm8MntLw32
24
+ l5PycgxQIsnC+omYoyxBo8/DP46HAO6n2Bdk0K6LAoGACP/UfrAg4Hyqi0jJcusl
25
+ Led0R3Fl0dw5i2N9PB++PUajt5LFhXXGHeOQnTlYbeJ/ioJgRS/k6W7MH43zP0me
26
+ wIYrVmazCewXwcIZiRv3ees73OsAVrn/yl17+u4KkVlXi0me8Opljl4/MS8026rE
27
+ iKMsJnco7XH/vaS9MrrrOvE=
28
+ -----END PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ 5C540DF8038EECA15D8953551666A7F012E445F9
@@ -0,0 +1,70 @@
1
+ import socket
2
+ import ssl
3
+ import threading
4
+ from pathlib import Path
5
+ from typing import List
6
+
7
+ import pytest
8
+ from testcontainers.core.network import Network
9
+
10
+ from pyrelukko import RelukkoClient
11
+ from pyrelukko.testcontainers import RelukkoContainer, RelukkoDbContainer
12
+
13
+ SCRIPT_DIR = Path(__file__).parent.absolute()
14
+ INITDB_DIR = SCRIPT_DIR / "initdb.d"
15
+
16
+
17
+ @pytest.fixture(scope="session")
18
+ def relukko_backend():
19
+ with Network() as rl_net:
20
+ with RelukkoDbContainer(net=rl_net, initdb_dir=INITDB_DIR,
21
+ image="postgres:16", hostname="relukkodb") as _db:
22
+ db_url = "postgresql://relukko:relukko@relukkodb/relukko"
23
+ with RelukkoContainer(rl_net, db_url=db_url) as backend:
24
+ relukko = RelukkoClient(
25
+ base_url=backend.get_api_url(), api_key="somekey")
26
+ yield relukko, backend
27
+
28
+ @pytest.fixture(scope="function")
29
+ def tls_listener():
30
+
31
+ certfile = SCRIPT_DIR / "cert" / "relukko.crt"
32
+ keyfile = SCRIPT_DIR / "cert" / "relukko.key"
33
+
34
+ def run_server(port_info: List, keep_running: threading.Event):
35
+ # Create a TCP socket
36
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
37
+ sock.bind(("127.0.0.1", 0))
38
+ sock.listen(5) # Listen for incoming connections
39
+
40
+ _, assigned_port = sock.getsockname()
41
+ port_info.append(assigned_port)
42
+
43
+ # Wrap the socket with TLS
44
+ context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
45
+ context.load_cert_chain(certfile=certfile, keyfile=keyfile)
46
+ with context.wrap_socket(sock, server_side=True) as ssock:
47
+
48
+ ssock.settimeout(1)
49
+
50
+ while keep_running.is_set():
51
+ try:
52
+ client_socket, _ = ssock.accept()
53
+ client_socket.sendall(b"Hello, TLS Client!")
54
+ client_socket.close()
55
+ except Exception as _:
56
+ continue
57
+
58
+ port_info = []
59
+ keep_running = threading.Event()
60
+ keep_running.set()
61
+ thread = threading.Thread(target=run_server, args=(port_info, keep_running))
62
+ thread.start()
63
+
64
+ while not port_info:
65
+ pass
66
+
67
+ yield thread, port_info[0]
68
+
69
+ keep_running.clear()
70
+ thread.join()
@@ -32,7 +32,7 @@ def _check_tls(ssl_ctx: ssl.SSLContext, port):
32
32
 
33
33
  def _check_has_serial_no(ssl_ctx: ssl.SSLContext):
34
34
  serial_numbers = [x["serialNumber"] for x in ssl_ctx.get_ca_certs()]
35
- assert "78B4E1E498136651B475BC2D0880A28E4835316C" in serial_numbers
35
+ assert "4573816C13FE0529EAD797EAB28DFED16930B76B" in serial_numbers
36
36
 
37
37
 
38
38
  def test_init_relukko_client():
@@ -152,7 +152,7 @@ def test_reconfigure_relukko_client():
152
152
  "https://relukko", api_key="secret-key")
153
153
 
154
154
  assert relukko.base_url == parse_url("https://relukko")
155
- assert relukko.ws_url == parse_url("wss://relukko/deletions")
155
+ assert relukko.ws_url == parse_url("wss://relukko/ws/broadcast")
156
156
  assert relukko.session.headers['X-api-Key'] == "secret-key"
157
157
 
158
158
  default_ctx = ssl.create_default_context()
@@ -191,7 +191,7 @@ def test_reconfigure_relukko_client_extended():
191
191
  assert relukko.session.trust_env == False
192
192
  assert relukko.session.cookies == cookies
193
193
  assert relukko.base_url == parse_url("https://relukko")
194
- assert relukko.ws_url == parse_url("wss://relukko/deletions")
194
+ assert relukko.ws_url == parse_url("wss://relukko/ws/broadcast")
195
195
  assert relukko.session.headers['X-api-Key'] == "my-API-key"
196
196
  http_adapter: HTTPAdapter = relukko.session.adapters.get("http://")
197
197
  assert http_adapter.max_retries.total == 100
@@ -233,7 +233,7 @@ def test_init_relukko_client_extented():
233
233
  assert relukko.session.trust_env == False
234
234
  assert relukko.session.cookies == cookies
235
235
  assert relukko.base_url == parse_url("http://relukko")
236
- assert relukko.ws_url == parse_url("ws://relukko/deletions")
236
+ assert relukko.ws_url == parse_url("ws://relukko/ws/broadcast")
237
237
  assert relukko.session.headers['X-api-Key'] == "my-API-key"
238
238
  assert relukko.ssl_ctx is None
239
239
  http_adapter: HTTPAdapter = relukko.session.adapters.get("http://")
@@ -1,9 +0,0 @@
1
- [tool.pylint.main]
2
- # Files or directories to be skipped. They should be base names, not paths.
3
- ignore = ["LICENSE", "pyproject.toml", "version.py",
4
- "README.md", "demo.py", "conftest.py"]
5
-
6
- # Files or directories matching the regular expression patterns are skipped. The
7
- # regex matches against base names, not paths. The default value ignores Emacs
8
- # file locks
9
- ignore-patterns = ["^\\.#", "^test_"]
@@ -1,8 +0,0 @@
1
- # How To
2
- ```
3
- openssl req -x509 -sha256 -days 7300 -noenc -newkey rsa:2048 -keyout rootCA.key -out rootCA.crt
4
- ln -s rootCA.crt "$(openssl x509 -hash -noout -in rootCA.crt)"
5
- openssl req -newkey rsa:2048 -noenc -keyout relukko.key -out relukko.csr
6
- openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in relukko.csr -out relukko.crt -days 7299 -CAcreateserial
7
- openssl x509 -inform PEM -in rootCA.crt -outform DER -out rootCA.der
8
- ```
@@ -1,21 +0,0 @@
1
- -----BEGIN CERTIFICATE-----
2
- MIIDeDCCAmCgAwIBAgIUIG2mO1IxfM3wqiLLFCO+6ubGdHswDQYJKoZIhvcNAQEL
3
- BQAwVDELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
4
- CgwTRGVmYXVsdCBDb21wYW55IEx0ZDEQMA4GA1UEAwwHUmVsdWtrbzAeFw0yNDEx
5
- MTMxNTQxNTdaFw00NDExMDcxNTQxNTdaMFQxCzAJBgNVBAYTAlhYMRUwEwYDVQQH
6
- DAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQxEDAO
7
- BgNVBAMMB3JlbHVra28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCr
8
- 89++zNQs+MG5opoCTWq/QxAJsr9Uul598XoQFXn1N/d/JOeSosy8BNvb1RXsr5sp
9
- sNJbJEun6OPFtUoVczUtivS99XNchWPjEQ18w22aiLcwl/uOrdfxWj04yEfKmejN
10
- ZXFrShhAWRGfc3fi2hD0Y5mtbS7T5iqaYzm4U5UDVFizVPnSgPFXMAiat/VQGvBF
11
- cv5IpBjXOJGkLZTzmFlW61T6m+MJGXF59CLC6vL6QJCqQpSUWG9UM00R8L2pQ1b8
12
- HLKYUuJ+vp4WVYwYyz769BNG4OG3IkdqIHKDFWBXFVmKaUkX9aAul4BOitKy4XFc
13
- 8eu653lbkVnRHb01RaP7AgMBAAGjQjBAMB0GA1UdDgQWBBSEFybZBM4O7khSofZl
14
- 0oAT+CSXEjAfBgNVHSMEGDAWgBRAo64Da82emF0q53wCdj4wbFTmMDANBgkqhkiG
15
- 9w0BAQsFAAOCAQEAs+zaKt8VqLoVT0OT24Oxyzc+/A0h4BYq3kYD11BaUJ6oKqQu
16
- 57FRKi0ZWxNSNCbzrwi6W+qNgIXtvSHWk4+BKxzqDVG6LCIuNn4bbvlQMGuTWctY
17
- ndArPxdKvN9AXeCvam+5XKcA5OJY/naoho7fSoGh2Zgkq9HS7DlKxfBW2GEY0mp8
18
- jeuxvBvh4xw/YuESVFbKedglaoNFf+aP44zL47Wn9QJcLqByGpTV472j238ObUFi
19
- k47o+v4Qt7nkJDOcx7ic//uLTcb/1rv1SppYpKr3YJ5fLspzMMPpTQbkt2H8hLiZ
20
- +1jj5GIoDgLi+/uxBgYQs78jEOIKkWO6EjwGUw==
21
- -----END CERTIFICATE-----
@@ -1,16 +0,0 @@
1
- -----BEGIN CERTIFICATE REQUEST-----
2
- MIICmTCCAYECAQAwVDELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0
3
- eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDEQMA4GA1UEAwwHcmVsdWtr
4
- bzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKvz377M1Cz4wbmimgJN
5
- ar9DEAmyv1S6Xn3xehAVefU3938k55KizLwE29vVFeyvmymw0lskS6fo48W1ShVz
6
- NS2K9L31c1yFY+MRDXzDbZqItzCX+46t1/FaPTjIR8qZ6M1lcWtKGEBZEZ9zd+La
7
- EPRjma1tLtPmKppjObhTlQNUWLNU+dKA8VcwCJq39VAa8EVy/kikGNc4kaQtlPOY
8
- WVbrVPqb4wkZcXn0IsLq8vpAkKpClJRYb1QzTRHwvalDVvwcsphS4n6+nhZVjBjL
9
- Pvr0E0bg4bciR2ogcoMVYFcVWYppSRf1oC6XgE6K0rLhcVzx67rneVuRWdEdvTVF
10
- o/sCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQCHkmw8bBBI9pOrlCrJ2u3sGdlx
11
- 3ZbW/+kGdsQ8Odb/pIHkLLKpu5yNLEey/U4EZyWSNewYDUKfS2FIyMN2c38QAex6
12
- 1Y9qPK74RzUB68ki7XKtp+GAGqVb0axxRe0IuBwc9d5jl6zjltcpdutAIIgXcJgg
13
- 8QPnfpz7Skhjjm/duTVp0rurWsPztQdDpkrcY3c49vuTLA5uKwfa//cPAOmVGwqq
14
- TMICj+0M2S+bgg9Ksph1IsDxxuIm1aa2EFnF5XRbJn9aOSdyfBkKoZz9ttgu1hP4
15
- +hPe8S3ekUyJiZAglSI1qJOkpyw14EDIhwJvE9FG5eN/mU8wS1/GU+vhZWKN
16
- -----END CERTIFICATE REQUEST-----
Binary file
@@ -1,28 +0,0 @@
1
- -----BEGIN PRIVATE KEY-----
2
- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCr89++zNQs+MG5
3
- opoCTWq/QxAJsr9Uul598XoQFXn1N/d/JOeSosy8BNvb1RXsr5spsNJbJEun6OPF
4
- tUoVczUtivS99XNchWPjEQ18w22aiLcwl/uOrdfxWj04yEfKmejNZXFrShhAWRGf
5
- c3fi2hD0Y5mtbS7T5iqaYzm4U5UDVFizVPnSgPFXMAiat/VQGvBFcv5IpBjXOJGk
6
- LZTzmFlW61T6m+MJGXF59CLC6vL6QJCqQpSUWG9UM00R8L2pQ1b8HLKYUuJ+vp4W
7
- VYwYyz769BNG4OG3IkdqIHKDFWBXFVmKaUkX9aAul4BOitKy4XFc8eu653lbkVnR
8
- Hb01RaP7AgMBAAECggEAF22KShjmkwavf7HfnDmyYMMWhSO//XTJBA1/DSrylg5d
9
- NQsGVsxslZ9vLyP4sT9PJjPWbUmO2fPuo1TVy6y0jZ3K8Qi8rNnrEphpBzB/Qe38
10
- +5dxfu6WUebIGZucFca42SdITTm9VSMYNhU0O98XLp0AEV4jYlvlPmoPhrAzSM50
11
- lEIuriNhqHuqZhXN0jPYI1jZDS5JVi2PlbgyO1125BBMsCMLfhW+wcme/Y/VAySc
12
- pNkvK3aHeWJUXEeVKuNfn5878PqeD6ZPjl9Hyq3lj6yOauIO/PCdIwm+2qjzrYsy
13
- IBhjFFEoMGofgz+KV7olZu9by38ZzhW7nZGGe+zbgQKBgQDmFyzzxz3/BF7FKTXL
14
- v6uVNkGpMGH8EQE1H+YJXTiSaqf/3ZrsXyBsbA6YBanKBXcY/F0PhQ7e/rjtqaGU
15
- OtekNTHSgosdbJgVX88EjfIa4/rbZPUsX6qRJBuDVOCcCZC1PyFBT2ehKYlIPHS0
16
- klbXo57pYzgDnzrYPr6UWbCZewKBgQC/UMGNvqJXszYZe3hjd9Ek9oSJMThfpfXn
17
- opNhCNHKZ8+xqry602TqIwyStYc7elB57R547ZR4kttT8iM1E7ZOoLRPP0r/FjOS
18
- scpCAk5ouVG9RZaUvTIbvzdEifEOt1Vf0RgIG3Y4DBqtotNoymqyT5wzuxyJQm1E
19
- 683UVIbXgQKBgQCLPJ0UTI7kwtVCxIRsbum7WuDzLHcvHW84obwIEKSKXgaaHJWC
20
- 0rIBSoauUkcEHLiMozMBkEiGg2iPUaaY197k3NfwhtT+kleaH6dcHzXSNgH5QCfp
21
- mV7ThCEuIW/mnRc3xyMtrYqNiWAtGYCaQTBSQA6LN2KPNo1ajOWxSnFG/wKBgQC2
22
- 9rBksq/nV4ihjidwWSI3S1stKVlUgA9QW3a/EgQwol9K9pJPyeN019gqZljSVQOp
23
- 10+RLwUS2r/O5H8vP47WW3KVZ1593emsnUNlJXd/R9wYOvjrfpTxXEmqzpEvFb4c
24
- SIfHGRxSNaE99b5hNVQc+23TO1rrGhAOHcVXDw92AQKBgQDCMEcIcwHx+ahVZbEb
25
- bAyWLwYxQFRStmYKbYBtEMFW39atRmc0wdAG0my/0cUyHUIfWbHvP5oTfyAthV9G
26
- 8G0qBk5fPhh6hfNRFMb2j1AqnZ3CadoBZq2HelTTUqt4UgU9Y4iDco+4ew34Uw76
27
- 2ki1bKXiJKkJYlk14AMrzckDUQ==
28
- -----END PRIVATE KEY-----
@@ -1,21 +0,0 @@
1
- -----BEGIN CERTIFICATE-----
2
- MIIDiTCCAnGgAwIBAgIUeLTh5JgTZlG0dbwtCICijkg1MWwwDQYJKoZIhvcNAQEL
3
- BQAwVDELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
4
- CgwTRGVmYXVsdCBDb21wYW55IEx0ZDEQMA4GA1UEAwwHUmVsdWtrbzAeFw0yNDEx
5
- MTMxNTM3MDBaFw00NDExMDgxNTM3MDBaMFQxCzAJBgNVBAYTAlhYMRUwEwYDVQQH
6
- DAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQxEDAO
7
- BgNVBAMMB1JlbHVra28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD4
8
- PWQPjCCXOvZYUDpYhZHR4Nw0ErkZEZWtPMyoBnyGkYwqK1SrHCcIYQL8C22dN1rn
9
- VdFvCVH13fQHz1SJ/v3jkS+9IiOUDenXpZP/G0pprTbLGh33aaQU53EqvO1T2CAA
10
- zIAVdme0cihOB+KL2A5bDzP9fu+c0ddn+N++ZgcqBHMYmZKIGJv5QZ+i+/1xrGqQ
11
- /znwV7RuBGms8fxA3x4Y4ELUzIHMpbXbQn95qC9u7ee4odQ5KjR1M0oocPKOYBGa
12
- /Dqnhd3Wx0lHR3No8HgC4TBfxruhs+NZtRyInOTFr99TWbBx+zrDvxecM/5j/AnH
13
- WHka8xMQSxJUeoXtlFT/AgMBAAGjUzBRMB0GA1UdDgQWBBRAo64Da82emF0q53wC
14
- dj4wbFTmMDAfBgNVHSMEGDAWgBRAo64Da82emF0q53wCdj4wbFTmMDAPBgNVHRMB
15
- Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQACdVeJ/CnXpY4t568bQRxIr+t3
16
- IqeIqJVg1nt6OaB/EJPJil/lvJD8bjO5W5uXAnbkv26i0Q89KFZH3xKFHRmL/zR+
17
- 0YPcbi3LmQ+NY6LtH1GtBlRiobROfSp8/GxTrGxqMGHHxBdY+v8lPiK1LHTE99ik
18
- cl8qF+DQMGeliPQcg9rLgXagymEc9oS3OgxjL7Al4/P8bLkdC/hxk+cEUFCXUX4v
19
- z/PAFnHwEeJPiiNYG+hpQQRloVncynEwhBr/pGGMdLGaFBje41kn9Ss2anc+YaiW
20
- DyoDLuQkCcRrUvc2dCGMZs0KaCv8i61QWGNy8suGq6nrXW9A57JhS7ak8xg9
21
- -----END CERTIFICATE-----
Binary file
@@ -1,28 +0,0 @@
1
- -----BEGIN PRIVATE KEY-----
2
- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD4PWQPjCCXOvZY
3
- UDpYhZHR4Nw0ErkZEZWtPMyoBnyGkYwqK1SrHCcIYQL8C22dN1rnVdFvCVH13fQH
4
- z1SJ/v3jkS+9IiOUDenXpZP/G0pprTbLGh33aaQU53EqvO1T2CAAzIAVdme0cihO
5
- B+KL2A5bDzP9fu+c0ddn+N++ZgcqBHMYmZKIGJv5QZ+i+/1xrGqQ/znwV7RuBGms
6
- 8fxA3x4Y4ELUzIHMpbXbQn95qC9u7ee4odQ5KjR1M0oocPKOYBGa/Dqnhd3Wx0lH
7
- R3No8HgC4TBfxruhs+NZtRyInOTFr99TWbBx+zrDvxecM/5j/AnHWHka8xMQSxJU
8
- eoXtlFT/AgMBAAECggEAeQhprIDsdP/dE4MOZ5G8XsHNa6BDWlsuCLivqi77cRsu
9
- 5XKaBhGkYFv4eg5SZAiUzF0Vz5cSPJf6vwISHHRUsqtbxNIL2ciM3sVO6t+SAQNg
10
- x1cVDEgYJc8QaL+T0UD7nZgXzR8dgif0ydLjXL67hR9dAHhu+J2BcqKv6KPTU2LB
11
- KWbCcLkY4PdCGwSNuvyPokc3Fo8U40Lm8tcWQ6sFV/+bv6+ShWhsb5Dx7sfVoijf
12
- YikzFc7sEHb//nH2+C/FoCqneDPYl8lVH9zKYis4xWcA68bNwyfWpaQLXo32DKYq
13
- rZxnwnawtU5b+t+TVp1DcCjOM3vaodeKI3Gqq5SjBQKBgQD/Sy33WOK+qelkvJxb
14
- IcyP3U/ijNpWP3UidYGmmpTBP5UdaXyObX1G4nmfQjDad080jPpP/r350Tr0Xi2s
15
- 6wZBw0HoTZrZw5MQQKRQyh0Hg5VHHoHbD97UuLGGZ+Yc/hSWWfuDQHeV5Ami+VXD
16
- TCYZGhtsjY9lUfUWYcsdcOA1fQKBgQD47TcVSC+3/8zKd2AAJeYrpx6wL/5X/4Zn
17
- U0VeBxfF6MjQlu3avnwi6MxjkuB4KJAgWVHvJspJaS8ilIJN5qBsivphtfD0RV+d
18
- UW9DCzoDUlU/AmNMD+stylgziSWoG9rzcY7P71izRE1tGGsgOXvZS5xUHzqWBwg6
19
- MtYB4EQNKwKBgQCTUBVpKmBE9xTXbUKoD5vT1Df5mZ+PrzRvOvEiawa1cHQiMbGP
20
- Gjz0/1CBBpfcKIaK42K5cFy9X++t/P5MTp4gqoRIgSd+yyz8buCiQc54fIRSMpdq
21
- CgFiLGU8Eo4lYrQMgkXw2e1nj9vDsC698B331CnI/PKm26EaVjn3dh/anQKBgGxB
22
- FWRu+TmmyBQA6EIIOVogmqr6pDz2xienQhKLOR57huGX0acAkhHIdiKTnIUE9vDq
23
- h0Re9TgJw1LhjO1976RkqFDYBArnJJbQ9HcOqdMJ+kKlsjNA9QD773GyIitCueyH
24
- JRluuH91o8pfBS+FcEPmqvy2fA8EzeIpe4JjWpTzAoGAQHoipuzDbhb02XMqioc+
25
- UCsa6erj3kGrBUiFcvNutTG+oVq3qXOebOc9bCZcGHwsm0fgX5zk1XgY+IRfCWJY
26
- X14DQfLMBi/vObDXH9BaoVvc50EPSBW0V5k2aXavJ6XelbBXSI33bzGb+5wAltI/
27
- CFKf5ePEAi3jE69yYnTwbdc=
28
- -----END PRIVATE KEY-----
@@ -1 +0,0 @@
1
- 206DA63B52317CCDF0AA22CB1423BEEAE6C6747B
File without changes
File without changes