Merge branch 'main' of ssh://git.ma-al.com:8822/goc_daniel/b2b into no-vat-customers
This commit is contained in:
@@ -10,14 +10,14 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/authService"
|
||||
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
// AuthMiddleware creates authentication middleware
|
||||
func AuthMiddleware() fiber.Handler {
|
||||
func Authenticate() fiber.Handler {
|
||||
authService := authService.NewAuthService()
|
||||
|
||||
return func(c fiber.Ctx) error {
|
||||
// Get token from Authorization header
|
||||
authHeader := c.Get("Authorization")
|
||||
@@ -25,17 +25,13 @@ func AuthMiddleware() fiber.Handler {
|
||||
// Try to get from cookie
|
||||
authHeader = c.Cookies("access_token")
|
||||
if authHeader == "" {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
||||
"error": "authorization token required",
|
||||
})
|
||||
return c.Next()
|
||||
}
|
||||
} else {
|
||||
// Extract token from "Bearer <token>"
|
||||
parts := strings.Split(authHeader, " ")
|
||||
if len(parts) != 2 || parts[0] != "Bearer" {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
||||
"error": "invalid authorization header format",
|
||||
})
|
||||
return c.Next()
|
||||
}
|
||||
authHeader = parts[1]
|
||||
}
|
||||
@@ -43,24 +39,18 @@ func AuthMiddleware() fiber.Handler {
|
||||
// Validate token
|
||||
claims, err := authService.ValidateToken(authHeader)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
||||
"error": "invalid or expired token",
|
||||
})
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Get user from database
|
||||
user, err := authService.GetUserByID(claims.UserID)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
||||
"error": "user not found",
|
||||
})
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Check if user is active
|
||||
if !user.IsActive {
|
||||
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
|
||||
"error": "user account is inactive",
|
||||
})
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
// Create locale. LangID is overwritten by auth Token
|
||||
@@ -79,9 +69,7 @@ func AuthMiddleware() fiber.Handler {
|
||||
|
||||
// We now populate the target user
|
||||
if model.CustomerRole(user.Role.Name) != model.RoleAdmin {
|
||||
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
|
||||
"error": "admin access required",
|
||||
})
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
targetUserID, err := strconv.Atoi(targetUserIDAttribute)
|
||||
@@ -114,6 +102,18 @@ func AuthMiddleware() fiber.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
func Authorize() fiber.Handler {
|
||||
return func(c fiber.Ctx) error {
|
||||
_, ok := localeExtractor.GetUserID(c)
|
||||
if !ok {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
||||
"error": "not authenticated",
|
||||
})
|
||||
}
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// Webdav
|
||||
func Webdav() fiber.Handler {
|
||||
authService := authService.NewAuthService()
|
||||
|
||||
@@ -49,7 +49,7 @@ func AuthHandlerRoutes(r fiber.Router) fiber.Router {
|
||||
r.Get("/google", handler.GoogleLogin)
|
||||
r.Get("/google/callback", handler.GoogleCallback)
|
||||
|
||||
authProtected := r.Group("", middleware.AuthMiddleware())
|
||||
authProtected := r.Group("", middleware.Authorize())
|
||||
authProtected.Get("/me", handler.Me)
|
||||
authProtected.Post("/update-choice", handler.UpdateJWTToken)
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package public
|
||||
|
||||
import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/menuService"
|
||||
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
@@ -31,12 +32,21 @@ func RoutingHandlerRoutes(r fiber.Router) fiber.Router {
|
||||
}
|
||||
|
||||
func (h *RoutingHandler) GetRouting(c fiber.Ctx) error {
|
||||
lang_id, ok := localeExtractor.GetLangID(c)
|
||||
langId, ok := localeExtractor.GetLangID(c)
|
||||
if !ok {
|
||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrInvalidBody)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrInvalidBody)))
|
||||
}
|
||||
menu, err := h.menuService.GetRoutes(lang_id)
|
||||
|
||||
var roleId uint
|
||||
customer, ok := localeExtractor.GetCustomer(c)
|
||||
if !ok {
|
||||
roleId = constdata.UNLOGGED_USER_ROLE_ID
|
||||
} else {
|
||||
roleId = customer.RoleID
|
||||
}
|
||||
|
||||
menu, err := h.menuService.GetRoutes(langId, roleId)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
|
||||
@@ -86,9 +86,10 @@ func (s *Server) Setup() error {
|
||||
|
||||
// API routes
|
||||
s.api = s.app.Group("/api/v1")
|
||||
s.api.Use(middleware.Authenticate())
|
||||
s.public = s.api.Group("/public")
|
||||
s.restricted = s.api.Group("/restricted")
|
||||
s.restricted.Use(middleware.AuthMiddleware())
|
||||
s.restricted.Use(middleware.Authorize())
|
||||
s.webdav = s.api.Group("/webdav")
|
||||
s.webdav.Use(middleware.Webdav())
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ type Route struct {
|
||||
Component string `gorm:"type:varchar(255);not null;comment:path to component file" json:"component"`
|
||||
Meta *string `gorm:"type:longtext;default:'{}'" json:"meta,omitempty"`
|
||||
Active *bool `gorm:"type:tinyint;default:1" json:"active,omitempty"`
|
||||
SortOrder *int `gorm:"type:int;default:0" json:"sort_order,omitempty"`
|
||||
}
|
||||
|
||||
func (Route) TableName() string {
|
||||
|
||||
@@ -18,7 +18,7 @@ type UIProductsRepo interface {
|
||||
// GetJSON(p_id_product, p_id_shop, p_id_lang, p_id_customer, b2b_id_country, p_quantity int) (*json.RawMessage, error)
|
||||
Find(id_lang uint, userID uint, p find.Paging, filt *filters.FiltersList) (*find.Found[model.ProductInList], error)
|
||||
GetProductVariants(langID uint, productID uint, shopID uint, customerID uint, countryID uint, quantity uint) ([]view.ProductAttribute, error)
|
||||
GetBase(p_id_product, p_id_shop, p_id_lang uint) (view.Product, error)
|
||||
GetBase(p_id_product, p_id_shop, p_id_lang, p_id_customer uint) (view.Product, error)
|
||||
GetPrice(p_id_product uint, productAttributeID *uint, p_id_shop uint, p_id_customer uint, p_id_country uint, p_quantity uint) (view.Price, error)
|
||||
GetVariants(p_id_product, p_id_shop, p_id_lang, p_id_customer, p_id_country, p_quantity uint) ([]view.ProductAttribute, error)
|
||||
AddToFavorites(userID uint, productID uint) error
|
||||
@@ -33,11 +33,11 @@ func New() UIProductsRepo {
|
||||
return &ProductsRepo{}
|
||||
}
|
||||
|
||||
func (repo *ProductsRepo) GetBase(p_id_product, p_id_shop, p_id_lang uint) (view.Product, error) {
|
||||
func (repo *ProductsRepo) GetBase(p_id_product, p_id_shop, p_id_lang, p_id_customer uint) (view.Product, error) {
|
||||
var result view.Product
|
||||
|
||||
err := db.DB.Raw(`CALL get_product_base(?,?,?)`,
|
||||
p_id_product, p_id_shop, p_id_lang).
|
||||
err := db.DB.Raw(`CALL get_product_base(?,?,?,?)`,
|
||||
p_id_product, p_id_shop, p_id_lang, p_id_customer).
|
||||
Scan(&result).Error
|
||||
|
||||
return result, err
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
type UIRoutesRepo interface {
|
||||
GetRoutes(langId uint) ([]model.Route, error)
|
||||
GetRoutes(langId uint, roleId uint) ([]model.Route, error)
|
||||
GetTopMenu(id uint, roleId uint) ([]model.B2BTopMenu, error)
|
||||
}
|
||||
|
||||
@@ -17,13 +17,18 @@ func New() UIRoutesRepo {
|
||||
return &RoutesRepo{}
|
||||
}
|
||||
|
||||
func (p *RoutesRepo) GetRoutes(langId uint) ([]model.Route, error) {
|
||||
func (p *RoutesRepo) GetRoutes(langId uint, roleId uint) ([]model.Route, error) {
|
||||
routes := []model.Route{}
|
||||
err := db.DB.Find(&routes, model.Route{Active: nullable.GetNil(true)}).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return routes, nil
|
||||
|
||||
err := db.
|
||||
Get().
|
||||
Model(model.Route{}).
|
||||
Joins("JOIN b2b_route_roles rr ON rr.route_id = b2b_routes.id").
|
||||
Where(model.Route{Active: nullable.GetNil(true)}).
|
||||
Where("rr.role_id = ?", roleId).
|
||||
Find(&routes).Error
|
||||
|
||||
return routes, err
|
||||
}
|
||||
|
||||
func (p *RoutesRepo) GetTopMenu(langId uint, roleId uint) ([]model.B2BTopMenu, error) {
|
||||
|
||||
@@ -102,8 +102,8 @@ func (s *MenuService) createTree(index int, all_categories *([]model.ScannedCate
|
||||
return node, true
|
||||
}
|
||||
|
||||
func (s *MenuService) GetRoutes(id_lang uint) ([]model.Route, error) {
|
||||
return s.routesRepo.GetRoutes(id_lang)
|
||||
func (s *MenuService) GetRoutes(id_lang, roleId uint) ([]model.Route, error) {
|
||||
return s.routesRepo.GetRoutes(id_lang, roleId)
|
||||
}
|
||||
|
||||
func (s *MenuService) scannedToNormalCategory(scanned model.ScannedCategory) model.Category {
|
||||
|
||||
@@ -27,7 +27,7 @@ func (s *ProductService) Get(
|
||||
p_id_product, p_id_lang, p_id_customer, b2b_id_country, p_quantity uint,
|
||||
) (*json.RawMessage, error) {
|
||||
|
||||
product, err := s.productsRepo.GetBase(p_id_product, constdata.SHOP_ID, p_id_lang)
|
||||
product, err := s.productsRepo.GetBase(p_id_product, constdata.SHOP_ID, p_id_lang, p_id_customer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -32,3 +32,5 @@ const WEBDAV_TRIMMED_ROOT = "localhost:3000/api/v1/webdav/storage"
|
||||
const NON_ALNUM_REGEX = `[^a-z0-9]+`
|
||||
const MULTI_DASH_REGEX = `-+`
|
||||
const SLUG_REGEX = `^[a-z0-9]+(?:-[a-z0-9]+)*$`
|
||||
|
||||
const UNLOGGED_USER_ROLE_ID = 4
|
||||
|
||||
Reference in New Issue
Block a user