-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
120 lines (102 loc) · 2.78 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
package main
import (
"embed"
"flag"
"fmt"
"io/fs"
"net/http"
"time"
"github.com/evdnx/fadmin/auth"
"github.com/evdnx/fadmin/db"
mw "github.com/evdnx/fadmin/middleware"
"github.com/evdnx/fadmin/store"
"github.com/golang/glog"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/gommon/log"
)
//go:embed ui/dist/pwa/*
var embedFS embed.FS
func main() {
// define and set program flags
// logging
flag.Set("logtostderr", "false")
flag.Set("alsologtostderr", "false")
flag.Set("log_dir", "/var/log/fadmin")
// port
port := flag.Int("port", 3000, "")
// read program flags
flag.Parse()
// setup logging
glog.MaxSize = 16777216 // 16 MB
// init db
if err := db.Init(); err != nil {
glog.Fatalln(err)
}
// get last login
last_login, err := db.Read(db.AuthBucket, "last_login")
if err == nil {
lastLogin, err := time.Parse(time.RFC3339, last_login)
if err == nil {
now := time.Now().UTC()
allowedTime := lastLogin.Add(24 * time.Hour)
if allowedTime.Before(now) {
// difference between now and allowedTime
auth.Timer = time.AfterFunc(now.Sub(allowedTime), func() { auth.Logout() })
}
}
}
// init services
err = auth.Init()
if err != nil {
glog.Fatal(err)
}
// create a new echo app
e := echo.New()
// use and config recovery middleware with custom stacktrace handler
e.Use(middleware.RecoverWithConfig(middleware.RecoverConfig{
StackSize: 1 << 10, // 1 KB
LogLevel: log.ERROR,
LogErrorFunc: func(c echo.Context, err error, stack []byte) error {
glog.Errorf("\npanic: %v\n%s\n", err, stack)
return err
},
}))
// initialize rate limiter store
//Database: "ratelimit.db",
//Bucket: "ratelimit",
// rate limiter
e.Use(middleware.RateLimiterWithConfig(middleware.RateLimiterConfig{
Store: store.NewRateLimiterPersistentStoreWithConfig(
store.RateLimiterPersistentStoreConfig{Rate: 10, Burst: 30, ExpiresIn: 3 * time.Minute},
),
IdentifierExtractor: func(ctx echo.Context) (string, error) {
id := ctx.RealIP()
return id, nil
},
ErrorHandler: func(context echo.Context, err error) error {
return context.JSON(http.StatusTooManyRequests, nil)
},
DenyHandler: func(context echo.Context, identifier string, err error) error {
return context.JSON(http.StatusForbidden, nil)
},
}))
// embed ui into program binary
f, err := fs.Sub(embedFS, "ui/dist/pwa")
if err != nil {
glog.Fatal(err)
}
assetHandler := http.FileServer(http.FS(f))
e.GET("/", echo.WrapHandler(assetHandler))
// auth not required for login
login := e.Group("/")
login.POST("/login", func(c echo.Context) error { return nil })
// auth required for everything else
api := e.Group("/")
api.Use(mw.AuthMiddleware())
// start app
err = e.Start(fmt.Sprint(":", *port))
if err != nil {
glog.Fatal(err)
}
}