From 99b9df5066a24ebd1c8e1c74530d99ad3d296d08 Mon Sep 17 00:00:00 2001 From: Nedim Date: Fri, 10 Nov 2023 17:32:17 +0100 Subject: [PATCH] Protected routes --- config/config.go | 12 +++-- config/models.go | 12 +++-- controllers/contracts_controller.go | 13 +++-- controllers/devices_controller.go | 8 ++-- controllers/invoices_controller.go | 10 ++-- controllers/users_controller.go | 2 +- database/contract/contract.go | 2 +- database/device/device.go | 2 +- database/invoice/invoice.go | 74 ++++++++++++++--------------- database/user/user.go | 22 ++++++--- env-example | 3 +- middlewares/jwt.go | 58 +++++++++++++++++++++- models/session_token.go | 7 +-- routes/public_routes.go | 47 +++++++++--------- 14 files changed, 172 insertions(+), 100 deletions(-) diff --git a/config/config.go b/config/config.go index f6f9e7b..6714ad8 100644 --- a/config/config.go +++ b/config/config.go @@ -23,9 +23,11 @@ func Load() error { Service: Service{ // 9000 DEFAULT FOR DEV ENVIRONMENT - Port: getEnv("NOVATECH_SERVICE_PORT", "9000"), - Environment: getEnv("NOVATECH_SERVICE_ENVIRONMENT", "DEV"), - MapboxAccessToken: getEnv("NOVATECH_SERVICE_MAPBOX_ACCESS_TOKEN", ""), + Port: getEnv("NOVATECH_SERVICE_PORT", "9000"), + Environment: getEnv("NOVATECH_SERVICE_ENVIRONMENT", "DEV"), + MapboxAccessToken: getEnv("NOVATECH_SERVICE_MAPBOX_ACCESS_TOKEN", ""), + JwtSecretKey: getEnv("JWT_SECRET_KEY", "MDQsCiJwYWNrZXRWZXJzaW9uIjogMSwKImhhcm"), + JwtSecretKeyExpiryHours: getEnv("JWT_SECRET_KEY_EXPIRY_HOURS", "24"), }, AdminService: Service{ // 8080 DEFAULT FOR DEV ENVIRONMENT @@ -44,8 +46,8 @@ func Load() error { ContractAddress: getEnv("NOVATECH_BLOCKCHAIN_CONTRACT_ADDRESS", ""), WalletAddress: getEnv("NOVATECH_BLOCKCHAIN_WALLET_ADDRESS", ""), WalletPrivateKey: getEnv("NOVATECH_BLOCKCHAIN_WALLET_PRIVATE_KEY", ""), - }, - AWS: AWS { + }, + AWS: AWS{ AccessKey: getEnv("AWS_ACCESS_KEY_ID", ""), SecretKey: getEnv("AWS_SECRET_ACCESS_KEY", ""), }, diff --git a/config/models.go b/config/models.go index bf17691..0686d8c 100644 --- a/config/models.go +++ b/config/models.go @@ -6,15 +6,17 @@ type Config struct { AdminService Service Database Database Blockchain Blockchain - AWS AWS + AWS AWS } // Service contains configuration for service type Service struct { - Port string - Environment string - WebPageURL string - MapboxAccessToken string + Port string + Environment string + WebPageURL string + MapboxAccessToken string + JwtSecretKey string + JwtSecretKeyExpiryHours string } // Blockchain contains configuration for blockchain diff --git a/controllers/contracts_controller.go b/controllers/contracts_controller.go index 23c395f..b6fbb7e 100644 --- a/controllers/contracts_controller.go +++ b/controllers/contracts_controller.go @@ -35,6 +35,8 @@ func GetLatestContracts(c *gin.Context) { deviceIDsStr := c.QueryArray("deviceIDs[]") iDsStr := c.QueryArray("ids[]") + company := c.GetInt("companyID") + // Convert limit and offset to int limit, err := strconv.Atoi(limitStr) if err != nil { @@ -93,7 +95,7 @@ func GetLatestContracts(c *gin.Context) { } // Fetch contracts - contracts, total, st, err := contract.GetContracts(status, companyName, companyAddress, companyEmail, companyPhone, &startTime, &endTime, contractName, deviceIDs, contractIDs, nil, limit, offset) + contracts, total, st, err := contract.GetContracts(status, companyName, companyAddress, companyEmail, companyPhone, &startTime, &endTime, contractName, deviceIDs, contractIDs, nil, company, limit, offset) if err != nil { c.JSON(st, gin.H{"error": err.Error()}) @@ -114,6 +116,7 @@ func GetBuyerContracts(c *gin.Context) { dateCreatedStr := c.Query("date_created") startTimeStr := c.Query("start_time") endTimeStr := c.Query("end_time") + company := c.GetInt("companyID") // Convert limit and offset to int limit, err := strconv.Atoi(limitStr) @@ -175,7 +178,7 @@ func GetBuyerContracts(c *gin.Context) { } // Fetch contracts - contracts, total, st, err := contract.GetContracts(status, "", "", "", "", startTime, endTime, qStr, nil, contractIDs, &dateCreated, limit, offset) + contracts, total, st, err := contract.GetContracts(status, "", "", "", "", startTime, endTime, qStr, nil, contractIDs, &dateCreated, company, limit, offset) if err != nil { c.JSON(st, gin.H{"error": err.Error()}) return @@ -354,7 +357,7 @@ func GetContractCountByStatus(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{"data": models.ActiveContractsResponse{ActiveCount: activeCount, ExecutedCount : executedCount, MonthlyContracts: monthly}}) + c.JSON(http.StatusOK, gin.H{"data": models.ActiveContractsResponse{ActiveCount: activeCount, ExecutedCount: executedCount, MonthlyContracts: monthly}}) } @@ -388,5 +391,5 @@ func GetTotalContractCount(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{"data" : totalCount}) -} \ No newline at end of file + c.JSON(http.StatusOK, gin.H{"data": totalCount}) +} diff --git a/controllers/devices_controller.go b/controllers/devices_controller.go index 33abd21..8750fb2 100644 --- a/controllers/devices_controller.go +++ b/controllers/devices_controller.go @@ -85,7 +85,6 @@ func SaveDeviceInfo(c *gin.Context) { } } - log.Printf("Successfully received and saved device info: %v", deviceInfo) c.JSON(http.StatusOK, gin.H{"message": "Successfully received and saved device info", "data": deviceInfo}) } @@ -153,6 +152,7 @@ func GetDevicesByContract(c *gin.Context) { c.JSON(http.StatusBadRequest, gin.H{"error": "Contract ID is required"}) return } + companyID := c.GetInt("companyID") // Convert string to uint contractID, err := strconv.ParseUint(contractIDStr, 10, 32) @@ -163,7 +163,7 @@ func GetDevicesByContract(c *gin.Context) { } log.Printf("This is the ID: %v", contractID) - devices, st, err := device.GetDevicesForContract(contractID) + devices, st, err := device.GetDevicesForContract(contractID, companyID) if err != nil { c.JSON(st, gin.H{"error": err.Error()}) @@ -230,7 +230,7 @@ func GetCompanyRelatedDeviceInfoCountWithTempRange(c *gin.Context) { // Convert Unix timestamps to time.Time startTime := time.Unix(startUnix, 0) endTime := time.Unix(endUnix, 0) - + // Convert string to uint for CompanyID companyID, err := strconv.ParseUint(companyIDStr, 10, 32) if err != nil { @@ -238,7 +238,6 @@ func GetCompanyRelatedDeviceInfoCountWithTempRange(c *gin.Context) { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid Company ID"}) return } - // Get the counts inRangeCount, outOfRangeCount, monthlyCount, err := device.CountDeviceBreachedAndNormalDevicesByCompany(uint(companyID), startTime, endTime) @@ -253,7 +252,6 @@ func GetCompanyRelatedDeviceInfoCountWithTempRange(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"data": data}) } - func GetContractsMatchingDeviceLocation(c *gin.Context) { startTimeStr := c.DefaultQuery("start_time", "") endTimeStr := c.DefaultQuery("end_time", "") diff --git a/controllers/invoices_controller.go b/controllers/invoices_controller.go index 9ef1e7e..d991316 100644 --- a/controllers/invoices_controller.go +++ b/controllers/invoices_controller.go @@ -17,6 +17,7 @@ func GetInvoices(c *gin.Context) { sortBy := c.Query("sort_by") iDsStr := c.QueryArray("ids[]") status := c.QueryArray("status") + companyID := c.GetInt("companyID") limit, err := strconv.Atoi(limitStr) if err != nil { @@ -41,7 +42,7 @@ func GetInvoices(c *gin.Context) { invoiceIDs = append(invoiceIDs, id) } - invoices, total, err := invoice.GetInvoices(buyerName, sortBy, limit, offset, invoiceIDs, status) + invoices, total, err := invoice.GetInvoices(buyerName, sortBy, limit, offset, invoiceIDs, status, companyID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -61,7 +62,9 @@ func GetInvoiceByID(c *gin.Context) { return } - invoices, _, err := invoice.GetInvoices("", "", 1, 0, []int64{int64(id)}, nil) + companyID := c.GetInt("companyID") + + invoices, _, err := invoice.GetInvoices("", "", 1, 0, []int64{int64(id)}, nil, companyID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return @@ -106,7 +109,6 @@ func convertToResponseModel(invoices []models.Invoice) []models.ListInvoiceRespo return listInvoiceResponses } - func GetInvoiceCountByStatus(c *gin.Context) { companyID := c.DefaultQuery("company_id", "0") startTimeStr := c.DefaultQuery("start_time", "") @@ -137,6 +139,6 @@ func GetInvoiceCountByStatus(c *gin.Context) { return } - c.JSON(http.StatusOK, gin.H{"data": models.ActiveInvoiceResponse{Claimed: activeCount, Issued : executedCount, MonthlyInvoices: monthly}}) + c.JSON(http.StatusOK, gin.H{"data": models.ActiveInvoiceResponse{Claimed: activeCount, Issued: executedCount, MonthlyInvoices: monthly}}) } diff --git a/controllers/users_controller.go b/controllers/users_controller.go index 407612c..6173082 100644 --- a/controllers/users_controller.go +++ b/controllers/users_controller.go @@ -130,7 +130,7 @@ func Login(c *gin.Context) { if usr.CheckPassword(user.Password, req.Password) { if user.IsActive && user.LoginAttempts < 10 { // Proceed with creating JWT token and resetting login attempts - token, err := usr.CreateSessionToken(user.ID) + token, err := usr.CreateSessionToken(user.ID, user.CompanyID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not create JWT token"}) return diff --git a/database/contract/contract.go b/database/contract/contract.go index 6f5c56c..b0ddf59 100644 --- a/database/contract/contract.go +++ b/database/contract/contract.go @@ -21,7 +21,7 @@ import ( func GetContracts(status []string, companyName string, companyAddress string, companyEmail string, companyPhone string, startTime *time.Time, endTime *time.Time, - contractName string, deviceIDs []int64, contractIDs []int64, dateCreated *time.Time, limit, offset int) ([]models.Contract, int64, int, error) { + contractName string, deviceIDs []int64, contractIDs []int64, dateCreated *time.Time, company, limit, offset int) ([]models.Contract, int64, int, error) { var contracts []models.Contract db := shared.GetDb() diff --git a/database/device/device.go b/database/device/device.go index a6658be..89a4596 100644 --- a/database/device/device.go +++ b/database/device/device.go @@ -15,7 +15,7 @@ import ( "gitlab.com/pactual1/backend/shared" ) -func GetDevicesForContract(contractID uint64) ([]models.Device, int, error) { +func GetDevicesForContract(contractID uint64, companyID int) ([]models.Device, int, error) { // Fetch the contract from the database var contract models.Contract if err := shared.GetDb().Where("id = ?", contractID).First(&contract).Error; err != nil { diff --git a/database/invoice/invoice.go b/database/invoice/invoice.go index ad43473..dc53d24 100644 --- a/database/invoice/invoice.go +++ b/database/invoice/invoice.go @@ -9,7 +9,7 @@ import ( "gitlab.com/pactual1/backend/shared" ) -func GetInvoices(buyerName string, sortBy string, limit int, offset int, ids []int64, status []string) ([]models.Invoice, int64, error) { +func GetInvoices(buyerName string, sortBy string, limit int, offset int, ids []int64, status []string, company int) ([]models.Invoice, int64, error) { var invoices []models.Invoice // Default sort by InvoiceDate DESC @@ -36,7 +36,7 @@ func GetInvoices(buyerName string, sortBy string, limit int, offset int, ids []i countDb = countDb.Where("id in (?)", ids) } - // Added conditional for status search + // Added conditional for status search if len(status) > 0 { db = db.Where("status in (?)", status) countDb = countDb.Where("status in (?)", status) @@ -69,46 +69,46 @@ func GetInvoices(buyerName string, sortBy string, limit int, offset int, ids []i } func CountInvoicesByMultipleStatuses(companyID uint, startTime, endTime time.Time) (int64, int64, map[string]map[string]int64, error) { - var claimed, issued int64 - monthlyCounts := make(map[string]map[string]int64) + var claimed, issued int64 + monthlyCounts := make(map[string]map[string]int64) - // Iterate through each month within the specified date range - for dt := startTime; dt.Before(endTime); dt = dt.AddDate(0, 1, 0) { - monthEnd := dt.AddDate(0, 1, 0) - if monthEnd.After(endTime) { - monthEnd = endTime - } + // Iterate through each month within the specified date range + for dt := startTime; dt.Before(endTime); dt = dt.AddDate(0, 1, 0) { + monthEnd := dt.AddDate(0, 1, 0) + if monthEnd.After(endTime) { + monthEnd = endTime + } - // Initialize monthlyCounts for the current month - monthKey := dt.Format("2006-01") - monthlyCounts[monthKey] = map[string]int64{"insurance_claimed": 0, "invoice_issued": 0} + // Initialize monthlyCounts for the current month + monthKey := dt.Format("2006-01") + monthlyCounts[monthKey] = map[string]int64{"insurance_claimed": 0, "invoice_issued": 0} - // Query for 'insurance_claimed' invoices for the current month - var monthlyClaimed int64 - err := shared.GetDb().Model(&models.Invoice{}). - Where("status = ? AND (buyer_id = ? OR seller_id = ?) AND invoice_date >= ? AND invoice_due_date <= ?", "insurance_claimed", companyID, companyID, dt, monthEnd). - Count(&monthlyClaimed).Error - if err != nil { - return 0, 0, nil, err - } + // Query for 'insurance_claimed' invoices for the current month + var monthlyClaimed int64 + err := shared.GetDb().Model(&models.Invoice{}). + Where("status = ? AND (buyer_id = ? OR seller_id = ?) AND invoice_date >= ? AND invoice_due_date <= ?", "insurance_claimed", companyID, companyID, dt, monthEnd). + Count(&monthlyClaimed).Error + if err != nil { + return 0, 0, nil, err + } - // Query for 'invoice_issued' invoices for the current month - var monthlyIssued int64 - err = shared.GetDb().Model(&models.Invoice{}). - Where("status = ? AND (buyer_id = ? OR seller_id = ?) AND invoice_date >= ? AND invoice_due_date <= ?", "invoice_issued", companyID, companyID, dt, monthEnd). - Count(&monthlyIssued).Error - if err != nil { - return 0, 0, nil, err - } + // Query for 'invoice_issued' invoices for the current month + var monthlyIssued int64 + err = shared.GetDb().Model(&models.Invoice{}). + Where("status = ? AND (buyer_id = ? OR seller_id = ?) AND invoice_date >= ? AND invoice_due_date <= ?", "invoice_issued", companyID, companyID, dt, monthEnd). + Count(&monthlyIssued).Error + if err != nil { + return 0, 0, nil, err + } - // Update the counts for the current month - monthlyCounts[monthKey]["insurance_claimed"] = monthlyClaimed - monthlyCounts[monthKey]["invoice_issued"] = monthlyIssued + // Update the counts for the current month + monthlyCounts[monthKey]["insurance_claimed"] = monthlyClaimed + monthlyCounts[monthKey]["invoice_issued"] = monthlyIssued - // Update the total counts - claimed += monthlyClaimed - issued += monthlyIssued - } + // Update the total counts + claimed += monthlyClaimed + issued += monthlyIssued + } - return claimed, issued, monthlyCounts, nil + return claimed, issued, monthlyCounts, nil } diff --git a/database/user/user.go b/database/user/user.go index adbde04..9cc42c3 100644 --- a/database/user/user.go +++ b/database/user/user.go @@ -3,10 +3,12 @@ package user import ( "errors" "fmt" + "strconv" "time" "github.com/golang-jwt/jwt" "github.com/jinzhu/gorm" + "gitlab.com/pactual1/backend/config" "gitlab.com/pactual1/backend/models" "gitlab.com/pactual1/backend/shared" "golang.org/x/crypto/bcrypt" @@ -50,7 +52,7 @@ func CheckPassword(hashedPassword, password string) bool { return err == nil } -func CreateSessionToken(userID uint) (string, error) { +func CreateSessionToken(userID, companyID uint) (string, error) { // Generate JWT token tokenString, err := CreateJWTToken(userID) if err != nil { @@ -59,9 +61,10 @@ func CreateSessionToken(userID uint) (string, error) { // Create and save the session token in the database sessionToken := models.SessionToken{ - UserID: userID, - Token: tokenString, - IsActive: true, + UserID: userID, + Token: tokenString, + CompanyID: companyID, + IsActive: true, } if result := shared.GetDb().Create(&sessionToken); result.Error != nil { return "", result.Error @@ -84,10 +87,15 @@ func IncrementLoginAttempts(user models.User) { shared.GetDb().Save(&user) } -var jwtKey = []byte("MDQsCiJwYWNrZXRWZXJzaW9uIjogMSwKImhhcm") - func CreateJWTToken(userID uint) (string, error) { - expirationTime := time.Now().Add(24 * time.Hour) + var jwtKey = []byte(config.AppConfig.Service.JwtSecretKey) + expiryHours, err := strconv.Atoi(config.AppConfig.Service.JwtSecretKeyExpiryHours) + + if err != nil { + return "", err + } + + expirationTime := time.Now().Add(time.Duration(expiryHours) * time.Hour) claims := &jwt.StandardClaims{ Subject: fmt.Sprint(userID), ExpiresAt: expirationTime.Unix(), diff --git a/env-example b/env-example index 3deee8b..52f2ba6 100644 --- a/env-example +++ b/env-example @@ -14,4 +14,5 @@ NOVATECH_BLOCKCHAIN_WALLET_ADDRESS=0x20eff5decaed29bd64f0c6385956363eeaaf4d3e NOVATECH_BLOCKCHAIN_WALLET_PRIVATE_KEY=PRIVATE_KEY NOVATECH_SERVICE_MAPBOX_ACCESS_TOKEN=pk.ey AWS_ACCESS_KEY_ID:access -AWS_SECRET_ACCESS_KEY:secret \ No newline at end of file +AWS_SECRET_ACCESS_KEY:secret +JWT_SECRET_KEY:key diff --git a/middlewares/jwt.go b/middlewares/jwt.go index 2578072..3eb7c16 100644 --- a/middlewares/jwt.go +++ b/middlewares/jwt.go @@ -5,10 +5,17 @@ package middlewares import ( - "github.com/dgrijalva/jwt-go" - "github.com/gin-gonic/gin" + "errors" + "net/http" "strings" "time" + + "github.com/dgrijalva/jwt-go" + "github.com/gin-gonic/gin" + "github.com/jinzhu/gorm" + "gitlab.com/pactual1/backend/config" + "gitlab.com/pactual1/backend/models" + "gitlab.com/pactual1/backend/shared" ) var ( @@ -102,3 +109,50 @@ func ValidateToken(tokenString string, key string) (*jwt.Token, error) { return token, err } + +// AuthMiddleware checks the session token and validates it +func AuthMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + var jwtKey = []byte(config.AppConfig.Service.JwtSecretKey) + tokenString := c.GetHeader("Authorization") + + // Check if token is in the correct format (Bearer token) + if len(tokenString) > 7 && strings.ToUpper(tokenString[0:7]) == "BEARER " { + tokenString = tokenString[7:] + } else { + c.JSON(http.StatusForbidden, gin.H{"message": "Your request is not authorized"}) + c.Abort() + return + } + + // Parse and validate the token + claims := &jwt.StandardClaims{} + token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) { + return jwtKey, nil + }) + + if err != nil || !token.Valid { + c.JSON(http.StatusForbidden, gin.H{"message": "Invalid authorization token"}) + c.Abort() + return + } + + // Check if the token is present and active in the SessionToken table + var sessionToken models.SessionToken + result := shared.GetDb().Where("token = ? AND is_active = ?", tokenString, true).First(&sessionToken) + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + c.JSON(http.StatusForbidden, gin.H{"message": "Invalid session token"}) + c.Abort() + return + } else if result.Error != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Internal server error"}) + c.Abort() + return + } + + // Set user ID in the Gin context + c.Set("userID", sessionToken.UserID) + c.Set("companyID", sessionToken.CompanyID) + c.Next() + } +} diff --git a/models/session_token.go b/models/session_token.go index 6671824..e778f4e 100644 --- a/models/session_token.go +++ b/models/session_token.go @@ -2,9 +2,10 @@ package models type SessionToken struct { BaseModel - UserID uint `json:"userId"` - Token string `json:"token"` - IsActive bool `json:"isActive"` + UserID uint `json:"userId"` + Token string `json:"token"` + IsActive bool `json:"isActive"` + CompanyID uint `json:"userId"` } func (SessionToken) Update() (bool, error) { diff --git a/routes/public_routes.go b/routes/public_routes.go index beabc77..822ea76 100644 --- a/routes/public_routes.go +++ b/routes/public_routes.go @@ -2,6 +2,7 @@ package routes import ( "gitlab.com/pactual1/backend/controllers" + "gitlab.com/pactual1/backend/middlewares" "github.com/gin-gonic/gin" ) @@ -12,42 +13,42 @@ func RegisterPublicRoutes(r *gin.Engine) { r.GET("/health", controllers.HealthCheck) // Map dashboard - r.GET("/dashboard/map/contract/devices", controllers.GetDevicesByContract) - r.GET("/dashboard/map/contracts", controllers.GetLatestContracts) - r.GET("/dashboard/map/device_data", controllers.GetDeviceData) + r.GET("/dashboard/map/contract/devices", middlewares.AuthMiddleware(), controllers.GetDevicesByContract) + r.GET("/dashboard/map/contracts", middlewares.AuthMiddleware(), controllers.GetLatestContracts) + r.GET("/dashboard/map/device_data", middlewares.AuthMiddleware(), controllers.GetDeviceData) // Invoices - r.GET("/invoices", controllers.GetInvoices) - r.GET("/invoices/:id", controllers.GetInvoiceByID) + r.GET("/invoices", middlewares.AuthMiddleware(), controllers.GetInvoices) + r.GET("/invoices/:id", middlewares.AuthMiddleware(), controllers.GetInvoiceByID) r.POST("/device_data/save", controllers.SaveDeviceInfo) - r.GET("/buyers", controllers.ListCompanies) - r.GET("/products", controllers.ListProductTemplates) - r.GET("/templates", controllers.ListTextTemplates) - r.POST("/templates/save", controllers.CreateTextTemplate) - r.GET("/products/:template_id", controllers.GetProductTemplate) + r.GET("/buyers", middlewares.AuthMiddleware(), controllers.ListCompanies) + r.GET("/products", middlewares.AuthMiddleware(), middlewares.AuthMiddleware(), controllers.ListProductTemplates) + r.GET("/templates", middlewares.AuthMiddleware(), controllers.ListTextTemplates) + r.POST("/templates/save", middlewares.AuthMiddleware(), controllers.CreateTextTemplate) + r.GET("/products/:template_id", middlewares.AuthMiddleware(), controllers.GetProductTemplate) // Contracts - r.GET("/contracts/statuses", controllers.GetContractStatuses) - r.GET("/contracts", controllers.GetBuyerContracts) - r.POST("/contracts/create", controllers.CreateContract) + r.GET("/contracts/statuses", middlewares.AuthMiddleware(), controllers.GetContractStatuses) + r.GET("/contracts", middlewares.AuthMiddleware(), controllers.GetBuyerContracts) + r.POST("/contracts/create", middlewares.AuthMiddleware(), controllers.CreateContract) - r.GET("/contracts/:contract_id", controllers.GetContractByID) - r.PATCH("/contracts/:contract_id", controllers.UpdateContract) + r.GET("/contracts/:contract_id", middlewares.AuthMiddleware(), controllers.GetContractByID) + r.PATCH("/contracts/:contract_id", middlewares.AuthMiddleware(), controllers.UpdateContract) // Locations - r.GET("/locations", controllers.SearchPlace) + r.GET("/locations", middlewares.AuthMiddleware(), controllers.SearchPlace) // Notifications - r.GET("/notifications", controllers.GetNotifications) + r.GET("/notifications", middlewares.AuthMiddleware(), controllers.GetNotifications) // Stats - r.GET("/stats/measurements", controllers.GetCompanyRelatedDeviceInfoCount) - r.GET("/stats/devices", controllers.GetCompanyRelatedDeviceInfoCountWithTempRange) - r.GET("/stats/contracts", controllers.GetContractCountByStatus) - r.GET("/stats/contracts/total", controllers.GetTotalContractCount) - r.GET("/stats/invoices", controllers.GetInvoiceCountByStatus) - r.GET("/stats/milestones", controllers.GetContractsMatchingDeviceLocation) + r.GET("/stats/measurements", middlewares.AuthMiddleware(), controllers.GetCompanyRelatedDeviceInfoCount) + r.GET("/stats/devices", middlewares.AuthMiddleware(), controllers.GetCompanyRelatedDeviceInfoCountWithTempRange) + r.GET("/stats/contracts", middlewares.AuthMiddleware(), controllers.GetContractCountByStatus) + r.GET("/stats/contracts/total", middlewares.AuthMiddleware(), controllers.GetTotalContractCount) + r.GET("/stats/invoices", middlewares.AuthMiddleware(), controllers.GetInvoiceCountByStatus) + r.GET("/stats/milestones", middlewares.AuthMiddleware(), controllers.GetContractsMatchingDeviceLocation) //Users r.POST("/user/reset/password", controllers.ResetPassword)