diff --git a/.env.example b/.env.example index 86c77e9..ba539bd 100644 --- a/.env.example +++ b/.env.example @@ -5,4 +5,9 @@ IS_RATE_LIMITER_ENABLED=true THREADS_MAX_COUNT=50 POSTGRES_URL=postgres://localhost/micrach?pool_max_conns=5 THREAD_BUMP_LIMIT=500 -IS_CAPTCHA_ACTIVE=true \ No newline at end of file +IS_CAPTCHA_ACTIVE=true +GATEWAY_URL=http://localhost:3001 +GATEWAY_API_KEY=example +GATEWAY_BOARD_ID=b +GATEWAY_BOARD_URL=http://localhost:3000 +GATEWAY_BOARD_DESCRIPTION=Random \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..913d0b1 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +dev: + nodemon --exec go run main.go --signal SIGTERM diff --git a/config/config.go b/config/config.go index 67dac10..45fcb40 100644 --- a/config/config.go +++ b/config/config.go @@ -7,6 +7,14 @@ import ( "strconv" ) +type GatewayConfig struct { + Url string + ApiKey string + BoardId string + BoardUrl string + BoardDescription string +} + type AppConfig struct { Env string Port int @@ -15,6 +23,7 @@ type AppConfig struct { ThreadsMaxCount int ThreadBumpLimit int IsCaptchaActive bool + Gateway GatewayConfig } type DbConfig struct { @@ -46,6 +55,22 @@ func getValueOrDefaultString(value string, defaultValue string) string { return value } +func getGatewayConfig() GatewayConfig { + url := os.Getenv("GATEWAY_URL") + apiKey := os.Getenv("GATEWAY_API_KEY") + boardId := os.Getenv("GATEWAY_BOARD_ID") + description := os.Getenv("GATEWAY_BOARD_DESCRIPTION") + boardUrl := os.Getenv("GATEWAY_BOARD_URL") + + return GatewayConfig{ + Url: url, + ApiKey: apiKey, + BoardId: boardId, + BoardUrl: boardUrl, + BoardDescription: description, + } +} + func getAppConfig() AppConfig { env := getValueOrDefaultString(os.Getenv("ENV"), "release") port := getValueOrDefaultInt(os.Getenv("PORT"), 3000) @@ -54,6 +79,7 @@ func getAppConfig() AppConfig { threadsMaxCount := getValueOrDefaultInt(os.Getenv("THREADS_MAX_COUNT"), 50) threadBumpLimit := getValueOrDefaultInt(os.Getenv("THREAD_BUMP_LIMIT"), 500) isCaptchaActive := getValueOrDefaultBoolean(os.Getenv("IS_CAPTCHA_ACTIVE"), true) + gateway := getGatewayConfig() return AppConfig{ Env: env, @@ -63,6 +89,7 @@ func getAppConfig() AppConfig { ThreadsMaxCount: threadsMaxCount, ThreadBumpLimit: threadBumpLimit, IsCaptchaActive: isCaptchaActive, + Gateway: gateway, } } diff --git a/docker-compose.yml b/docker-compose.yml index 256cc7b..0707256 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,13 @@ services: IS_RATE_LIMITER_ENABLED: ${IS_RATE_LIMITER_ENABLED} THREADS_MAX_COUNT: ${THREADS_MAX_COUNT} POSTGRES_URL: ${POSTGRES_URL} + THREAD_BUMP_LIMIT: ${THREAD_BUMP_LIMIT} + IS_CAPTCHA_ACTIVE: ${IS_CAPTCHA_ACTIVE} + GATEWAY_URL: ${GATEWAY_URL} + GATEWAY_API_KEY: ${GATEWAY_API_KEY} + GATEWAY_BOARD_ID: ${GATEWAY_BOARD_ID} + GATEWAY_BOARD_URL: ${GATEWAY_BOARD_URL} + GATEWAY_BOARD_DESCRIPTION: ${GATEWAY_BOARD_DESCRIPTION} volumes: - /root/micrach-go/uploads:/app/uploads deploy: @@ -33,11 +40,11 @@ services: traefik.http.middlewares.micrach-https-redirect.redirectscheme.scheme: "https" traefik.http.routers.micrach.entrypoints: "http" - traefik.http.routers.micrach.rule: "Host(`micrach.igonin.dev`)" + traefik.http.routers.micrach.rule: "Host(`micrach.igonin.dev`) && PathPrefix(`/${GATEWAY_BOARD_ID}`)" traefik.http.routers.micrach.middlewares: "micrach-https-redirect" traefik.http.routers.micrach-secure.entrypoints: "https" - traefik.http.routers.micrach-secure.rule: "Host(`micrach.igonin.dev`)" + traefik.http.routers.micrach-secure.rule: "Host(`micrach.igonin.dev`) && PathPrefix(`/${GATEWAY_BOARD_ID}`)" traefik.http.routers.micrach-secure.tls: "true" traefik.http.routers.micrach-secure.service: "micrach" diff --git a/gateway/connect.go b/gateway/connect.go new file mode 100644 index 0000000..2b859b2 --- /dev/null +++ b/gateway/connect.go @@ -0,0 +1,39 @@ +package gateway + +import ( + "bytes" + "encoding/json" + "io/ioutil" + "log" + "net/http" + + Config "micrach/config" +) + +// Make http request to gateway to tell the board id and description +func Connect() { + requestBody, _ := json.Marshal(map[string]string{ + "id": Config.App.Gateway.BoardId, + "name": Config.App.Gateway.BoardDescription, + "url": Config.App.Gateway.Url, + }) + url := Config.App.Gateway.Url + "/api/boards" + req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestBody)) + if err != nil { + log.Panicln(err) + } + req.Header.Set("Authorization", Config.App.Gateway.ApiKey) + req.Header.Set("Content-Type", "application/json") + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Panicln(err) + } + //We Read the response body on the line below. + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Panicln(err) + } + log.Println(string(body)) + log.Println("gateway - online") +} diff --git a/gateway/controllers.go b/gateway/controllers.go new file mode 100644 index 0000000..b0b7a16 --- /dev/null +++ b/gateway/controllers.go @@ -0,0 +1,19 @@ +package gateway + +import ( + Config "micrach/config" + "net/http" + + "github.com/gin-gonic/gin" +) + +func Ping(c *gin.Context) { + headerKey := c.Request.Header.Get("Authorization") + if Config.App.Gateway.ApiKey != headerKey { + c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) + return + } + c.JSON(200, gin.H{ + "message": "pong", + }) +} diff --git a/main.go b/main.go index 5f8c232..20240c3 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ import ( Config "micrach/config" Controllers "micrach/controllers" Db "micrach/db" + Gateway "micrach/gateway" Repositories "micrach/repositories" Templates "micrach/templates" Utils "micrach/utils" @@ -62,6 +63,10 @@ func main() { } router.Static("/uploads", "./uploads") router.Static("/static", "./static") + if Config.App.Gateway.Url != "" { + router.GET("/api/ping", Gateway.Ping) + Gateway.Connect() + } router.GET("/", Controllers.GetThreads) router.POST("/", Controllers.CreateThread) router.GET("/:threadID", Controllers.GetThread) diff --git a/static/icons/github.svg b/static/icons/github.svg new file mode 100644 index 0000000..aa05db9 --- /dev/null +++ b/static/icons/github.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg> \ No newline at end of file diff --git a/static/images/github-icon.png b/static/images/github-icon.png deleted file mode 100644 index 8b25551..0000000 Binary files a/static/images/github-icon.png and /dev/null differ diff --git a/static/styles/index.css b/static/styles/index.css index 8fb0bdb..4d9fde7 100644 --- a/static/styles/index.css +++ b/static/styles/index.css @@ -1,3 +1,7 @@ #pagesList { flex-wrap: wrap } + +.github-icon { + width: 2.5rem; +} \ No newline at end of file diff --git a/templates/components/footer.html b/templates/components/footer.html index b8613a3..7234109 100644 --- a/templates/components/footer.html +++ b/templates/components/footer.html @@ -2,7 +2,7 @@ <footer class="py-4"> <div class="container text-center"> <a href="https://github.com/yanislav-igonin/micrach" target="blank"> - <img src="/static/images/github-icon.png" alt="GitHub icon"> + <img class="github-icon" src="/static/icons/github.svg" alt="github icon"> </a> </div> </footer> diff --git a/templates/head/static.html b/templates/head/static.html index a7cf3d6..a8b980d 100644 --- a/templates/head/static.html +++ b/templates/head/static.html @@ -11,6 +11,6 @@ crossorigin="anonymous"> </script> <link rel="icon" href="/static/favicon.ico"/> - <link href="/static/styles/utils.css" rel="stylesheet"> - <link href="/static/styles/post-form.css" rel="stylesheet"> + <link href="/static/styles/utils.css" rel="stylesheet"> + <link href="/static/styles/post-form.css" rel="stylesheet"> {{ end }}