-
Notifications
You must be signed in to change notification settings - Fork 0
/
auth.go
99 lines (83 loc) · 2.37 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
package org
import (
"context"
"net/http"
"strings"
"github.com/cristianuser/go-bun-webserver/bunapp"
"github.com/cristianuser/go-bun-webserver/httputil"
"github.com/uptrace/bunrouter"
)
type (
userCtxKey struct{}
userErrCtxKey struct{}
sessionCtxKey struct{}
sessionErrCtxKey struct{}
)
func UserFromContext(ctx context.Context) *User {
user, _ := ctx.Value(userCtxKey{}).(*User)
return user
}
func SessionFromContext(ctx context.Context) *Session {
session, _ := ctx.Value(sessionCtxKey{}).(*Session)
return session
}
func authToken(req bunrouter.Request) string {
const prefix = "Token "
v := req.Header.Get("Authorization")
v = strings.TrimPrefix(v, prefix)
return v
}
type Middleware struct {
app *bunapp.App
}
func NewMiddleware(app *bunapp.App) Middleware {
return Middleware{
app: app,
}
}
func (m Middleware) User(next bunrouter.HandlerFunc) bunrouter.HandlerFunc {
return func(w http.ResponseWriter, req bunrouter.Request) error {
ctx := req.Context()
token := authToken(req)
userID, err := decodeUserToken(m.app, token)
if err != nil {
ctx = context.WithValue(ctx, userErrCtxKey{}, err)
return next(w, req.WithContext(ctx))
}
user, err := SelectUser(ctx, m.app, userID)
if err != nil {
ctx = context.WithValue(ctx, userErrCtxKey{}, err)
return next(w, req.WithContext(ctx))
}
session, err := SelectSessionByToken(ctx, m.app, token)
if err != nil {
ctx = context.WithValue(ctx, sessionErrCtxKey{}, err)
return next(w, req.WithContext(ctx))
}
err = session.UpdateLastTimeActive(ctx, m.app)
if err != nil {
ctx = context.WithValue(ctx, sessionErrCtxKey{}, err)
return next(w, req.WithContext(ctx))
}
ctx = context.WithValue(ctx, userCtxKey{}, user)
ctx = context.WithValue(ctx, sessionCtxKey{}, session)
return next(w, req.WithContext(ctx))
}
}
func (m Middleware) MustUser(next bunrouter.HandlerFunc) bunrouter.HandlerFunc {
return func(w http.ResponseWriter, req bunrouter.Request) error {
if _, ok := req.Context().Value(userErrCtxKey{}).(error); ok {
return httputil.JSON(w, bunrouter.H{
"ok": false,
"message": "Invalid token",
}, http.StatusUnauthorized)
}
if _, ok := req.Context().Value(sessionErrCtxKey{}).(error); ok {
return httputil.JSON(w, bunrouter.H{
"ok": false,
"message": "Invalid token",
}, http.StatusUnauthorized)
}
return next(w, req)
}
}