Compare commits

..

12 Commits

Author SHA1 Message Date
f519b94392 Use realIP
All checks were successful
Build and Push Docker Image on Tag / Build and Push Docker Image (push) Successful in 15m31s
Code was copied from https://github.com/go-chi/chi/blob/master/middleware/realip.go
2025-02-01 17:07:24 +01:00
5a0da6560d Fix env var in image-build.yaml
All checks were successful
Build and Push Docker Image on Tag / Build and Push Docker Image (push) Successful in 15m25s
2025-01-30 09:09:21 +01:00
6aed7cb7fa Add Gitea workflow
Some checks failed
Build and Push Docker Image on Tag / Build and Push Docker Image (push) Failing after 10m54s
2025-01-30 08:56:30 +01:00
5ed16bdab3 Remove allow_different_binary_count 2025-01-23 14:15:34 +01:00
7939a6fde1 Fix deprecated property 2025-01-23 14:12:59 +01:00
e78d0a7276 Add version in archive name 2025-01-23 14:12:16 +01:00
e544ea8426 Fix Makefile 2025-01-23 14:09:18 +01:00
56adeaf1b8 Configure for goreleaser 2025-01-23 14:03:58 +01:00
a72eead432 Fix TODOs in openapi.yml 2025-01-22 20:12:52 +01:00
6e0375c666 Use alpine as base image in Dockerfile. Image size went from 372MB to 17.9MB 2025-01-22 08:13:10 +01:00
ff2a90ed3d Add links for election results after creating 2025-01-22 08:08:28 +01:00
6d92358f79 Fix Makefile and add VOLUME in Dockerfile 2025-01-21 22:24:01 +01:00
10 changed files with 133 additions and 27 deletions

View File

@ -0,0 +1,35 @@
name: Build and Push Docker Image on Tag
on:
push:
tags:
- "v*"
jobs:
build:
name: Build and Push Docker Image
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
registry: code.dlmw.ch
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
push: true
tags: code.dlmw.ch/dlmw/qv:${{ env.GITHUB_REF_NAME }}

1
.gitignore vendored
View File

@ -30,3 +30,4 @@ go.work.sum
# exclude built binary
web
dist/

43
.goreleaser.yaml Normal file
View File

@ -0,0 +1,43 @@
version: 2
before:
hooks:
- go mod tidy
builds:
- id: qv
main: ./cmd/web
binary: qv
env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
goarch:
- amd64
- arm64
goamd64:
- v1
- v2
- v3
- v4
goarm64:
- v8.0
ldflags:
- -s -w
archives:
- id: qv-archive
name_template: >-
{{ .ProjectName }}_
{{- .Version }}_
{{- .Os }}_
{{- .Arch }}_
{{- if eq .Arch "amd64" }}{{ .Amd64 }}
{{- else if eq .Arch "arm64" }}{{ .Arm64 }}
{{- end }}
formats: [ "tar.gz" ]
format_overrides:
- goos: windows
formats: [ "zip" ]

View File

@ -1,7 +1,4 @@
FROM golang:1.23-alpine
RUN mkdir /qv
ENV QV_DATABASE_PATH="/qv/qv.sqlite"
FROM golang:1.23-alpine AS build
WORKDIR /usr/src/qv
@ -11,4 +8,12 @@ RUN go mod download && go mod verify
COPY . .
RUN go build -ldflags "-s -w" -v -o /usr/local/bin/qv ./cmd/web/
CMD ["qv"]
FROM alpine
RUN mkdir /qv
ENV QV_DATABASE_PATH="/qv/qv.sqlite"
VOLUME /qv
COPY --from=build /usr/local/bin/qv /usr/local/bin/
ENTRYPOINT ["qv"]

View File

@ -1,18 +1,10 @@
BINARY_NAME=qv
LD_FLAGS=-s -w
PLATFORMS=linux/amd64 darwin/amd64 windows/amd64
.PHONY: compile clean
.PHONY: compile compile-snapshot clean
compile:
@for PLATFORM in $(PLATFORMS); do \
GOOS=$$(echo $$PLATFORM | cut -d'/' -f1); \
GOARCH=$$(echo $$PLATFORM | cut -d'/' -f2); \
echo "Building for $$GOOS/$$GOARCH..."; \
go build -ldflags="$(LD_FLAGS)" -o "$(BINARY_NAME)-$$GOOS-$$GOARCH" ./cmd/web/ && \
echo "Build successful: $(BINARY_NAME)-$$GOOS-$$GOARCH" || \
echo "Build failed for $$GOOS/$$GOARCH"; \
done
@goreleaser release --clean --skip=publish
compile-snapshot:
@goreleaser release --clean --snapshot --skip=publish
clean:
@rm qv-*-amd64
@rm -r dist/

View File

@ -277,7 +277,7 @@ func (app *application) createVotesHandleKnownVotersElection(w http.ResponseWrit
}
func (app *application) createVotesHandleUnknownVotersElection(w http.ResponseWriter, r *http.Request, election *models.Election) (string, error) {
voterIdentity := r.RemoteAddr
voterIdentity := realIP(r)
voterExists, err := app.voters.Exists(voterIdentity, election.ID)
if err != nil {

View File

@ -5,7 +5,9 @@ import (
"code.dlmw.ch/dlmw/qv/internal/validator"
"encoding/json"
"io"
"net"
"net/http"
"strings"
)
func (app *application) serverError(w http.ResponseWriter, r *http.Request, err error) {
@ -67,3 +69,23 @@ func (app *application) unmarshalRequest(r *http.Request, dst any) error {
return nil
}
func realIP(r *http.Request) string {
var ip string
if tcip := r.Header.Get(http.CanonicalHeaderKey("True-Client-IP")); tcip != "" {
ip = tcip
} else if xrip := r.Header.Get(http.CanonicalHeaderKey("X-Real-IP")); xrip != "" {
ip = xrip
} else if xff := r.Header.Get(http.CanonicalHeaderKey("X-Forwarded-For")); xff != "" {
i := strings.Index(xff, ",")
if i == -1 {
i = len(xff)
}
ip = xff[:i]
}
if ip == "" || net.ParseIP(ip) == nil {
return ""
}
return ip
}

View File

@ -20,7 +20,7 @@ func (app *application) recoverPanic(next http.Handler) http.Handler {
func (app *application) logRequest(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var (
ip = r.RemoteAddr
ip = realIP(r)
proto = r.Proto
method = r.Method
uri = r.URL.RequestURI()

View File

@ -3,7 +3,7 @@ info:
title: qv - dlmw
description: |-
This is the documentation for the qv (Quadratic Voting) API.
termsOfService: http://swagger.io/terms/
termsOfService:
contact:
email: dylan@dlmw.ch
license:
@ -11,10 +11,10 @@ info:
url: https://www.gnu.org/licenses/gpl-3.0.txt
version: 0.0.1
externalDocs:
description: Find out more about qv # todo
url: http://swagger.io # todo
description: Get the code
url: https://code.dlmw.ch/dlmw/qv
servers:
- url: https://petstore3.swagger.io/api/v3 # todo
- url: https://qv.dlmw.ch/api
tags:
- name: election
description: Retrieve data related to elections

View File

@ -98,7 +98,15 @@
:href="`/election/${createdElectionId}`"
class="text-blue-600 underline hover:text-blue-800"
target="_blank">
View Election
View election
</a>
</p>
<p>
<a
:href="`/election/${createdElectionId}/results`"
class="text-blue-600 underline hover:text-blue-800"
target="_blank">
View results
</a>
</p>
</div>