Skip to content

feat: user project access management#16

Open
irfanuddinahmad wants to merge 23 commits intoarbisoft:productionfrom
irfanuddinahmad:feat/user-project-access-management
Open

feat: user project access management#16
irfanuddinahmad wants to merge 23 commits intoarbisoft:productionfrom
irfanuddinahmad:feat/user-project-access-management

Conversation

@irfanuddinahmad
Copy link
Copy Markdown

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

  • Added UserProjectMapping model to map Grafana user logins to DevLake project names, enabling per-user project visibility. (backend/core/models/project.go)
  • Introduced a database migration to create the user_project_mapping table. (backend/core/models/migrationscripts/20260311_add_user_project_mapping.go)
  • Registered the migration script in the migration pipeline. (backend/core/models/migrationscripts/register.go)
  • Implemented user-project mapping API endpoints for CRUD operations and integrated them into the router. (backend/server/api/user_project_mapping/user_project_mapping.go, backend/server/api/router.go) [1] [2] [3]
  • Added backend service functions to support user-project mapping operations. (backend/server/services/user_project_mapping.go)

Release Workflow Improvements

  • Created .github/workflows/release-images.yml for automated building and publishing of Docker images for backend, config UI, and Grafana dashboard on tag pushes.

Grafana Dashboard Enhancement

  • Updated grafana/Dockerfile to install the volkovlabs-form-panel plugin, expanding dashboard capabilities.

- 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
@irfanuddinahmad irfanuddinahmad force-pushed the feat/user-project-access-management branch from 002fe40 to 9a30ef9 Compare March 12, 2026 09:40
@jawad-khan jawad-khan requested a review from Copilot March 12, 2026 10:00
@irfanuddinahmad irfanuddinahmad changed the title Feat/user project access management feat: user project access management Mar 12, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_mapping model + 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.

Comment on lines +78 to +86
"update": {
"method": "POST",
"url": "https://aperture.arbisoft.com/api/user-project-mappings/${userLogin}",
"header": [
{
"name": "Content-Type",
"value": "application/json"
}
],
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +37 to +44
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)
}
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +73 to +90
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)
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +24
push:
tags:
- 'v*'

Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
push:
tags:
- 'v*'
workflow_call:

Copilot uses AI. Check for mistakes.
updateIntervalSeconds: 5
# <bool> allow updating provisioned dashboards from the UI
allowUiUpdates: false
allowUiUpdates: true
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
allowUiUpdates: true
allowUiUpdates: false

Copilot uses AI. Check for mistakes.
@irfanuddinahmad irfanuddinahmad force-pushed the feat/user-project-access-management branch from e2f18cd to b722fab Compare March 12, 2026 10:10
@irfanuddinahmad irfanuddinahmad force-pushed the feat/user-project-access-management branch 2 times, most recently from e088eab to 05a56f5 Compare March 12, 2026 11:14
@irfanuddinahmad irfanuddinahmad force-pushed the feat/user-project-access-management branch 2 times, most recently from 895af70 to 84acd99 Compare March 12, 2026 11:29
@irfanuddinahmad irfanuddinahmad force-pushed the feat/user-project-access-management branch from a289d82 to efc0efa Compare March 12, 2026 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants