Merge remote-tracking branch 'origin/api-v1.5.5' into dev

This commit is contained in:
Taha Yassine Kraiem 2022-04-11 14:47:24 +02:00
commit 5927f66e50
13 changed files with 108 additions and 35 deletions

24
api/auth/auth_project.py Normal file
View file

@ -0,0 +1,24 @@
from fastapi import Request
from starlette import status
from starlette.exceptions import HTTPException
import schemas
from chalicelib.core import projects
from or_dependencies import OR_context
class ProjectAuthorizer:
def __init__(self, project_identifier):
self.project_identifier: str = project_identifier
async def __call__(self, request: Request) -> None:
if len(request.path_params.keys()) == 0 or request.path_params.get(self.project_identifier) is None:
return
current_user: schemas.CurrentContext = await OR_context(request)
project_identifier = request.path_params[self.project_identifier]
if (self.project_identifier == "projectId" \
and projects.get_project(project_id=project_identifier, tenant_id=current_user.tenant_id) is None) \
or (self.project_identifier.lower() == "projectKey" \
and projects.get_internal_project_id(project_key=project_identifier) is None):
print("project not found")
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="project not found.")

View file

@ -13,9 +13,9 @@ def jwt_authorizer(token):
try:
payload = jwt.decode(
token[1],
"",
config("jwt_secret"),
algorithms=config("jwt_algorithm"),
audience=[ f"front:default-foss"]
audience=[f"plugin:{helper.get_stage_name()}", f"front:{helper.get_stage_name()}"]
)
except jwt.ExpiredSignatureError:
print("! JWT Expired signature")
@ -42,7 +42,7 @@ def generate_jwt(id, tenant_id, iat, aud):
payload={
"userId": id,
"tenantId": tenant_id,
"exp": iat // 1000 + config("jwt_exp_delta_seconds",cast=int) + TimeUTC.get_utc_offset() // 1000,
"exp": iat // 1000 + config("jwt_exp_delta_seconds", cast=int) + TimeUTC.get_utc_offset() // 1000,
"iss": config("jwt_issuer"),
"iat": iat // 1000,
"aud": aud

View file

@ -244,7 +244,8 @@ def get_project_key(project_id):
where project_id =%(project_id)s AND deleted_at ISNULL;""",
{"project_id": project_id})
)
return cur.fetchone()["project_key"]
project = cur.fetchone()
return project["project_key"] if project is not None else None
def get_capture_status(project_id):

View file

@ -571,7 +571,6 @@ def auth_exists(user_id, tenant_id, jwt_iat, jwt_aud):
)
@dev.timed
def authenticate(email, password, for_change_password=False, for_plugin=False):
with pg_client.PostgresClient() as cur:
query = cur.mogrify(

View file

@ -2,11 +2,13 @@ from fastapi import APIRouter, Depends
from auth.auth_apikey import APIKeyAuth
from auth.auth_jwt import JWTAuth
from auth.auth_project import ProjectAuthorizer
from or_dependencies import ORRoute
def get_routers() -> (APIRouter, APIRouter, APIRouter):
public_app = APIRouter(route_class=ORRoute)
app = APIRouter(dependencies=[Depends(JWTAuth())], route_class=ORRoute)
app_apikey = APIRouter(dependencies=[Depends(APIKeyAuth())], route_class=ORRoute)
app = APIRouter(dependencies=[Depends(JWTAuth()), Depends(ProjectAuthorizer("projectId"))], route_class=ORRoute)
app_apikey = APIRouter(dependencies=[Depends(APIKeyAuth()), Depends(ProjectAuthorizer("projectKey"))],
route_class=ORRoute)
return public_app, app, app_apikey

1
ee/api/.gitignore vendored
View file

@ -242,6 +242,7 @@ Pipfile
/auth/auth_apikey.py
/auth/auth_jwt.py
/build.sh
/routers/base.py
/routers/core.py
/routers/crons/core_crons.py
/routers/subs/dashboard.py

View file

@ -257,7 +257,8 @@ def get_project_key(project_id):
where project_id =%(project_id)s AND deleted_at ISNULL;""",
{"project_id": project_id})
)
return cur.fetchone()["project_key"]
project = cur.fetchone()
return project["project_key"] if project is not None else None
def get_capture_status(project_id):

View file

@ -632,7 +632,6 @@ def change_jwt_iat(user_id):
return cur.fetchone().get("jwt_iat")
@dev.timed
def authenticate(email, password, for_change_password=False, for_plugin=False):
with pg_client.PostgresClient() as cur:
query = cur.mogrify(

View file

@ -1,14 +0,0 @@
from fastapi import APIRouter, Depends
from auth.auth_apikey import APIKeyAuth
from auth.auth_jwt import JWTAuth
from auth.auth_project import ProjectAuthorizer
from or_dependencies import ORRoute
def get_routers() -> (APIRouter, APIRouter, APIRouter):
public_app = APIRouter(route_class=ORRoute)
app = APIRouter(dependencies=[Depends(JWTAuth()), Depends(ProjectAuthorizer("projectId"))], route_class=ORRoute)
app_apikey = APIRouter(dependencies=[Depends(APIKeyAuth()), Depends(ProjectAuthorizer("projectKey"))],
route_class=ORRoute)
return public_app, app, app_apikey

View file

@ -10,4 +10,5 @@ build.sh
servers/peerjs-server.js
servers/sourcemaps-handler.js
servers/sourcemaps-server.js
#servers/websocket.js
#servers/websocket.js
/utils/dump.js

View file

@ -1,8 +1,9 @@
var sourcemapsReaderServer = require('./servers/sourcemaps-server');
var {peerRouter, peerConnection, peerDisconnect, peerError} = require('./servers/peerjs-server');
var express = require('express');
const dumps = require('./utils/dump');
const sourcemapsReaderServer = require('./servers/sourcemaps-server');
const {peerRouter, peerConnection, peerDisconnect, peerError} = require('./servers/peerjs-server');
const express = require('express');
const {ExpressPeerServer} = require('peer');
var socket;
let socket;
if (process.env.redis === "true") {
console.log("Using Redis");
socket = require("./servers/websocket-cluster");
@ -13,7 +14,7 @@ if (process.env.redis === "true") {
const HOST = '0.0.0.0';
const PORT = 9000;
var app = express();
const app = express();
let debug = process.env.debug === "1" || false;
const request_logger = (identity) => {
@ -50,6 +51,8 @@ peerServer.on('disconnect', peerDisconnect);
peerServer.on('error', peerError);
app.use('/', peerServer);
app.enable('trust proxy');
app.get('/heapdump', dumps.sendHeapSnapshot);
app.get('/heapdump/save', dumps.saveHeapSnapshot);
if (process.env.uws !== "true") {
var wsapp = express();
@ -125,4 +128,5 @@ if (process.env.uws !== "true") {
// process.exit(1);
});
module.exports = {uapp, server};
}
}
console.log(`Heapdump enabled. Send a request to "/heapdump" to download a heapdump,\nor "/heapdump/save" to only generate a heapdump.`);

View file

@ -1,14 +1,15 @@
var sourcemapsReaderServer = require('./servers/sourcemaps-server');
var {peerRouter, peerConnection, peerDisconnect, peerError} = require('./servers/peerjs-server');
var express = require('express');
const dumps = require('./utils/dump');
const sourcemapsReaderServer = require('./servers/sourcemaps-server');
const {peerRouter, peerConnection, peerDisconnect, peerError} = require('./servers/peerjs-server');
const express = require('express');
const {ExpressPeerServer} = require('peer');
const socket = require("./servers/websocket");
const HOST = '0.0.0.0';
const PORT = 9000;
var app = express();
var wsapp = express();
const app = express();
const wsapp = express();
let debug = process.env.debug === "1" || false;
const request_logger = (identity) => {
return (req, res, next) => {
@ -29,6 +30,9 @@ app.use('/sourcemaps', sourcemapsReaderServer);
app.use('/assist', peerRouter);
wsapp.use('/assist', socket.wsRouter);
app.get('/heapdump', dumps.sendHeapSnapshot);
app.get('/heapdump/save', dumps.saveHeapSnapshot);
const server = app.listen(PORT, HOST, () => {
console.log(`App listening on http://${HOST}:${PORT}`);
console.log('Press Ctrl+C to quit.');
@ -51,3 +55,4 @@ app.enable('trust proxy');
wsapp.enable('trust proxy');
socket.start(wsserver);
module.exports = {wsserver, server};
console.log(`Heapdump enabled. Send a request to "/heapdump" to download a heapdump,\nor "/heapdump/save" to only generate a heapdump.`);

50
utilities/utils/dump.js Normal file
View file

@ -0,0 +1,50 @@
const fs = require('fs');
const v8 = require('v8');
const location = '/tmp/';
async function createHeapSnapshot() {
const fileName = `${Date.now()}.heapsnapshot`;
await fs.promises.writeFile(
location + fileName,
v8.getHeapSnapshot()
);
return fileName;
}
async function sendHeapSnapshot(req, res) {
const fileName = await createHeapSnapshot();
const file = fs.readFileSync(location + fileName, 'binary');
const stat = fs.statSync(location + fileName);
res.setHeader('Content-Length', stat.size);
res.setHeader('Content-Type', 'audio/mpeg');
res.setHeader('Content-Disposition', 'attachment; filename=' + fileName);
res.write(file, 'binary');
res.end();
try {
fs.unlinkSync(location + fileName)
} catch (err) {
console.error("error while deleting heapsnapshot file");
console.error(err);
}
}
process.on('USR2', () => {
console.info('USR2 signal received.');
});
async function saveHeapSnapshot(req, res) {
const fileName = await createHeapSnapshot();
const path = location + fileName;
console.log(`Heapdump saved to ${path}`)
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({path}));
}
process.on('USR2', () => {
console.info('USR2 signal received.');
});
module.exports = {sendHeapSnapshot, saveHeapSnapshot}