Skip to content

Commit 5579477

Browse files
committed
[FIX] auth layer
1 parent 4867ce2 commit 5579477

File tree

7 files changed

+107
-76
lines changed

7 files changed

+107
-76
lines changed

backend/ozon/core/OzonRawMiddleware.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
# Copyright INRIM (https://www.inrim.eu)
22
# See LICENSE file for full licensing details.
33

4-
from typing import Optional, Sequence, Union, Any
5-
from fastapi.responses import RedirectResponse, JSONResponse
4+
from typing import Optional, Union, Any
65

76
from starlette.requests import HTTPConnection, Request
87
from starlette.types import Message, Receive, Scope, Send
98
from fastapi import FastAPI
109
from .Ozon import Ozon
11-
from .SessionMain import SessionMain, SessionBase
1210
import logging
1311
import bson
1412

1513
logger = logging.getLogger(__name__)
1614

1715

16+
1817
class OzonRawMiddleware:
1918
def __init__(
20-
self, app: FastAPI, settings, pwd_context: Optional[Any] = None
19+
self, app: FastAPI, settings, pwd_context: Optional[Any] = None
2120
) -> None:
2221
self.app = app
2322
self.pwd_context = pwd_context
@@ -26,7 +25,7 @@ def __init__(
2625

2726
@staticmethod
2827
def get_request_object(
29-
scope, receive, send
28+
scope, receive, send
3029
) -> Union[Request, HTTPConnection]:
3130
# here we instantiate HTTPConnection instead of a Request object
3231
# because only headers are needed so that's sufficient.
@@ -35,7 +34,7 @@ def get_request_object(
3534
return Request(scope, receive, send)
3635

3736
async def __call__(
38-
self, scope: Scope, receive: Receive, send: Send
37+
self, scope: Scope, receive: Receive, send: Send
3938
) -> None:
4039
if scope["type"] not in ("http", "websocket"): # pragma: no cover
4140
await self.app(scope, receive, send)
@@ -62,8 +61,8 @@ async def send_wrapper(message: Message) -> None:
6261
f"object: {request.scope['ozon']} , params: {request.query_params}, headers{request.headers}"
6362
)
6463
# self.session = await self.init_request(request)
65-
66-
if not session or session is None:
64+
logger.info(f'Is public {request.scope["ozon"].auth_service.is_public_endpoint()}')
65+
if not session or session is None and not request.scope["ozon"].auth_service.is_public_endpoint():
6766
response = request.scope["ozon"].auth_service.login_page()
6867
await response(scope, receive, send)
6968
else:

backend/ozon/core/ServiceAuth.py

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,17 @@
11
# Copyright INRIM (https://www.inrim.eu)
22
# See LICENSE file for full licensing details.
3-
import sys
43
import os
5-
from os import listdir
6-
from os.path import isfile, join
7-
from fastapi.responses import RedirectResponse, JSONResponse
8-
import ujson
4+
import uuid
95

10-
# from ozon.settings import get_settings
11-
from .database.mongo_core import *
12-
from collections import OrderedDict
13-
from pathlib import Path
146
from fastapi import Request
15-
from .SessionMain import SessionMain
7+
from fastapi.responses import JSONResponse
8+
9+
from .BaseClass import PluginBase
1610
from .ModelData import ModelData
17-
from .BaseClass import BaseClass, PluginBase
18-
from pydantic import ValidationError
11+
from .SessionMain import SessionMain
12+
# from ozon.settings import get_settings
13+
from .database.mongo_core import *
1914

20-
import logging
21-
import pymongo
22-
import requests
23-
import httpx
24-
import uuid
25-
from cryptography.fernet import Fernet
2615

2716
logger = logging.getLogger(__name__)
2817

@@ -37,13 +26,13 @@ def __init_subclass__(cls, **kwargs):
3726
class ServiceAuthBase(ServiceAuth):
3827
@classmethod
3928
def create(
40-
cls,
41-
settings=None,
42-
public_endpoint="",
43-
parent=None,
44-
request=None,
45-
pwd_context=None,
46-
req_id="",
29+
cls,
30+
settings=None,
31+
public_endpoint="",
32+
parent=None,
33+
request=None,
34+
pwd_context=None,
35+
req_id="",
4736
):
4837
self = ServiceAuthBase()
4938
self.init(
@@ -52,13 +41,13 @@ def create(
5241
return self
5342

5443
def init(
55-
self,
56-
settings=None,
57-
public_endpoint="",
58-
parent=None,
59-
request=None,
60-
pwd_context=None,
61-
req_id="",
44+
self,
45+
settings=None,
46+
public_endpoint="",
47+
parent=None,
48+
request=None,
49+
pwd_context=None,
50+
req_id="",
6251
):
6352
self.session = None
6453
self.app_code = parent.app_code
@@ -155,7 +144,7 @@ async def check_default_token_header(self):
155144
logger.debug(f"ws_request {apitoken}")
156145
self.ws_request = True
157146
self.token = apitoken
158-
logger.info(f" Is WS {self.ws_request} with token {self.token}")
147+
logger.debug(f" Is WS {self.ws_request} with token {self.token}")
159148

160149
async def check_session(self):
161150
logger.info("check_session")
@@ -190,7 +179,7 @@ async def init_session(self):
190179
self.session = await self.session_service.find_session_by_token()
191180
if not self.session and self.is_public_endpoint:
192181
self.session = await self.create_session_public_user()
193-
if self.session.expire_datetime < datetime.now():
182+
if self.session and self.session.expire_datetime < datetime.now():
194183
self.session.active = False
195184
await self.mdata.save_record(self.session)
196185
self.session = None

web-client/appinit.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from core.cache.cache import get_cache
3636

3737
from client_api import client_api
38+
from auth_api import auth_api
3839
from process_api import process_api
3940
from requisition_api import requisition_api
4041
import asyncio
@@ -90,6 +91,7 @@
9091
),
9192
name="static",
9293
)
94+
app.mount("/auth", auth_api)
9395
app.mount("/client", client_api)
9496
app.mount("/process", process_api)
9597
app.mount("/requisition", requisition_api)

web-client/auth_api.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright INRIM (https://www.inrim.eu)
2+
# See LICENSE file for full licensing details.
3+
import logging
4+
from typing import Optional, Union
5+
6+
import ujson
7+
from fastapi import (
8+
FastAPI,
9+
Request,
10+
Header,
11+
)
12+
from fastapi.responses import (
13+
JSONResponse,
14+
)
15+
16+
from core.ExportService import ExportService
17+
from core.Gateway import Gateway
18+
from settings import get_settings, templates
19+
20+
logger = logging.getLogger(__name__)
21+
22+
auth_api = FastAPI(
23+
title=f"{get_settings().module_name} Client",
24+
description=get_settings().description,
25+
version=get_settings().version,
26+
openapi_url="/openapi.json",
27+
docs_url="/docs",
28+
redoc_url="/redoc",
29+
)

web-client/core/ClientMiddleware.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,13 @@ async def __call__(
3838
# await send(message)
3939

4040
await request.scope["interceptor"].before_request(request)
41-
response = await self.call_next(request)
42-
response = await request.scope["interceptor"].before_response(
43-
request, response
44-
)
41+
if request.scope.get("security_next_call"):
42+
response = await request.scope.get("security_next_call")(request)
43+
else:
44+
response = await self.call_next(request)
45+
response = await request.scope["interceptor"].before_response(
46+
request, response
47+
)
4548

4649
await response(scope, receive, send)
4750

web-client/core/Gateway.py

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
# Copyright INRIM (https://www.inrim.eu)
22
# See LICENSE file for full licensing details.
33
import copy
4-
import sys
5-
from typing import Optional
6-
from fastapi import FastAPI, Request, Header, HTTPException, Depends, Form
7-
from fastapi.responses import RedirectResponse, JSONResponse, HTMLResponse
8-
from .ContentService import ContentService
9-
from .main.base.base_class import BaseClass, PluginBase
10-
from .main.base.utils_for_service import requote_uri
11-
from starlette.status import HTTP_302_FOUND, HTTP_303_SEE_OTHER
12-
from fastapi.concurrency import run_in_threadpool
13-
from starlette.datastructures import QueryParams
14-
import httpx
154
import logging
16-
import ujson
175
import re
6+
7+
import httpx
8+
import ujson
189
from core.cache.cache import get_cache
10+
from fastapi import Request
11+
from fastapi.responses import RedirectResponse, JSONResponse, HTMLResponse
12+
from starlette.datastructures import QueryParams
13+
from starlette.status import HTTP_303_SEE_OTHER
14+
15+
from .ContentService import ContentService
16+
from .main.base.base_class import PluginBase
17+
from .main.base.utils_for_service import requote_uri
1918

2019
logger = logging.getLogger(__name__)
2120

@@ -54,7 +53,6 @@ def query_params(cls, url) -> QueryParams:
5453
qstring = url.split("?")[1] if "?" in url else ""
5554
return QueryParams(qstring)
5655

57-
5856
def clean_form(self, form_data):
5957
# logger.info(f"{form_data}")
6058
dat = {}
@@ -106,6 +104,12 @@ def init_headers_and_token(self):
106104
elif self.request.headers.get("apitoken"):
107105
self.token = self.request.headers.get("apitoken")
108106
self.is_api = True
107+
else:
108+
self.headers.update(
109+
{
110+
"authtoken": self.token,
111+
}
112+
)
109113

110114
# TODO move in shibboleth Gateway
111115
if "x-remote-user" not in self.request.headers:
@@ -152,7 +156,7 @@ async def compute_datagrid_rows(self, key, model_name, rec_name=""):
152156
return res
153157

154158
async def compute_datagrid_add_row(
155-
self, key, num_rows, model_name, rec_name="", data={}
159+
self, key, num_rows, model_name, rec_name="", data={}
156160
):
157161
logger.info("compute_datagrid_add_row")
158162
await self.get_session()
@@ -177,7 +181,7 @@ async def before_submit(self, data, is_create=False):
177181
return data.copy()
178182

179183
async def middleware_server_post_action(
180-
self, content_service, submitted_data
184+
self, content_service, submitted_data
181185
) -> dict:
182186
"""
183187
This middleware method is triggered form Gateway.server_post_action method
@@ -206,17 +210,17 @@ async def middleware_server_post_action(
206210

207211
if "rec_name" in submitted_data:
208212
allowed = (
209-
self.name_allowed.match(submitted_data.get("rec_name"))
210-
or False
213+
self.name_allowed.match(submitted_data.get("rec_name"))
214+
or False
211215
)
212216
if not allowed:
213217
logger.error(f"name {submitted_data.get('rec_name')}")
214218

215219
err = {
216220
"status": "error",
217221
"message": f"Errore nel campo name "
218-
f"{submitted_data.get('rec_name')} "
219-
f"caratteri non consentiti",
222+
f"{submitted_data.get('rec_name')} "
223+
f"caratteri non consentiti",
220224
"model": submitted_data.get("data_model"),
221225
"data": {},
222226
}
@@ -332,9 +336,9 @@ async def server_get_action(self, url_action="", modal=False):
332336
url = url_action
333337
server_response = {}
334338
if server_response and (
335-
server_response.get("action")
336-
or server_response.get("content", {}).get("action")
337-
or server_response.get("content", {}).get("reload")
339+
server_response.get("action")
340+
or server_response.get("content", {}).get("action")
341+
or server_response.get("content", {}).get("reload")
338342
):
339343
content = server_response
340344
if "content" in server_response:
@@ -425,7 +429,7 @@ async def get_list_models(self, domain={}, compute_label="title"):
425429
return data
426430

427431
async def get_remote_data_select(
428-
self, url, path_value, header_key, header_value_key
432+
self, url, path_value, header_key, header_value_key
429433
):
430434
"""
431435
name is a model name
@@ -466,7 +470,7 @@ async def get_resource_schema_select(self, type, select):
466470
return data
467471

468472
async def complete_json_response(
469-
self, res, orig_resp=None
473+
self, res, orig_resp=None
470474
) -> JSONResponse:
471475
response = JSONResponse(res)
472476
return self.complete_response(response)
@@ -514,12 +518,14 @@ async def get_remote_object(self, url, headers={}, params={}, cookies={}):
514518

515519
if "token" in params:
516520
cookies = {"authtoken": params.get("token")}
521+
if "cookie" in self.headers:
522+
self.headers.pop("cookie")
517523

518524
if not cookies:
519525
cookies = self.request.cookies.copy()
520526

521527
# logger.info(f" request headers {self.headers}")
522-
logger.debug(f"get_remote_object --> {url}")
528+
logger.debug(f"get_remote_object --> {url} cookies {cookies} self.headers {self.headers}")
523529

524530
async with httpx.AsyncClient(timeout=None) as client:
525531
res = await client.get(
@@ -550,11 +556,14 @@ async def get_remote_object(self, url, headers={}, params={}, cookies={}):
550556
return {}
551557

552558
async def get_remote_request(
553-
self, url, headers={}, params={}, cookies={}, use_app=True
559+
self, url, headers={}, params={}, cookies={}, use_app=True, service_url=False
554560
):
555561
if use_app:
556562
headers = self.headers
557563

564+
if service_url:
565+
url = f"{self.local_settings.service_url}{url}"
566+
558567
logger.info(f"get_remote_request --> {url}")
559568
logger.info(f" request updated headers before {headers}")
560569
async with httpx.AsyncClient(timeout=None) as client:
@@ -575,7 +584,7 @@ async def get_remote_request(
575584
return {"status": "error", "msg": res.status_code}
576585

577586
async def post_remote_object(
578-
self, url, data={}, headers={}, params={}, cookies={}
587+
self, url, data={}, headers={}, params={}, cookies={}
579588
):
580589
logger.debug(url)
581590
if self.local_settings.service_url not in url:
@@ -613,7 +622,7 @@ async def post_remote_object(
613622
return {"status": "error", "msg": f"{url} ERROR {res.status_code}"}
614623

615624
async def post_remote_request(
616-
self, url, data={}, headers={}, params={}, cookies={}, use_app=True
625+
self, url, data={}, headers={}, params={}, cookies={}, use_app=True
617626
):
618627
if use_app:
619628
headers = self.headers.copy()
@@ -638,7 +647,7 @@ async def post_remote_request(
638647
return {}
639648

640649
async def delete_remote_object(
641-
self, url, data={}, headers={}, params={}, cookies={}
650+
self, url, data={}, headers={}, params={}, cookies={}
642651
):
643652
logger.debug(f"delete_remote_object --> {url}")
644653

0 commit comments

Comments
 (0)