diff --git a/.woodpecker/.build.yml b/.woodpecker/.build.yml index e2fe848..5ed9927 100644 --- a/.woodpecker/.build.yml +++ b/.woodpecker/.build.yml @@ -3,15 +3,12 @@ when: steps: build: - image: golang:1.23-alpine + image: golang:1.24-alpine commands: - apk update - - apk add git - - go install github.com/goreleaser/goreleaser/v2@latest - - echo "$${SENTRY_DSN}" > cmd/api/sentry - - goreleaser build --snapshot - secrets: [sentry_dsn] - + - apk add bash + - bash scripts/build.sh + depends_on: - lint - tests \ No newline at end of file diff --git a/.woodpecker/.publish.yml b/.woodpecker/.publish.yml index 5759267..418ac4e 100644 --- a/.woodpecker/.publish.yml +++ b/.woodpecker/.publish.yml @@ -4,6 +4,11 @@ when: steps: - name: publish-docker image: docker:27-cli + environment: + DOCKER_USERNAME: + from_secret: docker_username + DOCKER_PASSWORD: + from_secret: docker_password commands: - tag="tintounn/trepa:$${CI_COMMIT_TAG}" - docker login -u="$${DOCKER_USERNAME}" -p="$${DOCKER_PASSWORD}" @@ -12,13 +17,6 @@ steps: - docker rmi $tag volumes: - /var/run/docker.sock:/var/run/docker.sock - secrets: [docker_username, docker_password] - - - name: publish-binaries - image: goreleaser/goreleaser - commands: - - goreleaser release - secrets: [ gitea_token ] depends_on: - build diff --git a/.woodpecker/.tests.yml b/.woodpecker/.tests.yml index e36c03d..70ee3e0 100644 --- a/.woodpecker/.tests.yml +++ b/.woodpecker/.tests.yml @@ -3,14 +3,15 @@ when: steps: tests: - image: golang:1.23-alpine + image: golang:1.24-alpine environment: - TEST_DATABASE_URL: postgres://dev:dev@db/trepa?sslmode=disable + TEST_DB_HOST: db + TEST_DB_PORT: 5432 + TEST_DB_USER: dev + TEST_DB_PASSWORD: dev + TEST_DB_NAME: trepa_test commands: - sleep 30 - - wget https://github.com/golang-migrate/migrate/releases/download/v4.17.1/migrate.linux-amd64.tar.gz - - tar -xf migrate.linux-amd64.tar.gz - - ./migrate -source file://migrations/ -database "$${TEST_DATABASE_URL}" up - go test -cover ./internal/... -v services: @@ -19,4 +20,4 @@ services: environment: - POSTGRES_USER=dev - POSTGRES_PASSWORD=dev - - POSTGRES_DB=trepa + - POSTGRES_DB=trepa_test diff --git a/go.mod b/go.mod index 97d1152..4da147d 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module gitea.qpismont.fr/qpismont/trepa go 1.24.0 require ( + github.com/golang-jwt/jwt/v5 v5.2.1 github.com/jackc/pgx v3.6.2+incompatible github.com/jmoiron/sqlx v1.4.0 github.com/joho/godotenv v1.5.1 diff --git a/go.sum b/go.sum index 29b24b3..dee274e 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc= github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o= diff --git a/internal/core/errors.go b/internal/core/errors.go index 3801bb0..c0ca822 100644 --- a/internal/core/errors.go +++ b/internal/core/errors.go @@ -4,6 +4,10 @@ import ( "net/http" ) +var ( + ErrInvalidToken = NewHTTPError(http.StatusUnauthorized, "Invalid token", nil) +) + type HTTPError struct { Code int `json:"code"` Message string `json:"message"` diff --git a/internal/core/jwt.go b/internal/core/jwt.go new file mode 100644 index 0000000..0f5a19e --- /dev/null +++ b/internal/core/jwt.go @@ -0,0 +1,40 @@ +package core + +import ( + "github.com/golang-jwt/jwt/v5" +) + +type JWTClaims struct { + jwt.RegisteredClaims + AccountId string `json:"account_id"` + RoleId string `json:"role_id"` +} + +var jwtSecret string + +func InitJWT(secret string) { + jwtSecret = secret +} + +func SignJWT(claims JWTClaims) (string, error) { + token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + + return token.SignedString([]byte(jwtSecret)) +} + +func VerifyJWT(token string) (JWTClaims, error) { + parsedClaims := JWTClaims{} + claims, err := jwt.ParseWithClaims(token, &parsedClaims, func(token *jwt.Token) (any, error) { + return []byte(jwtSecret), nil + }) + + if err != nil { + return JWTClaims{}, NewInternalServerError(err) + } + + if !claims.Valid { + return JWTClaims{}, ErrInvalidToken + } + + return parsedClaims, nil +}