upstream sync
This commit is contained in:
@@ -248,7 +248,7 @@ func GetContractByID(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fetch contract
|
// Fetch contract
|
||||||
contract, st, err := contract.GetContractByID(contractID)
|
contract, st, err := contract.GetContractByID(uint(contractID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(st, gin.H{"error": err.Error()})
|
c.JSON(st, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
|
"gitlab.com/pactual1/backend/config"
|
||||||
"gitlab.com/pactual1/backend/database/contract"
|
"gitlab.com/pactual1/backend/database/contract"
|
||||||
"gitlab.com/pactual1/backend/database/device"
|
"gitlab.com/pactual1/backend/database/device"
|
||||||
"gitlab.com/pactual1/backend/models"
|
"gitlab.com/pactual1/backend/models"
|
||||||
|
"gitlab.com/pactual1/backend/services/blockchain"
|
||||||
"gitlab.com/pactual1/backend/shared"
|
"gitlab.com/pactual1/backend/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -37,18 +42,18 @@ func SaveDeviceInfo(c *gin.Context) {
|
|||||||
if err := shared.GetDb().Unscoped().Where("device_id = ?", deviceInfo.ExternalDeviceID).First(&device).Error; err != nil {
|
if err := shared.GetDb().Unscoped().Where("device_id = ?", deviceInfo.ExternalDeviceID).First(&device).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
// Create new device
|
// Create new device
|
||||||
newDevice := models.Device{
|
device = models.Device{
|
||||||
IMEI: deviceInfo.IMEI,
|
IMEI: deviceInfo.IMEI,
|
||||||
IMSI: deviceInfo.IMSI,
|
IMSI: deviceInfo.IMSI,
|
||||||
DeviceID: deviceInfo.ExternalDeviceID,
|
DeviceID: deviceInfo.ExternalDeviceID,
|
||||||
DeviceConfiguration: string(rawData),
|
DeviceConfiguration: string(rawData),
|
||||||
}
|
}
|
||||||
if err := shared.GetDb().Create(&newDevice).Error; err != nil {
|
if err := shared.GetDb().Create(&device).Error; err != nil {
|
||||||
log.Printf("CREATE -Device DB Error: %v", err)
|
log.Printf("CREATE -Device DB Error: %v", err)
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not create new device"})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not create new device"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
deviceInfo.DeviceID = newDevice.ID
|
deviceInfo.DeviceID = device.ID
|
||||||
} else {
|
} else {
|
||||||
log.Printf("CREATE -Device DB Error: %v", err)
|
log.Printf("CREATE -Device DB Error: %v", err)
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
||||||
@@ -76,6 +81,33 @@ func SaveDeviceInfo(c *gin.Context) {
|
|||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not save device info"})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not save device info"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if device.CurrentContractID != nil {
|
||||||
|
deviceContract, _, err := contract.GetContractByID(*device.CurrentContractID)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("SaveDeviceInfo - GetContractByID error : %v", err)
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not fetch device contract"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if deviceContract.Status == models.ContractStatusActive {
|
||||||
|
deviceInfoBytes, _ := json.Marshal(deviceInfo)
|
||||||
|
deviceInfoEncryptedStr, err := shared.NewEncryptionClient(config.AppConfig.Service.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"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = blockchain.NewService(config.AppConfig.Blockchain).AddIOTData(context.Background(), shared.CovertUintToByte32(deviceContract.ID), shared.CovertUintToByte32(device.ID), big.NewInt(time.Now().Unix()), []byte(deviceInfoEncryptedStr))
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("SaveDeviceInfo CREATE -DeviceInfo Blockchain Error: %v", err)
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not save device info in blockchain"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log.Printf("Successfully received and saved device info: %v", deviceInfo)
|
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})
|
c.JSON(http.StatusOK, gin.H{"message": "Successfully received and saved device info", "data": deviceInfo})
|
||||||
}
|
}
|
||||||
@@ -105,8 +137,7 @@ func GetDeviceData(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
contract, st, err := contract.GetContractByID(contractID)
|
contract, st, err := contract.GetContractByID(uint(contractID))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(st, gin.H{"error": err.Error()})
|
c.JSON(st, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package contract
|
package contract
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -9,8 +10,10 @@ import (
|
|||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
|
"gitlab.com/pactual1/backend/config"
|
||||||
"gitlab.com/pactual1/backend/database/device"
|
"gitlab.com/pactual1/backend/database/device"
|
||||||
"gitlab.com/pactual1/backend/models"
|
"gitlab.com/pactual1/backend/models"
|
||||||
|
"gitlab.com/pactual1/backend/services/blockchain"
|
||||||
"gitlab.com/pactual1/backend/shared"
|
"gitlab.com/pactual1/backend/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -128,6 +131,12 @@ func UpdateContract(contract models.Contract) (models.Contract, int, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get old contract to compare updates
|
||||||
|
oldContract, status, err := GetContractByID(contract.ID)
|
||||||
|
if err != nil {
|
||||||
|
return contract, status, err
|
||||||
|
}
|
||||||
|
|
||||||
err = shared.GetDb().Transaction(func(tx *gorm.DB) error {
|
err = shared.GetDb().Transaction(func(tx *gorm.DB) error {
|
||||||
// Update contract
|
// Update contract
|
||||||
if err := tx.Model(contract).Updates(contract).Error; err != nil {
|
if err := tx.Model(contract).Updates(contract).Error; err != nil {
|
||||||
@@ -151,14 +160,48 @@ func UpdateContract(contract models.Contract) (models.Contract, int, error) {
|
|||||||
return contract, http.StatusInternalServerError, err
|
return contract, http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetContractByID(uint64(contract.ID))
|
contract, status, err = GetContractByID(contract.ID)
|
||||||
|
if err != nil {
|
||||||
|
return contract, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create contract in blockchain only when it is signed
|
||||||
|
if oldContract.Status != contract.Status && contract.Status == models.ContractStatusSigned {
|
||||||
|
err = blockchain.NewService(config.AppConfig.Blockchain).CreateContract(context.Background(), shared.CovertUintToByte32(contract.ID))
|
||||||
|
if err != nil {
|
||||||
|
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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return contract, status, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateContractDevices(contractID uint, devices []models.Device) (int, error) {
|
func validateContractDevices(contractID uint, devices []models.Device) (int, error) {
|
||||||
|
|
||||||
for _, device := range devices {
|
for _, device := range devices {
|
||||||
if device.CurrentContractID != nil && *device.CurrentContractID != contractID {
|
if device.CurrentContractID != nil && *device.CurrentContractID != contractID {
|
||||||
currentDeviceContract, status, err := GetContractByID(uint64(*device.CurrentContractID))
|
currentDeviceContract, status, err := GetContractByID(*device.CurrentContractID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return status, err
|
return status, err
|
||||||
}
|
}
|
||||||
@@ -173,7 +216,7 @@ func validateContractDevices(contractID uint, devices []models.Device) (int, err
|
|||||||
return http.StatusOK, nil
|
return http.StatusOK, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetContractByID(contractID uint64) (models.Contract, int, error) {
|
func GetContractByID(contractID uint) (models.Contract, int, error) {
|
||||||
|
|
||||||
// Fetch the contract creation date based on contractID
|
// Fetch the contract creation date based on contractID
|
||||||
var contract models.Contract
|
var contract models.Contract
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func NewService(blockchainConfig config.Blockchain) Service {
|
|||||||
type Service interface {
|
type Service interface {
|
||||||
CreateContract(ctx context.Context, contractID [32]byte) error
|
CreateContract(ctx context.Context, contractID [32]byte) error
|
||||||
AddIOTData(ctx context.Context, contractID [32]byte, deviceID [32]byte, timestamp *big.Int, data []byte) error
|
AddIOTData(ctx context.Context, contractID [32]byte, deviceID [32]byte, timestamp *big.Int, data []byte) error
|
||||||
RegisterNewDeviceIDs(ctx context.Context, contractID [32]byte, deviceIDs [][32]byte) error
|
RegisterNewDeviceID(ctx context.Context, contractID [32]byte, deviceID [32]byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) signerFunc(address common.Address, txn *types.Transaction) (*types.Transaction, error) {
|
func (s *service) signerFunc(address common.Address, txn *types.Transaction) (*types.Transaction, error) {
|
||||||
@@ -100,13 +100,13 @@ func (s *service) CreateContract(ctx context.Context, contractID [32]byte) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// map devices with blockchain contract
|
// map devices with blockchain contract
|
||||||
func (s *service) RegisterNewDeviceIDs(ctx context.Context, contractID [32]byte, deviceIDs [][32]byte) error {
|
func (s *service) RegisterNewDeviceID(ctx context.Context, contractID [32]byte, deviceID [32]byte) error {
|
||||||
conn, contract, err := s.getClient(ctx)
|
conn, contract, err := s.getClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
txn, err := contract.RegisterNewDeviceIds(s.getTransactOpts(), contractID, deviceIDs)
|
txn, err := contract.RegisterNewDeviceId(s.getTransactOpts(), contractID, deviceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,17 @@ import (
|
|||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func CovertUintToByte32(id uint) [32]byte {
|
||||||
|
b := make([]byte, 32)
|
||||||
|
binary.LittleEndian.PutUint32(b, uint32(id))
|
||||||
|
return [32]byte(b)
|
||||||
|
}
|
||||||
|
|
||||||
type EncryptionClient interface {
|
type EncryptionClient interface {
|
||||||
Encrypt(string) (string, error)
|
Encrypt(string) (string, error)
|
||||||
Decrypt(string) (string, error)
|
Decrypt(string) (string, error)
|
||||||
|
|||||||
Reference in New Issue
Block a user