Skip to content

Commit 0170855

Browse files
ISSUE #403
1 parent c8dd6a2 commit 0170855

File tree

1 file changed

+80
-0
lines changed
  • packages/plugins/minos-discovery-kong

1 file changed

+80
-0
lines changed

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

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@ Example:
7878
async def foo(self, request: Request) -> Response:
7979
...
8080
```
81+
## Route path
82+
It is important to know that it is best to define routes with a regular expression when it is an id, uuid or similar. This is to avoid collisions with similar routes.
83+
Instead of using:
84+
```python
85+
@enroute.rest.command("/users/{uuid}", "POST")
86+
```
87+
Use:
88+
```python
89+
import re
90+
UUID_REGEX = re.compile(r"\w{8}-\w{4}-\w{4}-\w{4}-\w{12}")
91+
@enroute.rest.command(f"/users/{{uuid:{UUID_REGEX.pattern}}}", "POST")
92+
```
8193

8294
## Authentication
8395

@@ -118,6 +130,74 @@ discovery:
118130
...
119131
```
120132

133+
### JWT Token creation & refresh
134+
Example on how to create and refresh token. You need to store in database or similar the secret and key returned form kong in order to refresh existing token.
135+
```python
136+
from minos.common import (
137+
UUID_REGEX,
138+
NotProvidedException,
139+
Config,
140+
Inject,
141+
)
142+
from minos.cqrs import (
143+
CommandService,
144+
)
145+
from minos.networks import (
146+
Request,
147+
Response,
148+
enroute,
149+
)
150+
151+
from ..aggregates import (
152+
User,
153+
)
154+
from minos.plugins.kong import KongClient
155+
156+
class UserCommandService(CommandService):
157+
"""UserCommandService class."""
158+
159+
def __init__(self, *args, **kwargs):
160+
super().__init__(*args, **kwargs)
161+
self.kong = self._get_kong_client()
162+
163+
@staticmethod
164+
@Inject()
165+
def _get_kong_client(config: Config) -> KongClient:
166+
"""Get the service name."""
167+
if config is None:
168+
raise NotProvidedException("The config object must be provided.")
169+
return KongClient.from_config(config)
170+
171+
@enroute.rest.command(f"/users/{{uuid:{UUID_REGEX.pattern}}}/jwt", "POST", authenticated=True,
172+
authorized_groups=["admin"], regex_priority=3)
173+
@enroute.broker.command("GetUserJWT")
174+
async def create_user_jwt(self, request: Request) -> Response:
175+
params = await request.params()
176+
uuid = params["uuid"]
177+
user = await User.get(uuid)
178+
179+
if user.uuid == request.user:
180+
token = await self.add_jwt_to_consumer(request.headers.get("X-Consumer-ID"))
181+
return Response({"token": token})
182+
else:
183+
return Response(status=404)
184+
185+
async def add_jwt_to_consumer(self, consumer: str):
186+
resp = await self.kong.add_jwt_to_consumer(consumer=consumer)
187+
res = resp.json()
188+
self.key = res['key']
189+
self.secret = res['secret']
190+
token = await self.kong.generate_jwt_token(key=self.key, secret=self.secret)
191+
return token
192+
193+
@enroute.rest.command(f"/users/{{uuid:{UUID_REGEX.pattern}}}/refresh-jwt", "POST", authenticated=True,
194+
authorized_groups=["admin"], regex_priority=3)
195+
@enroute.broker.command("RefreshJWT")
196+
async def refresh_jwt(self, request: Request) -> Response:
197+
token = await self.kong.generate_jwt_token(key=self.key, secret=self.secret)
198+
return Response({"token": token})
199+
```
200+
121201
For the route to be authenticated with the method specified above, a parameter called `authenticated` must be passed:
122202
```python
123203
class CategoryCommandService(CommandService):

0 commit comments

Comments
 (0)