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 ( ...@@ -7,7 +7,7 @@ import (
"dfss/dfssc/user" "dfss/dfssc/user"
) )
func authUser() { func authUser(_ []string) {
fmt.Println("Authenticating user") fmt.Println("Authenticating user")
var mail, token string 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 ( ...@@ -7,7 +7,8 @@ import (
) )
// export the certificate and private key of the user // 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") fmt.Println("Export user configuration")
var keyPassphrase, confPassphrase string var keyPassphrase, confPassphrase string
...@@ -52,7 +53,8 @@ func readPassphrases(keyPassphrase, confPassphrase *string, second bool) error { ...@@ -52,7 +53,8 @@ func readPassphrases(keyPassphrase, confPassphrase *string, second bool) error {
} }
// import the configuration // import the configuration
func importConf(confFile string) { func importConf(args []string) {
confFile := args[0]
var keyPassphrase, confPassphrase string var keyPassphrase, confPassphrase string
err := readPassphrases(&keyPassphrase, &confPassphrase, false) err := readPassphrases(&keyPassphrase, &confPassphrase, false)
if err != nil { if err != nil {
......
...@@ -38,6 +38,7 @@ func init() { ...@@ -38,6 +38,7 @@ func init() {
fmt.Println(" register register a new client") fmt.Println(" register register a new client")
fmt.Println(" auth authenticate a new client") fmt.Println(" auth authenticate a new client")
fmt.Println(" new create a new contract") 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(" 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(" 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") fmt.Println(" import <c> import private key and certificate from file c")
...@@ -50,29 +51,36 @@ func init() { ...@@ -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() { func main() {
flag.Parse() flag.Parse()
arg := flag.Arg(0)
c, ok := commands[arg]
command := flag.Arg(0) if !ok || flag.NArg()-1 < c.nbArgs {
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:
flag.Usage() flag.Usage()
return
} }
args := flag.Args()
args = append(args, "")
c.fn(args[1:])
} }
...@@ -7,7 +7,7 @@ import ( ...@@ -7,7 +7,7 @@ import (
"dfss/dfssc/sign" "dfss/dfssc/sign"
) )
func newContract() { func newContract(_ []string) {
fmt.Println("Creating a new contract") fmt.Println("Creating a new contract")
passphrase, filepath, comment, signers := getContractInfo() passphrase, filepath, comment, signers := getContractInfo()
......
...@@ -13,7 +13,7 @@ import ( ...@@ -13,7 +13,7 @@ import (
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
) )
func registerUser() { func registerUser(_ []string) {
fmt.Println("Registering a new user") fmt.Println("Registering a new user")
// Initialize variables // Initialize variables
var country, mail, organization, unit, passphrase string var country, mail, organization, unit, passphrase string
......
...@@ -22,8 +22,7 @@ Signers : ...@@ -22,8 +22,7 @@ Signers :
{{range .Signers}} - {{.Email}} {{range .Signers}} - {{.Email}}
{{end}}` {{end}}`
func showContract(filename string) *contract.JSON { func getContract(filename string) *contract.JSON {
data, err := ioutil.ReadFile(filename) data, err := ioutil.ReadFile(filename)
if err != nil { if err != nil {
fmt.Println("Cannot open file:", err) fmt.Println("Cannot open file:", err)
...@@ -35,19 +34,26 @@ func showContract(filename string) *contract.JSON { ...@@ -35,19 +34,26 @@ func showContract(filename string) *contract.JSON {
fmt.Println("Corrupted file:", err) fmt.Println("Corrupted file:", err)
return nil 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) tmpl, err := template.New("contract").Parse(contractShowTemplate)
if err != nil { if err != nil {
fmt.Println("Internal error:", err) fmt.Println("Internal error:", err)
return nil return
} }
b := new(bytes.Buffer)
err = tmpl.Execute(b, c) err = tmpl.Execute(b, c)
if err != nil { if err != nil {
fmt.Println("Cannot print contract:", err) fmt.Println("Cannot print contract:", err)
} }
fmt.Print(b.String()) fmt.Print(b.String())
return c
} }
...@@ -7,9 +7,10 @@ import ( ...@@ -7,9 +7,10 @@ import (
"dfss/dfssc/sign" "dfss/dfssc/sign"
) )
func signContract(filename string) { func signContract(args []string) {
filename := args[0]
fmt.Println("You are going to sign the following contract:") fmt.Println("You are going to sign the following contract:")
contract := showContract(filename) contract := getContract(filename)
if contract == nil { if contract == nil {
os.Exit(1) os.Exit(1)
} }
......
...@@ -52,11 +52,9 @@ func TestNewCreateManager(t *testing.T) { ...@@ -52,11 +52,9 @@ func TestNewCreateManager(t *testing.T) {
} }
func TestComputeFile(t *testing.T) { func TestComputeFile(t *testing.T) {
m := &CreateManager{filepath: fcontract} m := &CreateManager{filepath: fcontract}
err := m.computeFile() err := m.computeFile()
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
assert.Equal(t, "37fd29decfb2d689439478b1f64b60441534c1e373a7023676c94ac6772639edab46f80139d167a2741f159e62b3064eca58bb331d32cd10770f29064af2a9de", fmt.Sprintf("%x", m.hash)) assert.Equal(t, "37fd29decfb2d689439478b1f64b60441534c1e373a7023676c94ac6772639edab46f80139d167a2741f159e62b3064eca58bb331d32cd10770f29064af2a9de", fmt.Sprintf("%x", m.hash))
assert.Equal(t, "contract.txt", m.filename) 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 ...@@ -53,8 +53,7 @@ func (s *mockServer) PostContract(ctx context.Context, in *api.PostContractReque
// //
// Handle incoming GetContractRequest messages // Handle incoming GetContractRequest messages
func (s *mockServer) GetContract(ctx context.Context, in *api.GetContractRequest) (*api.Contract, error) { func (s *mockServer) GetContract(ctx context.Context, in *api.GetContractRequest) (*api.Contract, error) {
// TODO return fixtures.FetchFixture[in.Uuid], nil
return nil, nil
} }
// JoinSignature handler // 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