package main import ( "errors" "fmt" "strings" "github.com/AlecAivazis/survey" "github.com/safing/jess" ) func newEnvelope(name string) (*jess.Envelope, error) { // check name name = strings.TrimSpace(name) if name == "" { return nil, errors.New("missing envelope name") } // start init process envelope := jess.NewUnconfiguredEnvelope() envelope.Name = name // preset menu var preset string prompt := &survey.Select{ Message: "Select preset:", Options: []string{ "Encrypt with password", "Encrypt with keyfile", "Encrypt for someone", "Sign a file", "Custom from scratch", }, } err := survey.AskOne(prompt, &preset, nil) if err != nil { return nil, err } switch preset { case "Encrypt with password": envelope.Tools = jess.RecommendedStoragePassword err = selectSignets(envelope, "pw") case "Encrypt with keyfile": envelope.Tools = jess.RecommendedStorageKey err = selectSignets(envelope, "key") case "Encrypt for someone": envelope.Tools = jess.RecommendedStorageKey err = selectSignets(envelope, "recipient") if err == nil { err = selectSignets(envelope, "sender") } case "Sign a file": envelope.NoConfidentiality().NoIntegrity().NoRecipientAuth() err = selectSignets(envelope, "sender") case "Custom from scratch": // do nothing } if err != nil { return nil, err } return envelope, nil } func editEnvelope(envelope *jess.Envelope) error { for { // main menu // print envelope status session, err := envelope.Correspondence(trustStore) if err != nil { fmt.Printf("Envelope status: %s\n", err) } else { fmt.Println("Envelope status: valid.") envelope.MinimumSecurityLevel = session.SecurityLevel } // sub menu var submenu string prompt := &survey.Select{ Message: "Select to edit", Options: formatColumns([][]string{ {"Done", "save and return"}, {" "}, {"Requirements", formatRequirements(envelope)}, {"Tools", strings.Join(envelope.Tools, ", ")}, {"Secrets", formatSignetNames(envelope.Secrets)}, {"Recipients", formatSignetNames(envelope.Recipients)}, {"Senders", formatSignetNames(envelope.Senders)}, {" "}, {"Abort", "discard changes and return"}, {"Delete", "delete and return"}, }), PageSize: 10, } err = survey.AskOne(prompt, &submenu, nil) if err != nil { return err } switch { case strings.HasPrefix(submenu, "Done"): // save return trustStore.StoreEnvelope(envelope) case strings.HasPrefix(submenu, "Abort"): return nil case strings.HasPrefix(submenu, "Delete"): return trustStore.DeleteEnvelope(envelope.Name) case strings.HasPrefix(submenu, "Requirements"): err = editEnvelopeRequirements(envelope) case strings.HasPrefix(submenu, "Tools"): err = editEnvelopeTools(envelope) case strings.HasPrefix(submenu, "Secrets"): err = selectSignets(envelope, "pw/key") case strings.HasPrefix(submenu, "Recipients"): err = selectSignets(envelope, "recipient") case strings.HasPrefix(submenu, "Senders"): err = selectSignets(envelope, "sender") } if err != nil { return err } } } func editEnvelopeRequirements(envelope *jess.Envelope) error { // TODO: improve // get reqs requirements := envelope.Requirements() if requirements == nil { return errors.New("envelope requirements uninitialized") } // build defaults var defaults []string if requirements.Has(jess.Confidentiality) { defaults = append(defaults, "Confidentiality") } if requirements.Has(jess.Integrity) { defaults = append(defaults, "Integrity") } if requirements.Has(jess.RecipientAuthentication) { defaults = append(defaults, "Recipient Authentication") } if requirements.Has(jess.SenderAuthentication) { defaults = append(defaults, "Sender Authentication") } // prompt var selected []string prompt := &survey.MultiSelect{ Message: "Select requirements:", Options: []string{ "Confidentiality", "Integrity", "Recipient Authentication", "Sender Authentication", }, Default: defaults, } err := survey.AskOne(prompt, &selected, nil) if err != nil { return err } // parse requirements.Remove(jess.Confidentiality) requirements.Remove(jess.Integrity) requirements.Remove(jess.RecipientAuthentication) requirements.Remove(jess.SenderAuthentication) for _, req := range selected { switch req { case "Confidentiality": requirements.Add(jess.Confidentiality) case "Integrity": requirements.Add(jess.Integrity) case "Recipient Authentication": requirements.Add(jess.RecipientAuthentication) case "Sender Authentication": requirements.Add(jess.SenderAuthentication) } } return nil } func editEnvelopeTools(envelope *jess.Envelope) (err error) { envelope.Tools, err = pickTools(envelope.Tools, "Select tools:") return err }