diff --git a/config/config.go b/config/config.go index 83774b2..fcc9bea 100644 --- a/config/config.go +++ b/config/config.go @@ -25,7 +25,6 @@ func Load() error { // 9000 DEFAULT FOR DEV ENVIRONMENT Port: getEnv("NOVATECH_SERVICE_PORT", "9000"), Environment: getEnv("NOVATECH_SERVICE_ENVIRONMENT", "DEV"), - BlockchainSecret: getEnv("NOVATECH_SERVICE_BLOCKCHAIN_SECRET", "novatech_service_blockchain_secret"), MapboxAccessToken: getEnv("NOVATECH_SERVICE_MAPBOX_ACCESS_TOKEN", ""), }, AdminService: Service{ diff --git a/config/models.go b/config/models.go index 5c7148e..d04ac26 100644 --- a/config/models.go +++ b/config/models.go @@ -13,7 +13,6 @@ type Service struct { Port string Environment string WebPageURL string - BlockchainSecret string MapboxAccessToken string } diff --git a/controllers/contracts_controller.go b/controllers/contracts_controller.go index 98d3750..86a8dba 100644 --- a/controllers/contracts_controller.go +++ b/controllers/contracts_controller.go @@ -14,6 +14,10 @@ import ( "gitlab.com/pactual1/backend/shared" ) +const ( + BlockchainSecretLength = 16 +) + func GetLatestContracts(c *gin.Context) { // Existing parameters limitStr := c.DefaultQuery("limit", "50") @@ -200,24 +204,25 @@ func CreateContract(c *gin.Context) { db := shared.GetDb() newContract := models.Contract{ - BuyerID: payload.BuyerID, - SellerID: payload.SellerID, - Description: payload.Description, - ProductID: payload.ProductID, - MinTemp: payload.MinTemp, - MaxTemp: payload.MaxTemp, - ArrivalDate: time.Unix(payload.ArrivalDate, 0), - PenaltyType: payload.PenaltyType, - PenaltyValue: payload.PenaltyValue, - PenaltyRec: payload.PenaltyRec, - StartLat: payload.StartLat, - StartLon: payload.StartLon, - Status: models.ContractStatusDraft, - StartPlaceName: payload.StartPlaceName, - EndPlaceName: payload.EndPlaceName, - Name: payload.Name, - EndLat: payload.EndLat, - EndLon: payload.EndLon, + BuyerID: payload.BuyerID, + SellerID: payload.SellerID, + Description: payload.Description, + ProductID: payload.ProductID, + MinTemp: payload.MinTemp, + MaxTemp: payload.MaxTemp, + ArrivalDate: time.Unix(payload.ArrivalDate, 0), + PenaltyType: payload.PenaltyType, + PenaltyValue: payload.PenaltyValue, + PenaltyRec: payload.PenaltyRec, + StartLat: payload.StartLat, + StartLon: payload.StartLon, + Status: models.ContractStatusPending, + StartPlaceName: payload.StartPlaceName, + EndPlaceName: payload.EndPlaceName, + Name: payload.Name, + EndLat: payload.EndLat, + EndLon: payload.EndLon, + BlockchainSecret: shared.GenerateRandomString(BlockchainSecretLength), } if err := db.Create(&newContract).Error; err != nil { diff --git a/controllers/devices_controller.go b/controllers/devices_controller.go index 4b4aac3..302caf8 100644 --- a/controllers/devices_controller.go +++ b/controllers/devices_controller.go @@ -46,7 +46,16 @@ func SaveDeviceInfo(c *gin.Context) { if deviceContract.Status == models.ContractStatusActive { deviceInfoBytes, _ := json.Marshal(deviceInfo) - deviceInfoEncryptedStr, err := shared.NewEncryptionClient(config.AppConfig.Service.BlockchainSecret).Encrypt(string(deviceInfoBytes)) + if deviceContract.BlockchainSecret == "" { + deviceContract.BlockchainSecret = shared.GenerateRandomString(BlockchainSecretLength) + _, _, err := contract.UpdateContract(deviceContract) + if err != nil { + log.Printf("SaveDeviceInfo Update Contract error: %v", err) + c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not update contract secret"}) + return + } + } + deviceInfoEncryptedStr, err := shared.NewEncryptionClient(deviceContract.BlockchainSecret).Encrypt(string(deviceInfoBytes)) if err != nil { log.Printf("SaveDeviceInfo - Enrypt error : %v", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not encrypt device info"}) diff --git a/database/contract/contract.go b/database/contract/contract.go index d0b7241..0076788 100644 --- a/database/contract/contract.go +++ b/database/contract/contract.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "net/http" + "strings" "time" "github.com/jinzhu/gorm" @@ -63,8 +64,8 @@ func GetContracts(status []string, companyName string, companyAddress string, // Search by Contract Name if contractName != "" { - db = db.Where("contracts.name LIKE ?", "%"+contractName+"%") - countDb = countDb.Where("contracts.name LIKE ?", "%"+contractName+"%") + db = db.Where("lower(contracts.name) LIKE ?", "%"+strings.ToLower(contractName)+"%") + countDb = countDb.Where("lower(contracts.name) LIKE ?", "%"+strings.ToLower(contractName)+"%") } // Search by Start Time and End Time @@ -146,7 +147,7 @@ func UpdateContract(contract models.Contract) (models.Contract, int, error) { if devices != nil { // Update devices - if err := tx.Model(models.Device{}).Where("id IN (?)", contract.DeviceIDs).Updates(models.Device{CurrentContractID: &contract.ID}).Error; err != nil { + if err := tx.Model(models.Device{}).Where("id IN (?)", []int64(contract.DeviceIDs)).Updates(models.Device{CurrentContractID: &contract.ID}).Error; err != nil { log.Printf("UpdateContract Error: Could not update devices: %v", err) return err } @@ -172,24 +173,13 @@ func UpdateContract(contract models.Contract) (models.Contract, int, error) { log.Printf("UpdateContract Error: Could not create contract in blockchain: %v", err) return contract, http.StatusInternalServerError, err } - } - if contract.Status == models.ContractStatusSigned { - // Register devices in blockchain if contract is signed + // Register devices in blockchain when contract is signed for _, device := range devices { - var found bool - for _, deviceID := range oldContract.DeviceIDs { - if device.ID == uint(deviceID) { - found = true - break - } - } - if !found { - err = blockchain.NewService(config.AppConfig.Blockchain).RegisterNewDeviceID(context.Background(), shared.CovertUintToByte32(contract.ID), shared.CovertUintToByte32(device.ID)) - if err != nil { - log.Printf("UpdateContract Error: Could not register contract device in blockchain: %v", err) - return contract, http.StatusInternalServerError, err - } + err = blockchain.NewService(config.AppConfig.Blockchain).RegisterNewDeviceID(context.Background(), shared.CovertUintToByte32(contract.ID), shared.CovertUintToByte32(device.ID)) + if err != nil { + log.Printf("UpdateContract Error: Could not register contract device in blockchain: %v", err) + return contract, http.StatusInternalServerError, err } } } diff --git a/main.go b/main.go index a9bcc36..f2eaef2 100644 --- a/main.go +++ b/main.go @@ -8,8 +8,6 @@ import ( "gitlab.com/pactual1/backend/config" "gitlab.com/pactual1/backend/models" "gitlab.com/pactual1/backend/routes" - "gitlab.com/pactual1/backend/services/blockchain" - "gitlab.com/pactual1/backend/services/contract" "gitlab.com/pactual1/backend/services/erp" "gitlab.com/pactual1/backend/services/messaging" "gitlab.com/pactual1/backend/shared" @@ -75,11 +73,6 @@ func main() { go messagingService.MessagingService() go erp.ERPService(erpChannel) - encryptionClient := shared.NewEncryptionClient(config.AppConfig.Service.BlockchainSecret) - blockchainClient := blockchain.NewService(config.AppConfig.Blockchain) - contractService := contract.NewService(contractChannel, shared.GetDb(), encryptionClient, blockchainClient) - go contractService.ContractService() - // Sending messages via channels // messagingChannel <- "Send an email" erpChannel <- "Update ERP record" diff --git a/models/contract.go b/models/contract.go index 5f0e0ad..4ba3d7b 100644 --- a/models/contract.go +++ b/models/contract.go @@ -8,34 +8,34 @@ import ( type Contract struct { BaseModel - Name string `json:"name"` - DeviceIDs pq.Int64Array `json:"deviceIds" gorm:"type:integer[]"` - BuyerID uint `json:"buyerId"` - SellerID uint `json:"sellerId"` - Description string `json:"description"` - StartPlaceName string `json:"startPlaceName"` - StartLat float64 `json:"startLat"` - StartLon float64 `json:"startLon"` - EndPlaceName string `json:"endPlaceName"` - EndLat float64 `json:"endLat"` - EndLon float64 `json:"endLon"` - StartTime time.Time `json:"startTime"` - EndTime time.Time `json:"endTime"` - Status string `json:"status"` - BlockchainID string `json:"blockchainId"` - ContractInfos []ContractInfo `json:"contractInfos"` - ProductID uint `json:"productId"` - TemplateID uint `json:"templateId"` - MaxTemp float64 `json:"maxTemp"` - MinTemp float64 `json:"minTemp"` - ArrivalDate time.Time `json:"arrivalDate"` - PenaltyType string `json:"penaltyType"` - PenaltyValue int `json:"penaltyValue"` - PenaltyRec string `json:"penaltyRec"` - BuyerName string `json:"buyerName" gorm:"-"` - SellerName string `json:"sellerName" gorm:"-"` - ProductName string `json:"productName" gorm:"-"` - NumberOfDevices int `json:"numberOfDevices" gorm:"-"` + Name string `json:"name"` + DeviceIDs pq.Int64Array `json:"deviceIds" gorm:"type:integer[]"` + BuyerID uint `json:"buyerId"` + SellerID uint `json:"sellerId"` + Description string `json:"description"` + StartPlaceName string `json:"startPlaceName"` + StartLat float64 `json:"startLat"` + StartLon float64 `json:"startLon"` + EndPlaceName string `json:"endPlaceName"` + EndLat float64 `json:"endLat"` + EndLon float64 `json:"endLon"` + StartTime time.Time `json:"startTime"` + EndTime time.Time `json:"endTime"` + Status string `json:"status"` + BlockchainSecret string `json:"blockchainSecret"` + ContractInfos []ContractInfo `json:"contractInfos"` + ProductID uint `json:"productId"` + TemplateID uint `json:"templateId"` + MaxTemp float64 `json:"maxTemp"` + MinTemp float64 `json:"minTemp"` + ArrivalDate time.Time `json:"arrivalDate"` + PenaltyType string `json:"penaltyType"` + PenaltyValue int `json:"penaltyValue"` + PenaltyRec string `json:"penaltyRec"` + BuyerName string `json:"buyerName" gorm:"-"` + SellerName string `json:"sellerName" gorm:"-"` + ProductName string `json:"productName" gorm:"-"` + NumberOfDevices int `json:"numberOfDevices" gorm:"-"` } type DashboardContractResponse struct { @@ -164,7 +164,7 @@ func ConvertContractToContractResponse(contract Contract) ContractResponse { }, Description: contract.Description, Status: contract.Status, - BlockchainID: contract.BlockchainID, + BlockchainID: contract.BlockchainSecret, ContractInfos: contract.ContractInfos, MaxTemp: contract.MaxTemp, MinTemp: contract.MinTemp, @@ -198,7 +198,7 @@ func ConvertContractToDashboardResponse(contracts []Contract) []DashboardContrac StartTime: contract.StartTime, EndTime: contract.EndTime, Status: contract.Status, - BlockchainID: contract.BlockchainID, + BlockchainID: contract.BlockchainSecret, ContractInfos: contract.ContractInfos, ProductID: contract.ProductID, MaxTemp: contract.MaxTemp, @@ -236,6 +236,7 @@ func ConvertContractToListResponse(contracts []Contract) []ListContractResponse Status: KeyValue{Key: status.Key, Value: status.Value}, Buyer: CompanyShortResponse{ID: int(contract.BuyerID), Name: contract.BuyerName}, ContractID: int(contract.ID), + ContractName: contract.Name, DateCreated: contract.CreatedAt, NumberOfDevices: contract.NumberOfDevices, } @@ -280,6 +281,7 @@ type ListContractResponse struct { Status KeyValue `json:"status"` Buyer CompanyShortResponse `json:"buyer"` ContractID int `json:"contractID"` + ContractName string `json:"contractName"` NumberOfDevices int `json:"numberOfDevices"` DateCreated time.Time `json:"dateCreated"` } diff --git a/shared/encryption.go b/shared/encryption.go index 4468d59..a52b3a8 100644 --- a/shared/encryption.go +++ b/shared/encryption.go @@ -12,6 +12,15 @@ import ( "io" ) +func GenerateRandomString(length int) string { + b := make([]byte, length) + _, err := rand.Read(b) + if err != nil { + panic(err) + } + return base64.StdEncoding.EncodeToString(b) +} + func CovertUintToByte32(id uint) [32]byte { b := make([]byte, 32) binary.LittleEndian.PutUint32(b, uint32(id))