role and update the api endoint
This commit is contained in:
@@ -46,14 +46,14 @@ TOP_K_SUMMARY=4
|
|||||||
MAX_CONTEXT_CHARS=4000
|
MAX_CONTEXT_CHARS=4000
|
||||||
MIN_SIMILARITY_SCORE=0.18
|
MIN_SIMILARITY_SCORE=0.18
|
||||||
LOG_LEVEL=INFO
|
LOG_LEVEL=INFO
|
||||||
CORS_ORIGINS=https://docqube-test.maskantech.in,https://docqubeapp-test.maskantech.in,https://docqubeapi-test.maskantech.in
|
CORS_ORIGINS=https://saas-test.maskantech.in,https://docqubeapp-test.maskantech.in,https://docqube-test.maskantech.in,http://localhost:5173,http://localhost:3000
|
||||||
SMTP_HOST=smtp.gmail.com
|
SMTP_HOST=smtp.gmail.com
|
||||||
SMTP_PORT=465
|
SMTP_PORT=465
|
||||||
SMTP_USER=info.maskantech@gmail.com
|
SMTP_USER=info.maskantech@gmail.com
|
||||||
SMTP_PASSWORD=tuthpljtkrwchgxd
|
SMTP_PASSWORD=tuthpljtkrwchgxd
|
||||||
MAIL_FROM=info.maskantech@gmail.com
|
MAIL_FROM=info.maskantech@gmail.com
|
||||||
SMTP_SECURE=True
|
SMTP_SECURE=True
|
||||||
FRONTEND_URL=https://docqube-test.maskantech.in,https://docqubeapp-test.maskantech.in,https://docqubeapi-test.maskantech.in
|
FRONTEND_URL=https://docqubeapp-test.maskantech.in
|
||||||
CHAT_REDIS_MAX_MESSAGES=10
|
CHAT_REDIS_MAX_MESSAGES=10
|
||||||
CHAT_REDIS_TTL_SECONDS=86400
|
CHAT_REDIS_TTL_SECONDS=86400
|
||||||
CHAT_DAILY_CREDITS_LIMIT=1000
|
CHAT_DAILY_CREDITS_LIMIT=1000
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import hashlib
|
|||||||
|
|
||||||
from app.db.database import get_db
|
from app.db.database import get_db
|
||||||
from app.core.settings import settings
|
from app.core.settings import settings
|
||||||
|
from app.core.security import create_access_token, create_refresh_token
|
||||||
|
from app.core.request_body import read_json_body
|
||||||
from app.services.saas_service import SaaSService
|
from app.services.saas_service import SaaSService
|
||||||
from app.modules.tenant.models.tenant_model import Tenant
|
from app.modules.tenant.models.tenant_model import Tenant
|
||||||
from app.modules.auth.models.saas_models import SaaSTenantMapping
|
from app.modules.auth.models.saas_models import SaaSTenantMapping
|
||||||
@@ -98,14 +100,17 @@ async def sso_login(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
is_prod = settings.APP_ENV == "production"
|
is_secure = settings.APP_ENV in ["production", "test", "testing"] or request.url.scheme == "https"
|
||||||
|
samesite_mode = "none" if is_secure else "lax"
|
||||||
|
cookie_domain = getattr(settings, "COOKIE_DOMAIN", None) or None
|
||||||
|
|
||||||
response.set_cookie(
|
response.set_cookie(
|
||||||
key="docqube_access_token",
|
key="docqube_access_token",
|
||||||
value=access_token,
|
value=access_token,
|
||||||
httponly=True,
|
httponly=True,
|
||||||
secure=is_prod,
|
secure=is_secure,
|
||||||
samesite="lax",
|
samesite=samesite_mode,
|
||||||
|
domain=cookie_domain,
|
||||||
path="/",
|
path="/",
|
||||||
max_age=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60
|
max_age=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60
|
||||||
)
|
)
|
||||||
@@ -114,8 +119,9 @@ async def sso_login(
|
|||||||
key="docqube_refresh_token",
|
key="docqube_refresh_token",
|
||||||
value=refresh_token,
|
value=refresh_token,
|
||||||
httponly=True,
|
httponly=True,
|
||||||
secure=is_prod,
|
secure=is_secure,
|
||||||
samesite="lax",
|
samesite=samesite_mode,
|
||||||
|
domain=cookie_domain,
|
||||||
path="/",
|
path="/",
|
||||||
max_age=7 * 24 * 3600
|
max_age=7 * 24 * 3600
|
||||||
)
|
)
|
||||||
@@ -281,9 +287,6 @@ async def provision_tenant(request: Request, db: Session = Depends(get_db)):
|
|||||||
logger.exception("Provisioning webhook failed for event %s", event_type)
|
logger.exception("Provisioning webhook failed for event %s", event_type)
|
||||||
raise HTTPException(status_code=500, detail=f"Provisioning error: {str(e)}")
|
raise HTTPException(status_code=500, detail=f"Provisioning error: {str(e)}")
|
||||||
|
|
||||||
from app.core.security import create_access_token, create_refresh_token
|
|
||||||
from app.core.request_body import read_json_body
|
|
||||||
|
|
||||||
|
|
||||||
def _sync_subscription(db, tenant, plan_code, subscription: dict) -> None:
|
def _sync_subscription(db, tenant, plan_code, subscription: dict) -> None:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -41,10 +41,12 @@ class SaaSService:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def ensure_saas_user(db: Session, saas_data: Dict[str, Any]) -> Tuple[User, SaaSUserMapping]:
|
def ensure_saas_user(db: Session, saas_data: Dict[str, Any]) -> Tuple[User, SaaSUserMapping]:
|
||||||
"""
|
from sqlalchemy import text
|
||||||
Ensures a local user exists for the given SaaS user data.
|
try:
|
||||||
Maps the user if not already mapped.
|
db.execute(text("SELECT set_config('docqube.bypass', 'on', true)"))
|
||||||
"""
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
saas_user_id = str(saas_data.get("id"))
|
saas_user_id = str(saas_data.get("id"))
|
||||||
email = saas_data.get("email")
|
email = saas_data.get("email")
|
||||||
name = saas_data.get("name")
|
name = saas_data.get("name")
|
||||||
@@ -94,6 +96,29 @@ class SaaSService:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Could not create role {role_name} for tenant {tenant.id}: {e}")
|
logger.warning(f"Could not create role {role_name} for tenant {tenant.id}: {e}")
|
||||||
|
|
||||||
|
permissions = saas_data.get("metadata", {}).get("permissions", [])
|
||||||
|
if target_role and permissions:
|
||||||
|
try:
|
||||||
|
access_rows = db.query(Access).filter(Access.access_code.in_(permissions)).all()
|
||||||
|
existing_access_ids = {
|
||||||
|
ra.access_id for ra in db.query(RoleAccess).filter(RoleAccess.role_id == target_role.id).all()
|
||||||
|
}
|
||||||
|
new_access_ids = {a.id for a in access_rows}
|
||||||
|
|
||||||
|
to_delete = existing_access_ids - new_access_ids
|
||||||
|
if to_delete:
|
||||||
|
db.query(RoleAccess).filter(
|
||||||
|
RoleAccess.role_id == target_role.id,
|
||||||
|
RoleAccess.access_id.in_(to_delete)
|
||||||
|
).delete(synchronize_session=False)
|
||||||
|
|
||||||
|
to_add = new_access_ids - existing_access_ids
|
||||||
|
for aid in to_add:
|
||||||
|
db.add(RoleAccess(role_id=target_role.id, access_id=aid))
|
||||||
|
db.flush()
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Could not sync role accesses for {target_role.name}: {e}")
|
||||||
|
|
||||||
mapping = db.query(SaaSUserMapping).filter(SaaSUserMapping.saas_user_id == saas_user_id).first()
|
mapping = db.query(SaaSUserMapping).filter(SaaSUserMapping.saas_user_id == saas_user_id).first()
|
||||||
if mapping:
|
if mapping:
|
||||||
user = mapping.user
|
user = mapping.user
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ dependencies = [
|
|||||||
"python-jose==3.3.0",
|
"python-jose==3.3.0",
|
||||||
"passlib==1.7.4",
|
"passlib==1.7.4",
|
||||||
"bcrypt==5.0.0",
|
"bcrypt==5.0.0",
|
||||||
|
"cffi>=1.17.0",
|
||||||
"cryptography==48.0.0",
|
"cryptography==48.0.0",
|
||||||
"google-auth==2.57.0",
|
"google-auth==2.57.0",
|
||||||
"sqlalchemy==2.0.36",
|
"sqlalchemy==2.0.36",
|
||||||
|
|||||||
@@ -594,6 +594,7 @@ dependencies = [
|
|||||||
{ name = "beautifulsoup4" },
|
{ name = "beautifulsoup4" },
|
||||||
{ name = "boto3" },
|
{ name = "boto3" },
|
||||||
{ name = "celery" },
|
{ name = "celery" },
|
||||||
|
{ name = "cffi" },
|
||||||
{ name = "cryptography" },
|
{ name = "cryptography" },
|
||||||
{ name = "docx2txt" },
|
{ name = "docx2txt" },
|
||||||
{ name = "email-validator" },
|
{ name = "email-validator" },
|
||||||
@@ -664,6 +665,7 @@ requires-dist = [
|
|||||||
{ name = "beautifulsoup4", specifier = "==4.13.5" },
|
{ name = "beautifulsoup4", specifier = "==4.13.5" },
|
||||||
{ name = "boto3", specifier = "==1.36.23" },
|
{ name = "boto3", specifier = "==1.36.23" },
|
||||||
{ name = "celery", specifier = "==5.4.0" },
|
{ name = "celery", specifier = "==5.4.0" },
|
||||||
|
{ name = "cffi", specifier = ">=1.17.0" },
|
||||||
{ name = "cryptography", specifier = "==48.0.0" },
|
{ name = "cryptography", specifier = "==48.0.0" },
|
||||||
{ name = "docx2txt", specifier = "==0.9" },
|
{ name = "docx2txt", specifier = "==0.9" },
|
||||||
{ name = "email-validator", specifier = "==2.3.0" },
|
{ name = "email-validator", specifier = "==2.3.0" },
|
||||||
@@ -1443,8 +1445,8 @@ name = "mkl"
|
|||||||
version = "2021.4.0"
|
version = "2021.4.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "intel-openmp", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" },
|
{ name = "intel-openmp" },
|
||||||
{ name = "tbb", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" },
|
{ name = "tbb" },
|
||||||
]
|
]
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/ce/c6/892fe3bc91e811b78e4f85653864f2d92541d5e5c306b0cb3c2311e9ca64/mkl-2021.4.0-py2.py3-none-win32.whl", hash = "sha256:439c640b269a5668134e3dcbcea4350459c4a8bc46469669b2d67e07e3d330e8", size = 129048357, upload-time = "2021-09-28T17:08:58.256Z" },
|
{ url = "https://files.pythonhosted.org/packages/ce/c6/892fe3bc91e811b78e4f85653864f2d92541d5e5c306b0cb3c2311e9ca64/mkl-2021.4.0-py2.py3-none-win32.whl", hash = "sha256:439c640b269a5668134e3dcbcea4350459c4a8bc46469669b2d67e07e3d330e8", size = 129048357, upload-time = "2021-09-28T17:08:58.256Z" },
|
||||||
|
|||||||
Reference in New Issue
Block a user