-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
159 lines (128 loc) · 3.85 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/joho/godotenv"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/gommon/log"
echoSwagger "github.com/swaggo/echo-swagger"
"github.com/wadehrarshpreet/short/pkg/auth"
"github.com/wadehrarshpreet/short/pkg/shorten"
"github.com/wadehrarshpreet/short/pkg/util"
"github.com/wadehrarshpreet/short/pkg/web"
)
// @title Shorty URL Shortner
// @version 0.0.1
// @description This is a API Docs of Shorty URL Shortner Service.
// @contact.name Arshpreet Wadehra
// @contact.url https://github.com/wadehrarshpreet/shorty
// @contact.email [email protected]
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @BasePath /
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name Authorization
func main() {
// Create channel for shutdown signals.
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
signal.Notify(stop, syscall.SIGTERM)
// pick PORT from env before initialize .env
port := util.Getenv("PORT", "1234")
// Initialize env variable
err := godotenv.Load("configs/.env")
if err != nil {
log.Fatal("Error loading .env file")
}
e := echo.New()
// e.Logger.SetLevel(log.DEBUG)
// Init Swagger Routes
e.GET("/swagger/*", echoSwagger.WrapHandler)
// Connect Database
dbErr := util.ConnectDatabase()
if dbErr != nil {
e.Logger.Fatalf("Error in DB Connection...%s", dbErr)
}
// Init Request Id middleware
e.Use(middleware.RequestID())
// Init Request Logger
e.Use(middleware.Logger())
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
}))
// if JWT pass then check for valid Auth if not bypass and let API decide
apiGroup := e.Group("/api", middleware.JWTWithConfig(middleware.JWTConfig{
SigningKey: []byte(util.Getenv("JWT_SECRET", "shorty-secret123")),
Skipper: func(c echo.Context) bool {
headerToken := c.Request().Header.Get("Authorization")
if strings.Contains(headerToken, "Bearer") {
// skip check if hitting shorten url api & custom is not provided
if strings.Contains(c.Request().URL.String(), shorten.ShortURLAPIRoute) {
rq := c.Request()
bodyBytes, _ := ioutil.ReadAll(rq.Body)
rq.Body.Close() // must close
rq.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
// check if custom param missing
r := new(shorten.URLShorteningRequest)
if err := json.Unmarshal(bodyBytes, &r); err != nil {
return false
}
if len(r.Custom) == 0 {
return true
}
}
return false
}
return true
},
ErrorHandlerWithContext: func(err error, c echo.Context) error {
return util.GenerateErrorResponse(c, http.StatusUnauthorized, "UNAUTHORIZED")
},
}))
apiRouteError := shorten.Init(apiGroup)
if apiRouteError != nil {
e.Logger.Fatalf("Error in initializing APIs...%s", apiRouteError)
}
apiGroup.GET("/", func(c echo.Context) error {
return c.JSON(http.StatusOK, echo.Map{
"status": "ok",
"appVersion": util.Getenv("APP_VERSION", "0.0.1"),
})
})
// Init Static Assets
e.Static("/assets", "./web/dist")
// Initialize Auth Service
authServiceErr := auth.Init(e)
if authServiceErr != nil {
e.Logger.Fatalf("Error in initializing Auth Service... %s", authServiceErr)
}
// Initialize Webview
web.InitWebsite(e)
// Short URL Redirection Route
shorten.InitRedirectionRoute(e)
go func() {
e.Logger.Fatal(e.Start(fmt.Sprintf(":%s", port)))
}()
<-stop
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
e.Logger.Info("Disconnecting Database...")
if err = util.DbConn.Disconnect(ctx); err != nil {
panic(err)
}
e.Logger.Info("Shutting Down Server...")
if err := e.Shutdown(ctx); err != nil {
e.Logger.Fatal(err)
}
}