Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ ENV_APP_NAME="Gus Blog"
ENV_APP_ENV_TYPE=local
ENV_APP_LOG_LEVEL=debug
ENV_APP_LOGS_DIR="./storage/logs/logs_%s.log"
ENV_APP_LOGS_DATE_FORMAT="2006_02_01"
ENV_APP_LOGS_DATE_FORMAT="2006-01-02"
ENV_APP_URL=

# --- The App master key for encryption.
ENV_APP_MASTER_KEY=
Expand Down Expand Up @@ -32,3 +33,6 @@ ENV_DOCKER_USER_GROUP="ggroup"
# type: string, min: 16 characters.
ENV_PING_USERNAME=
ENV_PING_PASSWORD=

# --- SEO: SPA application directory
ENV_SPA_DIR=
5 changes: 0 additions & 5 deletions .env.gh.example

This file was deleted.

37 changes: 0 additions & 37 deletions .env.prod.example

This file was deleted.

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ tmp

database/infra/data

# -- [SEO]: static files
storage/seo/*.*
!storage/seo/.gitkeep

# --- [Caddy]: mtls
caddy/mtls/*.*
!caddy/mtls/.gitkeep
Expand Down
12 changes: 7 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,16 @@ help:
@printf " $(BOLD)$(GREEN)audit$(NC) : Run code audits and checks.\n"
@printf " $(BOLD)$(GREEN)watch$(NC) : Start a file watcher process.\n"
@printf " $(BOLD)$(GREEN)format$(NC) : Automatically format code.\n"
@printf " $(BOLD)$(GREEN)test-all$(NC) : Run all the application tests.\n\n"
@printf " $(BOLD)$(GREEN)run-cli$(NC) : Run the application CLI interface.\n\n"
@printf " $(BOLD)$(GREEN)run-cli-local$(NC) : Run the application dev's CLI interface.\n\n"
@printf " $(BOLD)$(GREEN)test-all$(NC) : Run all the application tests.\n"
@printf " $(BOLD)$(GREEN)run-cli$(NC) : Run the application CLI interface.\n"
@printf " $(BOLD)$(GREEN)run-cli-docker$(NC) : Run the application [docker] dev's CLI interface.\n\n"
@printf " $(BOLD)$(GREEN)run-metal$(NC) : Run the application dev's CLI interface.\n\n"

@printf "$(BOLD)$(BLUE)Build Commands:$(NC)\n"
@printf " $(BOLD)$(GREEN)build-local$(NC) : Build the main application for development.\n"
@printf " $(BOLD)$(GREEN)build-ci$(NC) : Build the main application for the CI.\n"
@printf " $(BOLD)$(GREEN)build-release$(NC) : Build a release version of the application.\n\n"
@printf " $(BOLD)$(GREEN)build-release$(NC) : Build a release version of the application.\n"
@printf " $(BOLD)$(GREEN)build-fresh$(NC) : Build a fresh development environment.\n\n"

@printf "$(BOLD)$(BLUE)Database Commands:$(NC)\n"
@printf " $(BOLD)$(GREEN)db:local$(NC) : Set up or manage the local database environment.\n"
Expand Down Expand Up @@ -95,7 +97,7 @@ help:
@printf " $(BOLD)$(GREEN)supv:api:stop$(NC) : Stop the API service supervisor.\n"
@printf " $(BOLD)$(GREEN)supv:api:restart$(NC) : Restart the API service supervisor.\n"
@printf " $(BOLD)$(GREEN)supv:api:logs$(NC) : Show the the API service supervisor logs.\n"
@printf " $(BOLD)$(GREEN)supv:api:logs-err$(NC): Show the the API service supervisor error logs.\n"
@printf " $(BOLD)$(GREEN)supv:api:logs-err$(NC): Show the the API service supervisor error logs.\n\n"

@printf "$(BOLD)$(BLUE)Caddy Commands:$(NC)\n"
@printf " $(BOLD)$(GREEN)caddy-gen-cert$(NC) : Generate the caddy's mtls certificates.\n"
Expand Down
18 changes: 17 additions & 1 deletion database/repository/categories.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,33 @@ package repository

import (
"fmt"
"strings"

"github.com/google/uuid"
"github.com/oullin/database"
"github.com/oullin/database/repository/pagination"
"github.com/oullin/pkg/gorm"
"strings"
)

type Categories struct {
DB *database.Connection
}

func (c Categories) Get() ([]database.Category, error) {
var categories []database.Category

err := c.DB.Sql().
Model(&database.Category{}).
Where("categories.deleted_at is null").
Find(&categories).Error

if err != nil {
return nil, err
}

return categories, nil
}

func (c Categories) GetAll(paginate pagination.Paginate) (*pagination.Pagination[database.Category], error) {
var numItems int64
var categories []database.Category
Expand Down
3 changes: 2 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ services:
# A dedicated service for running one-off Go commands
api-runner:
restart: no
env_file:
- ./.env
image: golang:1.25.1-alpine@sha256:b6ed3fd0452c0e9bcdef5597f29cc1418f61672e9d3a2f55bf02e7222c014abd
volumes:
- .:/app
- ./.env:/.env:ro
- go_mod_cache:/go/pkg/mod
working_dir: /app
environment:
Expand Down
4 changes: 2 additions & 2 deletions handler/keep_alive.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import (
)

type KeepAliveHandler struct {
env *env.Ping
env *env.PingEnvironment
}

func MakeKeepAliveHandler(e *env.Ping) KeepAliveHandler {
func MakeKeepAliveHandler(e *env.PingEnvironment) KeepAliveHandler {
return KeepAliveHandler{env: e}
}

Expand Down
4 changes: 2 additions & 2 deletions handler/keep_alive_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import (
)

type KeepAliveDBHandler struct {
env *env.Ping
env *env.PingEnvironment
db *database.Connection
}

func MakeKeepAliveDBHandler(e *env.Ping, db *database.Connection) KeepAliveDBHandler {
func MakeKeepAliveDBHandler(e *env.PingEnvironment, db *database.Connection) KeepAliveDBHandler {
return KeepAliveDBHandler{env: e, db: db}
}

Expand Down
2 changes: 1 addition & 1 deletion handler/keep_alive_db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

func TestKeepAliveDBHandler(t *testing.T) {
db, _ := handlertests.MakeTestDB(t)
e := env.Ping{Username: "user", Password: "pass"}
e := env.PingEnvironment{Username: "user", Password: "pass"}
h := MakeKeepAliveDBHandler(&e, db)

t.Run("valid credentials", func(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion handler/keep_alive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

func TestKeepAliveHandler(t *testing.T) {
e := env.Ping{Username: "user", Password: "pass"}
e := env.PingEnvironment{Username: "user", Password: "pass"}
h := MakeKeepAliveHandler(&e)

t.Run("valid credentials", func(t *testing.T) {
Expand Down
38 changes: 12 additions & 26 deletions metal/cli/accounts/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (h Handler) CreateAccount(accountName string) error {
return fmt.Errorf("failed to create the given account [%s] tokens pair: %v", accountName, err)
}

_, err = h.Tokens.Create(database.APIKeyAttr{
item, err := h.Tokens.Create(database.APIKeyAttr{
AccountName: token.AccountName,
SecretKey: token.EncryptedSecretKey,
PublicKey: token.EncryptedPublicKey,
Expand All @@ -25,12 +25,14 @@ func (h Handler) CreateAccount(accountName string) error {
return fmt.Errorf("failed to create account [%s]: %v", accountName, err)
}

cli.Successln("Account created successfully.\n")
if err = h.print(token, item); err != nil {
return fmt.Errorf("could not decode the given account [%s] keys: %v", item.AccountName, err)
}

return nil
}

func (h Handler) ReadAccount(accountName string) error {
func (h Handler) ShowAccount(accountName string) error {
item := h.Tokens.FindBy(accountName)

if item == nil {
Expand All @@ -43,30 +45,14 @@ func (h Handler) ReadAccount(accountName string) error {
item.PublicKey,
)

if err != nil {
if h.print(token, item) != nil {
return fmt.Errorf("could not decode the given account [%s] keys: %v", item.AccountName, err)
}

cli.Successln("\nThe given account has been found successfully!\n")
cli.Blueln(" > " + fmt.Sprintf("Account name: %s", token.AccountName))
cli.Blueln(" > " + fmt.Sprintf("Public Key: %s", token.PublicKey))
cli.Blueln(" > " + fmt.Sprintf("Secret Key: %s", token.SecretKey))
cli.Blueln(" > " + fmt.Sprintf("API Signature: %s", auth.CreateSignatureFrom(token.AccountName, token.SecretKey)))
cli.Warningln("----- Encrypted Values -----")
cli.Magentaln(" > " + fmt.Sprintf("Public Key: %x", token.EncryptedPublicKey))
cli.Magentaln(" > " + fmt.Sprintf("Secret Key: %x", token.EncryptedSecretKey))
fmt.Println(" ")

return nil
}

func (h Handler) CreateSignature(accountName string) error {
item := h.Tokens.FindBy(accountName)

if item == nil {
return fmt.Errorf("the given account [%s] was not found", accountName)
}

func (h Handler) print(token *auth.Token, item *database.APIKey) error {
token, err := h.TokenHandler.DecodeTokensFor(
item.AccountName,
item.SecretKey,
Expand All @@ -77,14 +63,14 @@ func (h Handler) CreateSignature(accountName string) error {
return fmt.Errorf("could not decode the given account [%s] keys: %v", item.AccountName, err)
}

signature := auth.CreateSignatureFrom(token.AccountName, token.SecretKey)

cli.Successln("\nThe given account has been found successfully!\n")
cli.Blueln(" > " + fmt.Sprintf("Account name: %s", token.AccountName))
cli.Blueln(" > " + fmt.Sprintf("Public Key: %s", auth.SafeDisplay(token.PublicKey)))
cli.Blueln(" > " + fmt.Sprintf("Secret Key: %s", auth.SafeDisplay(token.SecretKey)))
cli.Blueln(" > " + fmt.Sprintf("Public Key: %s", token.PublicKey))
cli.Blueln(" > " + fmt.Sprintf("Secret Key: %s", token.SecretKey))
cli.Blueln(" > " + fmt.Sprintf("API Signature: %s", auth.CreateSignatureFrom(token.AccountName, token.SecretKey)))
cli.Warningln("----- Encrypted Values -----")
cli.Magentaln(" > " + fmt.Sprintf("Signature: %s", signature))
cli.Magentaln(" > " + fmt.Sprintf("Public Key: %x", token.EncryptedPublicKey))
cli.Magentaln(" > " + fmt.Sprintf("Secret Key: %x", token.EncryptedSecretKey))
fmt.Println(" ")

return nil
Expand Down
18 changes: 3 additions & 15 deletions metal/cli/accounts/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,9 @@ func TestCreateReadSignature(t *testing.T) {
t.Fatalf("create: %v", err)
}

if err := h.ReadAccount("tester"); err != nil {
if err := h.ShowAccount("tester"); err != nil {
t.Fatalf("read: %v", err)
}

if err := h.CreateSignature("tester"); err != nil {
t.Fatalf("signature: %v", err)
}
}

func TestCreateAccountInvalid(t *testing.T) {
Expand All @@ -42,18 +38,10 @@ func TestCreateAccountInvalid(t *testing.T) {
}
}

func TestReadAccountNotFound(t *testing.T) {
h := setupAccountHandler(t)

if err := h.ReadAccount("missing"); err == nil {
t.Fatalf("expected error")
}
}

func TestCreateSignatureNotFound(t *testing.T) {
func TestShowAccountNotFound(t *testing.T) {
h := setupAccountHandler(t)

if err := h.CreateSignature("missing"); err == nil {
if err := h.ShowAccount("missing"); err == nil {
t.Fatalf("expected error")
}
}
Loading
Loading