create.go 2.28 KB
Newer Older
Loïck Bonniot's avatar
Loïck Bonniot committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
package sign

import (
	"crypto/sha512"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"time"

	"dfss/dfssc/common"
	"dfss/dfssc/security"
	"dfss/dfssp/api"
	"dfss/net"
	"golang.org/x/net/context"
)

// CreateManager handles the creation of a new contract.
//
// TODO create a specific structure containing crypto information
type CreateManager struct {
	fileCA     string
	fileCert   string
	fileKey    string
	addrPort   string
	passphrase string
	filepath   string
	comment    string
	signers    []string
	hash       string
	filename   string
}

// NewCreateManager tries to create a contract on the platform and returns an error or nil
func NewCreateManager(fileCA, fileCert, fileKey, addrPort, passphrase, filepath, comment string, signers []string) error {
	m := &CreateManager{
		fileCA:     fileCA,
		fileCert:   fileCert,
		fileKey:    fileKey,
		addrPort:   addrPort,
		passphrase: passphrase,
		filepath:   filepath,
		comment:    comment,
		signers:    signers,
	}

	err := m.computeFile()
	if err != nil {
		return err
	}

	result, err := m.sendRequest()
	if err != nil {
		return err
	}

	return common.EvaluateErrorCodeResponse(result)
}

// computeFile computes hash and filename providing the contract filepath
func (m *CreateManager) computeFile() error {
	data, err := ioutil.ReadFile(m.filepath)
	if err != nil {
		return err
	}

	hash := sha512.Sum512(data)
	m.hash = fmt.Sprintf("%x", hash)
	m.filename = filepath.Base(m.filepath)

	return nil
}

// sendRequest sends a new contract request for the platform and send it
func (m *CreateManager) sendRequest() (*api.ErrorCode, error) {
	ca, err := security.GetCertificate(m.fileCA)
	if err != nil {
		return nil, err
	}

	cert, err := security.GetCertificate(m.fileCert)
	if err != nil {
		return nil, err
	}

	key, err := security.GetPrivateKey(m.fileKey, m.passphrase)
	if err != nil {
		return nil, err
	}

	conn, err := net.Connect(m.addrPort, cert, key, ca)
	if err != nil {
		return nil, err
	}

	request := &api.PostContractRequest{
		Hash:     m.hash,
		Filename: m.filename,
		Signer:   m.signers,
		Comment:  m.comment,
	}

	client := api.NewPlatformClient(conn)
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	response, err := client.PostContract(ctx, request)
	if err != nil {
		return nil, err
	}

	return response, nil
}