Skip to content

Commit c8dd6a2

Browse files
ISSUE #403
1 parent 2d93d7a commit c8dd6a2

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

packages/plugins/minos-discovery-kong/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,22 @@ services:
6363
- NODE_ENV=production
6464
```
6565
66+
## Decorators
67+
Decorator `@enroute` can support next params:
68+
- `path` - route url path.
69+
- `method` - HTTP method.
70+
- `authenticated` (Optional) - True if route need authentication.
71+
- `authorized_groups` (Optional) - Groups which can access to specified route (they must exist in Kong).
72+
- `regex_priority` (Optional) - A number used to choose which route resolves a given request when several routes match it using regexes simultaneously. When two routes match the path and have the same regex_priority, the older one (lowest created_at) is used. Note that the priority for non-regex routes is different (longer non-regex routes are matched before shorter ones). Defaults to 0.
73+
74+
Example:
75+
```python
76+
@enroute.rest.command(f"/users/{{uuid:{UUID_REGEX.pattern}}}/jwt", "POST", authenticated=True, authorized_groups=["admin"], regex_priority=2)
77+
@enroute.broker.command("GetUserJWT")
78+
async def foo(self, request: Request) -> Response:
79+
...
80+
```
81+
6682
## Authentication
6783

6884
Modify `config.yml` file. Add new middleware and modify discovery section:
@@ -85,6 +101,23 @@ Currently, there are 2 possible types of authentication:
85101
- `basic-auth`
86102
- `jwt`
87103

104+
For jwt auth type you can specify default token expiration. Example:
105+
```yaml
106+
...
107+
middleware:
108+
...
109+
- minos.plugins.kong.middleware
110+
111+
discovery:
112+
connector: minos.networks.DiscoveryConnector
113+
client: minos.plugins.kong.KongDiscoveryClient
114+
host: localhost
115+
auth-type: jwt
116+
token-exp-minutes: 60
117+
port: 8001
118+
...
119+
```
120+
88121
For the route to be authenticated with the method specified above, a parameter called `authenticated` must be passed:
89122
```python
90123
class CategoryCommandService(CommandService):
@@ -222,6 +255,8 @@ class UserCommandService(CommandService):
222255
```
223256

224257
You can get read the official docs [here](https://pantsel.github.io/konga/).
258+
259+
225260
## Documentation
226261

227262
The official API Reference is publicly available at the [GitHub Pages](https://minos-framework.github.io/minos-python).

packages/plugins/minos-discovery-kong/minos/plugins/kong/discovery.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ async def subscribe(
112112
self.route,
113113
["http"],
114114
[endpoint["method"]],
115-
[endpointClass.path_as_str],
115+
[endpointClass.path_as_regex],
116116
content_service["id"],
117117
regex_priority,
118118
False,

packages/plugins/minos-discovery-kong/minos/plugins/kong/utils.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
import re
2+
3+
14
class PathPart:
25
def __init__(self, name: str):
36
self.name = name
47
self.is_generic: bool = True if self.name.startswith("{") and self.name.endswith("}") else False
58

69

710
class Endpoint:
11+
part_path_pattern = r"\{\S+:.+\}"
12+
813
def __init__(self, path: str):
914
self.path: tuple[PathPart] = tuple(PathPart(path_part) for path_part in path.split("/"))
1015

@@ -16,3 +21,18 @@ def path_as_str(self) -> str:
1621
part.name = ".*"
1722
list_parts.append(str(part.name))
1823
return "/".join(list_parts)
24+
25+
@property
26+
def path_as_regex(self) -> str:
27+
list_parts = []
28+
for part in self.path:
29+
if part.is_generic:
30+
if re.match(self.part_path_pattern, part.name):
31+
regex = part.name.split(":")[1]
32+
regex = regex[:-1]
33+
list_parts.append(regex)
34+
else:
35+
list_parts.append(".*")
36+
else:
37+
list_parts.append(part.name)
38+
return "/".join(list_parts)

packages/plugins/minos-discovery-kong/tests/test_kong/test_utils.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,29 @@ def test_path_constructor(self) -> None:
1818
self.assertIsInstance(pathpart, PathPart)
1919
self.assertEqual(pathpart.name, "minos")
2020
self.assertEqual(pathpart.is_generic, False)
21+
22+
def test_path_as_str(self) -> None:
23+
pathpart = Endpoint(r"/user/{uuid:\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}")
24+
self.assertEqual(pathpart.path_as_str, "/user/.*")
25+
26+
def test_path_as_regex(self) -> None:
27+
# pylint: disable=W605
28+
pathpart = Endpoint(r"/user/{uuid:\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}")
29+
self.assertEqual(pathpart.path_as_regex, "/user/\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}")
30+
31+
def test_path_as_regex_simple_parameter(self) -> None:
32+
pathpart = Endpoint("/user/{uuid}")
33+
self.assertEqual(pathpart.path_as_regex, "/user/.*")
34+
35+
def test_path_as_regex_parameter(self) -> None:
36+
pathpart = Endpoint("/user/{:uuid}")
37+
self.assertEqual(pathpart.path_as_regex, "/user/.*")
38+
39+
def test_path_as_regex_multiple_parameter(self) -> None:
40+
pathpart = Endpoint("/user/{:uuid}/{:uuid}")
41+
self.assertEqual(pathpart.path_as_regex, "/user/.*/.*")
42+
43+
def test_path_as_regex_uuid(self) -> None:
44+
# pylint: disable=W605
45+
pathpart = Endpoint(r"/user/{uuid:\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}/test")
46+
self.assertEqual(pathpart.path_as_regex, "/user/\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}/test")

0 commit comments

Comments
 (0)