@cryptotaxi247 / CoPilot / commits / b4ac0663

Grafana user org (#430)

* feat: add endpoint to add users to Grafana organizations * precommit fixes

taylor_socfortress committed Mar 27, 2025 at 17:58 UTC b4ac06632e943e97d2d6e3ab79568cc3bda2c7ed
4 files changed +109
backend/app/connectors/grafana/routes/user.py new
+36
@@ -0,0 +1,36 @@
1 +from fastapi import APIRouter
2 +from fastapi import Security
3 +from loguru import logger
4 +
5 +from app.auth.utils import AuthHandler
6 +from app.connectors.grafana.schema.user import UserOrganizationAddRequest
7 +from app.connectors.grafana.schema.user import UserOrganizationAddResponse
8 +from app.connectors.grafana.services.user import add_user_to_organization
9 +
10 +# App specific imports
11 +
12 +
13 +grafana_user_router = APIRouter()
14 +
15 +
16 +@grafana_user_router.post(
17 + "/user/organization/add",
18 + response_model=UserOrganizationAddResponse,
19 + description="Add a user to a Grafana organization",
20 + dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
21 +)
22 +async def add_user_organization_route(
23 + request: UserOrganizationAddRequest,
24 +) -> UserOrganizationAddResponse:
25 + """
26 + Endpoint to add a user to a Grafana organization.
27 +
28 + Args:
29 + request (UserOrganizationAddRequest): The request body containing the user and organization data.
30 +
31 + Returns:
32 + UserOrganizationAddResponse: The response containing the result of the user addition.
33 + """
34 + logger.info("Adding user to Grafana organization")
35 + response = await add_user_to_organization(request)
36 + return response
backend/app/connectors/grafana/schema/user.py new
+36
@@ -0,0 +1,36 @@
1 +from pydantic import BaseModel
2 +from pydantic import Field
3 +
4 +
5 +class UserOrganizationAddRequest(BaseModel):
6 + """
7 + Request model for adding a user to an organization in Grafana.
8 + """
9 +
10 + loginorEmail: str = Field(
11 + ...,
12 + description="Login or email of the user to be added.",
13 + )
14 + role: str = Field(
15 + "Viewer",
16 + description="Role to assign to the user in the organization.",
17 + )
18 + organizationId: str = Field(
19 + ...,
20 + description="ID of the organization to which the user will be added.",
21 + )
22 +
23 +
24 +class UserOrganizationAddResponse(BaseModel):
25 + """
26 + Response model for adding a user to an organization in Grafana.
27 + """
28 +
29 + success: bool = Field(
30 + ...,
31 + description="Indicates whether the operation was successful.",
32 + )
33 + message: str = Field(
34 + ...,
35 + description="Message describing the result of the operation.",
36 + )
backend/app/connectors/grafana/services/user.py new
+35
@@ -0,0 +1,35 @@
1 +from fastapi import HTTPException
2 +from loguru import logger
3 +
4 +from app.connectors.grafana.schema.user import UserOrganizationAddRequest
5 +from app.connectors.grafana.schema.user import UserOrganizationAddResponse
6 +from app.connectors.grafana.utils.universal import create_grafana_client
7 +
8 +
9 +async def add_user_to_organization(request: UserOrganizationAddRequest) -> UserOrganizationAddResponse:
10 + """
11 + Adds a user to a Grafana organization.
12 +
13 + Args:
14 + request (UserOrganizationAddRequest): The request body containing the user and organization data.
15 +
16 + Returns:
17 + UserOrganizationAddResponse: The response containing the result of the user addition.
18 + """
19 + logger.info("Adding user to Grafana organization")
20 + grafana_client = await create_grafana_client("Grafana")
21 + try:
22 + # Add the user to the specified organization
23 + user = {
24 + "loginorEmail": request.loginorEmail,
25 + "role": request.role,
26 + }
27 + request = grafana_client.organizations.organization_user_add(request.organizationId, user)
28 + logger.info(f"User {request.loginorEmail} added to organization {request.organizationId}")
29 + return UserOrganizationAddResponse(
30 + message=f"User {request.loginorEmail} added to organization {request.organizationId}",
31 + status="success",
32 + )
33 + except Exception as e:
34 + logger.error(f"Error adding user to organization: {e}")
35 + raise HTTPException(status_code=500, detail=f"Error adding user to organization: {e}")
backend/app/routers/grafana.py
+2
@@ -2,6 +2,7 @@ from fastapi import APIRouter
2
3 from app.connectors.grafana.routes.dashboards import grafana_dashboards_router
4 from app.connectors.grafana.routes.reporting import grafana_reporting_router
5 +from app.connectors.grafana.routes.user import grafana_user_router
6
7 # Instantiate the APIRouter
8 router = APIRouter()
@@ -9,3 +10,4 @@ router = APIRouter()
10 # Include the Shuffle related routes
11 router.include_router(grafana_dashboards_router, prefix="/grafana", tags=["Grafana"])
12 router.include_router(grafana_reporting_router, prefix="/reporting", tags=["Grafana-Reporting"])
13 +router.include_router(grafana_user_router, prefix="/user", tags=["Grafana-User"])