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:
Cian Johnston 2023-07-11 14:30:33 +01:00 committed by GitHub
parent 75f62dc39d
commit 3f6a158016
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 31 additions and 4 deletions

View File

@ -2,6 +2,10 @@
# Over time we should try tightening some of these.
linters-settings:
exhaustruct:
include:
# Gradually extend to cover more of the codebase.
- 'httpmw\.\w+'
gocognit:
min-complexity: 46 # Min code complexity (def 30).
@ -195,6 +199,10 @@ issues:
# We use assertions rather than explicitly checking errors in tests
- errcheck
- forcetypeassert
- exhaustruct # This is unhelpful in tests.
- path: scripts/*
linters:
- exhaustruct
fix: true
max-issues-per-linter: 0
@ -219,6 +227,7 @@ linters:
- errcheck
- errname
- errorlint
- exhaustruct
- exportloopref
- forcetypeassert
- gocritic

View File

@ -390,6 +390,7 @@ func New(options *Options) *API {
RedirectToLogin: false,
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
Optional: false,
SessionTokenFunc: nil, // Default behavior
})
// Same as above but it redirects to the login page.
apiKeyMiddlewareRedirect := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
@ -398,6 +399,7 @@ func New(options *Options) *API {
RedirectToLogin: true,
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
Optional: false,
SessionTokenFunc: nil, // Default behavior
})
// Same as the first but it's optional.
apiKeyMiddlewareOptional := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
@ -406,6 +408,7 @@ func New(options *Options) *API {
RedirectToLogin: false,
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
Optional: true,
SessionTokenFunc: nil, // Default behavior
})
// API rate limit middleware. The counter is local and not shared between

View File

@ -20,7 +20,7 @@ type HSTSConfig struct {
func HSTSConfigOptions(maxAge int, options []string) (HSTSConfig, error) {
if maxAge <= 0 {
// 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

View File

@ -56,7 +56,10 @@ func ExtractRealIP(config *RealIPConfig) func(next http.Handler) http.Handler {
// configuration and headers. It does not mutate the original request.
func ExtractRealIPAddress(config *RealIPConfig, req *http.Request) (net.IP, error) {
if config == nil {
config = &RealIPConfig{}
config = &RealIPConfig{
TrustedOrigins: nil,
TrustedHeaders: nil,
}
}
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.
func FilterUntrustedOriginHeaders(config *RealIPConfig, req *http.Request) {
if config == nil {
config = &RealIPConfig{}
config = &RealIPConfig{
TrustedOrigins: nil,
TrustedHeaders: nil,
}
}
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
// to produce a config.
func ParseRealIPConfig(headers, origins []string) (*RealIPConfig, error) {
config := &RealIPConfig{}
config := &RealIPConfig{
TrustedOrigins: []*net.IPNet{},
TrustedHeaders: []string{},
}
for _, origin := range origins {
_, network, err := net.ParseCIDR(origin)
if err != nil {

View File

@ -88,6 +88,7 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
RedirectToLogin: false,
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
Optional: false,
SessionTokenFunc: nil, // Default behavior
})
apiKeyMiddlewareOptional := httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
DB: options.Database,
@ -95,6 +96,7 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
RedirectToLogin: false,
DisableSessionExpiryRefresh: options.DeploymentValues.DisableSessionExpiryRefresh.Value(),
Optional: true,
SessionTokenFunc: nil, // Default behavior
})
deploymentID, err := options.Database.GetDeploymentID(ctx)

View File

@ -527,6 +527,7 @@ distro() {
if [ -f /etc/os-release ]; then
(
# shellcheck disable=SC1091
. /etc/os-release
if [ "${ID_LIKE-}" ]; then
for id_like in $ID_LIKE; do
@ -553,6 +554,7 @@ distro_name() {
if [ -f /etc/os-release ]; then
(
# shellcheck disable=SC1091
. /etc/os-release
echo "$PRETTY_NAME"
)

View File

@ -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
// the frontend will perform API requests if this fails.
DisableSessionExpiryRefresh: true,
RedirectToLogin: false,
SessionTokenFunc: nil,
})
if apiKey != nil && actor != nil {
ctx := dbauthz.As(r.Context(), actor.Actor)