Skip to content

refactor(coderd/httpapi): remove database, dbauthz and rbac imports #9481

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 2 commits into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions coderd/database/dbauthz/dbauthz.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"cdr.dev/slog"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi/httpapiconstraints"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/coderd/util/slice"
)
Expand All @@ -36,10 +37,18 @@ type NotAuthorizedError struct {
Err error
}

// Ensure we implement the IsUnauthorized interface.
var _ httpapiconstraints.IsUnauthorizedError = (*NotAuthorizedError)(nil)

func (e NotAuthorizedError) Error() string {
return fmt.Sprintf("unauthorized: %s", e.Err.Error())
}

// IsUnauthorized implements the IsUnauthorized interface.
func (NotAuthorizedError) IsUnauthorized() bool {
return true
}

// Unwrap will always unwrap to a sql.ErrNoRows so the API returns a 404.
// So 'errors.Is(err, sql.ErrNoRows)' will always be true.
func (e NotAuthorizedError) Unwrap() error {
Expand Down
11 changes: 8 additions & 3 deletions coderd/httpapi/httpapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import (
"github.com/go-playground/validator/v10"
"golang.org/x/xerrors"

"github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/coderd/httpapi/httpapiconstraints"
"github.com/coder/coder/v2/coderd/tracing"
"github.com/coder/coder/v2/codersdk"
)
Expand Down Expand Up @@ -90,7 +89,13 @@ func Is404Error(err error) bool {
if err == nil {
return false
}
return xerrors.Is(err, sql.ErrNoRows) || dbauthz.IsNotAuthorizedError(err) || rbac.IsUnauthorizedError(err)

// This tests for dbauthz.IsNotAuthorizedError and rbac.IsUnauthorizedError.
var unauthorized httpapiconstraints.IsUnauthorizedError
if errors.As(err, &unauthorized) && unauthorized.IsUnauthorized() {
return true
}
return xerrors.Is(err, sql.ErrNoRows)
}

// Convenience error functions don't take contexts since their responses are
Expand Down
10 changes: 10 additions & 0 deletions coderd/httpapi/httpapiconstraints/httpapiconstraints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Package httpapiconstraints contain types that can be used and implemented
// across the application to return specific HTTP status codes without pulling
// in large dependency trees.
package httpapiconstraints

// IsUnauthorizedError is an interface that can be implemented in other packages
// in order to return 404.
type IsUnauthorizedError interface {
IsUnauthorized() bool
}
7 changes: 3 additions & 4 deletions coderd/httpapi/queryparams.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/google/uuid"
"golang.org/x/xerrors"

"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/codersdk"
)

Expand Down Expand Up @@ -158,10 +157,10 @@ func (p *QueryParamParser) Strings(vals url.Values, def []string, queryParam str
})
}

// ValidEnum parses enum query params. Add more to the list as needed.
// ValidEnum represents an enum that can be parsed and validated.
type ValidEnum interface {
database.ResourceType | database.AuditAction | database.BuildReason | database.UserStatus |
database.WorkspaceStatus
// Add more types as needed (avoid importing large dependency trees).
~string

// Valid is required on the enum type to be used with ParseEnum.
Valid() bool
Expand Down
10 changes: 10 additions & 0 deletions coderd/rbac/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/open-policy-agent/opa/rego"
"github.com/open-policy-agent/opa/topdown"
"golang.org/x/xerrors"

"github.com/coder/coder/v2/coderd/httpapi/httpapiconstraints"
)

const (
Expand All @@ -33,6 +35,14 @@ type UnauthorizedError struct {
output rego.ResultSet
}

// Ensure we implement the IsUnauthorized interface.
var _ httpapiconstraints.IsUnauthorizedError = (*UnauthorizedError)(nil)

// IsUnauthorized implements the IsUnauthorized interface.
func (UnauthorizedError) IsUnauthorized() bool {
return true
}

// IsUnauthorizedError is a convenience function to check if err is UnauthorizedError.
// It is equivalent to errors.As(err, &UnauthorizedError{}).
func IsUnauthorizedError(err error) bool {
Expand Down