mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
chore: enable exhaustruct linter (#8403)
* chore: enable exhaustruct linter * add exlusion rules * move to allowlist instead * exhaustruct httpmw package * fixup! exhaustruct httpmw package * make lint * address PR comments
This commit is contained in:
@@ -2,6 +2,10 @@
|
|||||||
# Over time we should try tightening some of these.
|
# Over time we should try tightening some of these.
|
||||||
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
|
exhaustruct:
|
||||||
|
include:
|
||||||
|
# Gradually extend to cover more of the codebase.
|
||||||
|
- 'httpmw\.\w+'
|
||||||
gocognit:
|
gocognit:
|
||||||
min-complexity: 46 # Min code complexity (def 30).
|
min-complexity: 46 # Min code complexity (def 30).
|
||||||
|
|
||||||
@@ -195,6 +199,10 @@ issues:
|
|||||||
# We use assertions rather than explicitly checking errors in tests
|
# We use assertions rather than explicitly checking errors in tests
|
||||||
- errcheck
|
- errcheck
|
||||||
- forcetypeassert
|
- forcetypeassert
|
||||||
|
- exhaustruct # This is unhelpful in tests.
|
||||||
|
- path: scripts/*
|
||||||
|
linters:
|
||||||
|
- exhaustruct
|
||||||
|
|
||||||
fix: true
|
fix: true
|
||||||
max-issues-per-linter: 0
|
max-issues-per-linter: 0
|
||||||
@@ -219,6 +227,7 @@ linters:
|
|||||||
- errcheck
|
- errcheck
|
||||||
- errname
|
- errname
|
||||||
- errorlint
|
- errorlint
|
||||||
|
- exhaustruct
|
||||||
- exportloopref
|
- exportloopref
|
||||||
- forcetypeassert
|
- forcetypeassert
|
||||||
- gocritic
|
- gocritic
|
||||||
|
|||||||
@@ -390,6 +390,7 @@ func New(options *Options) *API {
|
|||||||
RedirectToLogin: false,
|
RedirectToLogin: false,
|
||||||
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
|
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
|
||||||
Optional: false,
|
Optional: false,
|
||||||
|
SessionTokenFunc: nil, // Default behavior
|
||||||
})
|
})
|
||||||
// Same as above but it redirects to the login page.
|
// Same as above but it redirects to the login page.
|
||||||
apiKeyMiddlewareRedirect := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
|
apiKeyMiddlewareRedirect := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
|
||||||
@@ -398,6 +399,7 @@ func New(options *Options) *API {
|
|||||||
RedirectToLogin: true,
|
RedirectToLogin: true,
|
||||||
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
|
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
|
||||||
Optional: false,
|
Optional: false,
|
||||||
|
SessionTokenFunc: nil, // Default behavior
|
||||||
})
|
})
|
||||||
// Same as the first but it's optional.
|
// Same as the first but it's optional.
|
||||||
apiKeyMiddlewareOptional := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
|
apiKeyMiddlewareOptional := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
|
||||||
@@ -406,6 +408,7 @@ func New(options *Options) *API {
|
|||||||
RedirectToLogin: false,
|
RedirectToLogin: false,
|
||||||
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
|
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
SessionTokenFunc: nil, // Default behavior
|
||||||
})
|
})
|
||||||
|
|
||||||
// API rate limit middleware. The counter is local and not shared between
|
// API rate limit middleware. The counter is local and not shared between
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ type HSTSConfig struct {
|
|||||||
func HSTSConfigOptions(maxAge int, options []string) (HSTSConfig, error) {
|
func HSTSConfigOptions(maxAge int, options []string) (HSTSConfig, error) {
|
||||||
if maxAge <= 0 {
|
if maxAge <= 0 {
|
||||||
// No header, so no need to build the header string.
|
// No header, so no need to build the header string.
|
||||||
return HSTSConfig{}, nil
|
return HSTSConfig{HeaderValue: ""}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
|
||||||
|
|||||||
+12
-3
@@ -56,7 +56,10 @@ func ExtractRealIP(config *RealIPConfig) func(next http.Handler) http.Handler {
|
|||||||
// configuration and headers. It does not mutate the original request.
|
// configuration and headers. It does not mutate the original request.
|
||||||
func ExtractRealIPAddress(config *RealIPConfig, req *http.Request) (net.IP, error) {
|
func ExtractRealIPAddress(config *RealIPConfig, req *http.Request) (net.IP, error) {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = &RealIPConfig{}
|
config = &RealIPConfig{
|
||||||
|
TrustedOrigins: nil,
|
||||||
|
TrustedHeaders: nil,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cf := isContainedIn(config.TrustedOrigins, getRemoteAddress(req.RemoteAddr))
|
cf := isContainedIn(config.TrustedOrigins, getRemoteAddress(req.RemoteAddr))
|
||||||
@@ -81,7 +84,10 @@ func ExtractRealIPAddress(config *RealIPConfig, req *http.Request) (net.IP, erro
|
|||||||
// of each proxy header is set.
|
// of each proxy header is set.
|
||||||
func FilterUntrustedOriginHeaders(config *RealIPConfig, req *http.Request) {
|
func FilterUntrustedOriginHeaders(config *RealIPConfig, req *http.Request) {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
config = &RealIPConfig{}
|
config = &RealIPConfig{
|
||||||
|
TrustedOrigins: nil,
|
||||||
|
TrustedHeaders: nil,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cf := isContainedIn(config.TrustedOrigins, getRemoteAddress(req.RemoteAddr))
|
cf := isContainedIn(config.TrustedOrigins, getRemoteAddress(req.RemoteAddr))
|
||||||
@@ -208,7 +214,10 @@ func RealIP(ctx context.Context) *RealIPState {
|
|||||||
// ParseRealIPConfig takes a raw string array of headers and origins
|
// ParseRealIPConfig takes a raw string array of headers and origins
|
||||||
// to produce a config.
|
// to produce a config.
|
||||||
func ParseRealIPConfig(headers, origins []string) (*RealIPConfig, error) {
|
func ParseRealIPConfig(headers, origins []string) (*RealIPConfig, error) {
|
||||||
config := &RealIPConfig{}
|
config := &RealIPConfig{
|
||||||
|
TrustedOrigins: []*net.IPNet{},
|
||||||
|
TrustedHeaders: []string{},
|
||||||
|
}
|
||||||
for _, origin := range origins {
|
for _, origin := range origins {
|
||||||
_, network, err := net.ParseCIDR(origin)
|
_, network, err := net.ParseCIDR(origin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
|
|||||||
RedirectToLogin: false,
|
RedirectToLogin: false,
|
||||||
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
|
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
|
||||||
Optional: false,
|
Optional: false,
|
||||||
|
SessionTokenFunc: nil, // Default behavior
|
||||||
})
|
})
|
||||||
apiKeyMiddlewareOptional := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
|
apiKeyMiddlewareOptional := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
|
||||||
DB: options.Database,
|
DB: options.Database,
|
||||||
@@ -95,6 +96,7 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
|
|||||||
RedirectToLogin: false,
|
RedirectToLogin: false,
|
||||||
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
|
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
SessionTokenFunc: nil, // Default behavior
|
||||||
})
|
})
|
||||||
|
|
||||||
deploymentID, err := options.Database.GetDeploymentID(ctx)
|
deploymentID, err := options.Database.GetDeploymentID(ctx)
|
||||||
|
|||||||
@@ -527,6 +527,7 @@ distro() {
|
|||||||
|
|
||||||
if [ -f /etc/os-release ]; then
|
if [ -f /etc/os-release ]; then
|
||||||
(
|
(
|
||||||
|
# shellcheck disable=SC1091
|
||||||
. /etc/os-release
|
. /etc/os-release
|
||||||
if [ "${ID_LIKE-}" ]; then
|
if [ "${ID_LIKE-}" ]; then
|
||||||
for id_like in $ID_LIKE; do
|
for id_like in $ID_LIKE; do
|
||||||
@@ -553,6 +554,7 @@ distro_name() {
|
|||||||
|
|
||||||
if [ -f /etc/os-release ]; then
|
if [ -f /etc/os-release ]; then
|
||||||
(
|
(
|
||||||
|
# shellcheck disable=SC1091
|
||||||
. /etc/os-release
|
. /etc/os-release
|
||||||
echo "$PRETTY_NAME"
|
echo "$PRETTY_NAME"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -297,6 +297,8 @@ func (h *Handler) renderHTMLWithState(rw http.ResponseWriter, r *http.Request, f
|
|||||||
// Special case for site, we can always disable refresh here because
|
// Special case for site, we can always disable refresh here because
|
||||||
// the frontend will perform API requests if this fails.
|
// the frontend will perform API requests if this fails.
|
||||||
DisableSessionExpiryRefresh: true,
|
DisableSessionExpiryRefresh: true,
|
||||||
|
RedirectToLogin: false,
|
||||||
|
SessionTokenFunc: nil,
|
||||||
})
|
})
|
||||||
if apiKey != nil && actor != nil {
|
if apiKey != nil && actor != nil {
|
||||||
ctx := dbauthz.As(r.Context(), actor.Actor)
|
ctx := dbauthz.As(r.Context(), actor.Actor)
|
||||||
|
|||||||
Reference in New Issue
Block a user