Skip to content

feat: Guard search queries against common mistakes #6404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Mar 2, 2023
Merged
Prev Previous commit
Next Next commit
Raise errors in FE on workspaces table
  • Loading branch information
Emyrk committed Mar 1, 2023
commit 5316ff08f0ccd9d86f170c55c0775d24d620faf3
22 changes: 11 additions & 11 deletions coderd/database/dbfake/databasefake.go
Original file line number Diff line number Diff line change
Expand Up @@ -966,13 +966,13 @@ func (q *fakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
return nil, xerrors.Errorf("get provisioner job: %w", err)
}

switch arg.Status {
case "pending":
switch database.WorkspaceStatus(arg.Status) {
case database.WorkspaceStatusPending:
if !job.StartedAt.Valid {
continue
}

case "starting":
case database.WorkspaceStatusStarting:
if !job.StartedAt.Valid &&
!job.CanceledAt.Valid &&
job.CompletedAt.Valid &&
Expand All @@ -981,15 +981,15 @@ func (q *fakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
continue
}

case "running":
case database.WorkspaceStatusRunning:
if !job.CompletedAt.Valid &&
job.CanceledAt.Valid &&
job.Error.Valid ||
build.Transition != database.WorkspaceTransitionStart {
continue
}

case "stopping":
case database.WorkspaceStatusStopping:
if !job.StartedAt.Valid &&
!job.CanceledAt.Valid &&
job.CompletedAt.Valid &&
Expand All @@ -998,31 +998,31 @@ func (q *fakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
continue
}

case "stopped":
case database.WorkspaceStatusStopped:
if !job.CompletedAt.Valid &&
job.CanceledAt.Valid &&
job.Error.Valid ||
build.Transition != database.WorkspaceTransitionStop {
continue
}

case "failed":
case database.WorkspaceStatusFailed:
if (!job.CanceledAt.Valid && !job.Error.Valid) ||
(!job.CompletedAt.Valid && !job.Error.Valid) {
continue
}

case "canceling":
case database.WorkspaceStatusCanceling:
if !job.CanceledAt.Valid && job.CompletedAt.Valid {
continue
}

case "canceled":
case database.WorkspaceStatusCanceled:
if !job.CanceledAt.Valid && !job.CompletedAt.Valid {
continue
}

case "deleted":
case database.WorkspaceStatusDeleted:
if !job.StartedAt.Valid &&
job.CanceledAt.Valid &&
!job.CompletedAt.Valid &&
Expand All @@ -1031,7 +1031,7 @@ func (q *fakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
continue
}

case "deleting":
case database.WorkspaceStatusDeleting:
if !job.CompletedAt.Valid &&
job.CanceledAt.Valid &&
job.Error.Valid &&
Expand Down
27 changes: 27 additions & 0 deletions coderd/database/modelmethods.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,33 @@ import (
"github.com/coder/coder/coderd/rbac"
)

type WorkspaceStatus string

const (
WorkspaceStatusPending WorkspaceStatus = "pending"
WorkspaceStatusStarting WorkspaceStatus = "starting"
WorkspaceStatusRunning WorkspaceStatus = "running"
WorkspaceStatusStopping WorkspaceStatus = "stopping"
WorkspaceStatusStopped WorkspaceStatus = "stopped"
WorkspaceStatusFailed WorkspaceStatus = "failed"
WorkspaceStatusCanceling WorkspaceStatus = "canceling"
WorkspaceStatusCanceled WorkspaceStatus = "canceled"
WorkspaceStatusDeleting WorkspaceStatus = "deleting"
WorkspaceStatusDeleted WorkspaceStatus = "deleted"
)

func (s WorkspaceStatus) Valid() bool {
switch s {
case WorkspaceStatusPending, WorkspaceStatusStarting, WorkspaceStatusRunning,
WorkspaceStatusStopping, WorkspaceStatusStopped, WorkspaceStatusFailed,
WorkspaceStatusCanceling, WorkspaceStatusCanceled, WorkspaceStatusDeleting,
WorkspaceStatusDeleted:
return true
default:
return false
}
}

type AuditableGroup struct {
Group
Members []GroupMember `json:"members"`
Expand Down
3 changes: 2 additions & 1 deletion coderd/httpapi/queryparams.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ func (p *QueryParamParser) Strings(vals url.Values, def []string, queryParam str

// ValidEnum parses enum query params. Add more to the list as needed.
type ValidEnum interface {
database.ResourceType | database.AuditAction | database.BuildReason | database.UserStatus
database.ResourceType | database.AuditAction | database.BuildReason | database.UserStatus |
database.WorkspaceStatus

// Valid is required on the enum type to be used with ParseEnum.
Valid() bool
Expand Down
3 changes: 2 additions & 1 deletion coderd/searchquery/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func Audit(query string) (database.GetAuditLogsOffsetParams, []codersdk.Validati
Action: string(httpapi.ParseCustom(parser, values, "", "action", httpapi.ParseEnum[database.ResourceType])),
BuildReason: string(httpapi.ParseCustom(parser, values, "", "build_reason", httpapi.ParseEnum[database.ResourceType])),
}
parser.ErrorExcessParams(values)
return filter, parser.Errors
}

Expand Down Expand Up @@ -98,7 +99,7 @@ func Workspace(query string, page codersdk.Pagination, agentInactiveDisconnectTi
filter.OwnerUsername = parser.String(values, "", "owner")
filter.TemplateName = parser.String(values, "", "template")
filter.Name = parser.String(values, "", "name")
filter.Status = parser.String(values, "", "status")
filter.Status = string(httpapi.ParseCustom(parser, values, "", "status", httpapi.ParseEnum[database.WorkspaceStatus]))
filter.HasAgent = parser.String(values, "", "has-agent")
parser.ErrorExcessParams(values)
return filter, parser.Errors
Expand Down
1 change: 1 addition & 0 deletions site/src/pages/WorkspacesPage/WorkspacesPageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export const WorkspacesPageView: FC<
filter={filter}
onFilter={onFilter}
presetFilters={presetFilters}
error={error}
/>
</Stack>
<WorkspacesTable
Expand Down