feat: user project access management#16
feat: user project access management#16irfanuddinahmad wants to merge 23 commits intoarbisoft:productionfrom
Conversation
- Add Grafana admin dashboard (Business Forms v6) for managing user-project mappings (add/remove) via DevLake REST API - Install volkovlabs-form-panel in Grafana Docker image - Add user_project_mapping DB table, migration, service and API handlers - Register user-project-mapping routes in server router - Rename devlake_project variable to project in all DORA dashboards (project filter now queries user_project_mapping for the logged-in user) - Add GitHub Actions workflow for building and pushing release images
002fe40 to
9a30ef9
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds a per-user project visibility mechanism for Grafana dashboards by introducing a user_project_mapping table and CRUD API endpoints, then wiring Grafana dashboards to filter the $project variable based on the logged-in user.
Changes:
- Added
user_project_mappingmodel + DB migration and registered it in the migration pipeline. - Added backend service + API handlers + router wiring for user↔project mapping CRUD.
- Updated Grafana dashboards and provisioning to use user-specific project lists and added an admin dashboard for managing mappings; updated Grafana image/plugins and added a release workflow.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| grafana/provisioning/dashboards/dashboard.yml | Enables UI updates for provisioned dashboards (impacts how access controls can be enforced). |
| grafana/dashboards/admin/AdminUserProjectAccess.json | New admin dashboard for adding/removing user-project mappings via API. |
| grafana/dashboards/DORADetails-TimetoRestoreService.json | Filters project variable via user_project_mapping and updates SQL variable interpolation. |
| grafana/dashboards/DORADetails-LeadTimeforChanges.json | Filters project variable via user_project_mapping and updates SQL variable interpolation. |
| grafana/dashboards/DORADetails-FailedDeploymentRecoveryTime.json | Filters project variable via user_project_mapping and updates SQL variable interpolation. |
| grafana/dashboards/DORADetails-DeploymentFrequency.json | Filters project variable via user_project_mapping and updates SQL variable interpolation. |
| grafana/dashboards/DORADetails-ChangeFailureRate.json | Filters project variable via user_project_mapping and updates SQL variable interpolation. |
| grafana/dashboards/DORADebug.json | Filters project variable via user_project_mapping and updates SQL variable interpolation for debugging panels. |
| grafana/dashboards/DORAByTeam.json | Adds a project template variable sourced from user_project_mapping. |
| grafana/dashboards/DORA.json | Filters project variable via user_project_mapping and updates SQL variable interpolation. |
| grafana/Dockerfile | Installs volkovlabs-form-panel plugin in the Grafana image. |
| backend/server/services/user_project_mapping.go | Adds service-layer CRUD helpers for user-project mappings. |
| backend/server/api/user_project_mapping/user_project_mapping.go | Adds HTTP endpoints for listing/creating/deleting mappings. |
| backend/server/api/router.go | Registers the new user-project-mappings routes. |
| backend/core/models/project.go | Adds models.UserProjectMapping GORM model. |
| backend/core/models/migrationscripts/register.go | Registers the new migration script. |
| backend/core/models/migrationscripts/20260311_add_user_project_mapping.go | Adds migration to create user_project_mapping table. |
| .github/workflows/release-images.yml | Adds a tag-triggered image build/push workflow (currently duplicates existing release workflow). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "update": { | ||
| "method": "POST", | ||
| "url": "https://aperture.arbisoft.com/api/user-project-mappings/${userLogin}", | ||
| "header": [ | ||
| { | ||
| "name": "Content-Type", | ||
| "value": "application/json" | ||
| } | ||
| ], |
There was a problem hiding this comment.
The form panel uses a hard-coded absolute DevLake API URL. This makes the dashboard non-portable across environments and can break in deployments where Grafana reaches DevLake via a different host/path (or needs to go through Grafana’s proxy to avoid CORS). Consider using a relative URL (e.g., pointing at the same origin) or a configurable dashboard variable for the DevLake base URL instead of embedding https://aperture.arbisoft.com in the JSON.
| func GetAllMappings(c *gin.Context) { | ||
| mappings, err := services.GetAllUserProjectMappings() | ||
| if err != nil { | ||
| shared.ApiOutputError(c, errors.Default.Wrap(err, "error getting user project mappings")) | ||
| return | ||
| } | ||
| shared.ApiOutputSuccess(c, mappings, http.StatusOK) | ||
| } |
There was a problem hiding this comment.
This endpoint returns the full user→project access list, but there’s no authorization/permission check at the handler level. Since these mappings are used to enforce per-user dashboard visibility, exposing the complete mapping table to any authenticated caller can leak which projects other users have access to. Consider restricting this route to an admin-only path / API-key-protected access, or otherwise enforcing that only privileged users can call it.
| func PostMapping(c *gin.Context) { | ||
| userLogin := c.Param("userLogin") | ||
| var body struct { | ||
| ProjectName string `json:"projectName" binding:"required"` | ||
| } | ||
| if err := c.ShouldBindJSON(&body); err != nil { | ||
| shared.ApiOutputError(c, errors.BadInput.Wrap(err, shared.BadRequestBody)) | ||
| return | ||
| } | ||
| mapping := &models.UserProjectMapping{ | ||
| UserLogin: userLogin, | ||
| ProjectName: body.ProjectName, | ||
| } | ||
| if err := services.CreateUserProjectMapping(mapping); err != nil { | ||
| shared.ApiOutputError(c, errors.Default.Wrap(err, "error creating user project mapping")) | ||
| return | ||
| } | ||
| shared.ApiOutputSuccess(c, mapping, http.StatusCreated) |
There was a problem hiding this comment.
PostMapping allows creating a mapping for any :userLogin provided in the path, without verifying the caller is authorized to modify that user’s access. That means a non-admin user could grant themselves (or others) access to additional projects and bypass the intended per-user visibility control. Consider adding an authorization check (e.g., require an admin identity / API key scope for managing other users, and/or only allow self-service updates when userLogin matches the authenticated user).
| push: | ||
| tags: | ||
| - 'v*' | ||
|
|
There was a problem hiding this comment.
This workflow duplicates the existing .github/workflows/release.yml (same name/trigger/jobs). As-is, tag pushes will run two nearly identical workflows, doubling CI time and potentially racing to push the same image tags. Consider removing one of them, or changing the trigger/name/tags so only a single release-image workflow runs per tag.
| push: | |
| tags: | |
| - 'v*' | |
| workflow_call: |
| updateIntervalSeconds: 5 | ||
| # <bool> allow updating provisioned dashboards from the UI | ||
| allowUiUpdates: false | ||
| allowUiUpdates: true |
There was a problem hiding this comment.
allowUiUpdates: true allows users to modify provisioned dashboards via the Grafana UI and have those changes persisted in Grafana’s DB. For this PR’s per-user project visibility to be meaningful, dashboards/variables shouldn’t be user-editable (otherwise a user can alter the project variable query and bypass visibility restrictions). Consider keeping allowUiUpdates: false (or locking down dashboard edit permissions at the Grafana org/folder level) and provisioning changes via Git instead.
| allowUiUpdates: true | |
| allowUiUpdates: false |
e2f18cd to
b722fab
Compare
e088eab to
05a56f5
Compare
895af70 to
84acd99
Compare
a289d82 to
efc0efa
Compare
…user_accounts join
…metrics per developer
This pull request introduces a new feature for managing per-user project visibility in Grafana dashboards by adding a user-project mapping table and related API endpoints. It also includes updates to the release workflow and Grafana dashboard setup. The most important changes are grouped below:
User-Project Mapping Feature
UserProjectMappingmodel to map Grafana user logins to DevLake project names, enabling per-user project visibility. (backend/core/models/project.go)user_project_mappingtable. (backend/core/models/migrationscripts/20260311_add_user_project_mapping.go)backend/core/models/migrationscripts/register.go)backend/server/api/user_project_mapping/user_project_mapping.go,backend/server/api/router.go) [1] [2] [3]backend/server/services/user_project_mapping.go)Release Workflow Improvements
.github/workflows/release-images.ymlfor automated building and publishing of Docker images for backend, config UI, and Grafana dashboard on tag pushes.Grafana Dashboard Enhancement
grafana/Dockerfileto install thevolkovlabs-form-panelplugin, expanding dashboard capabilities.