working on ron-example
This commit is contained in:
parent
ea5d85bd19
commit
4f108e1b05
1
.env.example
Normal file
1
.env.example
Normal file
@ -0,0 +1 @@
|
|||||||
|
DATASOURCE="postgresql://developer:secret@localhost:5432/ron?sslmode=disable"
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
.idea/
|
.idea/
|
||||||
logs/
|
logs/
|
||||||
|
.env
|
||||||
145
Makefile
Normal file
145
Makefile
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
GO ?= go
|
||||||
|
GOFMT ?= gofmt "-s"
|
||||||
|
GO_VERSION=$(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2)
|
||||||
|
PACKAGES ?= $(shell $(GO) list ./...)
|
||||||
|
VETPACKAGES ?= $(shell $(GO) list ./...)
|
||||||
|
GOFILES := $(shell find . -name "*.go")
|
||||||
|
|
||||||
|
.PHONY: sayhello
|
||||||
|
# Print Hello World
|
||||||
|
sayhello:
|
||||||
|
@echo "Hello World"
|
||||||
|
|
||||||
|
.PHONY: dockerize
|
||||||
|
# Creates a development database.
|
||||||
|
dockerize:
|
||||||
|
docker run --name ron-db-dev -e POSTGRES_PASSWORD=secret -e POSTGRES_USER=developer -e POSTGRES_DB=ron -p 5432:5432 -d postgres:16.3-alpine3.20
|
||||||
|
|
||||||
|
.PHONY: undockerize
|
||||||
|
# Destroy a development database.
|
||||||
|
undockerize:
|
||||||
|
docker rm -f ron-db-dev
|
||||||
|
|
||||||
|
.PHONY: migrateup
|
||||||
|
# Migrate all schemas, triggers and data located in cmd/database/migrations.
|
||||||
|
migrateup:
|
||||||
|
migrate -path cmd/database/migrations -database "postgresql://developer:secret@localhost:5432/ron?sslmode=disable" -verbose up
|
||||||
|
|
||||||
|
.PHONY: sqlc
|
||||||
|
# Generate or recreate SQLC queries.
|
||||||
|
sqlc:
|
||||||
|
sqlc generate
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
# Test all files and generate coverage file.
|
||||||
|
test:
|
||||||
|
$(GO) test -v -covermode=count -coverprofile=coverage.out $(PACKAGES)
|
||||||
|
|
||||||
|
.PHONY: gomock
|
||||||
|
# Generate mock files.
|
||||||
|
gomock:
|
||||||
|
mockgen -package mock -destination internal/repository/mock/querier.go arena-coins/internal/repository ExtendedQuerier
|
||||||
|
|
||||||
|
.PHONY: run
|
||||||
|
# Run project.
|
||||||
|
run:
|
||||||
|
$(GO) run ./cmd/.
|
||||||
|
|
||||||
|
.PHONY: recreate
|
||||||
|
# Destroy development DB and generate ones.
|
||||||
|
recreate:
|
||||||
|
make undockerize
|
||||||
|
make dockerize
|
||||||
|
sleep 2
|
||||||
|
make migrateup
|
||||||
|
|
||||||
|
.PHONY: tidy
|
||||||
|
# Runs a go mod tidy
|
||||||
|
tidy:
|
||||||
|
$(GO) mod tidy
|
||||||
|
|
||||||
|
.PHONY: build-linux
|
||||||
|
# Build and generate linux executable.
|
||||||
|
build-linux:
|
||||||
|
make tidy
|
||||||
|
make remove-debug
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./tmp/arena ./cmd/.
|
||||||
|
|
||||||
|
.PHONY: pack-docker
|
||||||
|
# Run docker build for pack binary and assets to Docker container.
|
||||||
|
pack-docker:
|
||||||
|
make test
|
||||||
|
make build-linux
|
||||||
|
docker build -t arena-coins:${version} -t arena-coins:latest .
|
||||||
|
|
||||||
|
.PHONY: remove-debug
|
||||||
|
# Remove all debug entries for reduce size binary.
|
||||||
|
remove-debug:
|
||||||
|
find . -name "*.go" -type f -exec sed -i '/slog\.Debug/d' {} +
|
||||||
|
|
||||||
|
.PHONY: fmt
|
||||||
|
# Ensure consistent code formatting.
|
||||||
|
fmt:
|
||||||
|
$(GOFMT) -w $(GOFILES)
|
||||||
|
|
||||||
|
.PHONY: fmt-check
|
||||||
|
# format (check only).
|
||||||
|
fmt-check:
|
||||||
|
@diff=$$($(GOFMT) -d $(GOFILES)); \
|
||||||
|
if [ -n "$$diff" ]; then \
|
||||||
|
echo "Please run 'make fmt' and commit the result:"; \
|
||||||
|
echo "$${diff}"; \
|
||||||
|
exit 1; \
|
||||||
|
fi;
|
||||||
|
|
||||||
|
.PHONY: vet
|
||||||
|
# Examine packages and report suspicious constructs if any.
|
||||||
|
vet:
|
||||||
|
$(GO) vet $(VETPACKAGES)
|
||||||
|
|
||||||
|
.PHONY: tools
|
||||||
|
# Install tools (migrate and sqlc).
|
||||||
|
tools:
|
||||||
|
@if [ $(GO_VERSION) -gt 16 ]; then \
|
||||||
|
$(GO) install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest; \
|
||||||
|
$(GO) install github.com/sqlc-dev/sqlc/cmd/sqlc@latest; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
.PHONY: env
|
||||||
|
# Copy .env.example to .env if .env does not already exist
|
||||||
|
env:
|
||||||
|
@if [ ! -f .env ]; then \
|
||||||
|
cp .env.example .env; \
|
||||||
|
echo ".env file created from .env.example"; \
|
||||||
|
else \
|
||||||
|
echo ".env file already exists"; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: first-run
|
||||||
|
# Runs for the first time
|
||||||
|
first-run:
|
||||||
|
make tools
|
||||||
|
make env
|
||||||
|
make recreate
|
||||||
|
make run
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
# Help.
|
||||||
|
help:
|
||||||
|
@echo ''
|
||||||
|
@echo 'Usage:'
|
||||||
|
@echo ' make [target]'
|
||||||
|
@echo ''
|
||||||
|
@echo 'Targets:'
|
||||||
|
@awk '/^[a-zA-Z\-\0-9]+:/ { \
|
||||||
|
helpMessage = match(lastLine, /^# (.*)/); \
|
||||||
|
if (helpMessage) { \
|
||||||
|
helpCommand = substr($$1, 0, index($$1, ":")-1); \
|
||||||
|
helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
|
||||||
|
printf " - \033[36m%-20s\033[0m %s\n", helpCommand, helpMessage; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
{ lastLine = $$0 }' $(MAKEFILE_LIST)
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := help
|
||||||
5
cmd/database/migrations/001_schema.up.sql
Normal file
5
cmd/database/migrations/001_schema.up.sql
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
create table pet
|
||||||
|
(
|
||||||
|
id serial unique not null,
|
||||||
|
name varchar(20) unique not null
|
||||||
|
);
|
||||||
4
cmd/database/queries/queries.sql
Normal file
4
cmd/database/queries/queries.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
-- name: CreatePet :one
|
||||||
|
insert into "pet" (name)
|
||||||
|
values ($1)
|
||||||
|
returning id;
|
||||||
74
cmd/main.go
Normal file
74
cmd/main.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"embed"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/golang-migrate/migrate/v4"
|
||||||
|
_ "github.com/golang-migrate/migrate/v4/database/postgres"
|
||||||
|
"github.com/golang-migrate/migrate/v4/source/iofs"
|
||||||
|
_ "github.com/lib/pq"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"ron"
|
||||||
|
"ron-pets/internal/config"
|
||||||
|
"ron-pets/internal/handlers"
|
||||||
|
"ron-pets/internal/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed database/migrations
|
||||||
|
var database embed.FS
|
||||||
|
|
||||||
|
func migrateDB() {
|
||||||
|
dbConn, err := sql.Open("postgres", os.Getenv("DATASOURCE"))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer dbConn.Close()
|
||||||
|
|
||||||
|
d, err := iofs.New(database, "database/migrations")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m, err := migrate.NewWithSourceInstance("iofs", d, os.Getenv("DATASOURCE"))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = m.Up()
|
||||||
|
if err != nil && !errors.Is(err, migrate.ErrNoChange) {
|
||||||
|
slog.Error("cannot migrate", "error", err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if errors.Is(err, migrate.ErrNoChange) {
|
||||||
|
slog.Info("migration has no changes")
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.Info("migration done")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := config.New()
|
||||||
|
migrateDB()
|
||||||
|
r := ron.New(func(e *ron.Engine) {
|
||||||
|
e.Render = ron.NewHTMLRender()
|
||||||
|
e.LogLevel = slog.LevelDebug
|
||||||
|
})
|
||||||
|
|
||||||
|
dbPool := config.NewPostgresPool(app.DataSource)
|
||||||
|
defer dbPool.Close()
|
||||||
|
|
||||||
|
q := repository.NewPGXRepo(dbPool)
|
||||||
|
h := handlers.New(app, q)
|
||||||
|
router(h, r)
|
||||||
|
|
||||||
|
err := r.Run(":8080")
|
||||||
|
if err != nil {
|
||||||
|
slog.Error(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
38
cmd/middleware.go
Normal file
38
cmd/middleware.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
"ron-pets/internal/sqlc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func someMiddleware(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
slog.Info("triggered middleware")
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func anotherMiddleware(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
slog.Info("triggered another middleware")
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func UserSessionMiddleware(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Simula la extracción de la sesión (en un caso real sería de cookies o tokens)
|
||||||
|
session := &sqlc.SessionData{
|
||||||
|
UserID: "12345",
|
||||||
|
Role: "admin",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Almacena los datos de sesión en el contexto
|
||||||
|
ctx := context.WithValue(r.Context(), "session", session)
|
||||||
|
|
||||||
|
// Pasa el contexto actualizado al siguiente handler
|
||||||
|
next.ServeHTTP(w, r.WithContext(ctx))
|
||||||
|
})
|
||||||
|
}
|
||||||
19
cmd/router.go
Normal file
19
cmd/router.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ron"
|
||||||
|
"ron-pets/internal/handlers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func router(h *handlers.Handlers, r *ron.Engine) {
|
||||||
|
r.Static("static", "static")
|
||||||
|
|
||||||
|
r.USE(UserSessionMiddleware)
|
||||||
|
|
||||||
|
r.GET("/put", h.HelloWorld)
|
||||||
|
//r.GET("/get", h.AnotherHelloWorld)
|
||||||
|
//
|
||||||
|
//r.GET("/create", h.CreateToken)
|
||||||
|
//r.GET("/validate", h.ValidateTokenAuthorization)
|
||||||
|
//r.GET("/cookie", h.ValidateTokenCookie)
|
||||||
|
}
|
||||||
17
go.mod
17
go.mod
@ -4,11 +4,24 @@ go 1.23.2
|
|||||||
|
|
||||||
replace ron => ./../ron-gola
|
replace ron => ./../ron-gola
|
||||||
|
|
||||||
require ron v0.0.0-00010101000000-000000000000
|
require (
|
||||||
|
aidanwoods.dev/go-paseto v1.5.2
|
||||||
|
github.com/golang-migrate/migrate/v4 v4.18.1
|
||||||
|
github.com/jackc/pgx/v5 v5.7.1
|
||||||
|
github.com/lib/pq v1.10.9
|
||||||
|
ron v0.0.0-00010101000000-000000000000
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
aidanwoods.dev/go-paseto v1.5.2 // indirect
|
|
||||||
aidanwoods.dev/go-result v0.1.0 // indirect
|
aidanwoods.dev/go-result v0.1.0 // indirect
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||||
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
golang.org/x/crypto v0.29.0 // indirect
|
golang.org/x/crypto v0.29.0 // indirect
|
||||||
|
golang.org/x/sync v0.9.0 // indirect
|
||||||
golang.org/x/sys v0.27.0 // indirect
|
golang.org/x/sys v0.27.0 // indirect
|
||||||
|
golang.org/x/text v0.20.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
79
go.sum
79
go.sum
@ -2,7 +2,86 @@ aidanwoods.dev/go-paseto v1.5.2 h1:9aKbCQQUeHCqis9Y6WPpJpM9MhEOEI5XBmfTkFMSF/o=
|
|||||||
aidanwoods.dev/go-paseto v1.5.2/go.mod h1:7eEJZ98h2wFi5mavCcbKfv9h86oQwut4fLVeL/UBFnw=
|
aidanwoods.dev/go-paseto v1.5.2/go.mod h1:7eEJZ98h2wFi5mavCcbKfv9h86oQwut4fLVeL/UBFnw=
|
||||||
aidanwoods.dev/go-result v0.1.0 h1:y/BMIRX6q3HwaorX1Wzrjo3WUdiYeyWbvGe18hKS3K8=
|
aidanwoods.dev/go-result v0.1.0 h1:y/BMIRX6q3HwaorX1Wzrjo3WUdiYeyWbvGe18hKS3K8=
|
||||||
aidanwoods.dev/go-result v0.1.0/go.mod h1:yridkWghM7AXSFA6wzx0IbsurIm1Lhuro3rYef8FBHM=
|
aidanwoods.dev/go-result v0.1.0/go.mod h1:yridkWghM7AXSFA6wzx0IbsurIm1Lhuro3rYef8FBHM=
|
||||||
|
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
||||||
|
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||||
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dhui/dktest v0.4.3 h1:wquqUxAFdcUgabAVLvSCOKOlag5cIZuaOjYIBOWdsR0=
|
||||||
|
github.com/dhui/dktest v0.4.3/go.mod h1:zNK8IwktWzQRm6I/l2Wjp7MakiyaFWv4G1hjmodmMTs=
|
||||||
|
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||||
|
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||||
|
github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4=
|
||||||
|
github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
|
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||||
|
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||||
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
|
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
|
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||||
|
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
|
github.com/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y=
|
||||||
|
github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks=
|
||||||
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
|
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
||||||
|
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||||
|
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||||
|
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||||
|
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||||
|
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||||
|
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||||
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
|
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||||
|
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
|
||||||
|
go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
|
||||||
|
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
|
||||||
|
go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
|
||||||
|
go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
|
||||||
|
go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
|
||||||
|
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
|
||||||
|
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||||
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||||
|
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||||
|
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||||
|
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
@ -2,10 +2,51 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"aidanwoods.dev/go-paseto"
|
"aidanwoods.dev/go-paseto"
|
||||||
|
"bufio"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func New() *App {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
err = loadEnvFile()
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("error loading env file", "error", err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var durationTime time.Duration
|
||||||
|
var ak paseto.V4AsymmetricSecretKey
|
||||||
|
|
||||||
|
ak, err = paseto.NewV4AsymmetricSecretKeyFromHex(os.Getenv("ASYMMETRICKEY"))
|
||||||
|
if err != nil {
|
||||||
|
ak = paseto.NewV4AsymmetricSecretKey()
|
||||||
|
}
|
||||||
|
pk := ak.Public()
|
||||||
|
|
||||||
|
duration := os.Getenv("DURATION")
|
||||||
|
if duration != "" {
|
||||||
|
durationTime, err = time.ParseDuration(duration)
|
||||||
|
if err != nil {
|
||||||
|
durationTime = time.Hour * 24 * 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &App{
|
||||||
|
DataSource: os.Getenv("DATASOURCE"),
|
||||||
|
Security: Security{
|
||||||
|
AsymmetricKey: ak,
|
||||||
|
PublicKey: pk,
|
||||||
|
Duration: durationTime,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type App struct {
|
type App struct {
|
||||||
|
DataSource string
|
||||||
Security Security
|
Security Security
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,3 +55,27 @@ type Security struct {
|
|||||||
PublicKey paseto.V4AsymmetricPublicKey
|
PublicKey paseto.V4AsymmetricPublicKey
|
||||||
Duration time.Duration
|
Duration time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadEnvFile() error {
|
||||||
|
file, err := os.Open(".env")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if len(line) == 0 || strings.HasPrefix(line, "#") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
parts := strings.SplitN(line, "=", 2)
|
||||||
|
if len(parts) != 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
key := strings.TrimSpace(parts[0])
|
||||||
|
value := strings.TrimSpace(parts[1])
|
||||||
|
os.Setenv(key, value)
|
||||||
|
}
|
||||||
|
return scanner.Err()
|
||||||
|
}
|
||||||
|
|||||||
23
internal/config/db.go
Normal file
23
internal/config/db.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewPostgresPool(dataSource string) *pgxpool.Pool {
|
||||||
|
dbPool, err := pgxpool.New(context.Background(), dataSource)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("error connecting to database", "error", err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dbPool.Ping(context.Background()); err != nil {
|
||||||
|
slog.Error("error pinging database, maybe incorrect datasource", "error", err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.Info("connected to database")
|
||||||
|
return dbPool
|
||||||
|
}
|
||||||
@ -1,38 +1,58 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
"ron"
|
"ron"
|
||||||
"ron-pets/internal/config"
|
"ron-pets/internal/config"
|
||||||
|
"ron-pets/internal/repository"
|
||||||
|
"ron-pets/internal/sqlc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handlers struct {
|
type Handlers struct {
|
||||||
app *config.App
|
app *config.App
|
||||||
|
queries repository.ExtendedQuerier
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(app *config.App) *Handlers {
|
func New(app *config.App, q repository.ExtendedQuerier) *Handlers {
|
||||||
return &Handlers{
|
return &Handlers{
|
||||||
app: app,
|
app: app,
|
||||||
|
queries: q,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hq *Handlers) HelloWorld(c *ron.Context) {
|
func (hq *Handlers) HelloWorld(c *ron.CTX, ctx context.Context) {
|
||||||
slog.Info("Dummy info message")
|
|
||||||
|
session, ok := ctx.Value("session").(*sqlc.SessionData)
|
||||||
|
if !ok || session == nil {
|
||||||
|
http.Error(c.W, "Unauthorized", http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(c.W, "User ID: %s, Role: %s", session.UserID, session.Role)
|
||||||
|
|
||||||
c.W.Write([]byte("hello world"))
|
c.W.Write([]byte("hello world"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hq *Handlers) AnotherHelloWorld(c *ron.Context) {
|
func (hq *Handlers) AnotherHelloWorld(c *ron.CTX) {
|
||||||
|
|
||||||
|
val := c.R.Context().Value("key")
|
||||||
|
//val := context.Background().Value("key")
|
||||||
|
slog.Info("context value", "value", val)
|
||||||
|
|
||||||
c.W.Write([]byte("another hello world"))
|
c.W.Write([]byte("another hello world"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hq *Handlers) HelloWorldJSON(c *ron.Context) {
|
func (hq *Handlers) HelloWorldJSON(c *ron.CTX) {
|
||||||
id := c.R.PathValue("id")
|
id := c.R.PathValue("id")
|
||||||
slog.Info("path value", "id", id)
|
slog.Info("path value", "id", id)
|
||||||
|
|
||||||
c.JSON(200, ron.Data{"message": "hello world"})
|
c.JSON(200, ron.Data{"message": "hello world"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hq *Handlers) HelloWorldHTML(c *ron.Context) {
|
func (hq *Handlers) HelloWorldHTML(c *ron.CTX) {
|
||||||
|
|
||||||
//pages := ron.Pages{
|
//pages := ron.Pages{
|
||||||
// TotalElements: len(elements),
|
// TotalElements: len(elements),
|
||||||
@ -50,6 +70,6 @@ func (hq *Handlers) HelloWorldHTML(c *ron.Context) {
|
|||||||
//c.HTML(200, "page.index.gohtml", td)
|
//c.HTML(200, "page.index.gohtml", td)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hq *Handlers) ComponentHTML(c *ron.Context) {
|
func (hq *Handlers) ComponentHTML(c *ron.CTX) {
|
||||||
c.HTML(200, "component.list.gohtml", nil)
|
c.HTML(200, "component.list.gohtml", nil)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ type UserPayload struct {
|
|||||||
Role string `json:"role"`
|
Role string `json:"role"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hq *Handlers) CreateToken(c *ron.Context) {
|
func (hq *Handlers) CreateToken(c *ron.CTX) {
|
||||||
token := paseto.NewToken()
|
token := paseto.NewToken()
|
||||||
token.Set("userPayload", UserPayload{User: "pedro", Role: "admin"})
|
token.Set("userPayload", UserPayload{User: "pedro", Role: "admin"})
|
||||||
token.SetExpiration(time.Now().Add(hq.app.Security.Duration))
|
token.SetExpiration(time.Now().Add(hq.app.Security.Duration))
|
||||||
@ -35,7 +35,7 @@ func (hq *Handlers) CreateToken(c *ron.Context) {
|
|||||||
c.JSON(http.StatusOK, ron.Data{"token": signed})
|
c.JSON(http.StatusOK, ron.Data{"token": signed})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hq *Handlers) ValidateTokenAuthorization(c *ron.Context) {
|
func (hq *Handlers) ValidateTokenAuthorization(c *ron.CTX) {
|
||||||
signed := c.R.Header.Get("Authorization")
|
signed := c.R.Header.Get("Authorization")
|
||||||
split := strings.Split(signed, "Bearer ")
|
split := strings.Split(signed, "Bearer ")
|
||||||
slog.Info("signed", "signed", split[1])
|
slog.Info("signed", "signed", split[1])
|
||||||
@ -56,7 +56,7 @@ func (hq *Handlers) ValidateTokenAuthorization(c *ron.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hq *Handlers) ValidateTokenCookie(c *ron.Context) {
|
func (hq *Handlers) ValidateTokenCookie(c *ron.CTX) {
|
||||||
cookie, err := c.R.Cookie("token")
|
cookie, err := c.R.Cookie("token")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("error", "err", err)
|
slog.Error("error", "err", err)
|
||||||
|
|||||||
18
internal/repository/pgxrepo.go
Normal file
18
internal/repository/pgxrepo.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
"ron-pets/internal/sqlc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type pgxRepository struct {
|
||||||
|
*sqlc.Queries
|
||||||
|
db *pgxpool.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPGXRepo(db *pgxpool.Pool) ExtendedQuerier {
|
||||||
|
return &pgxRepository{
|
||||||
|
Queries: sqlc.New(db),
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
7
internal/repository/querier.go
Normal file
7
internal/repository/querier.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import "ron-pets/internal/sqlc"
|
||||||
|
|
||||||
|
type ExtendedQuerier interface {
|
||||||
|
sqlc.Querier
|
||||||
|
}
|
||||||
32
internal/sqlc/db.go
Normal file
32
internal/sqlc/db.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.27.0
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
"github.com/jackc/pgx/v5/pgconn"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DBTX interface {
|
||||||
|
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
|
||||||
|
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
|
||||||
|
QueryRow(context.Context, string, ...interface{}) pgx.Row
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(db DBTX) *Queries {
|
||||||
|
return &Queries{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Queries struct {
|
||||||
|
db DBTX
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
|
||||||
|
return &Queries{
|
||||||
|
db: tx,
|
||||||
|
}
|
||||||
|
}
|
||||||
10
internal/sqlc/models.go
Normal file
10
internal/sqlc/models.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.27.0
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
type Pet struct {
|
||||||
|
ID int32
|
||||||
|
Name string
|
||||||
|
}
|
||||||
6
internal/sqlc/payloads.go
Normal file
6
internal/sqlc/payloads.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package sqlc
|
||||||
|
|
||||||
|
type SessionData struct {
|
||||||
|
UserID string
|
||||||
|
Role string
|
||||||
|
}
|
||||||
15
internal/sqlc/querier.go
Normal file
15
internal/sqlc/querier.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.27.0
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Querier interface {
|
||||||
|
CreatePet(ctx context.Context, name string) (int32, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Querier = (*Queries)(nil)
|
||||||
23
internal/sqlc/queries.sql.go
Normal file
23
internal/sqlc/queries.sql.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.27.0
|
||||||
|
// source: queries.sql
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
const createPet = `-- name: CreatePet :one
|
||||||
|
insert into "pet" (name)
|
||||||
|
values ($1)
|
||||||
|
returning id
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) CreatePet(ctx context.Context, name string) (int32, error) {
|
||||||
|
row := q.db.QueryRow(ctx, createPet, name)
|
||||||
|
var id int32
|
||||||
|
err := row.Scan(&id)
|
||||||
|
return id, err
|
||||||
|
}
|
||||||
94
main.go
94
main.go
@ -1,94 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"aidanwoods.dev/go-paseto"
|
|
||||||
"log/slog"
|
|
||||||
"ron"
|
|
||||||
"ron-pets/internal/config"
|
|
||||||
"ron-pets/internal/handlers"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SomethingElements struct {
|
|
||||||
Name string
|
|
||||||
Description string
|
|
||||||
}
|
|
||||||
|
|
||||||
var elements = []SomethingElements{
|
|
||||||
{"element 1", "description 1"},
|
|
||||||
{"element 2", "description 2"},
|
|
||||||
{"element 3", "description 3"},
|
|
||||||
{"element 4", "description 4"},
|
|
||||||
{"element 5", "description 5"},
|
|
||||||
{"element 6", "description 6"},
|
|
||||||
{"element 7", "description 7"},
|
|
||||||
{"element 8", "description 8"},
|
|
||||||
{"element 9", "description 9"},
|
|
||||||
{"element 10", "description 10"},
|
|
||||||
{"element 11", "description 11"},
|
|
||||||
{"element 12", "description 12"},
|
|
||||||
{"element 13", "description 13"},
|
|
||||||
{"element 14", "description 14"},
|
|
||||||
{"element 15", "description 15"},
|
|
||||||
{"element 16", "description 16"},
|
|
||||||
{"element 17", "description 17"},
|
|
||||||
{"element 18", "description 18"},
|
|
||||||
{"element 19", "description 19"},
|
|
||||||
{"element 20", "description 20"},
|
|
||||||
{"element 21", "description 21"},
|
|
||||||
{"element 22", "description 22"},
|
|
||||||
{"element 23", "description 23"},
|
|
||||||
{"element 24", "description 24"},
|
|
||||||
{"element 25", "description 25"},
|
|
||||||
{"element 26", "description 26"},
|
|
||||||
{"element 27", "description 27"},
|
|
||||||
{"element 28", "description 28"},
|
|
||||||
{"element 29", "description 29"},
|
|
||||||
{"element 30", "description 30"},
|
|
||||||
{"element 31", "description 31"},
|
|
||||||
{"element 32", "description 32"},
|
|
||||||
{"element 33", "description 33"},
|
|
||||||
{"element 34", "description 34"},
|
|
||||||
{"element 35", "description 35"},
|
|
||||||
{"element 36", "description 36"},
|
|
||||||
{"element 37", "description 37"},
|
|
||||||
{"element 38", "description 38"},
|
|
||||||
{"element 39", "description 39"},
|
|
||||||
{"element 40", "description 40"},
|
|
||||||
{"element 41", "description 41"},
|
|
||||||
{"element 42", "description 42"},
|
|
||||||
{"element 43", "description 43"},
|
|
||||||
{"element 44", "description 44"},
|
|
||||||
{"element 45", "description 45"},
|
|
||||||
{"element 46", "description 46"},
|
|
||||||
{"element 47", "description 47"},
|
|
||||||
{"element 48", "description 48"},
|
|
||||||
{"element 49", "description 49"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var app *config.App
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
r := ron.New(func(e *ron.Engine) {
|
|
||||||
e.LogLevel = slog.LevelDebug
|
|
||||||
})
|
|
||||||
|
|
||||||
asymmetricKey, _ := paseto.NewV4AsymmetricSecretKeyFromHex("c3e9d207e752bd506a89e4ab09210f4b0100ddd31d3c815c0ab671f6885e9eae4def9afa5e982684329746a0718ea0a534fd9ce64813efee08c89ad6700a045d")
|
|
||||||
app = &config.App{
|
|
||||||
Security: config.Security{
|
|
||||||
AsymmetricKey: asymmetricKey,
|
|
||||||
PublicKey: asymmetricKey.Public(),
|
|
||||||
Duration: time.Second * 20,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
slog.Info("asymmetric key", "key", asymmetricKey.ExportHex())
|
|
||||||
|
|
||||||
h := handlers.New(app)
|
|
||||||
router(h, r)
|
|
||||||
|
|
||||||
err := r.Run(":8080")
|
|
||||||
if err != nil {
|
|
||||||
slog.Error(err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log/slog"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func someMiddleware(next http.Handler) http.Handler {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
slog.Info("triggered middleware")
|
|
||||||
next.ServeHTTP(w, r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func anotherMiddleware(next http.Handler) http.Handler {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
slog.Info("triggered another middleware")
|
|
||||||
next.ServeHTTP(w, r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
17
router.go
17
router.go
@ -1,17 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"ron"
|
|
||||||
"ron-pets/internal/handlers"
|
|
||||||
)
|
|
||||||
|
|
||||||
func router(h *handlers.Handlers, r *ron.Engine) {
|
|
||||||
htmlRender := ron.NewHTMLRender()
|
|
||||||
r.Render = htmlRender
|
|
||||||
|
|
||||||
r.Static("static", "static")
|
|
||||||
|
|
||||||
r.GET("/create", h.CreateToken)
|
|
||||||
r.GET("/validate", h.ValidateTokenAuthorization)
|
|
||||||
r.GET("/cookie", h.ValidateTokenCookie)
|
|
||||||
}
|
|
||||||
13
sqlc.yaml
Normal file
13
sqlc.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
version: "2"
|
||||||
|
sql:
|
||||||
|
- engine: "postgresql"
|
||||||
|
schema: "./cmd/database/migrations/*"
|
||||||
|
queries: "./cmd/database/queries/*"
|
||||||
|
gen:
|
||||||
|
go:
|
||||||
|
package: "sqlc"
|
||||||
|
out: "./internal/sqlc"
|
||||||
|
sql_package: "pgx/v5"
|
||||||
|
emit_interface: true
|
||||||
|
emit_empty_slices: true
|
||||||
|
emit_json_tags: false
|
||||||
Loading…
Reference in New Issue
Block a user