Merged in feature/linting (pull request #168)

Linting Updates

* precommit

* smallerchecks

* govuln
This commit is contained in:
Michael McGuinness
2025-06-23 15:58:20 +00:00
parent daf4d4b94b
commit 3028fe7eaa
24 changed files with 226 additions and 128 deletions
+20 -5
View File
@@ -17,6 +17,14 @@ linters:
- cyclop
- unused
- usetesting
- paralleltest
- bodyclose # Check HTTP response bodies are closed
- gochecknoinits # Disallow `init` functions
# - gocritic # Advanced style/performance checks
# - errorlint # Enforce error wrapping best practices
# - exhaustive # Require case exhaustiveness in switches
# - forbidigo # Ban specific identifiers (e.g., unsafe patterns)
# - nestif # Limit nested complexity (default: min-complexity=5)
linters-settings:
errcheck:
@@ -36,9 +44,20 @@ linters-settings:
- HACK
- TODO
- FIXME
# govet:
# enable-all: true # Enable all vet analyzers
# gocritic:
# enabled-checks:
# - rangeValCopy # Warn on copying large range values
# - hugeParam # Warn on large parameters passed by value
# - badCall # Detect suspicious function calls
# # Add other strict checks from https://go-critic.com
issues:
exclude-rules:
- path-except: ^test/
linters:
- paralleltest
- path: cmd/metricsExample_test/main\.go
linters:
- gosec
@@ -54,10 +73,6 @@ issues:
- path: internal/serviceconfig/objectstore/config.go
linters:
- gosec
text: "G401"
- path: internal/serviceconfig/objectstore/config.go
linters:
- gosec
text: "G501"
text: "G401|G501"
max-issues-per-linter: 0
max-same-issues: 0
@@ -7,6 +7,7 @@ package main
import (
"context"
"encoding/csv"
"errors"
"flag"
"fmt"
"io"
@@ -114,7 +115,7 @@ func run() error {
// Initialize audit logger
auditLogger, err := NewAuditLogger(config.DryRun)
if err != nil {
return fmt.Errorf("failed to initialize audit logger: %v", err)
return fmt.Errorf("failed to initialize audit logger: %w", err)
}
defer auditLogger.Close()
@@ -138,20 +139,20 @@ func run() error {
// Validate configuration
if err := validateConfig(config); err != nil {
return fmt.Errorf("configuration error: %v", err)
return fmt.Errorf("configuration error: %w", err)
}
// Initialize AWS Cognito client
ctx := context.Background()
cognitoClient, err := initializeCognitoClient()
if err != nil {
return fmt.Errorf("error initializing Cognito client: %v", err)
return fmt.Errorf("error initializing Cognito client: %w", err)
}
// Read and parse CSV file
users, err := readCSV(config.CSVPath, config)
if err != nil {
return fmt.Errorf("error reading CSV file: %v", err)
return fmt.Errorf("error reading CSV file: %w", err)
}
if len(users) == 0 {
@@ -385,7 +386,7 @@ func readCSV(path string, config AppConfig) ([]map[string]string, error) {
// Read and validate header
header, err := reader.Read()
if err != nil {
return nil, fmt.Errorf("error reading CSV header: %v", err)
return nil, fmt.Errorf("error reading CSV header: %w", err)
}
if err := validateCSVHeader(header, config); err != nil {
@@ -443,11 +444,11 @@ func readUserRecords(reader *csv.Reader, config AppConfig) ([]map[string]string,
for {
record, err := reader.Read()
if err == io.EOF {
if errors.Is(err, io.EOF) {
break
}
if err != nil {
return nil, fmt.Errorf("error reading line %d: %v", lineNum+1, err)
return nil, fmt.Errorf("error reading line %d: %w", lineNum+1, err)
}
lineNum++
@@ -652,7 +653,7 @@ func ensureCognitoUser(ctx context.Context, procCtx *UserProcessingContext) (*Co
if err != nil {
auditLogger.LogAction(ActionCreate, SystemCognito, user["email"], ResultFailure, fmt.Sprintf("Failed to retrieve existing user: %v", err))
fmt.Printf(" ❌ Failed to retrieve existing Cognito user: %v\n", err)
return nil, fmt.Errorf("failed to retrieve existing Cognito user: %v", err)
return nil, fmt.Errorf("failed to retrieve existing Cognito user: %w", err)
}
return existingUser, nil
}
@@ -676,7 +677,7 @@ func ensureCognitoUser(ctx context.Context, procCtx *UserProcessingContext) (*Co
if err != nil {
auditLogger.LogAction(ActionCreate, SystemCognito, user["email"], ResultFailure, fmt.Sprintf("Failed to create: %v", err))
fmt.Printf(" ❌ Cognito creation failed: %v\n", err)
return nil, fmt.Errorf("failed to create in Cognito: %v", err)
return nil, fmt.Errorf("failed to create in Cognito: %w", err)
}
auditLogger.LogActionWithSubjectID(ActionCreate, SystemCognito, user["email"], cognitoUser.SubjectID, ResultSuccess, "User created successfully")
@@ -696,7 +697,7 @@ func ensurePermitUser(procCtx *UserProcessingContext, cognitoUser *CognitoUserRe
if err != nil {
auditLogger.LogAction(ActionCreate, SystemPermit, user["email"], ResultFailure, fmt.Sprintf("Failed to check user existence: %v", err))
fmt.Printf(" ❌ Failed to check Permit.io user existence: %v\n", err)
return fmt.Errorf("failed to check Permit.io user existence: %v", err)
return fmt.Errorf("failed to check Permit.io user existence: %w", err)
}
if permitExists {
@@ -716,7 +717,7 @@ func ensurePermitUser(procCtx *UserProcessingContext, cognitoUser *CognitoUserRe
if err != nil {
auditLogger.LogActionWithSubjectID(ActionCreate, SystemPermit, user["email"], cognitoUser.SubjectID, ResultFailure, fmt.Sprintf("Failed to create: %v", err))
fmt.Printf(" ❌ Permit.io creation failed: %v\n", err)
return fmt.Errorf("failed to create in Permit.io: %v", err)
return fmt.Errorf("failed to create in Permit.io: %w", err)
}
auditLogger.LogActionWithSubjectID(ActionCreate, SystemPermit, user["email"], cognitoUser.SubjectID, ResultSuccess, "User created successfully")
+23 -23
View File
@@ -46,12 +46,12 @@ func createPermitUser(client *http.Client, config AppConfig, cognitoUser *Cognit
jsonData, err := json.Marshal(userObj)
if err != nil {
return fmt.Errorf("error marshaling user data: %v", err)
return fmt.Errorf("error marshaling user data: %w", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("error creating request: %v", err)
return fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+config.PermitAPIKey)
@@ -59,7 +59,7 @@ func createPermitUser(client *http.Client, config AppConfig, cognitoUser *Cognit
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("error making request: %v", err)
return fmt.Errorf("error making request: %w", err)
}
defer resp.Body.Close()
@@ -100,12 +100,12 @@ func assignRole(client *http.Client, config AppConfig, userID, role string) erro
jsonData, err := json.Marshal(assignment)
if err != nil {
return fmt.Errorf("error marshaling role assignment: %v", err)
return fmt.Errorf("error marshaling role assignment: %w", err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("error creating request: %v", err)
return fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+config.PermitAPIKey)
@@ -113,7 +113,7 @@ func assignRole(client *http.Client, config AppConfig, userID, role string) erro
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("error making request: %v", err)
return fmt.Errorf("error making request: %w", err)
}
defer resp.Body.Close()
@@ -141,7 +141,7 @@ func findPermitUserByEmail(client *http.Client, config AppConfig, email string)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return "", fmt.Errorf("error creating request: %v", err)
return "", fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+config.PermitAPIKey)
@@ -149,7 +149,7 @@ func findPermitUserByEmail(client *http.Client, config AppConfig, email string)
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("error making request: %v", err)
return "", fmt.Errorf("error making request: %w", err)
}
defer resp.Body.Close()
@@ -163,7 +163,7 @@ func findPermitUserByEmail(client *http.Client, config AppConfig, email string)
// First try to unmarshal as an object (paginated response)
var response map[string]interface{}
if err := json.Unmarshal(body, &response); err != nil {
return "", fmt.Errorf("error parsing response: %v", err)
return "", fmt.Errorf("error parsing response: %w", err)
}
// Look for users in common pagination structures
@@ -207,14 +207,14 @@ func deletePermitUser(client *http.Client, config AppConfig, userKey string) err
req, err := http.NewRequest("DELETE", url, nil)
if err != nil {
return fmt.Errorf("error creating request: %v", err)
return fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+config.PermitAPIKey)
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("error making request: %v", err)
return fmt.Errorf("error making request: %w", err)
}
defer resp.Body.Close()
@@ -238,7 +238,7 @@ func getPermitUserRoles(client *http.Client, config AppConfig, userKey string) (
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
return nil, fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+config.PermitAPIKey)
@@ -246,7 +246,7 @@ func getPermitUserRoles(client *http.Client, config AppConfig, userKey string) (
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
return nil, fmt.Errorf("error making request: %w", err)
}
defer resp.Body.Close()
@@ -257,7 +257,7 @@ func getPermitUserRoles(client *http.Client, config AppConfig, userKey string) (
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
return nil, fmt.Errorf("error reading response: %w", err)
}
var roles []string
@@ -271,7 +271,7 @@ func getPermitUserRoles(client *http.Client, config AppConfig, userKey string) (
// If that fails, try as object with data/items/etc
var response map[string]interface{}
if err := json.Unmarshal(body, &response); err != nil {
return nil, fmt.Errorf("error parsing response as object or array: %v", err)
return nil, fmt.Errorf("error parsing response as object or array: %w", err)
}
// Look for role assignments in common response structures
@@ -308,12 +308,12 @@ func unassignRole(client *http.Client, config AppConfig, userID, role string) er
jsonData, err := json.Marshal(assignment)
if err != nil {
return fmt.Errorf("error marshaling role assignment: %v", err)
return fmt.Errorf("error marshaling role assignment: %w", err)
}
req, err := http.NewRequest("DELETE", url, bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("error creating request: %v", err)
return fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+config.PermitAPIKey)
@@ -321,7 +321,7 @@ func unassignRole(client *http.Client, config AppConfig, userID, role string) er
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("error making request: %v", err)
return fmt.Errorf("error making request: %w", err)
}
defer resp.Body.Close()
@@ -458,7 +458,7 @@ func ValidateCSVRoles(client *http.Client, config AppConfig, csvUsers []map[stri
// Get all existing roles from Permit.io
existingRoles, err := getExistingRoles(client, config)
if err != nil {
return requestedRoles, fmt.Errorf("failed to retrieve existing roles from Permit.io: %v", err)
return requestedRoles, fmt.Errorf("failed to retrieve existing roles from Permit.io: %w", err)
}
// Check which requested roles are missing
@@ -528,7 +528,7 @@ func getExistingRoles(client *http.Client, config AppConfig) ([]string, error) {
// Create HTTP request
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
return nil, fmt.Errorf("error creating request: %w", err)
}
// Set authorization header
@@ -538,7 +538,7 @@ func getExistingRoles(client *http.Client, config AppConfig) ([]string, error) {
// Execute request
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
return nil, fmt.Errorf("error making request: %w", err)
}
defer resp.Body.Close()
@@ -551,7 +551,7 @@ func getExistingRoles(client *http.Client, config AppConfig) ([]string, error) {
// Read and parse response body
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response: %v", err)
return nil, fmt.Errorf("error reading response: %w", err)
}
// Parse JSON response - try different response structures
@@ -566,7 +566,7 @@ func getExistingRoles(client *http.Client, config AppConfig) ([]string, error) {
// If that fails, try as object with data/items/etc
var response map[string]interface{}
if err := json.Unmarshal(body, &response); err != nil {
return nil, fmt.Errorf("error parsing response as object or array: %v", err)
return nil, fmt.Errorf("error parsing response as object or array: %w", err)
}
// Look for roles in common response structures
+11 -3
View File
@@ -2,19 +2,27 @@
package main
import (
"errors"
"net/http"
"os"
)
func main() {
resp, err := http.Get("http://localhost:8080/health")
err := check()
if err != nil {
os.Exit(1)
}
}
func check() error {
resp, err := http.Get("http://localhost:8080/health")
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
os.Exit(1)
return errors.New("Status code not OK")
}
os.Exit(0)
return nil
}
+1 -1
View File
@@ -101,7 +101,7 @@ func main() {
swagger, err := queryapi.GetSwagger()
if err != nil {
return nil, fmt.Errorf("error loading swagger: %s", err)
return nil, fmt.Errorf("error loading swagger: %w", err)
}
return swagger, nil
+6 -5
View File
@@ -57,13 +57,14 @@
"postgresql@17.2",
"bc@1.07.1",
"gomarkdoc@1.1.0",
"go@1.24.0",
"sqlcheck@1.3",
"docker-client@27.3.1",
"gotestsum@latest",
"goperf@latest",
"graphviz@latest",
"psrecord@latest"
"gotestsum@1.12.2",
"goperf@0-unstable-2025-05-05",
"graphviz@12.2.1",
"psrecord@1.2",
"govulncheck@1.1.4",
"go@1.24.3"
],
"shell": {
"init_hook": [
+96 -52
View File
@@ -161,10 +161,6 @@
}
}
},
"github:NixOS/nixpkgs/nixpkgs-unstable": {
"last_modified": "2025-06-10T02:39:58Z",
"resolved": "github:NixOS/nixpkgs/cdc68935eba9f86d155585fdf6f17af6824f38ac?lastModified=1749523198&narHash=sha256-How2kQw0psKmCdXgojc95Sf3K5maHB3qfINxTZFCAPM%3D"
},
"glibcLocales@latest": {
"last_modified": "2025-05-16T20:19:48Z",
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#glibcLocales",
@@ -289,51 +285,51 @@
}
}
},
"go@1.24.0": {
"last_modified": "2025-02-12T00:10:52Z",
"resolved": "github:NixOS/nixpkgs/83a2581c81ff5b06f7c1a4e7cc736a455dfcf7b4#go_1_24",
"go@1.24.3": {
"last_modified": "2025-05-16T20:19:48Z",
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#go",
"source": "devbox-search",
"version": "1.24.0",
"version": "1.24.3",
"systems": {
"aarch64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/qldcnifalkvyah0wnv7m4zb854yd9l88-go-1.24.0",
"path": "/nix/store/ps3admpzmc1ryvn9q7sw5xfd94dkrb3f-go-1.24.3",
"default": true
}
],
"store_path": "/nix/store/qldcnifalkvyah0wnv7m4zb854yd9l88-go-1.24.0"
"store_path": "/nix/store/ps3admpzmc1ryvn9q7sw5xfd94dkrb3f-go-1.24.3"
},
"aarch64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/rrxgml7w4pfmibjbspkdvrw8vd2vnarb-go-1.24.0",
"path": "/nix/store/45bnqhyyq40p91k3cjw0farx3hn1swx6-go-1.24.3",
"default": true
}
],
"store_path": "/nix/store/rrxgml7w4pfmibjbspkdvrw8vd2vnarb-go-1.24.0"
"store_path": "/nix/store/45bnqhyyq40p91k3cjw0farx3hn1swx6-go-1.24.3"
},
"x86_64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/7imv22pl4qrjwvi6jzlfb305rc2min45-go-1.24.0",
"path": "/nix/store/9z2kb6hxij7pqi0fgcn9ijhpb7ajpazs-go-1.24.3",
"default": true
}
],
"store_path": "/nix/store/7imv22pl4qrjwvi6jzlfb305rc2min45-go-1.24.0"
"store_path": "/nix/store/9z2kb6hxij7pqi0fgcn9ijhpb7ajpazs-go-1.24.3"
},
"x86_64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/vh5d5bj1sljdhdypy80x1ydx2jx6rv2q-go-1.24.0",
"path": "/nix/store/5xvi25nqmbrg58aixp4zgczilfnp7pwg-go-1.24.3",
"default": true
}
],
"store_path": "/nix/store/vh5d5bj1sljdhdypy80x1ydx2jx6rv2q-go-1.24.0"
"store_path": "/nix/store/5xvi25nqmbrg58aixp4zgczilfnp7pwg-go-1.24.3"
}
}
},
@@ -433,99 +429,99 @@
}
}
},
"goperf@latest": {
"last_modified": "2025-04-10T20:20:34Z",
"resolved": "github:NixOS/nixpkgs/d19cf9dfc633816a437204555afeb9e722386b76#goperf",
"goperf@0-unstable-2025-05-05": {
"last_modified": "2025-05-16T20:19:48Z",
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#goperf",
"source": "devbox-search",
"version": "0-unstable-2025-04-07",
"version": "0-unstable-2025-05-05",
"systems": {
"aarch64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/vf411izylvc8fq1m91ri8303xv1mha5d-goperf-0-unstable-2025-04-07",
"path": "/nix/store/sk50sp3wnhsb1lxf9495y2y5p2w0dkik-goperf-0-unstable-2025-05-05",
"default": true
}
],
"store_path": "/nix/store/vf411izylvc8fq1m91ri8303xv1mha5d-goperf-0-unstable-2025-04-07"
"store_path": "/nix/store/sk50sp3wnhsb1lxf9495y2y5p2w0dkik-goperf-0-unstable-2025-05-05"
},
"aarch64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/3f2ap46w6bshaf24s0d48rswm3rl12l6-goperf-0-unstable-2025-04-07",
"path": "/nix/store/gwlzys9sgp2vamgl4kvccqy3pv2x6a8k-goperf-0-unstable-2025-05-05",
"default": true
}
],
"store_path": "/nix/store/3f2ap46w6bshaf24s0d48rswm3rl12l6-goperf-0-unstable-2025-04-07"
"store_path": "/nix/store/gwlzys9sgp2vamgl4kvccqy3pv2x6a8k-goperf-0-unstable-2025-05-05"
},
"x86_64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/hp9gdz3y082isszsg6zcz8d6g0l1gk59-goperf-0-unstable-2025-04-07",
"path": "/nix/store/i8pyz4hx8hiqhmb6xxhinp1p4h5fjcsm-goperf-0-unstable-2025-05-05",
"default": true
}
],
"store_path": "/nix/store/hp9gdz3y082isszsg6zcz8d6g0l1gk59-goperf-0-unstable-2025-04-07"
"store_path": "/nix/store/i8pyz4hx8hiqhmb6xxhinp1p4h5fjcsm-goperf-0-unstable-2025-05-05"
},
"x86_64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/ardq6yb76al8kp45jlqa59by17l2a58y-goperf-0-unstable-2025-04-07",
"path": "/nix/store/9dmc6qyh3p2a3kpcm0zb8dh1ri70w5qv-goperf-0-unstable-2025-05-05",
"default": true
}
],
"store_path": "/nix/store/ardq6yb76al8kp45jlqa59by17l2a58y-goperf-0-unstable-2025-04-07"
"store_path": "/nix/store/9dmc6qyh3p2a3kpcm0zb8dh1ri70w5qv-goperf-0-unstable-2025-05-05"
}
}
},
"gotestsum@latest": {
"last_modified": "2025-04-05T00:48:53Z",
"resolved": "github:NixOS/nixpkgs/250b695f41e0e2f5afbf15c6b12480de1fe0001b#gotestsum",
"gotestsum@1.12.2": {
"last_modified": "2025-05-16T20:19:48Z",
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#gotestsum",
"source": "devbox-search",
"version": "1.12.0-unstable-2024-09-17",
"version": "1.12.2",
"systems": {
"aarch64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/93kwis02c81bwh382s1vdmsqp7s886fl-gotestsum-1.12.0-unstable-2024-09-17",
"path": "/nix/store/9kcdv1zs53izyy2a2j8qhdwq0nnn3rc7-gotestsum-1.12.2",
"default": true
}
],
"store_path": "/nix/store/93kwis02c81bwh382s1vdmsqp7s886fl-gotestsum-1.12.0-unstable-2024-09-17"
"store_path": "/nix/store/9kcdv1zs53izyy2a2j8qhdwq0nnn3rc7-gotestsum-1.12.2"
},
"aarch64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/hmil65sxh60c0mx2f1b41b883dmni5x9-gotestsum-1.12.0-unstable-2024-09-17",
"path": "/nix/store/lzg48k73z9n2zlb9znsrpmlv1g8c6f7a-gotestsum-1.12.2",
"default": true
}
],
"store_path": "/nix/store/hmil65sxh60c0mx2f1b41b883dmni5x9-gotestsum-1.12.0-unstable-2024-09-17"
"store_path": "/nix/store/lzg48k73z9n2zlb9znsrpmlv1g8c6f7a-gotestsum-1.12.2"
},
"x86_64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/1gj7gmd3jsxcn8sxa2zac13f7mh4frx4-gotestsum-1.12.0-unstable-2024-09-17",
"path": "/nix/store/wbc09rgw3yqz1k84xhqjkf6kcdd3k53p-gotestsum-1.12.2",
"default": true
}
],
"store_path": "/nix/store/1gj7gmd3jsxcn8sxa2zac13f7mh4frx4-gotestsum-1.12.0-unstable-2024-09-17"
"store_path": "/nix/store/wbc09rgw3yqz1k84xhqjkf6kcdd3k53p-gotestsum-1.12.2"
},
"x86_64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/5iq2g0zd9xiss7px89mdha3qlcws0cl4-gotestsum-1.12.0-unstable-2024-09-17",
"path": "/nix/store/4ixg21kip6xv15jm1p5zdcx46wmgnqw8-gotestsum-1.12.2",
"default": true
}
],
"store_path": "/nix/store/5iq2g0zd9xiss7px89mdha3qlcws0cl4-gotestsum-1.12.0-unstable-2024-09-17"
"store_path": "/nix/store/4ixg21kip6xv15jm1p5zdcx46wmgnqw8-gotestsum-1.12.2"
}
}
},
@@ -577,9 +573,57 @@
}
}
},
"graphviz@latest": {
"last_modified": "2025-03-24T07:07:41Z",
"resolved": "github:NixOS/nixpkgs/1750f3c1c89488e2ffdd47cab9d05454dddfb734#graphviz",
"govulncheck@1.1.4": {
"last_modified": "2025-05-16T20:19:48Z",
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#govulncheck",
"source": "devbox-search",
"version": "1.1.4",
"systems": {
"aarch64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/8rni7fry5sg928cqal7nglpqm8gppv81-govulncheck-1.1.4",
"default": true
}
],
"store_path": "/nix/store/8rni7fry5sg928cqal7nglpqm8gppv81-govulncheck-1.1.4"
},
"aarch64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/vkblf0jwdhrmy2m3pna5nn0cqrik7vlb-govulncheck-1.1.4",
"default": true
}
],
"store_path": "/nix/store/vkblf0jwdhrmy2m3pna5nn0cqrik7vlb-govulncheck-1.1.4"
},
"x86_64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/clr0jn9ggj928iyghhvd20h487rvz3r7-govulncheck-1.1.4",
"default": true
}
],
"store_path": "/nix/store/clr0jn9ggj928iyghhvd20h487rvz3r7-govulncheck-1.1.4"
},
"x86_64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/6nd9kbizh0w8yg0lsvm2gf458xd8m8j2-govulncheck-1.1.4",
"default": true
}
],
"store_path": "/nix/store/6nd9kbizh0w8yg0lsvm2gf458xd8m8j2-govulncheck-1.1.4"
}
}
},
"graphviz@12.2.1": {
"last_modified": "2025-05-16T20:19:48Z",
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#graphviz",
"source": "devbox-search",
"version": "12.2.1",
"systems": {
@@ -587,41 +631,41 @@
"outputs": [
{
"name": "out",
"path": "/nix/store/n261cb4vg4wijd3x0kbh2wxjccxk2b2y-graphviz-12.2.1",
"path": "/nix/store/jcznx2c2hz7iwk97xgzizi3rqkvnghmc-graphviz-12.2.1",
"default": true
}
],
"store_path": "/nix/store/n261cb4vg4wijd3x0kbh2wxjccxk2b2y-graphviz-12.2.1"
"store_path": "/nix/store/jcznx2c2hz7iwk97xgzizi3rqkvnghmc-graphviz-12.2.1"
},
"aarch64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/shsff1y57kvz22qkkgy269lvn8s9yckz-graphviz-12.2.1",
"path": "/nix/store/gpayvnlnryg41v41zkymfl5zvwifyzn3-graphviz-12.2.1",
"default": true
}
],
"store_path": "/nix/store/shsff1y57kvz22qkkgy269lvn8s9yckz-graphviz-12.2.1"
"store_path": "/nix/store/gpayvnlnryg41v41zkymfl5zvwifyzn3-graphviz-12.2.1"
},
"x86_64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/3mjmaid5ra8paxwf603dlc20w09739la-graphviz-12.2.1",
"path": "/nix/store/jswrjcp9ilxyvgl44ccya89smf52vwgz-graphviz-12.2.1",
"default": true
}
],
"store_path": "/nix/store/3mjmaid5ra8paxwf603dlc20w09739la-graphviz-12.2.1"
"store_path": "/nix/store/jswrjcp9ilxyvgl44ccya89smf52vwgz-graphviz-12.2.1"
},
"x86_64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/199jxrl2dwd5afi6njmj7wvaz9ni79kz-graphviz-12.2.1",
"path": "/nix/store/75f5zxbsnbciq33ahnawq8kpspvy4k3x-graphviz-12.2.1",
"default": true
}
],
"store_path": "/nix/store/199jxrl2dwd5afi6njmj7wvaz9ni79kz-graphviz-12.2.1"
"store_path": "/nix/store/75f5zxbsnbciq33ahnawq8kpspvy4k3x-graphviz-12.2.1"
}
}
},
@@ -898,7 +942,7 @@
}
}
},
"psrecord@latest": {
"psrecord@1.2": {
"last_modified": "2025-05-16T20:19:48Z",
"resolved": "github:NixOS/nixpkgs/12a55407652e04dcf2309436eb06fef0d3713ef3#psrecord",
"source": "devbox-search",
+16
View File
@@ -144,4 +144,20 @@ It supports the document initialisation and document text processing stages. Eve
## cognito.auth.harness
## permit.harness
## user.creation.tool
audit.go provides comprehensive audit trail logging functionality for compliance and monitoring. This file now uses the `log/slog` structured logging package introduced in Go 1.21. A single environment variable LOG_FORMAT controls the output format:
The public API (type AuditLogger and all its methods) is unchanged, so no callsites (e.g. cognito-permit-sync.go) need to be modified.
cognito-permit-sync.go is the main entry point and orchestration logic for the user creation tool. This file coordinates the synchronization of users between AWS Cognito and Permit.io systems, handling CSV parsing, user creation/deletion/disable/enable operations, role validation, configuration management, and command-line interface. It serves as the primary workflow controller.
cognito.go handles AWS Cognito User Pool operations for user identity management. This file provides functions to create, delete, enable, disable, and retrieve users from AWS Cognito User Pools, including credential validation, user attribute management, and integration with AWS SDK v2 for identity provider operations.
permit.go handles Permit.io API operations for user management and role-based access control (RBAC). This file provides functions to create, delete, search, and manage users in Permit.io, as well as assign/unassign roles and validate role definitions. It integrates with Cognito user data to sync user information between the two systems.
Generated by Doczy
+1 -1
View File
@@ -19,7 +19,7 @@ func parseDBCollector(c *repository.Fullactivecollector) (*Collector, error) {
if len(c.Fields) > 0 {
err := json.Unmarshal(c.Fields, &fields)
if err != nil {
return nil, fmt.Errorf("error unmarshalling: %s", err)
return nil, fmt.Errorf("error unmarshalling: %w", err)
}
} else {
fields = map[string]uuid.UUID{}
+8 -7
View File
@@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"embed"
"errors"
"fmt"
"log/slog"
@@ -21,14 +22,14 @@ func createDB(ctx context.Context, cfg database.ConfigProvider) error {
db, err := sql.Open(cfg.GetDBDriver(), cfg.GetDBAdminDBURI())
if err != nil {
return fmt.Errorf("error opening admin database: %v", err)
return fmt.Errorf("error opening admin database: %w", err)
}
slog.Debug("pinging admin database", "uri", cfg.GetDBAdminDBURI())
err = db.PingContext(ctx)
if err != nil {
return fmt.Errorf("error pinging admin database: %v", err)
return fmt.Errorf("error pinging admin database: %w", err)
}
slog.Debug("creating admin database", "uri", cfg.GetDBAdminDBURI())
@@ -44,14 +45,14 @@ func createDB(ctx context.Context, cfg database.ConfigProvider) error {
db, err = sql.Open(cfg.GetDBDriver(), cfg.GetDBURI())
if err != nil {
return fmt.Errorf("error opening database: %v", err)
return fmt.Errorf("error opening database: %w", err)
}
slog.Debug("pinging database", "uri", cfg.GetDBAdminDBURI())
err = db.PingContext(ctx)
if err != nil {
return fmt.Errorf("error pinging database: %v", err)
return fmt.Errorf("error pinging database: %w", err)
}
return nil
@@ -73,14 +74,14 @@ func RunMigrations(ctx context.Context, cfg database.ConfigProvider) error {
m, err := migrate.NewWithSourceInstance("iofs", source, cfg.GetDBURI())
if err != nil {
return fmt.Errorf("failed to create migrate instance: %v", err)
return fmt.Errorf("failed to create migrate instance: %w", err)
}
err = m.Up()
if err == migrate.ErrNoChange {
if errors.Is(err, migrate.ErrNoChange) {
slog.Info("No migration changes required")
} else if err != nil {
return fmt.Errorf("failed to apply migrations: %v", err)
return fmt.Errorf("failed to apply migrations: %w", err)
} else {
slog.Info("Migrations applied successfully!")
}
+1 -1
View File
@@ -98,7 +98,7 @@ func (s *Service) getBytesBuffer(ctx context.Context, params *CleanParams, start
buffer := make([]byte, length)
n, err := out.Body.Read(buffer)
if err != nil && n == 0 {
return nil, fmt.Errorf("unable to read object body: %v", err)
return nil, fmt.Errorf("unable to read object body: %w", err)
}
return buffer[:n], nil
+2 -2
View File
@@ -13,13 +13,13 @@ import (
func (s *Service) Clean(ctx context.Context, documentId uuid.UUID) error {
isclean, err := s.cfg.GetDBQueries().HasDocumentCleanEntry(ctx, documentId)
if err != nil {
return fmt.Errorf("unable to verify if document has been cleaned: %s", err)
return fmt.Errorf("unable to verify if document has been cleaned: %w", err)
}
if !isclean {
err = s.clean(ctx, documentId)
if err != nil {
return fmt.Errorf("unable to clean document: %s", err)
return fmt.Errorf("unable to clean document: %w", err)
}
}
+1 -1
View File
@@ -128,7 +128,7 @@ func (s *PDF) GetPageAsPNG(ctx context.Context, index int) ([]byte, error) {
img, err := fitzdoc.ImagePNG(0, float64(s.pngDPI))
if err != nil {
return nil, fmt.Errorf("failed to render page %d: %v", index, err)
return nil, fmt.Errorf("failed to render page %d: %w", index, err)
}
return img, nil
+2 -2
View File
@@ -36,12 +36,12 @@ func (s *Service) NormalizeConfig(config Config) error {
var data map[string]interface{}
if err := json.Unmarshal([]byte(trim), &data); err != nil {
return fmt.Errorf("error unmarshalling JSON: %s", err)
return fmt.Errorf("error unmarshalling JSON: %w", err)
}
prettyJSON, err := json.Marshal(data)
if err != nil {
return fmt.Errorf("error marshaling JSON: %s", err)
return fmt.Errorf("error marshaling JSON: %w", err)
}
strJSON := string(prettyJSON)
+4 -4
View File
@@ -44,7 +44,7 @@ type BaseConfig struct {
// experimental since it is not used yet and may pose cyclical dependency issues
// in handlers that are called by the generated
// swagger code. This needs to be verified.
//func GetConfigFromContext(ctx echo.Context) (Config, error) {
// func GetConfigFromContext(ctx echo.Context) (Config, error) {
// cfg, ok := ctx.Get(configContextKey).(Config)
// if !ok {
// return nil, errors.New("config not found in context")
@@ -170,13 +170,13 @@ func New(ctx context.Context, cfg Config) (*Server, error) {
// Put this in when refactoring is done and remove from main.go
//// This must be done before the rbac.InitializeAuthProvider then remove from main.go for service.
//errInitializingConfig := serviceconfig.InitializeConfig(cfg)
//if errInitializingConfig != nil {
// errInitializingConfig := serviceconfig.InitializeConfig(cfg)
// if errInitializingConfig != nil {
// return nil, errInitializingConfig
//}
//
//// Initialize the rbac config here since only the API service needs it
//errorGettingAuthProvider := rbac.InitializeAuthProvider(cfg.GetAuthConfig())
// errorGettingAuthProvider := rbac.InitializeAuthProvider(cfg.GetAuthConfig())
//if errorGettingAuthProvider != nil {
// return nil, errorGettingAuthProvider
//}
+2 -2
View File
@@ -43,7 +43,7 @@ func (c *Server[B]) pollMessage(ctx context.Context) error {
QueueURL: c.cfg.GetQueueURL(),
})
if err != nil {
return fmt.Errorf("message fetch fail: %v", err)
return fmt.Errorf("message fetch fail: %w", err)
}
for _, message := range result.Messages {
@@ -74,7 +74,7 @@ func (c *Server[B]) processMessage(ctx context.Context, message *types.Message)
ReceiptHandle: message.ReceiptHandle,
})
if err != nil {
return fmt.Errorf("message delete fail: %v", err)
return fmt.Errorf("message delete fail: %w", err)
}
return nil
+1 -1
View File
@@ -81,7 +81,7 @@ type ConfigProvider interface {
// Returns an error if initialization fails, nil otherwise.
func (c *CognitoConfig) InitializeAuthConfig(baseURL string, logger *slog.Logger) error {
tempConfig := InitializeConfig(baseURL, logger)
//fmt.Printf("base url after InitializeAuthConfig: %s\n", tempConfig.)
// fmt.Printf("base url after InitializeAuthConfig: %s\n", tempConfig.)
if tempConfig == nil {
return fmt.Errorf("could not initialize auth config")
}
+1 -1
View File
@@ -86,7 +86,7 @@ func (c *AWSConfig) SetAWSProfile(val Profile) {
func GetAWSConfigWithOpts(ctx context.Context, opts ...func(*config.LoadOptions) error) (aws.Config, error) {
cfg, err := config.LoadDefaultConfig(ctx, opts...)
if err != nil {
return aws.Config{}, fmt.Errorf("unable to load SDK config: %v", err)
return aws.Config{}, fmt.Errorf("unable to load SDK config: %w", err)
}
return cfg, nil
@@ -1,4 +1,4 @@
//ignore go:build ignore
// ignore go:build ignore
package main
@@ -17,12 +17,12 @@ func GetFreePortForTesting() (int, error) {
// Create a TCP listener on port 0 (lets OS choose a free port)
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {
return 0, fmt.Errorf("failed to resolve TCP address: %v", err)
return 0, fmt.Errorf("failed to resolve TCP address: %w", err)
}
l, err := net.ListenTCP("tcp", addr)
if err != nil {
return 0, fmt.Errorf("failed to create TCP listener: %v", err)
return 0, fmt.Errorf("failed to create TCP listener: %w", err)
}
defer l.Close()
@@ -143,7 +143,7 @@ func TestMetricsIntegration(t *testing.T) {
metricsOutput := string(body)
// if needed for debugging.
//log.Infof("Metrics output: %s", metricsOutput)
// log.Infof("Metrics output: %s", metricsOutput)
// Step 6: Verify that our custom metrics and go metrics are present
expectedMetrics := []string{
@@ -190,9 +190,11 @@ func TestMetricsIntegration(t *testing.T) {
// Try to connect to the server - it should fail after a short delay
time.Sleep(time.Second)
testingUrl := fmt.Sprintf("http://localhost:%d/metrics", testingPort)
_, err = http.Get(testingUrl)
resp, err := http.Get(testingUrl)
if err == nil {
t.Error("Expected server to be shutdown after context cancellation")
} else if resp != nil {
defer resp.Body.Close()
}
})
}
+1
View File
@@ -82,6 +82,7 @@ func TestWaitForMockEndpoint(t *testing.T) {
resp, err := server.Client.Do(req)
require.NoError(t, err)
defer resp.Body.Close()
respStr, err := io.ReadAll(resp.Body)
require.NoError(t, err)
+2
View File
@@ -52,6 +52,8 @@ func GetRunnerEnvFromName(name RunnerName) RunnerEnv {
switch name {
case StoreEventRunnerName:
return StoreEventRunnerEnv
case DocInitRunnerName:
return DocInitRunnerEnv
case DocSyncRunnerName:
return DocSyncRunnerEnv
case DocCleanRunnerName:
+3 -1
View File
@@ -78,7 +78,9 @@ tasks:
- task: docker:lint
- task: openapi:lint
- task: compose:lint
go:lint: golangci-lint run {{.CLI_ARGS}}
go:lint:
- golangci-lint run {{.CLI_ARGS}}
# - govulncheck ./...
yaml:lint: yamllint . -s {{.CLI_ARGS}}
json:lint: jsonlint devbox.json -q -s -i {{.CLI_ARGS}}
docs:generate:
+5
View File
@@ -23,26 +23,31 @@ func TestQueryAPIAccessories(t *testing.T) {
resp, err := http.Get(fmt.Sprintf("%s/swagger/doc.json", c.API.URI))
require.NoError(t, err)
defer resp.Body.Close()
assert.NotNil(t, resp)
assert.Equal(t, http.StatusOK, resp.StatusCode)
resp, err = http.Get(fmt.Sprintf("%s/swagger/doc.yaml", c.API.URI))
require.NoError(t, err)
defer resp.Body.Close()
assert.NotNil(t, resp)
assert.Equal(t, http.StatusOK, resp.StatusCode)
resp, err = http.Get(fmt.Sprintf("%s/swagger/index.html", c.API.URI))
require.NoError(t, err)
defer resp.Body.Close()
assert.NotNil(t, resp)
assert.Equal(t, http.StatusOK, resp.StatusCode)
resp, err = http.Get(fmt.Sprintf("%s/metrics", c.API.URI))
require.NoError(t, err)
defer resp.Body.Close()
assert.NotNil(t, resp)
assert.Equal(t, http.StatusOK, resp.StatusCode)
resp, err = http.Get(fmt.Sprintf("%s/health", c.API.URI))
require.NoError(t, err)
defer resp.Body.Close()
assert.NotNil(t, resp)
assert.Equal(t, http.StatusOK, resp.StatusCode)