mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat: improve RBAC preconditions for Insights endpoint (#8794)
This commit is contained in:
@ -2,7 +2,9 @@ package coderd_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -14,6 +16,7 @@ import (
|
||||
"cdr.dev/slog/sloggers/slogtest"
|
||||
"github.com/coder/coder/agent"
|
||||
"github.com/coder/coder/coderd/coderdtest"
|
||||
"github.com/coder/coder/coderd/rbac"
|
||||
"github.com/coder/coder/codersdk"
|
||||
"github.com/coder/coder/codersdk/agentsdk"
|
||||
"github.com/coder/coder/provisioner/echo"
|
||||
@ -380,3 +383,213 @@ func TestTemplateInsights_BadRequest(t *testing.T) {
|
||||
})
|
||||
assert.Error(t, err, "want error for bad interval")
|
||||
}
|
||||
|
||||
func TestTemplateInsights_RBAC(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
y, m, d := time.Now().UTC().Date()
|
||||
today := time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
type test struct {
|
||||
interval codersdk.InsightsReportInterval
|
||||
withTemplate bool
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
{codersdk.InsightsReportIntervalDay, true},
|
||||
{codersdk.InsightsReportIntervalDay, false},
|
||||
{"", true},
|
||||
{"", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
|
||||
t.Run(fmt.Sprintf("with interval=%q", tt.interval), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("AsOwner", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{})
|
||||
admin := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||
defer cancel()
|
||||
|
||||
var templateIDs []uuid.UUID
|
||||
if tt.withTemplate {
|
||||
version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, admin.OrganizationID, version.ID)
|
||||
templateIDs = append(templateIDs, template.ID)
|
||||
}
|
||||
|
||||
_, err := client.TemplateInsights(ctx, codersdk.TemplateInsightsRequest{
|
||||
StartTime: today.AddDate(0, 0, -1),
|
||||
EndTime: today,
|
||||
Interval: tt.interval,
|
||||
TemplateIDs: templateIDs,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Run("AsTemplateAdmin", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{})
|
||||
admin := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleTemplateAdmin())
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||
defer cancel()
|
||||
|
||||
var templateIDs []uuid.UUID
|
||||
if tt.withTemplate {
|
||||
version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, admin.OrganizationID, version.ID)
|
||||
templateIDs = append(templateIDs, template.ID)
|
||||
}
|
||||
|
||||
_, err := templateAdmin.TemplateInsights(ctx, codersdk.TemplateInsightsRequest{
|
||||
StartTime: today.AddDate(0, 0, -1),
|
||||
EndTime: today,
|
||||
Interval: tt.interval,
|
||||
TemplateIDs: templateIDs,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Run("AsRegularUser", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{})
|
||||
admin := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
regular, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||
defer cancel()
|
||||
|
||||
var templateIDs []uuid.UUID
|
||||
if tt.withTemplate {
|
||||
version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, admin.OrganizationID, version.ID)
|
||||
templateIDs = append(templateIDs, template.ID)
|
||||
}
|
||||
|
||||
_, err := regular.TemplateInsights(ctx, codersdk.TemplateInsightsRequest{
|
||||
StartTime: today.AddDate(0, 0, -1),
|
||||
EndTime: today,
|
||||
Interval: tt.interval,
|
||||
TemplateIDs: templateIDs,
|
||||
})
|
||||
require.Error(t, err)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserLatencyInsights_RBAC(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
y, m, d := time.Now().UTC().Date()
|
||||
today := time.Date(y, m, d, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
type test struct {
|
||||
interval codersdk.InsightsReportInterval
|
||||
withTemplate bool
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
{codersdk.InsightsReportIntervalDay, true},
|
||||
{codersdk.InsightsReportIntervalDay, false},
|
||||
{"", true},
|
||||
{"", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(fmt.Sprintf("with interval=%q", tt.interval), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("AsOwner", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{})
|
||||
admin := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||
defer cancel()
|
||||
|
||||
var templateIDs []uuid.UUID
|
||||
if tt.withTemplate {
|
||||
version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, admin.OrganizationID, version.ID)
|
||||
templateIDs = append(templateIDs, template.ID)
|
||||
}
|
||||
|
||||
_, err := client.UserLatencyInsights(ctx, codersdk.UserLatencyInsightsRequest{
|
||||
StartTime: today,
|
||||
EndTime: time.Now().UTC().Truncate(time.Hour).Add(time.Hour), // Round up to include the current hour.
|
||||
TemplateIDs: templateIDs,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Run("AsTemplateAdmin", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{})
|
||||
admin := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleTemplateAdmin())
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||
defer cancel()
|
||||
|
||||
var templateIDs []uuid.UUID
|
||||
if tt.withTemplate {
|
||||
version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, admin.OrganizationID, version.ID)
|
||||
templateIDs = append(templateIDs, template.ID)
|
||||
}
|
||||
|
||||
_, err := templateAdmin.UserLatencyInsights(ctx, codersdk.UserLatencyInsightsRequest{
|
||||
StartTime: today,
|
||||
EndTime: time.Now().UTC().Truncate(time.Hour).Add(time.Hour), // Round up to include the current hour.
|
||||
TemplateIDs: templateIDs,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Run("AsRegularUser", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{})
|
||||
admin := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
regular, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||
defer cancel()
|
||||
|
||||
var templateIDs []uuid.UUID
|
||||
if tt.withTemplate {
|
||||
version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, admin.OrganizationID, version.ID)
|
||||
templateIDs = append(templateIDs, template.ID)
|
||||
}
|
||||
|
||||
_, err := regular.UserLatencyInsights(ctx, codersdk.UserLatencyInsightsRequest{
|
||||
StartTime: today,
|
||||
EndTime: time.Now().UTC().Truncate(time.Hour).Add(time.Hour), // Round up to include the current hour.
|
||||
TemplateIDs: templateIDs,
|
||||
})
|
||||
require.Error(t, err)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user