diff options
author | Vidhu Kant Sharma <vidhukant@vidhukant.com> | 2025-10-11 20:55:48 +0530 |
---|---|---|
committer | Vidhu Kant Sharma <vidhukant@vidhukant.com> | 2025-10-11 20:55:48 +0530 |
commit | bc154857fb5569d7c1fa9785cc891cb927a6a156 (patch) | |
tree | 590c9f6a00a1b97b2ee45cfa5a767558089affe0 | |
parent | 8a47978ca17d2f251d67d12b0e34fa26bb1e4ace (diff) |
removed per-user itemsv0.17.0
-rw-r--r-- | auth/middleware.go | 2 | ||||
-rw-r--r-- | customer/controller.go | 71 | ||||
-rw-r--r-- | customer/customer.go | 3 | ||||
-rw-r--r-- | customer/service.go | 7 | ||||
-rw-r--r-- | customer/validators.go | 26 | ||||
-rw-r--r-- | errors/errors.go | 4 | ||||
-rw-r--r-- | errors/status.go | 6 | ||||
-rw-r--r-- | invoice/controller.go | 229 | ||||
-rw-r--r-- | invoice/invoice.go | 3 | ||||
-rw-r--r-- | invoice/router.go | 4 | ||||
-rw-r--r-- | invoice/service.go | 42 | ||||
-rw-r--r-- | invoice/validators.go | 28 | ||||
-rw-r--r-- | item/controller.go | 101 | ||||
-rw-r--r-- | item/hooks.go | 13 | ||||
-rw-r--r-- | item/item.go | 7 | ||||
-rw-r--r-- | item/router.go | 1 | ||||
-rw-r--r-- | item/service.go | 22 | ||||
-rw-r--r-- | item/validators.go | 58 | ||||
-rw-r--r-- | main.go | 2 | ||||
-rw-r--r-- | user/validators.go | 45 |
20 files changed, 59 insertions, 615 deletions
diff --git a/auth/middleware.go b/auth/middleware.go index 9a065d5..9ce5e12 100644 --- a/auth/middleware.go +++ b/auth/middleware.go @@ -70,8 +70,6 @@ func Authorize() gin.HandlerFunc { return } - ctx.Set("UserID", claims.UserID) - ctx.Next() } } diff --git a/customer/controller.go b/customer/controller.go index f2704bd..83423da 100644 --- a/customer/controller.go +++ b/customer/controller.go @@ -31,17 +31,7 @@ func handleGetSingleCustomer (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var customer Customer - err = getCustomer(&customer, uint(id)) if err != nil { ctx.Error(err) @@ -49,14 +39,7 @@ func handleGetSingleCustomer (ctx *gin.Context) { return } - if customer.UserID != userId { - ctx.Error(e.ErrForbidden) - ctx.Abort() - return - } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": customer, }) } @@ -64,16 +47,7 @@ func handleGetSingleCustomer (ctx *gin.Context) { func handleGetCustomers (ctx *gin.Context) { var customers []Customer - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - - err := getCustomers(&customers, userId) + err := getCustomers(&customers) if err != nil { ctx.Error(err) ctx.Abort() @@ -81,7 +55,6 @@ func handleGetCustomers (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": customers, }) } @@ -90,26 +63,6 @@ func handleSaveCustomer (ctx *gin.Context) { var customer Customer ctx.Bind(&customer) - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - customer.UserID = userId // necessary even when editing, just in case if UserID was ommitted in the request - - if customer.ID != 0 { - // if customer is being edited, check ownership - err := checkCustomerOwnership(customer.ID, userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - } - err := customer.upsert() if err != nil { ctx.Error(err) @@ -118,7 +71,6 @@ func handleSaveCustomer (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": customer, }) } @@ -133,23 +85,6 @@ func handleDelCustomer (ctx *gin.Context) { var customer Customer customer.ID = uint(id) - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - customer.UserID = userId - - err = checkCustomerOwnership(customer.ID, customer.UserID) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - err = customer.del() if err != nil { ctx.Error(err) @@ -157,7 +92,5 @@ func handleDelCustomer (ctx *gin.Context) { return } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - }) + ctx.JSON(http.StatusOK, nil) } diff --git a/customer/customer.go b/customer/customer.go index 2303ae8..25c4645 100644 --- a/customer/customer.go +++ b/customer/customer.go @@ -21,7 +21,6 @@ import ( "gorm.io/gorm" d "vidhukant.com/openbills/db" u "vidhukant.com/openbills/util" - "vidhukant.com/openbills/user" ) var db *gorm.DB @@ -45,8 +44,6 @@ type CustomerShippingAddress struct { type Customer struct { gorm.Model - UserID uint `json:"-"` - User user.User `json:"-"` FirmName string Gstin string ContactName string diff --git a/customer/service.go b/customer/service.go index 8cd2bde..a0ed4dc 100644 --- a/customer/service.go +++ b/customer/service.go @@ -37,8 +37,8 @@ func getCustomer(customer *Customer, id uint) error { return nil } -func getCustomers(customers *[]Customer, userId uint) error { - res := db.Where("user_id = ?", userId).Find(&customers) +func getCustomers(customers *[]Customer) error { + res := db.Find(&customers) // TODO: handle potential errors if res.Error != nil { @@ -60,14 +60,13 @@ func (c *Customer) upsert() error { } func (c *Customer) del() error { - res := db.Where("id = ? and user_id = ?", c.ID, c.UserID).Delete(c) + res := db.Where("id = ?", c.ID).Delete(c) // TODO: handle potential errors if res.Error != nil { return res.Error } - // returns 404 if either row doesn't exist or if the user doesn't own it if res.RowsAffected == 0 { return e.ErrNotFound } diff --git a/customer/validators.go b/customer/validators.go index b8c2a14..5693116 100644 --- a/customer/validators.go +++ b/customer/validators.go @@ -62,29 +62,3 @@ func (c *Customer) validate() error { return nil } - -func checkCustomerOwnership(customerId, userId uint) error { - var customer Customer - err := db. - Select("id", "user_id"). - Where("id = ?", customerId). - Find(&customer). - Error - - // TODO: handle potential errors - if err != nil { - return err - } - - // customer doesn't exist - if customer.ID == 0 { - return errors.ErrNotFound - } - - // user doesn't own this customer - if customer.UserID != userId { - return errors.ErrForbidden - } - - return nil -} diff --git a/errors/errors.go b/errors/errors.go index 0d88490..17afdfe 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -62,11 +62,7 @@ var ( ErrCannotEditInvoice = errors.New("This Invoice Cannot Be Edited Now") // 409 - ErrNonUniqueGSTIN = errors.New("GSTIN Must Be Unique") - ErrNonUniquePhone = errors.New("Phone Number Is Already In Use") - ErrNonUniqueEmail = errors.New("Email Address Is Already In Use") ErrNonUniqueUsername = errors.New("Username Is Already In Use") - ErrNonUniqueWebsite = errors.New("Website Is Already In Use") ErrNonUniqueBrandName = errors.New("Brand Name Is Already In Use") ErrNonUniqueBrandItem = errors.New("Item With Same Name And Brand Already Exists") ErrNonUniqueInvoiceNumber = errors.New("Invoice Number Must Be Unique") diff --git a/errors/status.go b/errors/status.go index 47820b5..a874423 100644 --- a/errors/status.go +++ b/errors/status.go @@ -70,11 +70,7 @@ func StatusCodeFromErr(err error) int { } // 409 - if errors.Is(err, ErrNonUniqueGSTIN) || - errors.Is(err, ErrNonUniquePhone) || - errors.Is(err, ErrNonUniqueUsername) || - errors.Is(err, ErrNonUniqueEmail) || - errors.Is(err, ErrNonUniqueWebsite) || + if errors.Is(err, ErrNonUniqueUsername) || errors.Is(err, ErrNonUniqueBrandName) || errors.Is(err, ErrNonUniqueInvoiceNumber) || errors.Is(err, ErrNonUniqueBrandItem) { diff --git a/invoice/controller.go b/invoice/controller.go index ad6df3e..b03ec22 100644 --- a/invoice/controller.go +++ b/invoice/controller.go @@ -32,17 +32,7 @@ func handleGetSingleInvoice (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var invoice Invoice - err = getInvoice(&invoice, uint(id)) if err != nil { ctx.Error(err) @@ -50,85 +40,36 @@ func handleGetSingleInvoice (ctx *gin.Context) { return } - if invoice.UserID != userId { - ctx.Error(e.ErrForbidden) - ctx.Abort() - return - } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": invoice, }) } -func handleGetInvoices (ctx *gin.Context) { - var invoices []Invoice - - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - - err := getInvoices(&invoices, userId, false) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - "data": invoices, - }) -} - -func handleGetDrafts (ctx *gin.Context) { - var invoices []Invoice - - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } +func handleGetInvoices(getDrafts bool) func(*gin.Context) { + return func(ctx *gin.Context) { + var invoices []Invoice - userId := uId.(uint) + err := getInvoices(&invoices, getDrafts) + if err != nil { + ctx.Error(err) + ctx.Abort() + return + } - err := getInvoices(&invoices, userId, true) - if err != nil { - ctx.Error(err) - ctx.Abort() - return + ctx.JSON(http.StatusOK, gin.H{ + "data": invoices, + }) } - - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - "data": invoices, - }) } func handleSaveInvoice (ctx *gin.Context) { var invoice Invoice ctx.Bind(&invoice) - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - invoice.UserID = userId - // if invoice number is 0, generate one! + // (maybe the client didn't give us one) if invoice.InvoiceNumber == 0 { - n, err := getNewInvoiceNumber(invoice.UserID) + n, err := getNewInvoiceNumber() if err != nil { ctx.Error(err) @@ -147,12 +88,12 @@ func handleSaveInvoice (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": invoice, }) } func handleDelInvoice (ctx *gin.Context) { + // TODO: only drafts can be deleted, non-drafts should be "cancelled" id, err := strconv.ParseUint(ctx.Param("id"), 10, 64) if err != nil { ctx.Error(e.ErrInvalidID) @@ -163,23 +104,6 @@ func handleDelInvoice (ctx *gin.Context) { var invoice Invoice invoice.ID = uint(id) - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - invoice.UserID = userId - - err = checkInvoiceOwnership(invoice.ID, invoice.UserID) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - err = invoice.del() if err != nil { ctx.Error(err) @@ -187,9 +111,7 @@ func handleDelInvoice (ctx *gin.Context) { return } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - }) + ctx.JSON(http.StatusOK, nil) } // get items belonging to a certain invoice @@ -201,22 +123,6 @@ func handleGetInvoiceItems (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - - err = checkInvoiceOwnership(uint(id), userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - var items []InvoiceItem err = getInvoiceItems(&items, uint(id)) if err != nil { @@ -226,12 +132,12 @@ func handleGetInvoiceItems (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": items, }) } func addItem (ctx *gin.Context) { + // TODO: only drafts can be edited id, err := strconv.ParseUint(ctx.Param("id"), 10, 64) if err != nil { ctx.Error(e.ErrInvalidID) @@ -239,27 +145,11 @@ func addItem (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var item InvoiceItem ctx.Bind(&item) item.InvoiceID = uint(id) - err = checkInvoiceOwnership(item.InvoiceID, userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - err = item.upsert() if err != nil { ctx.Error(err) @@ -267,13 +157,11 @@ func addItem (ctx *gin.Context) { return } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - "data": item, - }) + ctx.JSON(http.StatusOK, nil) } func removeItem (ctx *gin.Context) { + // TODO: only drafts can be edited id, err := strconv.ParseUint(ctx.Param("id"), 10, 64) if err != nil { ctx.Error(e.ErrInvalidID) @@ -281,27 +169,9 @@ func removeItem (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var item InvoiceItem item.ID = uint(id) - invoiceId, err := getItemInvoice(item.ID, userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - - item.InvoiceID = invoiceId - err = item.del() if err != nil { ctx.Error(err) @@ -309,10 +179,7 @@ func removeItem (ctx *gin.Context) { return } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - "data": item, - }) + ctx.JSON(http.StatusOK, nil) } // get custom fields belonging to a certain invoice @@ -324,22 +191,6 @@ func handleGetInvoiceCustomFields (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - - err = checkInvoiceOwnership(uint(id), userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - var cf []CustomField err = getInvoiceCustomFields(&cf, uint(id)) if err != nil { @@ -349,12 +200,12 @@ func handleGetInvoiceCustomFields (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": cf, }) } func addCustomField (ctx *gin.Context) { + // TODO: only drafts can be edited id, err := strconv.ParseUint(ctx.Param("id"), 10, 64) if err != nil { ctx.Error(e.ErrInvalidID) @@ -362,27 +213,10 @@ func addCustomField (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var cf CustomField ctx.Bind(&cf) - cf.InvoiceID = uint(id) - err = checkInvoiceOwnership(cf.InvoiceID, userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - err = cf.upsert() if err != nil { ctx.Error(err) @@ -391,12 +225,12 @@ func addCustomField (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": cf, }) } func removeCustomField (ctx *gin.Context) { + // TODO: only drafts can be edited id, err := strconv.ParseUint(ctx.Param("id"), 10, 64) if err != nil { ctx.Error(e.ErrInvalidID) @@ -404,27 +238,9 @@ func removeCustomField (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var cf CustomField cf.ID = uint(id) - invoiceId, err := getCustomFieldInvoice(cf.ID, userId) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - - cf.InvoiceID = invoiceId - err = cf.del() if err != nil { ctx.Error(err) @@ -433,7 +249,6 @@ func removeCustomField (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": cf, }) } diff --git a/invoice/invoice.go b/invoice/invoice.go index 4397710..9fa931b 100644 --- a/invoice/invoice.go +++ b/invoice/invoice.go @@ -20,7 +20,6 @@ package invoice import ( "gorm.io/gorm" d "vidhukant.com/openbills/db" - "vidhukant.com/openbills/user" u "vidhukant.com/openbills/util" i "vidhukant.com/openbills/item" "time" @@ -63,8 +62,6 @@ type CustomField struct { type Invoice struct { gorm.Model - UserID uint `json:"-"` - User user.User `json:"-"` InvoiceDate time.Time InvoiceNumber uint BillingAddress InvoiceBillingAddress diff --git a/invoice/router.go b/invoice/router.go index febd8fd..f406786 100644 --- a/invoice/router.go +++ b/invoice/router.go @@ -24,8 +24,8 @@ import ( func Routes(route *gin.RouterGroup) { g := route.Group("/invoice") { - g.GET("/", handleGetInvoices) - g.GET("/draft", handleGetDrafts) + g.GET("/", handleGetInvoices(false)) + g.GET("/draft", handleGetInvoices(true)) g.GET("/:id", handleGetSingleInvoice) g.POST("/", handleSaveInvoice) g.DELETE("/:id", handleDelInvoice) diff --git a/invoice/service.go b/invoice/service.go index 163b21e..55b1319 100644 --- a/invoice/service.go +++ b/invoice/service.go @@ -22,18 +22,12 @@ import ( ) // returns greatest invoice number + 1 -func getNewInvoiceNumber(userId uint) (uint, error) { - var i uint - +func getNewInvoiceNumber() (uint, error) { // check if number of invoices is 0 var count int64 - err := db.Model(&Invoice{}). - Where("user_id = ?", userId). - Count(&count). - Error - + err := db.Model(&Invoice{}).Count(&count).Error if err != nil { - return i, err + return 0, err } // if no records exist, then invoice number should be 1 @@ -45,7 +39,8 @@ func getNewInvoiceNumber(userId uint) (uint, error) { // NOTE: if there are gaps in invoice numbers, // they won't be filled and the series would continue // from the greatest invoice number. - row := db.Model(&Invoice{}).Where("user_id = ?", userId).Select("max(invoice_number)").Row() + var i uint + row := db.Model(&Invoice{}).Select("max(invoice_number)").Row() err = row.Scan(&i) return i + 1, err @@ -66,8 +61,8 @@ func getInvoice(invoice *Invoice, id uint) error { return nil } -func getInvoices(invoices *[]Invoice, userId uint, isDraft bool) error { - res := db.Where("user_id = ? and is_draft = ?", userId, isDraft).Find(&invoices) +func getInvoices(invoices *[]Invoice, isDraft bool) error { + res := db.Where("is_draft = ?", isDraft).Find(&invoices) // TODO: handle potential errors if res.Error != nil { @@ -118,14 +113,13 @@ func (i *Invoice) upsert() error { } func (i *Invoice) del() error { - res := db.Where("id = ? and user_id = ?", i.ID, i.UserID).Delete(i) + res := db.Where("id = ?", i.ID).Delete(i) // TODO: handle potential errors if res.Error != nil { return res.Error } - // returns 404 if either row doesn't exist or if the user doesn't own it if res.RowsAffected == 0 { return e.ErrNotFound } @@ -133,8 +127,7 @@ func (i *Invoice) del() error { return nil } -// also checks for ownership -func getItemInvoice(itemId, userId uint) (uint, error) { +func getItemInvoice(itemId uint) (uint, error) { var invoiceId uint res := db. Model(&InvoiceItem{}). @@ -151,17 +144,10 @@ func getItemInvoice(itemId, userId uint) (uint, error) { return invoiceId, e.ErrNotFound } - err := checkInvoiceOwnership(invoiceId, userId) - - if err != nil { - return invoiceId, err - } - return invoiceId, nil } -// also checks for ownership -func getCustomFieldInvoice(fieldId, userId uint) (uint, error) { +func getCustomFieldInvoice(fieldId uint) (uint, error) { var invoiceId uint res := db. Model(&CustomField{}). @@ -178,12 +164,6 @@ func getCustomFieldInvoice(fieldId, userId uint) (uint, error) { return invoiceId, e.ErrNotFound } - err := checkInvoiceOwnership(invoiceId, userId) - - if err != nil { - return invoiceId, err - } - return invoiceId, nil } @@ -195,7 +175,6 @@ func (i *InvoiceItem) del() error { return res.Error } - // returns 404 if either row doesn't exist or if the user doesn't own it if res.RowsAffected == 0 { return e.ErrNotFound } @@ -211,7 +190,6 @@ func (c *CustomField) del() error { return res.Error } - // returns 404 if either row doesn't exist or if the user doesn't own it if res.RowsAffected == 0 { return e.ErrNotFound } diff --git a/invoice/validators.go b/invoice/validators.go index 9f145dc..1c39cbe 100644 --- a/invoice/validators.go +++ b/invoice/validators.go @@ -24,7 +24,7 @@ import ( func (i *Invoice) validate() error { var count int64 err := db.Model(&Invoice{}). - Where("user_id = ? and invoice_number = ?", i.UserID, i.InvoiceNumber). + Where("invoice_number = ?", i.InvoiceNumber). Count(&count). Error @@ -59,29 +59,3 @@ func isDraft(invoiceId uint) (bool, error) { return invoice.IsDraft, nil } - -func checkInvoiceOwnership(invoiceId, userId uint) error { - var invoice Invoice - err := db. - Select("id", "user_id"). - Where("id = ?", invoiceId). - Find(&invoice). - Error - - // TODO: handle potential errors - if err != nil { - return err - } - - // invoice doesn't exist - if invoice.ID == 0 { - return errors.ErrNotFound - } - - // user doesn't own this invoice - if invoice.UserID != userId { - return errors.ErrForbidden - } - - return nil -} diff --git a/item/controller.go b/item/controller.go index 9993688..bb2eb94 100644 --- a/item/controller.go +++ b/item/controller.go @@ -31,17 +31,8 @@ func handleGetBrandItems (ctx *gin.Context) { return } - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - var items []SavedItem - err = getBrandItems(&items, uint(id), userId) + err = getBrandItems(&items, uint(id)) if err != nil { ctx.Error(err) ctx.Abort() @@ -49,7 +40,6 @@ func handleGetBrandItems (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": items, }) } @@ -57,16 +47,7 @@ func handleGetBrandItems (ctx *gin.Context) { func handleGetBrands (ctx *gin.Context) { var brands []Brand - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - - err := getBrands(&brands, userId) + err := getBrands(&brands) if err != nil { ctx.Error(err) ctx.Abort() @@ -74,7 +55,6 @@ func handleGetBrands (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": brands, }) } @@ -83,16 +63,6 @@ func handleSaveBrand (ctx *gin.Context) { var brand Brand ctx.Bind(&brand) - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - brand.UserID = userId - err := brand.upsert() if err != nil { ctx.Error(err) @@ -101,7 +71,6 @@ func handleSaveBrand (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": brand, }) } @@ -116,24 +85,6 @@ func handleDelBrand (ctx *gin.Context) { var brand Brand brand.ID = uint(id) - - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - brand.UserID = userId - - err = checkBrandOwnership(brand.ID, brand.UserID) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - err = brand.del() if err != nil { ctx.Error(err) @@ -141,24 +92,13 @@ func handleDelBrand (ctx *gin.Context) { return } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - }) + ctx.JSON(http.StatusOK, nil) } func handleGetItems (ctx *gin.Context) { var items []SavedItem - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - - err := getItems(&items, userId) + err := getItems(&items) if err != nil { ctx.Error(err) ctx.Abort() @@ -166,7 +106,6 @@ func handleGetItems (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": items, }) } @@ -175,16 +114,6 @@ func handleSaveItem (ctx *gin.Context) { var item SavedItem ctx.Bind(&item) - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - item.UserID = userId - err := item.upsert() if err != nil { ctx.Error(err) @@ -193,7 +122,6 @@ func handleSaveItem (ctx *gin.Context) { } ctx.JSON(http.StatusOK, gin.H{ - "message": "success", "data": item, }) } @@ -208,23 +136,6 @@ func handleDelItem (ctx *gin.Context) { var item SavedItem item.ID = uint(id) - uId, ok := ctx.Get("UserID") - if !ok { - ctx.Error(e.ErrUnauthorized) - ctx.Abort() - return - } - - userId := uId.(uint) - item.UserID = userId - - err = checkItemOwnership(item.ID, item.UserID) - if err != nil { - ctx.Error(err) - ctx.Abort() - return - } - err = item.del() if err != nil { ctx.Error(err) @@ -232,7 +143,5 @@ func handleDelItem (ctx *gin.Context) { return } - ctx.JSON(http.StatusOK, gin.H{ - "message": "success", - }) + ctx.JSON(http.StatusOK, nil) } diff --git a/item/hooks.go b/item/hooks.go index 74b6860..5056cb1 100644 --- a/item/hooks.go +++ b/item/hooks.go @@ -20,22 +20,11 @@ package item import ( "gorm.io/gorm" "vidhukant.com/openbills/errors" - e "errors" ) func (i *SavedItem) BeforeSave(tx *gorm.DB) error { var err error - // also checks if brand actually exists - err = checkBrandOwnership(i.BrandID, i.UserID) - if err != nil { - if e.Is(err, errors.ErrBrandNotFound) { - // this error has a better error message for this case - return errors.ErrBrandNotFound - } - return err - } - err = i.validate() if err != nil { return err @@ -60,7 +49,7 @@ func (b *Brand) BeforeDelete(tx *gorm.DB) error { } // delete all items - err := db.Where("brand_id = ? and user_id = ?", b.ID, b.UserID).Delete(&SavedItem{}).Error + err := db.Where("brand_id = ?", b.ID).Delete(&SavedItem{}).Error if err != nil { return err } diff --git a/item/item.go b/item/item.go index 3f911fa..617a662 100644 --- a/item/item.go +++ b/item/item.go @@ -20,7 +20,6 @@ package item import ( "gorm.io/gorm" d "vidhukant.com/openbills/db" - "vidhukant.com/openbills/user" ) var db *gorm.DB @@ -32,8 +31,6 @@ func init() { type Brand struct { gorm.Model - UserID uint `json:"-"` - User user.User `json:"-"` Name string } @@ -41,7 +38,7 @@ type Item struct { Name string Description string HSN string - UnitOfMeasure string // TODO: probably has to be a custom type + UnitOfMeasure string UnitPrice string // float GSTPercentage string // float } @@ -51,6 +48,4 @@ type SavedItem struct { Item BrandID uint Brand Brand - UserID uint `json:"-"` - User user.User `json:"-"` } diff --git a/item/router.go b/item/router.go index fab973f..b953d09 100644 --- a/item/router.go +++ b/item/router.go @@ -33,7 +33,6 @@ func Routes(route *gin.RouterGroup) { i := route.Group("/item") { i.GET("/", handleGetItems) - //i.GET("/:id", handleGetBrandItems) i.POST("/", handleSaveItem) i.DELETE("/:id", handleDelItem) } diff --git a/item/service.go b/item/service.go index 80faff0..0b2afaf 100644 --- a/item/service.go +++ b/item/service.go @@ -21,12 +21,7 @@ import ( "vidhukant.com/openbills/errors" ) -func getBrandItems(items *[]SavedItem, id, userId uint) error { - err := checkBrandOwnership(id, userId) - if err != nil { - return err - } - +func getBrandItems(items *[]SavedItem, id uint) error { // get items res := db.Model(&SavedItem{}).Where("brand_id = ?", id).Find(&items) @@ -35,7 +30,6 @@ func getBrandItems(items *[]SavedItem, id, userId uint) error { return res.Error } - // returns 404 if either row doesn't exist or if the user doesn't own it if res.RowsAffected == 0 { return errors.ErrEmptyResponse } @@ -43,8 +37,8 @@ func getBrandItems(items *[]SavedItem, id, userId uint) error { return nil } -func getBrands(brands *[]Brand, userId uint) error { - res := db.Where("user_id = ?", userId).Find(&brands) +func getBrands(brands *[]Brand) error { + res := db.Find(&brands) // TODO: handle potential errors if res.Error != nil { @@ -66,14 +60,13 @@ func (b *Brand) upsert() error { func (b *Brand) del() error { // delete brand - res := db.Where("id = ? and user_id = ?", b.ID, b.UserID).Delete(b) + res := db.Where("id = ?", b.ID).Delete(b) // TODO: handle potential errors if res.Error != nil { return res.Error } - // returns 404 if either row doesn't exist or if the user doesn't own it if res.RowsAffected == 0 { return errors.ErrNotFound } @@ -81,8 +74,8 @@ func (b *Brand) del() error { return nil } -func getItems(items *[]SavedItem, userId uint) error { - res := db.Where("user_id = ?", userId).Preload("Brand").Find(&items) +func getItems(items *[]SavedItem) error { + res := db.Preload("Brand").Find(&items) // TODO: handle potential errors if res.Error != nil { @@ -103,14 +96,13 @@ func (i *SavedItem) upsert() error { } func (i *SavedItem) del() error { - res := db.Where("id = ? and user_id = ?", i.ID, i.UserID).Delete(i) + res := db.Where("id = ?", i.ID).Delete(i) // TODO: handle potential errors if res.Error != nil { return res.Error } - // returns 404 if either row doesn't exist or if the user doesn't own it if res.RowsAffected == 0 { return errors.ErrNotFound } diff --git a/item/validators.go b/item/validators.go index b808ae4..63c254f 100644 --- a/item/validators.go +++ b/item/validators.go @@ -32,11 +32,11 @@ func (b *Brand) validate() error { return errors.ErrEmptyBrandName } - // make sure GSTIN is unique + // make sure brand name is unique var count int64 err := db.Model(&Brand{}). Select("name"). - Where("name = ? and user_id = ?", b.Name, b.UserID). + Where("name = ?", b.Name). Count(&count). Error @@ -75,7 +75,7 @@ func (i *SavedItem) validate() error { var count int64 err = db.Model(&SavedItem{}). Select("name, brand_id"). - Where("brand_id = ? and name = ? and user_id = ?", i.BrandID, i.Name, i.UserID). + Where("brand_id = ? and name = ?", i.BrandID, i.Name). Count(&count). Error @@ -89,55 +89,3 @@ func (i *SavedItem) validate() error { return nil } - -func checkBrandOwnership(brandId, userId uint) error { - var brand Brand - err := db. - Select("id", "user_id"). - Where("id = ?", brandId). - Find(&brand). - Error - - // TODO: handle potential errors - if err != nil { - return err - } - - // brand doesn't exist - if brand.ID == 0 { - return errors.ErrNotFound - } - - // user doesn't own this brand - if brand.UserID != userId { - return errors.ErrForbidden - } - - return nil -} - -func checkItemOwnership(itemId, userId uint) error { - var item SavedItem - err := db. - Select("id", "user_id"). - Where("id = ?", itemId). - Find(&item). - Error - - // TODO: handle potential errors - if err != nil { - return err - } - - // item doesn't exist - if item.ID == 0 { - return errors.ErrNotFound - } - - // user doesn't own this item - if item.UserID != userId { - return errors.ErrForbidden - } - - return nil -} @@ -38,7 +38,7 @@ import ( "log" ) -const OPENBILLS_VERSION = "v0.16.0" +const OPENBILLS_VERSION = "v0.17.0" func init() { if !viper.GetBool("debug_mode") { diff --git a/user/validators.go b/user/validators.go index b54457f..e497122 100644 --- a/user/validators.go +++ b/user/validators.go @@ -19,7 +19,6 @@ package user import ( "strings" - e "errors" "github.com/spf13/viper" "vidhukant.com/openbills/errors" "vidhukant.com/openbills/util" @@ -59,41 +58,6 @@ func validateUsername(username string) error { return nil } -// NOTE: very inefficient and really really really dumb but it works -// TODO: find a better (or even a remotely good) way -func validateUserField(field, value string) error { - if value != "" { - var count int64 - err := db.Model(&User{}). - Where(field + " = ?", value). - Count(&count). - Error - - if err != nil { - return err - } - - if count > 0 { - switch(field) { - case "username": - return errors.ErrNonUniqueUsername - case "phone": - return errors.ErrNonUniquePhone - case "email": - return errors.ErrNonUniqueEmail - case "website": - return errors.ErrNonUniqueWebsite - case "gstin": - return errors.ErrNonUniqueGSTIN - default: - return e.New(field + " is not unique") - } - } - } - - return nil -} - func (u *User) validate() error { u.Username = strings.TrimSpace(u.Username) u.Email = strings.TrimSpace(u.Email) @@ -102,8 +66,6 @@ func (u *User) validate() error { u.Gstin = strings.TrimSpace(u.Gstin) u.IsVerified = false - // TODO: validate username length and stuff - // don't validate if GSTIN is empty if u.Gstin != "" && !util.ValidateGstin(u.Gstin) { return errors.ErrInvalidGSTIN @@ -146,12 +108,5 @@ func (u *User) validate() error { return err } - for _, i := range [][]string{{"username", u.Username}, {"email", u.Email}, {"website", u.Website}, {"gstin", u.Gstin}, {"phone", u.Phone}} { - err := validateUserField(i[0], i[1]) - if err != nil { - return err - } - } - return nil } |