Commit 956984e4 authored by Loïck Bonniot's avatar Loïck Bonniot

[c] Add `fetch` command

parent 13dd77aa
Pipeline #614 passed with stage
......@@ -7,7 +7,7 @@ import (
"dfss/dfssc/user"
)
func authUser() {
func authUser(_ []string) {
fmt.Println("Authenticating user")
var mail, token string
......
package main
import (
"fmt"
"os"
"path/filepath"
"dfss/dfssc/sign"
)
func fetchContract(_ []string) {
fmt.Println("Fetching a saved contract")
var passphrase, uuid, directory string
_ = readPassword(&passphrase, false)
readStringParam("Contract UUID", "", &uuid)
readStringParam("Save directory", ".", &directory)
path := filepath.Join(directory, uuid+".json")
err := sign.FetchContract(fca, fcert, fkey, addrPort, passphrase, uuid, path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
......@@ -7,7 +7,8 @@ import (
)
// export the certificate and private key of the user
func exportConf(confFile string) {
func exportConf(args []string) {
confFile := args[0]
fmt.Println("Export user configuration")
var keyPassphrase, confPassphrase string
......@@ -52,7 +53,8 @@ func readPassphrases(keyPassphrase, confPassphrase *string, second bool) error {
}
// import the configuration
func importConf(confFile string) {
func importConf(args []string) {
confFile := args[0]
var keyPassphrase, confPassphrase string
err := readPassphrases(&keyPassphrase, &confPassphrase, false)
if err != nil {
......
......@@ -38,6 +38,7 @@ func init() {
fmt.Println(" register register a new client")
fmt.Println(" auth authenticate a new client")
fmt.Println(" new create a new contract")
fmt.Println(" fetch get a contract hosted on the platform")
fmt.Println(" show <c> print contract information from file c")
fmt.Println(" export <c> export certificate and private key of the user to file c")
fmt.Println(" import <c> import private key and certificate from file c")
......@@ -50,29 +51,36 @@ func init() {
}
}
type command struct {
nbArgs int
fn func([]string)
}
var commands = map[string]command{
"version": command{0, func([]string) {
fmt.Println("v"+dfss.Version, runtime.GOOS, runtime.GOARCH)
}},
"register": command{0, registerUser},
"auth": command{0, authUser},
"new": command{0, newContract},
"fetch": command{0, fetchContract},
"show": command{1, showContract},
"export": command{1, exportConf},
"import": command{1, importConf},
"sign": command{1, signContract},
}
func main() {
flag.Parse()
arg := flag.Arg(0)
c, ok := commands[arg]
command := flag.Arg(0)
switch command {
case "version":
fmt.Println("v"+dfss.Version, runtime.GOOS, runtime.GOARCH)
case "register":
registerUser()
case "auth":
authUser()
case "new":
newContract()
case "show":
showContract(flag.Arg(1))
case "export":
exportConf(flag.Arg(1))
case "import":
importConf(flag.Arg(1))
case "sign":
signContract(flag.Arg(1))
default:
if !ok || flag.NArg()-1 < c.nbArgs {
flag.Usage()
return
}
args := flag.Args()
args = append(args, "")
c.fn(args[1:])
}
......@@ -7,7 +7,7 @@ import (
"dfss/dfssc/sign"
)
func newContract() {
func newContract(_ []string) {
fmt.Println("Creating a new contract")
passphrase, filepath, comment, signers := getContractInfo()
......
......@@ -13,7 +13,7 @@ import (
"golang.org/x/crypto/ssh/terminal"
)
func registerUser() {
func registerUser(_ []string) {
fmt.Println("Registering a new user")
// Initialize variables
var country, mail, organization, unit, passphrase string
......
......@@ -22,8 +22,7 @@ Signers :
{{range .Signers}} - {{.Email}}
{{end}}`
func showContract(filename string) *contract.JSON {
func getContract(filename string) *contract.JSON {
data, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Println("Cannot open file:", err)
......@@ -35,19 +34,26 @@ func showContract(filename string) *contract.JSON {
fmt.Println("Corrupted file:", err)
return nil
}
return c
}
func showContract(args []string) {
filename := args[0]
c := getContract(filename)
if c == nil {
return
}
b := new(bytes.Buffer)
tmpl, err := template.New("contract").Parse(contractShowTemplate)
if err != nil {
fmt.Println("Internal error:", err)
return nil
return
}
b := new(bytes.Buffer)
err = tmpl.Execute(b, c)
if err != nil {
fmt.Println("Cannot print contract:", err)
}
fmt.Print(b.String())
return c
}
......@@ -7,9 +7,10 @@ import (
"dfss/dfssc/sign"
)
func signContract(filename string) {
func signContract(args []string) {
filename := args[0]
fmt.Println("You are going to sign the following contract:")
contract := showContract(filename)
contract := getContract(filename)
if contract == nil {
os.Exit(1)
}
......
......@@ -52,11 +52,9 @@ func TestNewCreateManager(t *testing.T) {
}
func TestComputeFile(t *testing.T) {
m := &CreateManager{filepath: fcontract}
err := m.computeFile()
assert.Equal(t, nil, err)
assert.Equal(t, "37fd29decfb2d689439478b1f64b60441534c1e373a7023676c94ac6772639edab46f80139d167a2741f159e62b3064eca58bb331d32cd10770f29064af2a9de", fmt.Sprintf("%x", m.hash))
assert.Equal(t, "contract.txt", m.filename)
}
package sign
import (
"io/ioutil"
"time"
"dfss/dfssc/common"
"dfss/dfssc/security"
"dfss/dfssp/api"
"dfss/net"
"golang.org/x/net/context"
)
// FetchContract tries to download contract metadata from specified uuid, and stores the resulting json at path
func FetchContract(fileCA, fileCert, fileKey, addrPort, passphrase, uuid, path string) error {
auth := security.NewAuthContainer(fileCA, fileCert, fileKey, addrPort, passphrase)
ca, cert, key, err := auth.LoadFiles()
if err != nil {
return err
}
conn, err := net.Connect(auth.AddrPort, cert, key, ca)
if err != nil {
return err
}
request := &api.GetContractRequest{
Uuid: uuid,
}
client := api.NewPlatformClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
response, err := client.GetContract(ctx, request)
if err != nil {
return err
}
err = common.EvaluateErrorCodeResponse(response.ErrorCode)
if err != nil {
return err
}
return ioutil.WriteFile(path, response.Json, 0600)
}
package sign
import (
"fmt"
"io/ioutil"
"os"
"testing"
"github.com/bmizerany/assert"
)
func TestFetchContract(t *testing.T) {
checkFetchResult(t, "01", false, "Hello")
}
func TestFetchContractWrongUUID(t *testing.T) {
checkFetchResult(t, "02", true, "")
}
func checkFetchResult(t *testing.T, uuid string, errExpected bool, content string) {
file, _ := ioutil.TempFile("", "")
defer func() { _ = os.Remove(file.Name()) }()
err := FetchContract(fca, fcert, fkey, addrPort, "password", uuid, file.Name())
if errExpected {
assert.NotEqual(t, nil, err)
} else {
assert.Equal(t, nil, err)
}
data, _ := ioutil.ReadFile(file.Name())
assert.Equal(t, content, fmt.Sprintf("%s", data))
}
package fixtures
import (
"dfss/dfssp/api"
)
var FetchFixture map[string]*api.Contract = map[string]*api.Contract{
"01": &api.Contract{
ErrorCode: &api.ErrorCode{Code: api.ErrorCode_SUCCESS},
Json: []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f}, // Hello
},
"02": &api.Contract{
ErrorCode: &api.ErrorCode{Code: api.ErrorCode_BADAUTH},
},
"03": &api.Contract{
ErrorCode: &api.ErrorCode{Code: api.ErrorCode_INVARG},
},
}
......@@ -53,8 +53,7 @@ func (s *mockServer) PostContract(ctx context.Context, in *api.PostContractReque
//
// Handle incoming GetContractRequest messages
func (s *mockServer) GetContract(ctx context.Context, in *api.GetContractRequest) (*api.Contract, error) {
// TODO
return nil, nil
return fixtures.FetchFixture[in.Uuid], nil
}
// JoinSignature handler
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment