refactor public dashboards middleware testing (#55706)

This PR refactors how we add the orgId to the context on a public dashboard paths. We also split out accessToken handling into its own package and rework status code for "RequiresValidAccessToken". We will be modeling all endpoints to use these status codes going forward. Additionally, it includes a scaffold for better middleware testing and refactors existing tests to table drive tests.
This commit is contained in:
Jeff Levin
2022-10-06 12:35:19 -08:00
committed by GitHub
parent 609abf00d1
commit 331110bde5
13 changed files with 460 additions and 121 deletions
+29 -15
View File
@@ -2,46 +2,60 @@ package api
import (
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/publicdashboards"
"github.com/grafana/grafana/pkg/services/publicdashboards/internal/tokens"
"github.com/grafana/grafana/pkg/web"
)
func SetPublicDashboardFlag() func(c *models.ReqContext) {
// Adds orgId to context based on org of public dashboard
func SetPublicDashboardOrgIdOnContext(publicDashboardService publicdashboards.Service) func(c *models.ReqContext) {
return func(c *models.ReqContext) {
// TODO: Find a better place to set this, or rename this function
orgIDValue := c.Req.URL.Query().Get("orgId")
orgID, err := strconv.ParseInt(orgIDValue, 10, 64)
if err == nil && orgID > 0 && orgID != c.OrgID {
c.OrgID = orgID
accessToken, ok := web.Params(c.Req)[":accessToken"]
if !ok || !tokens.IsValidAccessToken(accessToken) {
return
}
c.IsPublicDashboardView = true
// Get public dashboard
orgId, err := publicDashboardService.GetPublicDashboardOrgId(c.Req.Context(), accessToken)
if err != nil {
return
}
c.OrgID = orgId
}
}
// Adds public dashboard flag on context
func SetPublicDashboardFlag(c *models.ReqContext) {
c.IsPublicDashboardView = true
}
// Middleware to enforce that a public dashboards exists before continuing to
// handler
func RequiresValidAccessToken(publicDashboardService publicdashboards.Service) func(c *models.ReqContext) {
return func(c *models.ReqContext) {
accessToken, ok := web.Params(c.Req)[":accessToken"]
// Check access token is present on the request
if !ok || accessToken == "" {
c.JsonApiErr(http.StatusBadRequest, "Invalid access token", nil)
if !ok {
c.JsonApiErr(http.StatusBadRequest, "No access token provided", nil)
return
}
if !tokens.IsValidAccessToken(accessToken) {
c.JsonApiErr(http.StatusBadRequest, "Invalid access token", nil)
}
// Check that the access token references an enabled public dashboard
exists, err := publicDashboardService.AccessTokenExists(c.Req.Context(), accessToken)
if err != nil {
c.JsonApiErr(http.StatusInternalServerError, "Error validating access token", nil)
c.JsonApiErr(http.StatusInternalServerError, "Failed to query access token", nil)
return
}
if !exists {
c.JsonApiErr(http.StatusBadRequest, "Invalid access token", nil)
c.JsonApiErr(http.StatusNotFound, "Public dashboard not found", nil)
return
}
}