Refactoring
This commit is contained in:
62
.drone.yml
62
.drone.yml
@@ -1,62 +0,0 @@
|
|||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: default
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: static_check
|
|
||||||
image: golang:latest
|
|
||||||
commands:
|
|
||||||
- go install honnef.co/go/tools/cmd/staticcheck@latest
|
|
||||||
- cd src && staticcheck ./...
|
|
||||||
volumes:
|
|
||||||
- name: gopath
|
|
||||||
path: /go
|
|
||||||
|
|
||||||
- name: lint
|
|
||||||
image: golang:latest
|
|
||||||
commands:
|
|
||||||
- go install golang.org/x/lint/golint@latest
|
|
||||||
- golint ./src/...
|
|
||||||
volumes:
|
|
||||||
- name: gopath
|
|
||||||
path: /go
|
|
||||||
|
|
||||||
- name: analyze
|
|
||||||
image: golang:latest
|
|
||||||
commands:
|
|
||||||
- cd src && go vet ./...
|
|
||||||
volumes:
|
|
||||||
- name: gopath
|
|
||||||
path: /go
|
|
||||||
|
|
||||||
- name: publish_image
|
|
||||||
image: plugins/docker
|
|
||||||
environment:
|
|
||||||
DOCKER_USERNAME:
|
|
||||||
from_secret: registry_username
|
|
||||||
DOCKER_PASSWORD:
|
|
||||||
from_secret: registry_password
|
|
||||||
commands:
|
|
||||||
- sleep 5
|
|
||||||
- ./deploy/image-build.sh
|
|
||||||
- ./deploy/image-push.sh
|
|
||||||
volumes:
|
|
||||||
- name: docker-sock
|
|
||||||
path: /var/run
|
|
||||||
when:
|
|
||||||
branch:
|
|
||||||
- main
|
|
||||||
|
|
||||||
services:
|
|
||||||
- name: docker
|
|
||||||
image: docker:dind
|
|
||||||
privileged: true
|
|
||||||
volumes:
|
|
||||||
- name: docker-sock
|
|
||||||
path: /var/run
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
- name: gopath
|
|
||||||
temp: {}
|
|
||||||
- name: docker-sock
|
|
||||||
temp: {}
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,6 +1,7 @@
|
|||||||
deploy/.env
|
deploy/.env
|
||||||
!deploy/.env.dist
|
!deploy/.env.dist
|
||||||
deploy/.env.*
|
!deploy/.env.docker
|
||||||
|
deploy/.env.local
|
||||||
|
|
||||||
deploy/server
|
deploy/server
|
||||||
deploy/scheduler
|
deploy/scheduler
|
||||||
|
|||||||
8
Makefile
8
Makefile
@@ -2,16 +2,16 @@ DEPLOY_DIR := ./deploy
|
|||||||
SRC_DIR := ./src
|
SRC_DIR := ./src
|
||||||
|
|
||||||
build-image-dev:
|
build-image-dev:
|
||||||
- sh ${DEPLOY_DIR}/image-build.sh dev
|
- sh ${DEPLOY_DIR}/scripts/image-build.sh dev
|
||||||
|
|
||||||
build-image-prod:
|
build-image-prod:
|
||||||
- sh ${DEPLOY_DIR}/image-build.sh
|
- sh ${DEPLOY_DIR}/scripts/image-build.sh
|
||||||
|
|
||||||
push-image-dev:
|
push-image-dev:
|
||||||
- sh ${DEPLOY_DIR}/image-push.sh dev
|
- sh ${DEPLOY_DIR}/scripts/image-push.sh dev
|
||||||
|
|
||||||
push-image-prod:
|
push-image-prod:
|
||||||
- sh ${DEPLOY_DIR}/image-push.sh
|
- sh ${DEPLOY_DIR}/scripts/image-push.sh
|
||||||
|
|
||||||
build-local-server:
|
build-local-server:
|
||||||
- go build -C ${SRC_DIR} -o ../deploy/server cmd/server/main.go
|
- go build -C ${SRC_DIR} -o ../deploy/server cmd/server/main.go
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ Prepare local dev environment
|
|||||||
|
|
||||||
```ln -s PATH_TO_THE_STACK_DIR/deploy/certs/identity-svc/identity-svc.key deploy/certs/identity-svc.key```
|
```ln -s PATH_TO_THE_STACK_DIR/deploy/certs/identity-svc/identity-svc.key deploy/certs/identity-svc.key```
|
||||||
4. Build server app binary:
|
4. Build server app binary:
|
||||||
```make build-local```
|
```make build-local-server```
|
||||||
5. Run server app:
|
5. Run server app:
|
||||||
```make run-local```
|
```make run-local-server```
|
||||||
|
|
||||||
Build prod image:
|
Build prod image:
|
||||||
$ make build-image-prod
|
$ make build-image-prod
|
||||||
|
|||||||
16
deploy/.env.docker
Normal file
16
deploy/.env.docker
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
SERVER_ADDR=:443
|
||||||
|
|
||||||
|
APP_NAME=identity-svc
|
||||||
|
APP_DOMAIN=identity.service.ego.io
|
||||||
|
|
||||||
|
API_DATABASE_URL=postgres://postgres:12345678@db-postgres:5432/egommerce
|
||||||
|
API_CACHE_ADDR=api-cache:6379
|
||||||
|
API_CACHE_USERNAME=default
|
||||||
|
API_CACHE_PASSWORD=12345678
|
||||||
|
API_MONGODB_URL=mongodb://mongodb:12345678@db-mongo:27017
|
||||||
|
|
||||||
|
JWT_ACCESS_TOKEN_SECRET_KEY=SomeFancySecretAndRandomString
|
||||||
|
JWT_ACCESS_TOKEN_EXPIRE_TIME=1 # hours
|
||||||
|
|
||||||
|
JWT_REFRESH_TOKEN_SECRET_KEY=SomeFancySecretAndRandomStringAgain
|
||||||
|
JWT_REFRESH_TOKEN_EXPIRE_TIME=7 # days
|
||||||
@@ -11,7 +11,7 @@ TARGET=${1:-latest}
|
|||||||
[ ! -d "src/vendor" ] && sh -c "cd src; go mod vendor"
|
[ ! -d "src/vendor" ] && sh -c "cd src; go mod vendor"
|
||||||
|
|
||||||
echo "Building target $IMAGE_PREFIX images..."
|
echo "Building target $IMAGE_PREFIX images..."
|
||||||
docker build --rm -t $BUILDER_IMAGE -f Dockerfile.builder .
|
docker build --rm -t $BUILDER_IMAGE -f deploy/docker/Dockerfile.builder .
|
||||||
|
|
||||||
if [ $TARGET = "latest" ]
|
if [ $TARGET = "latest" ]
|
||||||
then
|
then
|
||||||
@@ -23,7 +23,7 @@ then
|
|||||||
--build-arg BUILD_TIME \
|
--build-arg BUILD_TIME \
|
||||||
--rm --cache-from $SERVER_IMAGE:$TARGET \
|
--rm --cache-from $SERVER_IMAGE:$TARGET \
|
||||||
-t $SERVER_IMAGE:$TARGET \
|
-t $SERVER_IMAGE:$TARGET \
|
||||||
-f Dockerfile.target . > /dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET"
|
-f deploy/docker/Dockerfile.target . > /dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET"
|
||||||
else
|
else
|
||||||
# DEV
|
# DEV
|
||||||
docker build \
|
docker build \
|
||||||
@@ -32,7 +32,7 @@ else
|
|||||||
--build-arg BUILDER_IMAGE=$BUILDER_IMAGE \
|
--build-arg BUILDER_IMAGE=$BUILDER_IMAGE \
|
||||||
--build-arg BUILD_TIME \
|
--build-arg BUILD_TIME \
|
||||||
--rm --no-cache -t $SERVER_IMAGE:$TARGET \
|
--rm --no-cache -t $SERVER_IMAGE:$TARGET \
|
||||||
-f Dockerfile.target . > /dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET"
|
-f deploy/docker/Dockerfile.target . > /dev/null 2>&1 && echo "Successfully tagged $SERVER_IMAGE:$TARGET"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Done."
|
echo "Done."
|
||||||
@@ -36,5 +36,5 @@ func (app *App) Shutdown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) RegisterPlugin(plugin Plugin) {
|
func (app *App) RegisterPlugin(plugin Plugin) {
|
||||||
app.worker.addPlugin(plugin.name, plugin.fn)
|
app.worker.addPlugin(plugin.name, plugin.connect, &app.worker)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ const (
|
|||||||
defCacheUsername = "default"
|
defCacheUsername = "default"
|
||||||
defCachePassword = "12345678"
|
defCachePassword = "12345678"
|
||||||
defDbURL = "postgres://postgres:12345678@db-postgres:5432/egommerce"
|
defDbURL = "postgres://postgres:12345678@db-postgres:5432/egommerce"
|
||||||
defMongoDbURL = "mongodb://mongodb:12345678@db-mongo:27017"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -33,7 +32,6 @@ type Config struct {
|
|||||||
CacheAddr string `json:"cache_addr"`
|
CacheAddr string `json:"cache_addr"`
|
||||||
CacheUsername string `json:"cache_username"`
|
CacheUsername string `json:"cache_username"`
|
||||||
CachePassword string `json:"cache_password"`
|
CachePassword string `json:"cache_password"`
|
||||||
MongoDbUrl string `json:"mongodb_url"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfig(name string) *Config {
|
func NewConfig(name string) *Config {
|
||||||
@@ -47,7 +45,6 @@ func NewConfig(name string) *Config {
|
|||||||
c.CacheUsername = cnf.GetEnv("API_CACHE_USERNAME", defCacheUsername)
|
c.CacheUsername = cnf.GetEnv("API_CACHE_USERNAME", defCacheUsername)
|
||||||
c.CachePassword = cnf.GetEnv("API_CACHE_PASSWORD", defCachePassword)
|
c.CachePassword = cnf.GetEnv("API_CACHE_PASSWORD", defCachePassword)
|
||||||
c.DbURL = cnf.GetEnv("API_DATABASE_URL", defDbURL)
|
c.DbURL = cnf.GetEnv("API_DATABASE_URL", defDbURL)
|
||||||
c.MongoDbUrl = cnf.GetEnv("API_MONGO_URL", defMongoDbURL)
|
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,13 +11,6 @@ type (
|
|||||||
Start() error
|
Start() error
|
||||||
OnShutdown()
|
OnShutdown()
|
||||||
|
|
||||||
addPlugin(name string, fn PluginFn)
|
addPlugin(name string, fn PluginConnectFn, w *WorkerInterface)
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin struct {
|
|
||||||
name string
|
|
||||||
fn PluginFn
|
|
||||||
}
|
|
||||||
|
|
||||||
PluginFn func() any
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,12 +3,19 @@ package app
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
redis "github.com/go-redis/redis/v8"
|
redis "github.com/go-redis/redis/v8"
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
db "github.com/jackc/pgx/v5/pgxpool"
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Plugin struct {
|
||||||
|
name string
|
||||||
|
connect PluginConnectFn
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginConnectFn func(w *WorkerInterface) any // returns connection handle
|
||||||
)
|
)
|
||||||
|
|
||||||
type PluginManager struct {
|
type PluginManager struct {
|
||||||
@@ -21,44 +28,83 @@ func NewPluginManager() *PluginManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *PluginManager) addPlugin(name string, fn PluginFn) {
|
func (pm *PluginManager) addPlugin(name string, fn PluginConnectFn, w *WorkerInterface) {
|
||||||
pm.plugins[name] = fn()
|
pm.plugins[name] = fn(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *PluginManager) getCache() *redis.Client {
|
func (pm *PluginManager) GetCache() *redis.Client {
|
||||||
return (pm.plugins["cache"]).(*redis.Client)
|
return (pm.plugins["cache"]).(*redis.Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *PluginManager) getDatabase() *pgxpool.Pool {
|
func (pm *PluginManager) GetDatabase() *pgxpool.Pool {
|
||||||
return (pm.plugins["database"]).(*pgxpool.Pool)
|
return (pm.plugins["database"]).(*pgxpool.Pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CachePlugin(cnf *Config) Plugin {
|
func CachePlugin(cnf *Config, w WorkerInterface) Plugin {
|
||||||
|
connectFn := func(w WorkerInterface) *redis.Client {
|
||||||
|
log.Println("establishing api-cache connection...")
|
||||||
|
|
||||||
|
return redis.NewClient(&redis.Options{
|
||||||
|
Addr: cnf.CacheAddr,
|
||||||
|
Username: cnf.CacheUsername,
|
||||||
|
Password: cnf.CachePassword,
|
||||||
|
DB: 0, // TODO
|
||||||
|
DialTimeout: 100 * time.Millisecond, // TODO
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// checking if the connection is still alive and try to reconnect when it is not
|
||||||
|
go func(conn *redis.Client) {
|
||||||
|
tick := time.NewTicker(5 * time.Second) // is 5 seconds is not too much?
|
||||||
|
defer tick.Stop()
|
||||||
|
|
||||||
|
for range tick.C {
|
||||||
|
if err := conn.Ping(context.Background()).Err(); err != nil {
|
||||||
|
log.Println("lost connection with api-cache. Reconnecting...")
|
||||||
|
conn = connectFn(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}(connectFn(w))
|
||||||
|
|
||||||
return Plugin{
|
return Plugin{
|
||||||
name: "cache",
|
name: "cache",
|
||||||
fn: func() any {
|
connect: func(w *WorkerInterface) any {
|
||||||
return redis.NewClient(&redis.Options{
|
return connectFn(*w)
|
||||||
Addr: cnf.CacheAddr,
|
|
||||||
Username: cnf.CacheUsername,
|
|
||||||
Password: cnf.CachePassword,
|
|
||||||
DB: 0, // TODO
|
|
||||||
DialTimeout: 100 * time.Millisecond, // TODO
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DatabasePlugin(cnf *Config) Plugin {
|
func DatabasePlugin(cnf *Config, w WorkerInterface) Plugin {
|
||||||
|
connectFn := func(w WorkerInterface) *pgxpool.Pool {
|
||||||
|
log.Println("establishing db-postgres connection...")
|
||||||
|
|
||||||
|
conn, err := pgxpool.New(context.Background(), cnf.DbURL)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to connect to the database: %s. Err: %s\n", cnf.DbURL, err.Error())
|
||||||
|
return nil
|
||||||
|
// os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn
|
||||||
|
}
|
||||||
|
|
||||||
|
// checking if the connection is still alive and try to reconnect when it is not
|
||||||
|
go func(conn *pgxpool.Pool) {
|
||||||
|
tick := time.NewTicker(5 * time.Second) // is 5 seconds is not too much?
|
||||||
|
defer tick.Stop()
|
||||||
|
|
||||||
|
for range tick.C {
|
||||||
|
if err := conn.Ping(context.Background()); err != nil {
|
||||||
|
log.Println("lost connection with db-postgres. Reconnecting...")
|
||||||
|
conn = connectFn(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}(connectFn(w))
|
||||||
|
|
||||||
return Plugin{
|
return Plugin{
|
||||||
name: "database",
|
name: "database",
|
||||||
fn: func() any {
|
connect: func(w *WorkerInterface) any {
|
||||||
dbConn, err := db.New(context.Background(), cnf.DbURL)
|
return connectFn(*w)
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to connect to the Database: %s. Err: %v\n", cnf.DbURL, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return dbConn
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ func NewScheduler(c *Config) *Scheduler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Scheduler) Start() error { // STILL NEEDS REFACTORING ;)
|
func (c *Scheduler) Start() error { // STILL NEEDS REFACTORING ;)
|
||||||
userRepo := repository.NewUserRepository(c.getDatabase())
|
userRepo := repository.NewUserRepository(c.GetDatabase())
|
||||||
roleRepo := repository.NewRoleRepository(c.getDatabase())
|
roleRepo := repository.NewRoleRepository(c.GetDatabase())
|
||||||
urlRepo := repository.NewURLAccessRepository(c.getDatabase())
|
urlRepo := repository.NewURLAccessRepository(c.GetDatabase())
|
||||||
authSrv := service.NewAuthService(userRepo, c.getCache())
|
authSrv := service.NewAuthService(userRepo, c.GetCache())
|
||||||
guardSrv := service.NewGuardService(authSrv, c.getCache(), userRepo, roleRepo, urlRepo)
|
guardSrv := service.NewGuardService(authSrv, c.GetCache(), userRepo, roleRepo, urlRepo)
|
||||||
|
|
||||||
job := scheduler.NewCachePermissionsJob(guardSrv)
|
job := scheduler.NewCachePermissionsJob(guardSrv)
|
||||||
sch := clockwerk.New()
|
sch := clockwerk.New()
|
||||||
@@ -39,6 +39,6 @@ func (c *Scheduler) Start() error { // STILL NEEDS REFACTORING ;)
|
|||||||
func (c *Scheduler) OnShutdown() {
|
func (c *Scheduler) OnShutdown() {
|
||||||
log.Println("Scheduler is going down...")
|
log.Println("Scheduler is going down...")
|
||||||
|
|
||||||
c.getDatabase().Close()
|
c.GetDatabase().Close()
|
||||||
c.getCache().Close()
|
c.GetCache().Close()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ func (s *Server) Start() error {
|
|||||||
|
|
||||||
crt, err := tls.LoadX509KeyPair("certs/identity-svc.crt", "certs/identity-svc.key")
|
crt, err := tls.LoadX509KeyPair("certs/identity-svc.crt", "certs/identity-svc.key")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal("failed to load certificates: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsCnf := &tls.Config{Certificates: []tls.Certificate{crt}}
|
tlsCnf := &tls.Config{Certificates: []tls.Certificate{crt}}
|
||||||
@@ -74,8 +74,8 @@ func (s *Server) Start() error {
|
|||||||
func (s *Server) OnShutdown() {
|
func (s *Server) OnShutdown() {
|
||||||
log.Printf("Server %s is going down...", s.ID)
|
log.Printf("Server %s is going down...", s.ID)
|
||||||
|
|
||||||
s.getDatabase().Close()
|
s.GetDatabase().Close()
|
||||||
s.getCache().Close()
|
s.GetCache().Close()
|
||||||
|
|
||||||
s.Shutdown()
|
s.Shutdown()
|
||||||
}
|
}
|
||||||
@@ -84,13 +84,13 @@ func (s *Server) setupRouter() {
|
|||||||
s.Options("*", defaultCORS)
|
s.Options("*", defaultCORS)
|
||||||
s.Use(defaultCORS)
|
s.Use(defaultCORS)
|
||||||
|
|
||||||
s.Get("/health", http.HealthHandlerFn(s.getDatabase(), s.getCache()))
|
s.Get("/health", http.HealthHandlerFn(s.GetDatabase(), s.GetCache()))
|
||||||
|
|
||||||
s.Group("/v1").
|
s.Group("/v1").
|
||||||
Post("/login", http.LoginHandlerFn(s.getDatabase(), s.getCache())).
|
Post("/login", http.LoginHandlerFn(s.GetDatabase(), s.GetCache())).
|
||||||
Post("/refresh", http.RefreshHandlerFn(s.getDatabase(), s.getCache())). // add JWTProtected() and get token from Auth Bearer header not from the body?
|
Post("/refresh", http.RefreshHandlerFn(s.GetDatabase(), s.GetCache())). // add JWTProtected() and get token from Auth Bearer header not from the body?
|
||||||
Post("/register", http.RegisterHandlerFn(s.getDatabase(), s.getCache())).
|
Post("/register", http.RegisterHandlerFn(s.GetDatabase(), s.GetCache())).
|
||||||
Get("/access", JWTProtected(), http.AccessHandlerFn(s.getDatabase(), s.getCache()))
|
Get("/access", JWTProtected(), http.AccessHandlerFn(s.GetDatabase(), s.GetCache()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) setupMiddleware() {
|
func (s *Server) setupMiddleware() {
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cnf := app.NewConfig("identity-scheduler")
|
cnf := app.NewConfig("identity-scheduler")
|
||||||
w := app.NewScheduler(cnf)
|
srv := app.NewScheduler(cnf)
|
||||||
a := app.NewApp(w)
|
a := app.NewApp(srv)
|
||||||
a.RegisterPlugin(app.CachePlugin(cnf))
|
a.RegisterPlugin(app.CachePlugin(cnf, srv))
|
||||||
a.RegisterPlugin(app.DatabasePlugin(cnf))
|
a.RegisterPlugin(app.DatabasePlugin(cnf, srv))
|
||||||
|
|
||||||
while := make(chan struct{})
|
while := make(chan struct{})
|
||||||
err := a.Start(while)
|
err := a.Start(while)
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cnf := app.NewConfig("identity-svc")
|
cnf := app.NewConfig("identity-svc")
|
||||||
w := app.NewServer(cnf)
|
srv := app.NewServer(cnf)
|
||||||
a := app.NewApp(w)
|
a := app.NewApp(srv)
|
||||||
a.RegisterPlugin(app.CachePlugin(cnf))
|
a.RegisterPlugin(app.CachePlugin(cnf, srv))
|
||||||
a.RegisterPlugin(app.DatabasePlugin(cnf))
|
a.RegisterPlugin(app.DatabasePlugin(cnf, srv))
|
||||||
|
|
||||||
while := make(chan struct{})
|
while := make(chan struct{})
|
||||||
err := a.Start(while)
|
err := a.Start(while)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ go 1.24.0
|
|||||||
toolchain go1.24.1
|
toolchain go1.24.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.ego.freeddns.org/egommerce/api-entities v0.3.34
|
git.ego.freeddns.org/egommerce/api-entities v0.3.36
|
||||||
git.ego.freeddns.org/egommerce/go-api-pkg v0.5.3
|
git.ego.freeddns.org/egommerce/go-api-pkg v0.5.3
|
||||||
github.com/georgysavva/scany/v2 v2.1.4
|
github.com/georgysavva/scany/v2 v2.1.4
|
||||||
github.com/go-pg/migrations/v8 v8.1.0
|
github.com/go-pg/migrations/v8 v8.1.0
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
git.ego.freeddns.org/egommerce/api-entities v0.3.34 h1:WftM9cvV3JmbS1DlHCIiV3tsYIpALj9IXo90mkgZNWQ=
|
git.ego.freeddns.org/egommerce/api-entities v0.3.36 h1:vqIR7CCcRmO7xBpRUnmQuF0DlXozpbBf5w7ud62otvw=
|
||||||
git.ego.freeddns.org/egommerce/api-entities v0.3.34/go.mod h1:IqynARw+06GOm4eZGZuepmbi7bUxWBnOB4jd5cI7jf8=
|
git.ego.freeddns.org/egommerce/api-entities v0.3.36/go.mod h1:IqynARw+06GOm4eZGZuepmbi7bUxWBnOB4jd5cI7jf8=
|
||||||
git.ego.freeddns.org/egommerce/go-api-pkg v0.5.3 h1:so+OWWVJEg6JZ5XOSmCpfW7Pd7IL6ETH0QsC6zCwndo=
|
git.ego.freeddns.org/egommerce/go-api-pkg v0.5.3 h1:so+OWWVJEg6JZ5XOSmCpfW7Pd7IL6ETH0QsC6zCwndo=
|
||||||
git.ego.freeddns.org/egommerce/go-api-pkg v0.5.3/go.mod h1:T3ia8iprzlTRznPVXYCgEzQb/1UvIcdn9FHabE58vy0=
|
git.ego.freeddns.org/egommerce/go-api-pkg v0.5.3/go.mod h1:T3ia8iprzlTRznPVXYCgEzQb/1UvIcdn9FHabE58vy0=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type HealthResponse struct {
|
|||||||
|
|
||||||
func HealthHandlerFn(db *pgxpool.Pool, cache *redis.Client) fiber.Handler {
|
func HealthHandlerFn(db *pgxpool.Pool, cache *redis.Client) fiber.Handler {
|
||||||
return func(c *fiber.Ctx) error {
|
return func(c *fiber.Ctx) error {
|
||||||
// Only 404 indicate service as not-healthy
|
// Default behavior of k8s is only 404 indicate service as not-healthy
|
||||||
err := db.Ping(context.Background())
|
err := db.Ping(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.SendStatus(http.StatusNotFound)
|
return c.SendStatus(http.StatusNotFound)
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ func LoginHandlerFn(db *pgxpool.Pool, cache *redis.Client) fiber.Handler {
|
|||||||
req := new(identityDTO.AuthLoginRequestDTO)
|
req := new(identityDTO.AuthLoginRequestDTO)
|
||||||
if err := c.BodyParser(req); err != nil {
|
if err := c.BodyParser(req); err != nil {
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(&commonDTO.ErrorResponseDTO{Error: "error parsing input"})
|
return c.Status(fiber.StatusBadRequest).JSON(&commonDTO.ErrorResponseDTO{Error: "error parsing input"})
|
||||||
// return srv.Error(c, fiber.StatusBadRequest, "error parsing input")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
userRepo := repository.NewUserRepository(db)
|
userRepo := repository.NewUserRepository(db)
|
||||||
@@ -26,8 +25,7 @@ func LoginHandlerFn(db *pgxpool.Pool, cache *redis.Client) fiber.Handler {
|
|||||||
|
|
||||||
token, err := ui.NewLoginActionUI(authSrv).Execute(req)
|
token, err := ui.NewLoginActionUI(authSrv).Execute(req)
|
||||||
if err != nil { // TODO: handle other response status codes -- add struct to decorate error with code and message
|
if err != nil { // TODO: handle other response status codes -- add struct to decorate error with code and message
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(commonDTO.ErrorResponseDTO{Error: err.Error()})
|
return c.Status(fiber.StatusBadRequest).JSON(&commonDTO.ErrorResponseDTO{Error: err.Error()})
|
||||||
// return srv.Error(c, fiber.StatusBadRequest, err.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(&identityDTO.AuthLoginResponseDTO{Token: token})
|
return c.JSON(&identityDTO.AuthLoginResponseDTO{Token: token})
|
||||||
|
|||||||
@@ -43,11 +43,6 @@ func NewAuthService(userRepo repository.UserRepositoryInterface, cache *redis.Cl
|
|||||||
func (a *AuthService) Login(login, passwd string) (string, error) {
|
func (a *AuthService) Login(login, passwd string) (string, error) {
|
||||||
user, err := a.userRepo.FindByUsername(login)
|
user, err := a.userRepo.FindByUsername(login)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO place code below in better place...
|
|
||||||
// if err = database.NoRowsInQuerySet(err); err != nil {
|
|
||||||
// return "", errors.New("no user found")
|
|
||||||
// }
|
|
||||||
|
|
||||||
return "", ErrLoginIncorrect
|
return "", ErrLoginIncorrect
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +56,6 @@ func (a *AuthService) Login(login, passwd string) (string, error) {
|
|||||||
return "", ErrUnableToCacheToken
|
return "", ErrUnableToCacheToken
|
||||||
}
|
}
|
||||||
|
|
||||||
// REFACTOR: save uid in cache under "user:$ACCES_TOKEN" key
|
|
||||||
res := a.cache.Set(context.Background(), "user:"+accessToken, user.ID, accessTokenExpireTime)
|
res := a.cache.Set(context.Background(), "user:"+accessToken, user.ID, accessTokenExpireTime)
|
||||||
if err := res.Err(); err != nil {
|
if err := res.Err(); err != nil {
|
||||||
fmt.Println("failed to save user:$ACCESS_TOKEN in cache: ", err.Error())
|
fmt.Println("failed to save user:$ACCESS_TOKEN in cache: ", err.Error())
|
||||||
@@ -73,8 +67,8 @@ func (a *AuthService) Login(login, passwd string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *AuthService) RefreshToken(accessToken string) (string, error) {
|
func (a *AuthService) RefreshToken(accessToken string) (string, error) {
|
||||||
// POSSIBLE BIG SECURITY ISSUE- WHEN REFRESH WITH ABANDONED (or EXPIRED)
|
// POSSIBLE BIG SECURITY ISSUE - WHEN REFRESH WITH ABANDONED (or EXPIRED)
|
||||||
// ACCESS TOKEN WE GET NEW ACCESS TOKEN
|
// ACCESS TOKEN WE CAN GET A NEW ACCESS TOKEN
|
||||||
token, claims, err := jwtSrv.ValidateAccessToken(accessToken)
|
token, claims, err := jwtSrv.ValidateAccessToken(accessToken)
|
||||||
if err != nil || !token.Valid {
|
if err != nil || !token.Valid {
|
||||||
return "", ErrInvalidAccessToken
|
return "", ErrInvalidAccessToken
|
||||||
|
|||||||
@@ -15,19 +15,19 @@ import (
|
|||||||
|
|
||||||
type GuardService struct {
|
type GuardService struct {
|
||||||
authSrv *AuthService
|
authSrv *AuthService
|
||||||
cache *redis.Client
|
|
||||||
userRepo *repository.UserRepository
|
userRepo *repository.UserRepository
|
||||||
roleRepo *repository.RoleRepository
|
roleRepo *repository.RoleRepository
|
||||||
urlRepo *repository.URLAccessRepository
|
urlRepo *repository.URLAccessRepository
|
||||||
|
cache *redis.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGuardService(authSrv *AuthService, cache *redis.Client, userRepo *repository.UserRepository, roleRepo *repository.RoleRepository, urlRepo *repository.URLAccessRepository) *GuardService {
|
func NewGuardService(authSrv *AuthService, cache *redis.Client, userRepo *repository.UserRepository, roleRepo *repository.RoleRepository, urlRepo *repository.URLAccessRepository) *GuardService {
|
||||||
return &GuardService{
|
return &GuardService{
|
||||||
authSrv: authSrv,
|
authSrv: authSrv,
|
||||||
cache: cache,
|
|
||||||
userRepo: userRepo,
|
userRepo: userRepo,
|
||||||
roleRepo: roleRepo,
|
roleRepo: roleRepo,
|
||||||
urlRepo: urlRepo,
|
urlRepo: urlRepo,
|
||||||
|
cache: cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,5 +78,3 @@ func (g *GuardService) CacheAllPermissions() error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (g *GuardService) fetchURLAccessFromCache() {}
|
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ func NewLoginActionUI(authSrv *service.AuthService) *LoginActionUI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ui *LoginActionUI) Execute(data *identityDTO.AuthLoginRequestDTO) (string, error) {
|
func (ui *LoginActionUI) Execute(dto *identityDTO.AuthLoginRequestDTO) (string, error) {
|
||||||
token, err := ui.authSrv.Login(data.Username, data.Password)
|
token, err := ui.authSrv.Login(dto.Username, dto.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: handle other response status codes -- add struct to decorate error with code and message
|
// TODO: handle other response status codes -- add struct to decorate error with code and message
|
||||||
if err == service.ErrUnableToCacheToken {
|
if err == service.ErrUnableToCacheToken {
|
||||||
|
|||||||
Reference in New Issue
Block a user