1package ext
2
3import (
4 "encoding/base64"
5 "time"
6
7 "github.com/sirupsen/logrus"
8 "github.com/valyala/fasthttp"
9)
10
11func HTML(next fasthttp.RequestHandler) fasthttp.RequestHandler {
12 return func(ctx *fasthttp.RequestCtx) {
13 ctx.Response.Header.SetContentType("text/html")
14 next(ctx)
15 }
16}
17
18type LogMiddleware struct {
19 entry *logrus.Entry
20}
21
22func NewLogMiddleare(log *logrus.Entry) *LogMiddleware {
23 return &LogMiddleware{
24 entry: log,
25 }
26}
27
28func (l *LogMiddleware) HTTP(next fasthttp.RequestHandler) fasthttp.RequestHandler {
29 return func(ctx *fasthttp.RequestCtx) {
30 start := time.Now()
31 next(ctx)
32 elapsed := time.Since(start)
33 l.entry.
34 WithField("time", elapsed).
35 WithField("code", ctx.Response.StatusCode()).
36 WithField("path", string(ctx.Path())).
37 WithField("bytes", len(ctx.Response.Body())).
38 Info(string(ctx.Request.Header.Method()))
39 }
40}
41
42type AuthMiddleware struct {
43 key []byte
44 entry *logrus.Entry
45}
46
47func NewAuthMiddleware(key []byte, log *logrus.Entry) *AuthMiddleware {
48 return &AuthMiddleware{
49 key: key,
50 entry: log.WithField("context", "auth"),
51 }
52}
53
54func (a *AuthMiddleware) LoggedIn(next fasthttp.RequestHandler) fasthttp.RequestHandler {
55 return func(ctx *fasthttp.RequestCtx) {
56 path := string(ctx.Path())
57 if path == "/login" {
58 next(ctx)
59 return
60 }
61
62 redirectLogin := "/login?redirect=" + path
63 authBase64 := ctx.Request.Header.Cookie("auth")
64 if authBase64 == nil {
65 a.entry.Info("No auth provided")
66 ctx.Redirect(redirectLogin, 307)
67 return
68 }
69
70 auth, err := base64.StdEncoding.DecodeString(string(authBase64))
71 if err != nil {
72 a.entry.Error(err)
73 return
74 }
75
76 token, err := ReadToken(auth, a.key)
77 if err != nil {
78 a.entry.Error(err)
79 ctx.Redirect(redirectLogin, 307)
80 return
81 }
82 ctx.SetUserValue("token", token)
83 a.entry.
84 WithField("userID", token.UserID).
85 WithField("username", token.Username).
86 Info("user recognized")
87 next(ctx)
88 }
89}