Merge branch 'main' of ssh://git.ma-al.com:8822/goc_daniel/b2b into storage
This commit is contained in:
@@ -79,7 +79,7 @@ func AuthMiddleware() fiber.Handler {
|
||||
}
|
||||
|
||||
// We now populate the target user
|
||||
if user.Role != model.RoleAdmin {
|
||||
if model.CustomerRole(user.Role.Name) != model.RoleAdmin {
|
||||
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
|
||||
"error": "admin access required",
|
||||
})
|
||||
|
||||
28
app/delivery/middleware/permissions.go
Normal file
28
app/delivery/middleware/permissions.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware/perms"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func Require(p perms.Permission) fiber.Handler {
|
||||
return func(c fiber.Ctx) error {
|
||||
u := c.Locals("user")
|
||||
if u == nil {
|
||||
return c.SendStatus(fiber.StatusUnauthorized)
|
||||
}
|
||||
|
||||
user, ok := u.(*model.UserSession)
|
||||
if !ok {
|
||||
return c.SendStatus(fiber.StatusInternalServerError)
|
||||
}
|
||||
|
||||
for _, perm := range user.Permissions {
|
||||
if perm == p {
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
return c.SendStatus(fiber.StatusForbidden)
|
||||
}
|
||||
}
|
||||
10
app/delivery/middleware/perms/permissions.go
Normal file
10
app/delivery/middleware/perms/permissions.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package perms
|
||||
|
||||
type Permission string
|
||||
|
||||
const (
|
||||
UserReadAny Permission = "user.read.any"
|
||||
UserWriteAny Permission = "user.write.any"
|
||||
UserDeleteAny Permission = "user.delete.any"
|
||||
CurrencyWrite Permission = "currency.write"
|
||||
)
|
||||
70
app/delivery/web/api/restricted/currency.go
Normal file
70
app/delivery/web/api/restricted/currency.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package restricted
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"git.ma-al.com/goc_daniel/b2b/app/config"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware/perms"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/currencyService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
type CurrencyHandler struct {
|
||||
CurrencyService *currencyService.CurrencyService
|
||||
config *config.Config
|
||||
}
|
||||
|
||||
func NewCurrencyHandler() *CurrencyHandler {
|
||||
currencyService := currencyService.New()
|
||||
return &CurrencyHandler{
|
||||
CurrencyService: currencyService,
|
||||
config: config.Get(),
|
||||
}
|
||||
}
|
||||
|
||||
func CurrencyHandlerRoutes(r fiber.Router) fiber.Router {
|
||||
handler := NewCurrencyHandler()
|
||||
|
||||
r.Post("/currency-rate", middleware.Require(perms.CurrencyWrite), handler.PostCurrencyRate)
|
||||
r.Get("/currency-rate/:id", handler.GetCurrencyRate)
|
||||
return r
|
||||
}
|
||||
|
||||
func (h *CurrencyHandler) PostCurrencyRate(c fiber.Ctx) error {
|
||||
var currencyRate model.CurrencyRate
|
||||
if err := c.Bind().Body(¤cyRate); err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrJSONBody)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrJSONBody)))
|
||||
}
|
||||
|
||||
err := h.CurrencyService.CreateCurrencyRate(¤cyRate)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
return c.JSON(response.Make(nullable.GetNil(""), 1, i18n.T_(c, response.Message_OK)))
|
||||
}
|
||||
|
||||
func (h *CurrencyHandler) GetCurrencyRate(c fiber.Ctx) error {
|
||||
idStr := c.Params("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
|
||||
}
|
||||
|
||||
currency, err := h.CurrencyService.GetCurrency(uint(id))
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
return c.JSON(response.Make(currency, 0, i18n.T_(c, response.Message_OK)))
|
||||
}
|
||||
111
app/delivery/web/api/restricted/customer.go
Normal file
111
app/delivery/web/api/restricted/customer.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package restricted
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware/perms"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/customerService"
|
||||
"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"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/query/query_params"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
type customerHandler struct {
|
||||
service *customerService.CustomerService
|
||||
}
|
||||
|
||||
func NewCustomerHandler() *customerHandler {
|
||||
customerService := customerService.New()
|
||||
return &customerHandler{
|
||||
service: customerService,
|
||||
}
|
||||
}
|
||||
|
||||
func CustomerHandlerRoutes(r fiber.Router) fiber.Router {
|
||||
handler := NewCustomerHandler()
|
||||
|
||||
r.Get("", handler.customerData)
|
||||
r.Get("/list", handler.listCustomers)
|
||||
return r
|
||||
}
|
||||
|
||||
func (h *customerHandler) customerData(fc fiber.Ctx) error {
|
||||
var customerId uint
|
||||
|
||||
user, ok := localeExtractor.GetCustomer(fc)
|
||||
if !ok || user == nil {
|
||||
return fc.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrBadAttribute)))
|
||||
}
|
||||
|
||||
customerIdStr := fc.Query("id")
|
||||
if customerIdStr != "" {
|
||||
id, err := strconv.ParseUint(customerIdStr, 10, 64)
|
||||
if err != nil {
|
||||
return fiber.ErrBadRequest
|
||||
}
|
||||
|
||||
if user.ID != uint(id) && !user.HasPermission(perms.UserReadAny) {
|
||||
return fc.Status(fiber.StatusForbidden).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrForbidden)))
|
||||
}
|
||||
|
||||
customerId = uint(id)
|
||||
} else {
|
||||
customerId = user.ID
|
||||
}
|
||||
|
||||
customer, err := h.service.GetById(customerId)
|
||||
if err != nil {
|
||||
return fc.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
|
||||
}
|
||||
|
||||
return fc.JSON(response.Make(&customer, 0, i18n.T_(fc, response.Message_OK)))
|
||||
}
|
||||
|
||||
func (h *customerHandler) listCustomers(fc fiber.Ctx) error {
|
||||
user, ok := localeExtractor.GetCustomer(fc)
|
||||
if !ok || user == nil {
|
||||
return fc.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrBadAttribute)))
|
||||
}
|
||||
if !user.HasPermission(perms.UserReadAny) {
|
||||
return fc.Status(fiber.StatusForbidden).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrForbidden)))
|
||||
}
|
||||
|
||||
p, filt, err := query_params.ParseFilters[model.Customer](fc, columnMappingListUsers)
|
||||
if err != nil {
|
||||
return fc.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
|
||||
}
|
||||
|
||||
search := fc.Query("search")
|
||||
if search != "" {
|
||||
if !user.HasPermission(perms.UserReadAny) {
|
||||
return fc.Status(fiber.StatusForbidden).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, responseErrors.ErrForbidden)))
|
||||
}
|
||||
}
|
||||
|
||||
customer, err := h.service.Find(user.LangID, p, filt, search)
|
||||
if err != nil {
|
||||
return fc.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
|
||||
}
|
||||
|
||||
return fc.JSON(response.Make(&customer, 0, i18n.T_(fc, response.Message_OK)))
|
||||
}
|
||||
|
||||
var columnMappingListUsers map[string]string = map[string]string{
|
||||
"user_id": "users.id",
|
||||
"email": "users.email",
|
||||
"first_name": "users.first_name",
|
||||
"last_name": "users.last_name",
|
||||
}
|
||||
@@ -87,12 +87,12 @@ func (h *MenuHandler) GetBreadcrumb(c fiber.Ctx) error {
|
||||
}
|
||||
|
||||
func (h *MenuHandler) GetTopMenu(c fiber.Ctx) error {
|
||||
lang_id, ok := localeExtractor.GetLangID(c)
|
||||
if !ok {
|
||||
customer, ok := localeExtractor.GetCustomer(c)
|
||||
if !ok || customer == nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||
}
|
||||
menu, err := h.menuService.GetTopMenu(lang_id)
|
||||
menu, err := h.menuService.GetTopMenu(customer.LangID, customer.RoleID)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package restricted
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"git.ma-al.com/goc_daniel/b2b/app/config"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/listService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/productService"
|
||||
"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"
|
||||
@@ -13,31 +15,69 @@ import (
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
// ListHandler handles endpoints that list various things (e.g. products or users)
|
||||
type ListHandler struct {
|
||||
listService *listService.ListService
|
||||
config *config.Config
|
||||
type ProductsHandler struct {
|
||||
productService *productService.ProductService
|
||||
config *config.Config
|
||||
}
|
||||
|
||||
// NewListHandler creates a new ListHandler instance
|
||||
func NewListHandler() *ListHandler {
|
||||
listService := listService.New()
|
||||
return &ListHandler{
|
||||
listService: listService,
|
||||
config: config.Get(),
|
||||
// NewListProductsHandler creates a new ListProductsHandler instance
|
||||
func NewProductsHandler() *ProductsHandler {
|
||||
productService := productService.New()
|
||||
return &ProductsHandler{
|
||||
productService: productService,
|
||||
config: config.Get(),
|
||||
}
|
||||
}
|
||||
|
||||
func ListHandlerRoutes(r fiber.Router) fiber.Router {
|
||||
handler := NewListHandler()
|
||||
func ProductsHandlerRoutes(r fiber.Router) fiber.Router {
|
||||
handler := NewProductsHandler()
|
||||
|
||||
r.Get("/list-products", handler.ListProducts)
|
||||
r.Get("/list-users", handler.ListUsers)
|
||||
r.Get("/:id/:country_id/:quantity", handler.GetProductJson)
|
||||
r.Get("/list", handler.ListProducts)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func (h *ListHandler) ListProducts(c fiber.Ctx) error {
|
||||
func (h *ProductsHandler) GetProductJson(c fiber.Ctx) error {
|
||||
idStr := c.Params("id")
|
||||
|
||||
p_id_product, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
country_idStr := c.Params("country_id")
|
||||
|
||||
b2b_id_country, err := strconv.Atoi(country_idStr)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
quantityStr := c.Params("quantity")
|
||||
|
||||
p_quantity, err := strconv.Atoi(quantityStr)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
customer, ok := localeExtractor.GetCustomer(c)
|
||||
if !ok || customer == nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||
}
|
||||
productJson, err := h.productService.GetJSON(p_id_product, int(customer.LangID), int(customer.ID), b2b_id_country, p_quantity)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
return c.JSON(response.Make(&productJson, 1, i18n.T_(c, response.Message_OK)))
|
||||
}
|
||||
|
||||
func (h *ProductsHandler) ListProducts(c fiber.Ctx) error {
|
||||
paging, filters, err := query_params.ParseFilters[model.Product](c, columnMappingListProducts)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
@@ -50,7 +90,7 @@ func (h *ListHandler) ListProducts(c fiber.Ctx) error {
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||
}
|
||||
|
||||
list, err := h.listService.ListProducts(id_lang, paging, filters)
|
||||
list, err := h.productService.Find(id_lang, paging, filters)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
@@ -67,33 +107,3 @@ var columnMappingListProducts map[string]string = map[string]string{
|
||||
"category_id": "cp.id_category",
|
||||
"quantity": "sa.quantity",
|
||||
}
|
||||
|
||||
func (h *ListHandler) ListUsers(c fiber.Ctx) error {
|
||||
paging, filters, err := query_params.ParseFilters[model.Customer](c, columnMappingListUsers)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
id_lang, ok := localeExtractor.GetLangID(c)
|
||||
if !ok {
|
||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||
}
|
||||
|
||||
list, err := h.listService.ListUsers(id_lang, paging, filters)
|
||||
if err != nil {
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
return c.JSON(response.Make(&list.Items, int(list.Count), i18n.T_(c, response.Message_OK)))
|
||||
}
|
||||
|
||||
var columnMappingListUsers map[string]string = map[string]string{
|
||||
"user_id": "users.id",
|
||||
"email": "users.email",
|
||||
"first_name": "users.first_name",
|
||||
"second_name": "users.second_name",
|
||||
"role": "users.role",
|
||||
}
|
||||
@@ -105,13 +105,15 @@ func (s *Server) Setup() error {
|
||||
menuRouting := s.public.Group("/menu")
|
||||
public.RoutingHandlerRoutes(menuRouting)
|
||||
|
||||
pCustomer := s.restricted.Group("/customer")
|
||||
restricted.CustomerHandlerRoutes(pCustomer)
|
||||
|
||||
// product translation routes (restricted)
|
||||
productTranslation := s.restricted.Group("/product-translation")
|
||||
restricted.ProductTranslationHandlerRoutes(productTranslation)
|
||||
|
||||
// lists of things routes (restricted)
|
||||
list := s.restricted.Group("/list")
|
||||
restricted.ListHandlerRoutes(list)
|
||||
product := s.restricted.Group("/product")
|
||||
restricted.ProductsHandlerRoutes(product)
|
||||
|
||||
// locale selector (restricted)
|
||||
// this is basically for changing user's selected language and country
|
||||
@@ -136,6 +138,8 @@ func (s *Server) Setup() error {
|
||||
restricted.StorageHandlerRoutes(restrictedStorage)
|
||||
webdav.StorageHandlerRoutes(webdavStorage)
|
||||
|
||||
restricted.CurrencyHandlerRoutes(s.restricted)
|
||||
|
||||
s.api.All("*", func(c fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusNotFound)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user