Passed
Pull Request — main (#166)
by Yume
02:09
created

v2.*JwtMiddleware.AuthorizeVip   A

Complexity

Conditions 2

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
package v2
2
3
import (
4
	"errors"
5
	"net/http"
6
	"strconv"
7
8
	"github.com/getsentry/sentry-go"
9
	"github.com/labstack/echo/v4"
10
	"github.com/memnix/memnix-rest/domain"
11
	"github.com/memnix/memnix-rest/infrastructures"
12
	"github.com/memnix/memnix-rest/pkg/jwt"
13
	"github.com/memnix/memnix-rest/services/user"
14
)
15
16
const (
17
	// SessionTokenCookieKey is the key for the session token cookie.
18
	SessionTokenCookieKey = "session_token"
19
)
20
21
// JwtMiddleware is the controller for the jwt routes.
22
type JwtMiddleware struct {
23
	user.IUseCase
24
}
25
26
// NewJwtController creates a new jwt controller.
27
func NewJwtMiddleware(user user.IUseCase) JwtMiddleware {
28
	return JwtMiddleware{IUseCase: user}
29
}
30
31
// VerifyPermissions checks if the user has the required permissions.
32
func (*JwtMiddleware) VerifyPermissions(user domain.User, p domain.Permission) bool {
33
	return user.HasPermission(p)
34
}
35
36
func (j *JwtMiddleware) AuthorizeUser(next echo.HandlerFunc) echo.HandlerFunc {
37
	return func(c echo.Context) error {
38
		return j.IsConnectedMiddleware(domain.PermissionUser, next)(c)
39
	}
40
}
41
42
func (j *JwtMiddleware) AuthorizeVip(next echo.HandlerFunc) echo.HandlerFunc {
43
	return func(c echo.Context) error {
44
		return j.IsConnectedMiddleware(domain.PermissionVip, next)(c)
45
	}
46
}
47
48
func (j *JwtMiddleware) AuthorizeAdmin(next echo.HandlerFunc) echo.HandlerFunc {
49
	return func(c echo.Context) error {
50
		return j.IsConnectedMiddleware(domain.PermissionAdmin, next)(c)
51
	}
52
}
53
54
func (j *JwtMiddleware) IsConnectedMiddleware(p domain.Permission, next echo.HandlerFunc) func(c echo.Context) error {
55
	return func(c echo.Context) error {
56
		_, span := infrastructures.GetTracerInstance().Tracer().Start(c.Request().Context(), "IsConnectedMiddleware")
57
		defer span.End()
58
59
		// get the token from the request header
60
		tokenHeader := c.Request().Header.Get("Authorization")
61
		// if the token is empty, the userModel is not connected, and we return an error
62
		if tokenHeader == "" {
63
			return c.JSON(http.StatusUnauthorized, errors.New("unauthorized: token missing"))
64
		}
65
66
		userID, err := jwt.GetJwtInstance().GetJwt().GetConnectedUserID(c.Request().Context(), tokenHeader)
67
		if err != nil {
68
			return c.JSON(http.StatusUnauthorized, errors.New("unauthorized: invalid token"))
69
		}
70
71
		userModel, err := j.IUseCase.GetByID(c.Request().Context(), userID)
72
		if err != nil {
73
			return c.JSON(http.StatusUnauthorized, errors.New("unauthorized: invalid user"))
74
		}
75
76
		sentry.ConfigureScope(func(scope *sentry.Scope) {
77
			scope.SetUser(sentry.User{
78
				ID:       strconv.Itoa(int(userModel.ID)),
79
				Username: userModel.Username,
80
				Email:    userModel.Email,
81
			})
82
		})
83
84
		// Check permissions
85
		if !j.VerifyPermissions(userModel, p) {
86
			return c.JSON(http.StatusUnauthorized, errors.New("unauthorized: invalid user"))
87
		}
88
89
		// Set userModel in locals
90
		SetUserToContext(c, userModel)
91
		span.End()
92
		return next(c)
93
	}
94
}
95
96
func SetUserToContext(c echo.Context, user domain.User) {
97
	c.Set("user", user)
98
}
99
100
func GetUserFromContext(c echo.Context) (domain.User, error) {
101
	if c.Get("user") == nil {
102
		return domain.User{}, errors.New("user is not initialized")
103
	}
104
	return c.Get("user").(domain.User), nil
105
}
106