/
echo.go
107 lines (85 loc) · 2.58 KB
/
echo.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
package server
import (
"log/slog"
"net/http"
_ "embed"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
slogecho "github.com/samber/slog-echo"
)
// InitEcho initializes a new Echo instance
func InitEcho(config Config, challengeManager *ChallengeManager) (*echo.Echo, error) {
// Initialize Echo
app := echo.New()
// Register middleware
app.Use(slogecho.New(slog.Default()))
app.Use(middleware.BodyLimit("4M"))
app.Use(middleware.Decompress())
app.Use(middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(10)))
app.Use(middleware.Recover())
app.Use(middleware.Secure())
app.Use(middleware.Timeout())
app.Use(middleware.AddTrailingSlash())
app.Use(middleware.Gzip())
app.Group("static").Use(middleware.StaticWithConfig(middleware.StaticConfig{
Root: "web/static",
Filesystem: http.FS(staticFiles),
}))
// Register routes
app.GET("/oauth/begin", func(ctx echo.Context) error {
// Get the query parameters
challengeId := ctx.QueryParam("challenge")
if challengeId == "" {
return ctx.String(http.StatusBadRequest, "challenge query parameter is required")
}
// Log
slog.Debug("beginning OAuth flow",
slog.String("challenge ID", challengeId),
)
// Generate the OAuth callback URL
oAuthUrl, err := challengeManager.Step2(challengeId)
if err != nil {
return ctx.String(http.StatusBadRequest, err.Error())
}
// Redirect
return ctx.Redirect(http.StatusFound, oAuthUrl)
})
app.GET("/oauth/end", func(ctx echo.Context) error {
// Get the query parameters
state := ctx.QueryParam("state")
code := ctx.QueryParam("code")
if state == "" {
return ctx.String(http.StatusBadRequest, "state query parameter is required")
}
if code == "" {
return ctx.String(http.StatusBadRequest, "code query parameter is required")
}
// Log
slog.Debug("verifying challenge",
slog.String("OAuth state", state),
slog.String("OAuth code", code),
)
// Generate the verification code
verificationCode, message, err := challengeManager.Step3(state, code)
if err != nil {
return ctx.String(http.StatusBadRequest, err.Error())
}
// Log
slog.Debug("verification status",
slog.String("OAuth state", state),
slog.String("OAuth code", code),
slog.String("verification code", verificationCode),
slog.String("message", message),
)
// Execute the flow end page template
err = renderFlowPage(ctx.Response().Writer, flowEndPageEnv{
Message: message,
Code: verificationCode,
})
if err != nil {
return ctx.String(http.StatusInternalServerError, err.Error())
}
return nil
})
return app, nil
}