Skip to content

Commit

Permalink
refactor (backend): update use of project_id for rbac
Browse files Browse the repository at this point in the history
  • Loading branch information
aybruhm committed Sep 24, 2024
1 parent 920ec3c commit 1027d18
Show file tree
Hide file tree
Showing 15 changed files with 278 additions and 358 deletions.
4 changes: 4 additions & 0 deletions agenta-backend/agenta_backend/models/api/api_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class VariantAction(BaseModel):

class CreateApp(BaseModel):
app_name: str
project_id: Optional[str] = None
workspace_id: Optional[str] = None


class CreateAppOutput(BaseModel):
Expand Down Expand Up @@ -239,6 +241,8 @@ class DockerEnvVars(BaseModel):
class CreateAppVariant(BaseModel):
app_name: str
template_id: str
project_id: Optional[str] = None
workspace_id: Optional[str] = None
env_vars: Dict[str, str]


Expand Down
51 changes: 27 additions & 24 deletions agenta-backend/agenta_backend/routers/app_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,11 @@ async def list_app_variants(
List[AppVariantResponse]: A list of app variants for the given app ID.
"""
try:
app = await db_manager.get_app_instance_by_id(app_id=app_id)
if isCloudEE():
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(app.project_id),
permission=Permission.VIEW_APPLICATION,
)
logger.debug(f"User has Permission to list app variants: {has_permission}")
Expand All @@ -116,9 +117,7 @@ async def list_app_variants(
status_code=403,
)

app_variants = await db_manager.list_app_variants(
app_id=app_id, project_id=request.state.project_id
)
app_variants = await db_manager.list_app_variants(app_id=app_id)
return [
await converters.app_variant_db_to_output(app_variant)
for app_variant in app_variants
Expand Down Expand Up @@ -156,10 +155,11 @@ async def get_variant_by_env(
AppVariantResponse: The retrieved app variant.
"""
try:
app = await db_manager.get_app_instance_by_id(app_id=app_id)
if isCloudEE():
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(app.project_id),
permission=Permission.VIEW_APPLICATION,
)
logger.debug(
Expand Down Expand Up @@ -231,7 +231,7 @@ async def create_app(

has_permission = await check_rbac_permission(
user_org_workspace_data=user_org_workspace_data,
project_id=request.state.project_id,
project_id=payload.project_id or request.state.project_id,
permission=Permission.CREATE_APPLICATION,
)
logger.debug(
Expand All @@ -247,7 +247,9 @@ async def create_app(
raise HTTPException(status_code=500, detail=str(e))

app_db = await db_manager.create_app_and_envs(
payload.app_name, request.state.project_id
payload.app_name,
project_id=payload.project_id or request.state.project_id,
workspace_id=payload.workspace_id,
)
return CreateAppOutput(app_id=str(app_db.id), app_name=str(app_db.app_name))
except Exception as e:
Expand Down Expand Up @@ -277,11 +279,11 @@ async def update_app(
"""

try:
app = await db_manager.fetch_app_by_id(app_id, request.state.project_id)
app = await db_manager.fetch_app_by_id(app_id)
if isCloudEE():
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(app.project_id),
permission=Permission.EDIT_APPLICATION,
)
logger.debug(f"User has Permission to update app: {has_permission}")
Expand Down Expand Up @@ -369,12 +371,11 @@ async def add_variant_from_image(
raise HTTPException(status_code=404, detail="Image not found")

try:
app = await db_manager.fetch_app_by_id(app_id, request.state.project_id)

app = await db_manager.fetch_app_by_id(app_id)
if isCloudEE():
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(app.project_id),
permission=Permission.CREATE_APPLICATION,
)
logger.debug(
Expand All @@ -389,7 +390,7 @@ async def add_variant_from_image(

variant_db = await app_manager.add_variant_based_on_image(
app=app,
project_id=request.state.project_id,
project_id=str(app.project_id),
variant_name=payload.variant_name,
docker_id_or_template_uri=payload.docker_id,
tags=payload.tags,
Expand All @@ -398,13 +399,11 @@ async def add_variant_from_image(
is_template_image=False,
user_uid=request.state.user_id,
)
app_variant_db = await db_manager.fetch_app_variant_by_id(
str(variant_db.id), request.state.project_id
)
app_variant_db = await db_manager.fetch_app_variant_by_id(str(variant_db.id))

logger.debug("Step 8: We create ready-to use evaluators")
await evaluator_manager.create_ready_to_use_evaluators(
app_name=app.app_name, project_id=request.state.project_id
app_name=app.app_name, project_id=str(app.project_id)
)

return await converters.app_variant_db_to_output(app_variant_db)
Expand All @@ -424,12 +423,11 @@ async def remove_app(
app -- App to remove
"""
try:
app = await db_manager.fetch_app_by_id(app_id, request.state.project_id)

app = await db_manager.fetch_app_by_id(app_id)
if isCloudEE():
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(app.project_id),
permission=Permission.DELETE_APPLICATION,
)
logger.debug(f"User has Permission to delete app: {has_permission}")
Expand All @@ -440,7 +438,7 @@ async def remove_app(
status_code=403,
)

await app_manager.remove_app(app, request.state.project_id)
await app_manager.remove_app(app)
except DockerException as e:
detail = f"Docker error while trying to remove the app: {str(e)}"
logger.exception(f"Docker error while trying to remove the app: {str(e)}")
Expand Down Expand Up @@ -489,9 +487,12 @@ async def create_app_and_variant_from_template(
)

logger.debug("Step 3: Checking user has permission to create app")
project = await db_manager_ee.get_project_by_workspace(
workspace_id=payload.workspace_id
)
has_permission = await check_rbac_permission(
user_org_workspace_data=user_org_workspace_data,
project_id=request.state.project_id,
project_id=str(project.id),
permission=Permission.CREATE_APPLICATION,
)
logger.debug(
Expand All @@ -512,7 +513,7 @@ async def create_app_and_variant_from_template(
)
app_name = payload.app_name.lower()
app = await db_manager.fetch_app_by_name_and_parameters(
app_name, request.state.project_id
app_name, payload.workspace_id
)
if app is not None:
raise Exception(
Expand All @@ -526,7 +527,9 @@ async def create_app_and_variant_from_template(
)
if app is None:
app = await db_manager.create_app_and_envs(
app_name, request.state.project_id
app_name,
project_id=payload.project_id or request.state.project_id,
workspace_id=payload.workspace_id,
)

logger.debug(
Expand Down
3 changes: 2 additions & 1 deletion agenta-backend/agenta_backend/routers/bases_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ async def list_bases(
HTTPException: If there was an error retrieving the bases.
"""
try:
app = await db_manager.fetch_app_by_id(app_id=app_id)
if isCloudEE() and app_id is not None:
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(app.project_i),
permission=Permission.VIEW_APPLICATION,
)
if not has_permission:
Expand Down
23 changes: 9 additions & 14 deletions agenta-backend/agenta_backend/routers/configs_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,12 @@ async def save_config(
request: Request,
):
try:
base_db = await db_manager.fetch_base_by_id(
payload.base_id, request.state.project_id
)
base_db = await db_manager.fetch_base_by_id(payload.base_id)

if isCloudEE():
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(base_db.project_id),
permission=Permission.MODIFY_VARIANT_CONFIGURATIONS,
)
if not has_permission:
Expand All @@ -50,7 +48,7 @@ async def save_config(
)

variants_db = await db_manager.list_variants_for_base(
base_db, request.state.project_id
base_db, str(base_db.project_id)
)
variant_to_overwrite = None
for variant_db in variants_db:
Expand All @@ -65,14 +63,14 @@ async def save_config(
app_variant_id=str(variant_to_overwrite.id),
parameters=payload.parameters,
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(base_db.project_id),
)

logger.debug("Deploying to production environment")
await db_manager.deploy_to_environment(
environment_name="production",
variant_id=str(variant_to_overwrite.id),
project_id=request.state.project_id,
project_id=str(base_db.project_id),
user_uid=request.state.user_id,
)
else:
Expand All @@ -89,7 +87,7 @@ async def save_config(
new_config_name=payload.config_name,
parameters=payload.parameters,
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(base_db.project_id),
)

except HTTPException as e:
Expand Down Expand Up @@ -118,7 +116,7 @@ async def get_config(
if isCloudEE():
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(base_db.project_id),
permission=Permission.MODIFY_VARIANT_CONFIGURATIONS,
)
if not has_permission:
Expand All @@ -133,7 +131,6 @@ async def get_config(
if environment_name:
app_environments = await db_manager.list_environments(
app_id=str(base_db.app_id), # type: ignore
project_id=request.state.project_id,
)
found_variant_revision = next(
(
Expand All @@ -160,9 +157,7 @@ async def get_config(
"parameters": found_variant_revision.config_parameters,
}
elif config_name:
variants_db = await db_manager.list_variants_for_base(
base_db, request.state.project_id
)
variants_db = await db_manager.list_variants_for_base(base_db)
found_variant = next(
(
variant_db
Expand Down Expand Up @@ -261,7 +256,7 @@ async def revert_deployment_revision(
if isCloudEE():
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(environment_revision.project_id),
permission=Permission.EDIT_APP_ENVIRONMENT_DEPLOYMENT,
)
if not has_permission:
Expand Down
24 changes: 9 additions & 15 deletions agenta-backend/agenta_backend/routers/container_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,11 @@ async def build_image(
Image: The Docker image that was built.
"""
try:
app_db = await db_manager.fetch_app_by_id(app_id, request.state.project_id)

# Check app access
app_db = await db_manager.fetch_app_by_id(app_id)
if isCloudEE():
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(app_db.project_id),
permission=Permission.CREATE_APPLICATION,
)
if not has_permission:
Expand Down Expand Up @@ -105,12 +103,10 @@ async def restart_docker_container(
"""
logger.debug(f"Restarting container for variant {payload.variant_id}")

app_variant_db = await db_manager.fetch_app_variant_by_id(
payload.variant_id, request.state.project_id
)
app_variant_db = await db_manager.fetch_app_variant_by_id(payload.variant_id)
try:
deployment = await db_manager.get_deployment_by_id(
app_variant_db.base.deployment, request.state.project_id
app_variant_db.base.deployment
)
container_id = deployment.container_id

Expand Down Expand Up @@ -166,7 +162,7 @@ async def construct_app_container_url(
assert base_id or variant_id, "Please provide either base_id or variant_id"

if base_id:
object_db = await db_manager.fetch_base_by_id(base_id, request.state.project_id)
object_db = await db_manager.fetch_base_by_id(base_id)
elif variant_id and variant_id != "None":
# NOTE: Backward Compatibility
# ---------------------------
Expand All @@ -177,9 +173,7 @@ async def construct_app_container_url(
# This change ensures that users can still view their evaluations; however,
# they will no longer be able to access a deployment URL for the deleted variant.
# Therefore, we ensure that variant_id is not "None".
object_db = await db_manager.fetch_app_variant_by_id(
variant_id, request.state.project_id
)
object_db = await db_manager.fetch_app_variant_by_id(variant_id)
else:
# NOTE: required for backward compatibility
object_db = None
Expand All @@ -188,7 +182,7 @@ async def construct_app_container_url(
if isCloudEE() and object_db is not None:
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(object_db.project_id),
permission=Permission.VIEW_APPLICATION,
)
if not has_permission:
Expand All @@ -199,11 +193,11 @@ async def construct_app_container_url(
try:
if getattr(object_db, "deployment_id", None): # this is a base
deployment = await db_manager.get_deployment_by_id(
str(object_db.deployment_id), request.state.project_id # type: ignore
str(object_db.deployment_id) # type: ignore
)
elif getattr(object_db, "base_id", None): # this is a variant
deployment = await db_manager.get_deployment_by_id(
str(object_db.base.deployment_id), request.state.project_id # type: ignore
str(object_db.base.deployment_id) # type: ignore
)
else:
raise HTTPException(
Expand Down
8 changes: 5 additions & 3 deletions agenta-backend/agenta_backend/routers/environment_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ async def deploy_to_environment(
HTTPException: If the deployment fails.
"""
try:
variant = await db_manager.fetch_app_variant_by_id(
app_variant_id=payload.variant_id
)
if isCloudEE():
has_permission = await check_action_access(
user_uid=request.state.user_id,
project_id=request.state.project_id,
project_id=str(variant.project_id),
permission=Permission.DEPLOY_APPLICATION,
)
logger.debug(f"User has permission deploy to environment: {has_permission}")
Expand All @@ -52,7 +55,6 @@ async def deploy_to_environment(
await db_manager.deploy_to_environment(
environment_name=payload.environment_name,
variant_id=payload.variant_id,
project_id=request.state.project_id,
user_uid=request.state.user_id,
)

Expand All @@ -61,7 +63,7 @@ async def deploy_to_environment(
user_uid=request.state.user_id,
object_id=payload.variant_id,
object_type="variant",
project_id=request.state.project_id,
project_id=str(variant.project_id),
)
logger.debug("Successfully updated last_modified_by app information")
except Exception as e:
Expand Down
Loading

0 comments on commit 1027d18

Please sign in to comment.