working on ron-example

This commit is contained in:
2024-11-20 23:09:25 +01:00
parent ea5d85bd19
commit 4f108e1b05
25 changed files with 627 additions and 147 deletions
+66 -1
View File
@@ -2,11 +2,52 @@ package config
import (
"aidanwoods.dev/go-paseto"
"bufio"
"log/slog"
"os"
"strings"
"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 {
Security Security
DataSource string
Security Security
}
type Security struct {
@@ -14,3 +55,27 @@ type Security struct {
PublicKey paseto.V4AsymmetricPublicKey
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
View 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
}
+29 -9
View File
@@ -1,38 +1,58 @@
package handlers
import (
"context"
"fmt"
"log/slog"
"net/http"
"ron"
"ron-pets/internal/config"
"ron-pets/internal/repository"
"ron-pets/internal/sqlc"
)
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{
app: app,
app: app,
queries: q,
}
}
func (hq *Handlers) HelloWorld(c *ron.Context) {
slog.Info("Dummy info message")
func (hq *Handlers) HelloWorld(c *ron.CTX, ctx context.Context) {
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"))
}
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"))
}
func (hq *Handlers) HelloWorldJSON(c *ron.Context) {
func (hq *Handlers) HelloWorldJSON(c *ron.CTX) {
id := c.R.PathValue("id")
slog.Info("path value", "id", id)
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{
// TotalElements: len(elements),
@@ -50,6 +70,6 @@ func (hq *Handlers) HelloWorldHTML(c *ron.Context) {
//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)
}
+3 -3
View File
@@ -14,7 +14,7 @@ type UserPayload struct {
Role string `json:"role"`
}
func (hq *Handlers) CreateToken(c *ron.Context) {
func (hq *Handlers) CreateToken(c *ron.CTX) {
token := paseto.NewToken()
token.Set("userPayload", UserPayload{User: "pedro", Role: "admin"})
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})
}
func (hq *Handlers) ValidateTokenAuthorization(c *ron.Context) {
func (hq *Handlers) ValidateTokenAuthorization(c *ron.CTX) {
signed := c.R.Header.Get("Authorization")
split := strings.Split(signed, "Bearer ")
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")
if err != nil {
slog.Error("error", "err", err)
+18
View 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
View File
@@ -0,0 +1,7 @@
package repository
import "ron-pets/internal/sqlc"
type ExtendedQuerier interface {
sqlc.Querier
}
+32
View 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
View 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
View File
@@ -0,0 +1,6 @@
package sqlc
type SessionData struct {
UserID string
Role string
}
+15
View 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
View 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
}