Skip to content

Commit ab20318

Browse files
committed
Merge branch 'release/1.2.0' into main
Release 1.2.0 includes: - Teams and projects API with OpenAPI schemas, handlers, and tests - Survey response API improvements - Client credentials grant for machine-to-machine auth - Unicode validation for international text - Pre-release label support in version system - Comprehensive unit and integration test coverage - Lint cleanup and staticcheck resolution - Container security improvements with Chainguard Redis - OWASP-required patterns for teams/projects OpenAPI spec - include_in_report field for sub-entity types
2 parents 03ba346 + 24fa69f commit ab20318

File tree

292 files changed

+55915
-20830
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

292 files changed

+55915
-20830
lines changed

.golangci.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ version: "2"
33

44
linters:
55
enable:
6+
# Existing linters
67
- errcheck
78
- govet
89
- ineffassign
@@ -11,6 +12,22 @@ linters:
1112
- gosec
1213
- misspell
1314
- unconvert
15+
# Bug-catching linters
16+
- bodyclose # HTTP response body closure
17+
- nilerr # nil return when err != nil
18+
- nilnesserr # wrong nil error returned
19+
- errorlint # correct error wrapping (errors.Is/As)
20+
- forcetypeassert # unguarded type assertions
21+
- durationcheck # time.Duration arithmetic bugs
22+
- sqlclosecheck # unclosed sql.Rows/Stmt
23+
# Code quality linters
24+
- goconst # repeated string literals
25+
- gocritic # broad bug/style/performance checks
26+
- predeclared # shadowing of builtins
27+
- musttag # missing tags on marshaled structs
28+
- sloglint # consistent slog usage
29+
- nolintlint # validates nolint directives
30+
- wastedassign # assignments never read
1431
disable:
1532
- lll
1633
- revive
@@ -29,6 +46,34 @@ linters:
2946
- gosec
3047
- misspell
3148
- unconvert
49+
- bodyclose
50+
- nilerr
51+
- nilnesserr
52+
- errorlint
53+
- forcetypeassert
54+
- durationcheck
55+
- sqlclosecheck
56+
- goconst
57+
- gocritic
58+
- predeclared
59+
- musttag
60+
- sloglint
61+
- nolintlint
62+
- wastedassign
63+
# forcetypeassert: Test files use unguarded assertions for mock returns and JSON parsing
64+
- path: "_test\\.go$"
65+
linters:
66+
- forcetypeassert
67+
# G101: Test files legitimately use hardcoded test credentials
68+
- path: "_test\\.go$"
69+
linters:
70+
- gosec
71+
text: "G101:"
72+
# G115: Integer overflow conversions are safe in context (test helpers)
73+
- path: "_test\\.go$"
74+
linters:
75+
- gosec
76+
text: "G115:"
3277

3378
formatters:
3479
enable:

.version

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"major": 1,
3-
"minor": 1,
4-
"patch": 0
3+
"minor": 2,
4+
"patch": 0,
5+
"prerelease": ""
56
}

CLAUDE.md

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -335,17 +335,10 @@ TMI uses staticcheck for Go code quality analysis. The project has intentionally
335335
- Manual edits would be overwritten on next OpenAPI regeneration
336336
- **Expected behavior**: These warnings are acceptable and should be ignored
337337

338-
- **Auth Handler Functions**: 4 unused functions in auth/handlers.go - left for potential future refactoring:
339-
- `setUserHintContext` (line 559)
340-
- `exchangeCodeAndGetUser` (line 571)
341-
- `createOrGetUser` (line 648)
342-
- `generateAndReturnTokens` (line 716)
343-
344338
- **Running Staticcheck**:
345339
- `staticcheck ./...` - Shows all issues (including expected ones)
346340
- `staticcheck ./... | grep -v "api/api.go"` - Filter out auto-generated code warnings
347-
- **Expected count**: 344 total issues (338 in api/api.go + 6 intentionally unused functions)
348-
- **Clean hand-written code**: 19 unused code items were removed for 1.0 release
341+
- **Expected count**: 338 issues (all in auto-generated api/api.go)
349342

350343
## Git & Versioning
351344

Dockerfile.redis

Lines changed: 17 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -1,226 +1,28 @@
1-
# Multi-stage distroless Redis build
2-
# Stage 1: Build environment with Redis compilation
3-
FROM debian:bookworm-slim AS builder
4-
5-
# Install build dependencies
6-
RUN apt-get update && \
7-
apt-get install -y --no-install-recommends \
8-
build-essential \
9-
wget \
10-
ca-certificates \
11-
gcc \
12-
libc6-dev \
13-
make \
14-
pkg-config \
15-
tcl \
16-
curl && \
17-
# Post-installation security patching for build dependencies
18-
apt-get upgrade -y --no-install-recommends && \
19-
# Install only security updates for critical packages
20-
apt-get install -y --only-upgrade \
21-
$(apt list --upgradable 2>/dev/null | grep -E "(security|critical)" | cut -d'/' -f1 || true) && \
22-
# Clean package cache to reduce image size and attack surface
23-
apt-get autoremove -y && \
24-
apt-get autoclean && \
25-
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /var/cache/apt/* && \
26-
# Additional security hardening
27-
find /var/log -type f -exec truncate -s 0 {} \; 2>/dev/null || true && \
28-
# Remove unnecessary files and documentation
29-
rm -rf /usr/share/doc/* /usr/share/man/* /usr/share/info/* /usr/share/locale/*/LC_MESSAGES/*.mo 2>/dev/null || true
30-
31-
# Redis version
32-
ENV REDIS_VERSION=8.4.0
33-
ENV REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-${REDIS_VERSION}.tar.gz
34-
ENV REDIS_DOWNLOAD_SHA=TBD
35-
36-
# Download and compile Redis from source
37-
RUN wget -O redis.tar.gz "$REDIS_DOWNLOAD_URL" && \
38-
mkdir -p /usr/src/redis && \
39-
tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 && \
40-
rm redis.tar.gz && \
41-
cd /usr/src/redis && \
42-
make && \
43-
make install PREFIX=/redis-build
44-
45-
# Create redis user and set up runtime directory structure
46-
RUN groupadd -r redis --gid=999 && \
47-
useradd -r -g redis --uid=999 --home-dir=/var/lib/redis --shell=/bin/sh redis && \
48-
mkdir -p /runtime/usr/local/bin && \
49-
mkdir -p /runtime/var/lib/redis && \
50-
mkdir -p /runtime/var/log/redis && \
51-
mkdir -p /runtime/etc && \
52-
# Copy Redis binaries
53-
cp /redis-build/bin/redis-server /runtime/usr/local/bin/ && \
54-
cp /redis-build/bin/redis-cli /runtime/usr/local/bin/ && \
55-
cp /redis-build/bin/redis-benchmark /runtime/usr/local/bin/ && \
56-
cp /redis-build/bin/redis-check-aof /runtime/usr/local/bin/ && \
57-
cp /redis-build/bin/redis-check-rdb /runtime/usr/local/bin/ && \
58-
# Copy required shared libraries
59-
mkdir -p /runtime/usr/lib/x86_64-linux-gnu && \
60-
mkdir -p /runtime/lib/x86_64-linux-gnu && \
61-
ldd /redis-build/bin/redis-server | grep "=> /" | awk '{print $3}' | xargs -I '{}' cp -v '{}' /runtime/usr/lib/x86_64-linux-gnu/ || true && \
62-
# Copy essential configuration files
63-
cp /etc/passwd /runtime/etc/ && \
64-
cp /etc/group /runtime/etc/ && \
65-
# Create redis user in runtime passwd
66-
echo "redis:x:999:999:Redis administrator:/var/lib/redis:/bin/sh" >> /runtime/etc/passwd && \
67-
echo "redis:x:999:" >> /runtime/etc/group && \
68-
# Set ownership
69-
chown -R 999:999 /runtime/var/lib/redis && \
70-
chown -R 999:999 /runtime/var/log/redis && \
71-
chmod 755 /runtime/var/lib/redis && \
72-
# Create the necessary directories in runtime for Redis
73-
mkdir -p /runtime/etc/redis && \
74-
chown -R 999:999 /runtime/etc/redis
75-
76-
# Create Redis configuration and entrypoint script
77-
RUN mkdir -p /scripts && cat > /scripts/redis.conf << 'EOF'
78-
# Redis configuration for TMI
79-
port 6379
80-
bind 0.0.0.0
81-
protected-mode no
82-
requirepass ""
83-
84-
# Persistence
85-
save 900 1
86-
save 300 10
87-
save 60 10000
88-
89-
# Logging
90-
loglevel notice
91-
logfile /var/log/redis/redis-server.log
92-
93-
# Security
94-
rename-command FLUSHDB ""
95-
rename-command FLUSHALL ""
96-
rename-command DEBUG ""
97-
98-
# Memory management
99-
maxmemory 256mb
100-
maxmemory-policy allkeys-lru
101-
102-
# Directories
103-
dir /var/lib/redis
104-
105-
# Security settings that can be overridden by environment variables
106-
# These will be updated by the entrypoint script based on environment
107-
EOF
108-
109-
RUN cat > /scripts/docker-entrypoint.sh << 'EOF'
110-
#!/bin/sh
111-
set -e
112-
113-
# Redis configuration
114-
export REDIS_CONF="${REDIS_CONF:-/etc/redis/redis.conf}"
115-
export REDIS_DATA_DIR="${REDIS_DATA_DIR:-/var/lib/redis}"
116-
export REDIS_LOG_DIR="${REDIS_LOG_DIR:-/var/log/redis}"
117-
118-
# Environment variables for configuration
119-
export REDIS_PASSWORD="${REDIS_PASSWORD:-${REDIS_PASSWORD}}"
120-
export REDIS_PORT="${REDIS_PORT:-6379}"
121-
export REDIS_PROTECTED_MODE="${REDIS_PROTECTED_MODE:-yes}"
122-
export REDIS_DISABLE_COMMANDS="${REDIS_DISABLE_COMMANDS:-FLUSHDB,FLUSHALL,DEBUG}"
123-
124-
# Create directories if they don't exist
125-
mkdir -p "$REDIS_DATA_DIR"
126-
mkdir -p "$REDIS_LOG_DIR"
127-
mkdir -p "$(dirname "$REDIS_CONF")"
128-
129-
# Ensure proper ownership
130-
chown -R redis:redis "$REDIS_DATA_DIR"
131-
chown -R redis:redis "$REDIS_LOG_DIR"
132-
133-
# Generate Redis configuration
134-
cat > "$REDIS_CONF" << EOREDIS
135-
# Redis configuration for TMI
136-
port ${REDIS_PORT}
137-
bind 0.0.0.0
138-
protected-mode ${REDIS_PROTECTED_MODE}
139-
140-
# Authentication
141-
$([ -n "$REDIS_PASSWORD" ] && echo "requirepass $REDIS_PASSWORD" || echo "# No password set")
142-
143-
# Persistence
144-
save 900 1
145-
save 300 10
146-
save 60 10000
147-
148-
# Logging
149-
loglevel notice
150-
logfile ${REDIS_LOG_DIR}/redis-server.log
151-
152-
# Disable dangerous commands
153-
$(echo "$REDIS_DISABLE_COMMANDS" | tr ',' '\n' | while read cmd; do
154-
[ -n "$cmd" ] && echo "rename-command $cmd \"\""
155-
done)
156-
157-
# Memory management
158-
maxmemory 256mb
159-
maxmemory-policy allkeys-lru
160-
161-
# Directories
162-
dir ${REDIS_DATA_DIR}
163-
164-
# Additional security
165-
tcp-keepalive 300
166-
timeout 0
167-
tcp-backlog 511
168-
databases 16
169-
170-
# Slow log
171-
slowlog-log-slower-than 10000
172-
slowlog-max-len 128
173-
174-
# Client output buffer limits
175-
client-output-buffer-limit normal 0 0 0
176-
client-output-buffer-limit replica 256mb 64mb 60
177-
client-output-buffer-limit pubsub 32mb 8mb 60
178-
179-
EOREDIS
180-
181-
# Set proper permissions
182-
chmod 644 "$REDIS_CONF"
183-
184-
# Switch to redis user and start Redis
185-
echo "Starting Redis with configuration: $REDIS_CONF"
186-
exec /usr/local/bin/redis-server "$REDIS_CONF"
187-
EOF
188-
189-
RUN chmod +x /scripts/docker-entrypoint.sh && \
190-
chmod +x /scripts/redis.conf
191-
192-
# Stage 2: Distroless runtime with C++ support (required for Redis 8.x)
193-
FROM gcr.io/distroless/cc-debian12
1+
# Chainguard Redis build
2+
FROM cgr.dev/chainguard/redis:latest
1943

1954
# Metadata for tracking
196-
LABEL security.distroless="true"
5+
LABEL security.base="chainguard"
1976
LABEL security.scan-date="AUTO_GENERATED"
1987
LABEL security.patch-level="minimal-attack-surface"
1998
LABEL maintainer="TMI Security Team"
200-
LABEL org.opencontainers.image.title="TMI Redis Distroless"
201-
LABEL org.opencontainers.image.description="Redis 8.4.0 on distroless base"
202-
203-
# Copy Redis runtime from builder
204-
COPY --from=builder /runtime/ /
205-
# Copy configuration and entrypoint
206-
COPY --from=builder /scripts/docker-entrypoint.sh /docker-entrypoint.sh
207-
COPY --from=builder /scripts/redis.conf /etc/redis/redis.conf
208-
209-
# Environment variables for Redis
210-
ENV PATH="/usr/local/bin:$PATH"
211-
ENV REDIS_VERSION=8.4.0
212-
213-
# Note: Directories are created in the builder stage and copied over
9+
LABEL org.opencontainers.image.title="TMI Redis Chainguard"
10+
LABEL org.opencontainers.image.description="Redis on Chainguard secure base"
21411

21512
# Expose Redis port
21613
EXPOSE 6379
21714

21815
# Health check
21916
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
220-
CMD ["/usr/local/bin/redis-cli", "ping"]
221-
222-
# Use redis user
223-
USER 999:999
224-
225-
# Set the entrypoint to Redis directly for distroless compatibility
226-
ENTRYPOINT ["/usr/local/bin/redis-server", "/etc/redis/redis.conf"]
17+
CMD ["redis-cli", "ping"]
18+
19+
# Use redis user (Chainguard images already have proper user setup)
20+
USER redis
21+
22+
# Chainguard Redis images come with built-in entrypoint
23+
# Pass TMI-specific configuration flags as CMD
24+
CMD ["--appendonly", "yes", \
25+
"--maxmemory", "256mb", \
26+
"--maxmemory-policy", "allkeys-lru", \
27+
"--bind", "0.0.0.0", \
28+
"--protected-mode", "no"]

Dockerfile.server

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ COPY . .
2424
# Note: Oracle support is excluded (requires CGO). To include Oracle, use -tags oracle with CGO_ENABLED=1
2525
# Chainguard Go image includes git, so git commands will work
2626
RUN CGO_ENABLED=0 GOOS=linux go build \
27-
-ldflags "-s -w -X github.com/ericfitz/tmi/api.VersionMajor=0 -X github.com/ericfitz/tmi/api.VersionMinor=9 -X github.com/ericfitz/tmi/api.VersionPatch=0 -X github.com/ericfitz/tmi/api.GitCommit=$(git rev-parse --short HEAD 2>/dev/null || echo 'development') -X github.com/ericfitz/tmi/api.BuildDate=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
27+
-ldflags "-s -w -X github.com/ericfitz/tmi/api.VersionMajor=0 -X github.com/ericfitz/tmi/api.VersionMinor=9 -X github.com/ericfitz/tmi/api.VersionPatch=0 -X github.com/ericfitz/tmi/api.VersionPreRelease= -X github.com/ericfitz/tmi/api.GitCommit=$(git rev-parse --short HEAD 2>/dev/null || echo 'development') -X github.com/ericfitz/tmi/api.BuildDate=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
2828
-trimpath \
2929
-buildmode=exe \
3030
-o tmiserver \

Dockerfile.server-oracle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ ARG GIT_COMMIT
3030
ARG VERSION_MAJOR=1
3131
ARG VERSION_MINOR=0
3232
ARG VERSION_PATCH=0
33+
ARG VERSION_PRERELEASE=""
3334

3435
# Install security patches and required packages
3536
# This updates all packages to latest patched versions
@@ -100,6 +101,7 @@ RUN CGO_ENABLED=1 GOOS=linux GOARCH=${TARGETARCH} go build \
100101
-X github.com/ericfitz/tmi/api.VersionMajor=${VERSION_MAJOR} \
101102
-X github.com/ericfitz/tmi/api.VersionMinor=${VERSION_MINOR} \
102103
-X github.com/ericfitz/tmi/api.VersionPatch=${VERSION_PATCH} \
104+
-X github.com/ericfitz/tmi/api.VersionPreRelease=${VERSION_PRERELEASE} \
103105
-X github.com/ericfitz/tmi/api.GitCommit=${GIT_COMMIT:-development} \
104106
-X github.com/ericfitz/tmi/api.BuildDate=${BUILD_DATE:-unknown}" \
105107
-trimpath \

0 commit comments

Comments
 (0)