Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor CoRIM display to use DisplayOptions #22

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 46 additions & 38 deletions cmd/corimDisplay.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,22 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"os"

"github.com/spf13/afero"
"github.com/spf13/cobra"

"github.com/veraison/corim/corim"
"github.com/veraison/corim/cots"
)

// displayOptions holds output and rendering configuration.
type DisplayOptions struct {
Writer io.Writer
ShowTags bool
}

var (
corimDisplayCorimFile *string
corimDisplayShowTags *bool
Expand All @@ -28,7 +37,7 @@ func NewCorimDisplayCmd() *cobra.Command {
Short: "display the content of a CoRIM as JSON",
Long: `display the content of a CoRIM as JSON

Display the contents of the signed CoRIM signed-corim.cbor
Display the contents of the signed CoRIM signed-corim.cbor

cocli corim display --file signed-corim.cbor

Expand All @@ -37,13 +46,17 @@ func NewCorimDisplayCmd() *cobra.Command {

cocli corim display --file yet-another-signed-corim.cbor --show-tags
`,

RunE: func(cmd *cobra.Command, args []string) error {
if err := checkCorimDisplayArgs(); err != nil {
return err
}

return display(*corimDisplayCorimFile, *corimDisplayShowTags)
// Prepare our display options
opts := &DisplayOptions{
Writer: os.Stdout,
ShowTags: *corimDisplayShowTags,
}
return display(*corimDisplayCorimFile, opts)
},
}

Expand All @@ -57,108 +70,103 @@ func checkCorimDisplayArgs() error {
if corimDisplayCorimFile == nil || *corimDisplayCorimFile == "" {
return errors.New("no CoRIM supplied")
}

return nil
}

func displaySignedCorim(s corim.SignedCorim, corimFile string, showTags bool) error {
// displaySignedCorim marshals the signed CoRIM to JSON and prints it.
func displaySignedCorim(s corim.SignedCorim, corimFile string, opts *DisplayOptions) error {
metaJSON, err := json.MarshalIndent(&s.Meta, "", " ")
if err != nil {
return fmt.Errorf("error encoding CoRIM Meta from %s: %w", corimFile, err)
}

fmt.Println("Meta:")
fmt.Println(string(metaJSON))
fmt.Fprintln(opts.Writer, "Meta:")
fmt.Fprintln(opts.Writer, string(metaJSON))

corimJSON, err := json.MarshalIndent(&s.UnsignedCorim, "", " ")
if err != nil {
return fmt.Errorf("error encoding unsigned CoRIM from %s: %w", corimFile, err)
}

fmt.Println("CoRIM:")
fmt.Println(string(corimJSON))
fmt.Fprintln(opts.Writer, "CoRIM:")
fmt.Fprintln(opts.Writer, string(corimJSON))

if showTags {
fmt.Println("Tags:")
displayTags(s.UnsignedCorim.Tags)
if opts.ShowTags {
fmt.Fprintln(opts.Writer, "Tags:")
displayTags(s.UnsignedCorim.Tags, opts)
}

return nil
}

func displayUnsignedCorim(u corim.UnsignedCorim, corimFile string, showTags bool) error {
// displayUnsignedCorim marshals the unsigned CoRIM to JSON and prints it.
func displayUnsignedCorim(u corim.UnsignedCorim, corimFile string, opts *DisplayOptions) error {
corimJSON, err := json.MarshalIndent(&u, "", " ")
if err != nil {
return fmt.Errorf("error encoding unsigned CoRIM from %s: %w", corimFile, err)
}

fmt.Println("Corim:")
fmt.Println(string(corimJSON))
fmt.Fprintln(opts.Writer, "Corim:")
fmt.Fprintln(opts.Writer, string(corimJSON))

if showTags {
fmt.Println("Tags:")
displayTags(u.Tags)
if opts.ShowTags {
fmt.Fprintln(opts.Writer, "Tags:")
displayTags(u.Tags, opts)
}

return nil
}

func display(corimFile string, showTags bool) error {
var (
corimCBOR []byte
err error
)

// read the CoRIM file
if corimCBOR, err = afero.ReadFile(fs, corimFile); err != nil {
// display reads the given file, decodes it as either a signed or unsigned CoRIM,
// and then calls the appropriate display function.
func display(corimFile string, opts *DisplayOptions) error {
corimCBOR, err := afero.ReadFile(fs, corimFile)
if err != nil {
return fmt.Errorf("error loading CoRIM from %s: %w", corimFile, err)
}

// try to decode as a signed CoRIM
var s corim.SignedCorim
if err = s.FromCOSE(corimCBOR); err == nil {
// successfully decoded as signed CoRIM
return displaySignedCorim(s, corimFile, showTags)
return displaySignedCorim(s, corimFile, opts)
}

// if decoding as signed CoRIM failed, attempt to decode as unsigned CoRIM
var u corim.UnsignedCorim
if err = u.FromCBOR(corimCBOR); err != nil {
return fmt.Errorf("error decoding CoRIM (signed or unsigned) from %s: %w", corimFile, err)
}

// successfully decoded as unsigned CoRIM
return displayUnsignedCorim(u, corimFile, showTags)
return displayUnsignedCorim(u, corimFile, opts)
}

// displayTags processes and displays embedded tags within a CoRIM.
func displayTags(tags []corim.Tag) {
// displayTags loops over each tag, identifies its type, and prints the JSON.
func displayTags(tags []corim.Tag, opts *DisplayOptions) {
for i, t := range tags {
if len(t) < 4 {
fmt.Printf(">> skipping malformed tag at index %d\n", i)
fmt.Fprintf(opts.Writer, ">> skipping malformed tag at index %d\n", i)
continue
}

// Split tag identifier from data
cborTag, cborData := t[:3], t[3:]

hdr := fmt.Sprintf(">> [ %d ]", i)

switch {
case bytes.Equal(cborTag, corim.ComidTag):
if err := printComid(cborData, hdr); err != nil {
fmt.Printf(">> skipping malformed CoMID tag at index %d: %v\n", i, err)
fmt.Fprintf(opts.Writer, ">> skipping malformed CoMID tag at index %d: %v\n", i, err)
}
case bytes.Equal(cborTag, corim.CoswidTag):
if err := printCoswid(cborData, hdr); err != nil {
fmt.Printf(">> skipping malformed CoSWID tag at index %d: %v\n", i, err)
fmt.Fprintf(opts.Writer, ">> skipping malformed CoSWID tag at index %d: %v\n", i, err)
}
case bytes.Equal(cborTag, cots.CotsTag):
if err := printCots(cborData, hdr); err != nil {
fmt.Printf(">> skipping malformed CoTS tag at index %d: %v\n", i, err)
fmt.Fprintf(opts.Writer, ">> skipping malformed CoTS tag at index %d: %v\n", i, err)
}
default:
fmt.Printf(">> unmatched CBOR tag: %x\n", cborTag)
fmt.Fprintf(opts.Writer, ">> unmatched CBOR tag: %x\n", cborTag)
}
}
}
Expand Down
Loading