Passed
Push — main ( f6597a...58b626 )
by Yume
01:31 queued 12s
created

controllers.*JwtController.IsConnectedMiddleware   B

Complexity

Conditions 7

Size

Total Lines 36
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 18
nop 1
dl 0
loc 36
rs 8
c 0
b 0
f 0
1
package controllers
2
3
import (
4
	"errors"
5
6
	"github.com/gofiber/fiber/v2"
7
	"github.com/memnix/memnix-rest/domain"
8
	"github.com/memnix/memnix-rest/internal/user"
9
	"github.com/memnix/memnix-rest/pkg/jwt"
10
	"github.com/memnix/memnix-rest/pkg/utils"
11
	"github.com/memnix/memnix-rest/views"
12
	"github.com/rs/zerolog/log"
13
)
14
15
type JwtController struct {
16
	user.IUseCase
17
}
18
19
func NewJwtController(user user.IUseCase) JwtController {
20
	return JwtController{IUseCase: user}
21
}
22
23
// VerifyPermissions checks if the user has the required permissions
24
func (j *JwtController) VerifyPermissions(user domain.User, p domain.Permission) bool {
25
	return user.HasPermission(p)
26
}
27
28
// IsConnectedMiddleware checks if the user is connected and has the required permissions
29
// the permissions are defined in the route definition
30
// returns an error if the user is not connected or has not the required permissions
31
//
32
// if the user is connected and has the required permissions, it sets the user in the locals
33
// and calls the next middleware
34
func (j *JwtController) IsConnectedMiddleware(p domain.Permission) func(c *fiber.Ctx) error {
35
	return func(c *fiber.Ctx) error {
36
		// if the route is public, we don't need to check if the userModel is connected
37
		if p == domain.PermissionNone {
38
			return c.Next()
39
		}
40
41
		// get the token from the request header
42
		tokenHeader := c.Get("Authorization")
43
		// if the token is empty, the userModel is not connected, and we return an error
44
		if tokenHeader == "" {
45
			return c.Status(fiber.StatusUnauthorized).JSON(views.NewHTTPResponseVMFromError(errors.New("not authorized")))
46
		}
47
48
		// get the userModel from the token
49
		// if the token is invalid, we return an error
50
		userID, err := jwt.GetConnectedUserID(tokenHeader)
51
		if err != nil {
52
			return c.Status(fiber.StatusUnauthorized).JSON(views.NewHTTPResponseVMFromError(errors.New("not connected")))
53
		}
54
55
		// get the userModel from the database
56
		userModel, err := j.IUseCase.GetByID(userID)
57
		if err != nil {
58
			log.Warn().Err(err).Msg("user not found")
59
			return c.Status(fiber.StatusUnauthorized).JSON(views.NewHTTPResponseVMFromError(errors.New("not connected")))
60
		}
61
62
		// if the userModel has the required permissions, we set the userModel in the locals and call the next middleware
63
		if j.VerifyPermissions(userModel, p) {
64
			utils.SetUserToContext(c, &userModel) // Set userModel in locals
65
			return c.Next()
66
		}
67
68
		// if the userModel does not have the required permissions, we return an error
69
		return c.Status(fiber.StatusUnauthorized).JSON(views.NewHTTPResponseVMFromError(errors.New("not authorized")))
70
	}
71
}
72