Skip to content

Commit 91475ec

Browse files
rayozziezfields
andauthored
Zak payload modified (#39)
* fix: Include payload in validation * fix: Remove `goto` * feat: Toggle switch for JSON validation * chore: Refactor validation enablement * fix: Address Alex's feedback * feat: pretty validation errors * cleanup * include request type * english * fix: explain esoteric string manipulation --------- Co-authored-by: Zachary J. Fields <[email protected]>
1 parent b14ccdc commit 91475ec

File tree

3 files changed

+153
-106
lines changed

3 files changed

+153
-106
lines changed

lib/config.go

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"github.com/blues/note-go/notehub"
1919
)
2020

21-
// ConfigCreds are the credentials for a given notehub
21+
// ConfigCreds are the credentials for a given Notehub
2222
type ConfigCreds struct {
2323
User string `json:"user,omitempty"`
2424
Token string `json:"token,omitempty"`
@@ -37,7 +37,6 @@ type ConfigSettings struct {
3737
HubCreds map[string]ConfigCreds `json:"creds,omitempty"`
3838
Interface string `json:"interface,omitempty"`
3939
IPort map[string]ConfigPort `json:"iport,omitempty"`
40-
SchemaUrl string `json:"json-schema-url,omitempty"`
4140
}
4241

4342
// Config are the master config settings
@@ -46,7 +45,6 @@ var configFlagHub string
4645
var configFlagInterface string
4746
var configFlagPort string
4847
var configFlagPortConfig int
49-
var configFlagJsonSchemaUrl string
5048

5149
// ConfigRead reads the current info from config file
5250
func ConfigRead() error {
@@ -105,7 +103,6 @@ func ConfigReset() {
105103
configResetInterface()
106104
ConfigSetHub("-")
107105
Config.When = time.Now().UTC().Format("2006-01-02T15:04:05Z")
108-
Config.SchemaUrl = ""
109106
}
110107

111108
// ConfigShow displays all current config parameters
@@ -138,9 +135,6 @@ func ConfigShow() error {
138135
fmt.Printf(" -portconfig %d\n", Config.IPort[Config.Interface].PortConfig)
139136
}
140137
}
141-
if Config.SchemaUrl != "" {
142-
fmt.Printf(" -json-schema-url %s\n", Config.SchemaUrl)
143-
}
144138

145139
return nil
146140

@@ -174,11 +168,6 @@ func ConfigFlagsProcess() (err error) {
174168
} else if configFlagInterface != "" {
175169
Config.Interface = configFlagInterface
176170
}
177-
if configFlagJsonSchemaUrl == "-" {
178-
Config.SchemaUrl = ""
179-
} else if configFlagJsonSchemaUrl != "" {
180-
Config.SchemaUrl = configFlagJsonSchemaUrl
181-
}
182171
if configFlagPort == "-" {
183172
temp := Config.IPort[Config.Interface]
184173
temp.Port = ""
@@ -212,13 +201,12 @@ func ConfigFlagsRegister(notecardFlags bool, notehubFlags bool) {
212201

213202
// Process the commands
214203
if notecardFlags {
215-
flag.StringVar(&configFlagInterface, "interface", "", "select 'serial' or 'i2c' interface for notecard")
216-
flag.StringVar(&configFlagJsonSchemaUrl, "json-schema-url", "", "set the schema URL for the notecard")
217-
flag.StringVar(&configFlagPort, "port", "", "select serial or i2c port for notecard")
218-
flag.IntVar(&configFlagPortConfig, "portconfig", 0, "set serial device speed or i2c address for notecard")
204+
flag.StringVar(&configFlagInterface, "interface", "", "select 'serial' or 'i2c' interface for Notecard")
205+
flag.StringVar(&configFlagPort, "port", "", "select serial or i2c port for Notecard")
206+
flag.IntVar(&configFlagPortConfig, "portconfig", 0, "set serial device speed or i2c address for Notecard")
219207
}
220208
if notehubFlags {
221-
flag.StringVar(&configFlagHub, "hub", "", "set notehub domain")
209+
flag.StringVar(&configFlagHub, "hub", "", "set Notehub domain")
222210
}
223211

224212
}
@@ -250,7 +238,6 @@ func FlagParse(notecardFlags bool, notehubFlags bool) (err error) {
250238
case "-interface":
251239
case "-port":
252240
case "-portconfig":
253-
case "-json-schema-url":
254241
case "-hub":
255242
// any odd argument that isn't one of our switches
256243
default:
@@ -271,11 +258,6 @@ func FlagParse(notecardFlags bool, notehubFlags bool) (err error) {
271258
Config.Interface = str
272259
}
273260

274-
str = os.Getenv("NOTE_JSON_SCHEMA_URL")
275-
if str != "" {
276-
Config.SchemaUrl = str
277-
}
278-
279261
// Override via env vars if specified
280262
str = os.Getenv("NOTE_PORT")
281263
if str != "" {
@@ -332,7 +314,7 @@ func ConfigAuthenticationHeader(httpReq *http.Request) (err error) {
332314
if hub == "" {
333315
hub = notehub.DefaultAPIService
334316
}
335-
err = fmt.Errorf("not authenticated to %s: please use 'notehub -signin' to sign into the notehub service", hub)
317+
err = fmt.Errorf("not authenticated to %s: please use 'notehub -signin' to sign into the Notehub service", hub)
336318
return
337319
}
338320

notecard/main.go

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ var card *notecard.Context
2929
// CLI Version - Set by ldflags during build/release
3030
var version = "development"
3131

32+
// JSON schema control variables
33+
var validateJSON bool = false
34+
var jsonSchemaUrl string = "https://raw.githubusercontent.com/blues/notecard-schema/master/notecard.api.json"
35+
3236
// getFlagGroups returns the organized flag groups
3337
func getFlagGroups() []lib.FlagGroup {
3438
return []lib.FlagGroup{
@@ -66,7 +70,6 @@ func getFlagGroups() []lib.FlagGroup {
6670
lib.GetFlagByName("output"),
6771
lib.GetFlagByName("fast"),
6872
lib.GetFlagByName("trace"),
69-
lib.GetFlagByName("force"),
7073
},
7174
},
7275
{
@@ -108,7 +111,6 @@ func getFlagGroups() []lib.FlagGroup {
108111
lib.GetFlagByName("interface"),
109112
lib.GetFlagByName("port"),
110113
lib.GetFlagByName("portconfig"),
111-
lib.GetFlagByName("json-schema-url"),
112114
},
113115
},
114116
{
@@ -144,6 +146,13 @@ func main() {
144146
os.Exit(exitFail)
145147
}()
146148

149+
// Check the environment for JSON schema control variables
150+
_, validateJSON = os.LookupEnv("BLUES") // Opt-in Blues employees to validation
151+
url := os.Getenv("NOTE_JSON_SCHEMA_URL") // Override the default schema URL
152+
if url != "" {
153+
jsonSchemaUrl = url
154+
}
155+
147156
// Override the default usage function to use our grouped format
148157
flag.Usage = func() {
149158
lib.PrintGroupedFlags(getFlagGroups(), "notecard")
@@ -162,8 +171,6 @@ func main() {
162171
flag.BoolVar(&actionWhenDisarmed, "when-disarmed", false, "wait until ATTN is disarmed")
163172
var actionVerbose bool
164173
flag.BoolVar(&actionVerbose, "verbose", false, "display Notecard requests and responses")
165-
var actionForce bool
166-
flag.BoolVar(&actionForce, "force", false, "bypass JSON request validation against the Notecard schema (when used with -req)")
167174
var actionWhenSynced bool
168175
flag.BoolVar(&actionWhenSynced, "when-synced", false, "sync if needed and wait until sync completed")
169176
var actionReserved bool
@@ -678,48 +685,41 @@ func main() {
678685
actionRequest = ""
679686
}
680687

681-
// If the user has provided a JSON schema URL, we need to clear the cache
682-
// and re-initialize the schema. This is because the schema URL may have
683-
// changed, and we need to make sure that the schema is up to date.
684-
json_provided := false
685-
for _, arg := range os.Args {
686-
if arg == "-json-schema-url" {
687-
json_provided = true
688-
break
689-
}
690-
}
691-
if err == nil && json_provided {
692-
clearCache()
693-
url := lib.Config.SchemaUrl
694-
if url == "" {
695-
url = defaultJsonSchemaUrl
696-
}
697-
err = initSchema(url)
698-
}
699-
700688
if err == nil && actionRequest != "" {
701689
var rspJSON []byte
702690
var req, rsp notecard.Request
703691
note.JSONUnmarshal([]byte(actionRequest), &req)
704692

705-
if !actionForce {
706-
err = validateRequest([]byte(actionRequest), lib.Config.SchemaUrl)
707-
if err != nil {
708-
goto done
709-
}
710-
}
711-
712-
// If we want to read the payload from a file, do so
693+
// Append payload from the specified file
713694
if actionInput != "" {
714695
var contents []byte
715696
contents, err = os.ReadFile(actionInput)
716697
if err == nil {
717698
req.Payload = &contents
699+
700+
// Update the original request with the payload
701+
var reqBytes []byte
702+
reqBytes, err = note.JSONMarshal(req)
703+
if err == nil {
704+
actionRequest = string(reqBytes)
705+
}
706+
}
707+
}
708+
709+
// Validate the request against the schema
710+
if err == nil && validateJSON {
711+
var reqMap map[string]interface{}
712+
err = note.JSONUnmarshal([]byte(actionRequest), &reqMap)
713+
if err == nil {
714+
validationErr := validateRequest(reqMap, jsonSchemaUrl, actionVerbose)
715+
if validationErr != nil {
716+
fmt.Fprintf(os.Stderr, "warning: %s\n", validationErr)
717+
}
718718
}
719719
}
720720

721721
// Perform the transaction and do special handling for binary
722-
if req.Req == "card.binary.get" {
722+
if err == nil && req.Req == "card.binary.get" {
723723
expectedMD5 := req.Status
724724
rsp, err = card.TransactionRequest(req)
725725
if err == nil {
@@ -739,7 +739,7 @@ func main() {
739739
}
740740
}
741741
}
742-
} else if req.Req == "card.binary.put" && (req.Body == nil || len(*req.Body) == 0) {
742+
} else if err == nil && req.Req == "card.binary.put" && (req.Body == nil || len(*req.Body) == 0) {
743743
payload := *req.Payload
744744
actualMD5 := fmt.Sprintf("%x", md5.Sum(payload))
745745
if req.Status != "" && !strings.EqualFold(req.Status, actualMD5) {
@@ -757,7 +757,8 @@ func main() {
757757
}
758758
}
759759
}
760-
} else {
760+
} else if err == nil {
761+
// Transact using CLI input to avoid JSON parsing complications
761762
actionRequest = strings.ReplaceAll(actionRequest, "\\n", "\n")
762763
rspJSON, err = card.TransactionJSON([]byte(actionRequest))
763764
if err == nil {
@@ -766,25 +767,23 @@ func main() {
766767
}
767768

768769
// Write the payload to an output file if appropriate
769-
if err == nil && actionOutput != "" {
770-
if rsp.Payload != nil {
771-
err = os.WriteFile(actionOutput, *rsp.Payload, 0644)
772-
if err != nil {
773-
rsp.Payload = nil
774-
}
770+
if err == nil && actionOutput != "" && rsp.Payload != nil {
771+
err = os.WriteFile(actionOutput, *rsp.Payload, 0644)
772+
// If we can't write the file, set the payload to nil so
773+
// we don't try to print it out and cause a JSON error.
774+
if err != nil {
775+
rsp.Payload = nil
775776
}
776777
}
777778

778779
// Output the response to the console
779-
if !actionVerbose {
780-
if err == nil {
781-
if actionPretty {
782-
rspJSON, _ = note.JSONMarshalIndent(rsp, "", " ")
783-
} else {
784-
rspJSON, _ = note.JSONMarshal(rsp)
785-
}
786-
fmt.Printf("%s\n", rspJSON)
780+
if err == nil && !actionVerbose {
781+
if actionPretty {
782+
rspJSON, _ = note.JSONMarshalIndent(rsp, "", " ")
783+
} else {
784+
rspJSON, _ = note.JSONMarshal(rsp)
787785
}
786+
fmt.Printf("%s\n", rspJSON)
788787
}
789788
}
790789

@@ -854,7 +853,6 @@ func main() {
854853
err = explore(actionReserved, actionPretty)
855854
}
856855

857-
done:
858856
// Process errors
859857
if err != nil {
860858
if actionRequest != "" && !actionVerbose {

0 commit comments

Comments
 (0)