2021-01-13 15:50:07 -08:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
2023-02-02 17:15:17 -08:00
2020-06-10 17:58:52 -04:00
package perms
import (
2023-06-06 16:13:44 -04:00
"context"
2021-06-08 11:31:58 -05:00
"fmt"
2020-06-10 17:58:52 -04:00
"testing"
2023-03-10 15:06:39 -05:00
"github.com/hashicorp/boundary/globals"
2020-08-10 17:15:02 -04:00
"github.com/hashicorp/boundary/internal/types/action"
"github.com/hashicorp/boundary/internal/types/resource"
2020-06-10 17:58:52 -04:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_ActionParsingValidation ( t * testing . T ) {
t . Parallel ()
2023-06-06 16:13:44 -04:00
ctx := context . Background ()
2020-06-10 17:58:52 -04:00
type input struct {
name string
input Grant
errResult string
result Grant
}
tests := [] input {
{
name : "no actions" ,
2021-01-13 15:50:07 -08:00
errResult : "perms.(Grant).parseAndValidateActions: missing actions: parameter violation: error #100" ,
2020-06-10 17:58:52 -04:00
},
{
name : "empty action" ,
input : Grant {
actionsBeingParsed : [] string { "create" , "" , "read" },
},
2021-01-13 15:50:07 -08:00
errResult : "perms.(Grant).parseAndValidateActions: empty action found: parameter violation: error #100" ,
2020-06-10 17:58:52 -04:00
},
2021-05-04 19:57:35 -05:00
{
name : "empty action with output fields" ,
input : Grant {
2023-01-06 17:27:19 -06:00
OutputFields : & OutputFields {
fields : map [ string ] bool {
"id" : true ,
},
2021-05-04 19:57:35 -05:00
},
},
result : Grant {
2023-01-06 17:27:19 -06:00
OutputFields : & OutputFields {
fields : map [ string ] bool {
"id" : true ,
},
2021-05-04 19:57:35 -05:00
},
},
},
2020-06-10 17:58:52 -04:00
{
name : "unknown action" ,
input : Grant {
actionsBeingParsed : [] string { "create" , "foobar" , "read" },
},
2021-01-13 15:50:07 -08:00
errResult : `perms.(Grant).parseAndValidateActions: unknown action "foobar": parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
},
{
name : "all" ,
input : Grant {
actionsBeingParsed : [] string { "*" },
},
result : Grant {
2020-06-26 11:00:14 -04:00
actions : map [ action . Type ] bool {
action . All : true ,
2020-06-10 17:58:52 -04:00
},
},
},
{
name : "all valid plus all" ,
input : Grant {
2020-10-05 11:02:23 -04:00
actionsBeingParsed : [] string { "list" , "create" , "update" , "*" , "read" , "delete" , "authenticate" , "authorize-session" },
2020-06-10 17:58:52 -04:00
},
2021-01-13 15:50:07 -08:00
errResult : `perms.(Grant).parseAndValidateActions: "*" cannot be specified with other actions: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
},
{
name : "all valid" ,
input : Grant {
2021-02-05 14:01:03 -05:00
actionsBeingParsed : [] string { "list" , "create" , "update" , "read" , "delete" , "authenticate" , "authorize-session" },
2020-06-10 17:58:52 -04:00
},
result : Grant {
2020-06-26 11:00:14 -04:00
actions : map [ action . Type ] bool {
2020-10-05 11:02:23 -04:00
action . List : true ,
action . Create : true ,
action . Update : true ,
action . Read : true ,
action . Delete : true ,
action . Authenticate : true ,
action . AuthorizeSession : true ,
2020-06-10 17:58:52 -04:00
},
},
},
}
for _ , test := range tests {
t . Run ( test . name , func ( t * testing . T ) {
2023-06-06 16:13:44 -04:00
err := test . input . parseAndValidateActions ( ctx )
2020-06-10 17:58:52 -04:00
if test . errResult == "" {
require . NoError ( t , err )
assert . Equal ( t , test . result , test . input )
} else {
require . Error ( t , err )
assert . Equal ( t , test . errResult , err . Error ())
}
})
}
}
func Test_ValidateType ( t * testing . T ) {
t . Parallel ()
2023-06-06 16:13:44 -04:00
ctx := context . Background ()
2021-09-13 13:56:44 -04:00
var g Grant
2024-01-31 09:54:12 -08:00
for i := resource . Unknown ; i <= resource . Alias ; i ++ {
2021-09-13 13:56:44 -04:00
g . typ = i
2022-06-05 16:43:02 -04:00
if i == resource . Controller {
2023-06-06 16:13:44 -04:00
assert . Error ( t , g . validateType ( ctx ))
2021-09-13 13:56:44 -04:00
} else {
2023-06-06 16:13:44 -04:00
assert . NoError ( t , g . validateType ( ctx ))
2021-09-13 13:56:44 -04:00
}
2020-06-10 17:58:52 -04:00
}
}
2020-09-21 02:22:59 -04:00
func Test_MarshalingAndCloning ( t * testing . T ) {
2020-06-10 17:58:52 -04:00
t . Parallel ()
type input struct {
name string
input Grant
jsonOutput string
canonicalString string
}
tests := [] input {
{
2024-09-17 10:07:43 -04:00
name : "empty" ,
2020-06-10 17:58:52 -04:00
jsonOutput : `{}` ,
canonicalString : `` ,
},
{
2020-06-23 11:28:44 -04:00
name : "type and id" ,
2020-06-10 17:58:52 -04:00
input : Grant {
2024-09-17 10:07:43 -04:00
id : "baz" ,
2020-07-31 17:46:04 -04:00
typ : resource . Group ,
2020-06-10 17:58:52 -04:00
},
2020-07-31 17:46:04 -04:00
jsonOutput : `{"id":"baz","type":"group"}` ,
canonicalString : `id=baz;type=group` ,
2020-06-10 17:58:52 -04:00
},
2021-05-04 19:57:35 -05:00
{
2023-06-06 16:13:44 -04:00
name : "type and ids" ,
input : Grant {
ids : [] string { "baz" , "bop" },
typ : resource . Group ,
},
jsonOutput : `{"ids":["baz","bop"],"type":"group"}` ,
canonicalString : `ids=baz,bop;type=group` ,
},
{
name : "type and ids single id" ,
input : Grant {
ids : [] string { "baz" },
typ : resource . Group ,
},
jsonOutput : `{"ids":["baz"],"type":"group"}` ,
canonicalString : `ids=baz;type=group` ,
},
{
name : "output fields id" ,
2021-05-04 19:57:35 -05:00
input : Grant {
2024-09-17 10:07:43 -04:00
id : "baz" ,
2021-05-04 19:57:35 -05:00
typ : resource . Group ,
2023-01-06 17:27:19 -06:00
OutputFields : & OutputFields {
fields : map [ string ] bool {
"name" : true ,
"version" : true ,
"id" : true ,
},
2021-05-04 19:57:35 -05:00
},
},
jsonOutput : `{"id":"baz","output_fields":["id","name","version"],"type":"group"}` ,
canonicalString : `id=baz;type=group;output_fields=id,name,version` ,
},
2020-06-10 17:58:52 -04:00
{
2023-06-06 16:13:44 -04:00
name : "output fields ids" ,
input : Grant {
ids : [] string { "baz" , "bop" },
typ : resource . Group ,
OutputFields : & OutputFields {
fields : map [ string ] bool {
"name" : true ,
"version" : true ,
"id" : true ,
},
},
},
jsonOutput : `{"ids":["baz","bop"],"output_fields":["id","name","version"],"type":"group"}` ,
canonicalString : `ids=baz,bop;type=group;output_fields=id,name,version` ,
},
{
name : "everything id" ,
2020-06-10 17:58:52 -04:00
input : Grant {
2024-09-17 10:07:43 -04:00
id : "baz" ,
2020-07-31 17:46:04 -04:00
typ : resource . Group ,
2020-06-26 11:00:14 -04:00
actions : map [ action . Type ] bool {
action . Create : true ,
action . Read : true ,
2020-06-10 17:58:52 -04:00
},
actionsBeingParsed : [] string { "create" , "read" },
2023-01-06 17:27:19 -06:00
OutputFields : & OutputFields {
fields : map [ string ] bool {
"name" : true ,
"version" : true ,
"id" : true ,
},
2021-05-04 19:57:35 -05:00
},
2020-06-10 17:58:52 -04:00
},
2021-05-04 19:57:35 -05:00
jsonOutput : `{"actions":["create","read"],"id":"baz","output_fields":["id","name","version"],"type":"group"}` ,
canonicalString : `id=baz;type=group;actions=create,read;output_fields=id,name,version` ,
2020-06-10 17:58:52 -04:00
},
2023-06-06 16:13:44 -04:00
{
name : "everything ids" ,
input : Grant {
ids : [] string { "baz" , "bop" },
typ : resource . Group ,
actions : map [ action . Type ] bool {
action . Create : true ,
action . Read : true ,
},
actionsBeingParsed : [] string { "create" , "read" },
OutputFields : & OutputFields {
fields : map [ string ] bool {
"name" : true ,
"version" : true ,
"ids" : true ,
},
},
},
jsonOutput : `{"actions":["create","read"],"ids":["baz","bop"],"output_fields":["ids","name","version"],"type":"group"}` ,
canonicalString : `ids=baz,bop;type=group;actions=create,read;output_fields=ids,name,version` ,
},
2020-06-10 17:58:52 -04:00
}
for _ , test := range tests {
t . Run ( test . name , func ( t * testing . T ) {
2024-02-21 16:32:26 -05:00
output , err := test . input . MarshalJSON ()
2020-06-10 17:58:52 -04:00
require . NoError ( t , err )
assert . Equal ( t , test . jsonOutput , string ( output ))
assert . Equal ( t , test . canonicalString , test . input . CanonicalString ())
assert . Equal ( t , & test . input , test . input . clone ())
})
}
}
func Test_Unmarshaling ( t * testing . T ) {
t . Parallel ()
2023-06-06 17:09:08 -04:00
ctx := context . Background ()
2020-06-10 17:58:52 -04:00
type input struct {
name string
jsonInput string
textInput string
jsonErr string
textErr string
expected Grant
}
tests := [] input {
{
name : "empty" ,
expected : Grant {},
jsonInput : `{}` ,
textInput : `` ,
textErr : `segment "" not formatted correctly, wrong number of equal signs` ,
},
{
name : "bad json" ,
jsonInput : `w329uf` ,
2021-01-13 15:50:07 -08:00
jsonErr : "perms.(Grant).unmarshalJSON: error occurred during decode, encoding issue: error #303: invalid character 'w' looking for beginning of value" ,
2020-06-10 17:58:52 -04:00
},
{
2023-06-06 16:13:44 -04:00
name : "bad segment id" ,
2020-06-23 11:28:44 -04:00
jsonInput : `{"id":true}` ,
2021-01-13 15:50:07 -08:00
jsonErr : `perms.(Grant).unmarshalJSON: unable to interpret "id" as string: parameter violation: error #100` ,
2020-06-23 11:28:44 -04:00
textInput : `id=` ,
2021-01-13 15:50:07 -08:00
textErr : `perms.(Grant).unmarshalText: segment "id=" not formatted correctly, missing value: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
},
2023-09-06 09:11:56 -07:00
{
name : "bad segment id comma" ,
jsonInput : `{"id":","}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
textInput : `id=,` ,
textErr : `perms.(Grant).unmarshalText: ID cannot contain a comma: parameter violation: error #100` ,
},
{
name : "bad segment id start with comma" ,
jsonInput : `{"id":",something"}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
textInput : `id=,something` ,
textErr : `perms.(Grant).unmarshalText: ID cannot contain a comma: parameter violation: error #100` ,
},
{
name : "bad segment id with comma" ,
jsonInput : `{"id":"some,thing"}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
textInput : `id=some,thing` ,
textErr : `perms.(Grant).unmarshalText: ID cannot contain a comma: parameter violation: error #100` ,
},
{
name : "bad segment id end with comma" ,
jsonInput : `{"id":"something,"}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
textInput : `id=something,` ,
textErr : `perms.(Grant).unmarshalText: ID cannot contain a comma: parameter violation: error #100` ,
},
2023-06-06 16:13:44 -04:00
{
name : "bad segment ids" ,
jsonInput : `{"ids":true}` ,
jsonErr : `perms.(Grant).unmarshalJSON: unable to interpret "ids" as array: parameter violation: error #100` ,
textInput : `ids=` ,
textErr : `perms.(Grant).unmarshalText: segment "ids=" not formatted correctly, missing value: parameter violation: error #100` ,
},
2023-09-06 09:11:56 -07:00
{
name : "empty segment ids" ,
jsonInput : `{"ids":[""]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: empty ID provided: parameter violation: error #100` ,
textInput : `ids=,` ,
textErr : `perms.(Grant).unmarshalText: empty ID provided: parameter violation: error #100` ,
},
{
name : "segment ids comma" ,
jsonInput : `{"ids":[","]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids starting with comma" ,
jsonInput : `{"ids":[",something"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids with comma" ,
jsonInput : `{"ids":["some,thing"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids ending with comma" ,
jsonInput : `{"ids":["something,"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids semicolon" ,
jsonInput : `{"ids":[","]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids starting with semicolon" ,
jsonInput : `{"ids":[";something"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids with semicolon" ,
jsonInput : `{"ids":["some;thing"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids ending with semicolon" ,
jsonInput : `{"ids":["something;"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids equals sign" ,
jsonInput : `{"ids":["="]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids starting with equals sign" ,
jsonInput : `{"ids":["=something"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids with equals sign" ,
jsonInput : `{"ids":["some=thing"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids ending with equals sign" ,
jsonInput : `{"ids":["something="]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
2020-06-10 17:58:52 -04:00
{
name : "good id" ,
expected : Grant {
id : "foobar" ,
},
jsonInput : `{"id":"foobar"}` ,
textInput : `id=foobar` ,
},
2023-06-06 16:13:44 -04:00
{
name : "good ids" ,
expected : Grant {
ids : [] string { "foobar" },
},
jsonInput : `{"ids":["foobar"]}` ,
textInput : `ids=foobar` ,
},
2020-06-10 17:58:52 -04:00
{
name : "bad id" ,
jsonInput : `{"id":true}` ,
2021-01-13 15:50:07 -08:00
jsonErr : `perms.(Grant).unmarshalJSON: unable to interpret "id" as string: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
textInput : `=id` ,
2021-01-13 15:50:07 -08:00
textErr : `perms.(Grant).unmarshalText: segment "=id" not formatted correctly, missing key: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
},
2023-06-06 16:13:44 -04:00
{
name : "bad ids" ,
jsonInput : `{"ids":true}` ,
jsonErr : `perms.(Grant).unmarshalJSON: unable to interpret "ids" as array: parameter violation: error #100` ,
textInput : `=ids` ,
textErr : `perms.(Grant).unmarshalText: segment "=ids" not formatted correctly, missing key: parameter violation: error #100` ,
},
2020-06-10 17:58:52 -04:00
{
name : "good type" ,
expected : Grant {
2020-06-26 11:00:14 -04:00
typ : resource . HostCatalog ,
2020-06-10 17:58:52 -04:00
},
jsonInput : `{"type":"host-catalog"}` ,
textInput : `type=host-catalog` ,
},
{
name : "bad type" ,
jsonInput : `{"type":true}` ,
2021-01-13 15:50:07 -08:00
jsonErr : `perms.(Grant).unmarshalJSON: unable to interpret "type" as string: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
textInput : `type=host-catalog=id` ,
2021-01-13 15:50:07 -08:00
textErr : `perms.(Grant).unmarshalText: segment "type=host-catalog=id" not formatted correctly, wrong number of equal signs: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
},
2021-05-04 19:57:35 -05:00
{
2023-06-06 16:13:44 -04:00
name : "good output fields id" ,
2021-05-04 19:57:35 -05:00
expected : Grant {
2023-01-06 17:27:19 -06:00
OutputFields : & OutputFields {
fields : map [ string ] bool {
"name" : true ,
"version" : true ,
"id" : true ,
},
2021-05-04 19:57:35 -05:00
},
},
jsonInput : `{"output_fields":["id","name","version"]}` ,
textInput : `output_fields=id,version,name` ,
},
{
2023-06-06 16:13:44 -04:00
name : "good output fields ids" ,
expected : Grant {
OutputFields : & OutputFields {
fields : map [ string ] bool {
"name" : true ,
"version" : true ,
"ids" : true ,
},
},
},
jsonInput : `{"output_fields":["ids","name","version"]}` ,
textInput : `output_fields=ids,version,name` ,
},
{
name : "bad output fields id" ,
2021-05-04 19:57:35 -05:00
jsonInput : `{"output_fields":true}` ,
jsonErr : `perms.(Grant).unmarshalJSON: unable to interpret "output_fields" as array: parameter violation: error #100` ,
textInput : `output_fields=id=version,name` ,
textErr : `perms.(Grant).unmarshalText: segment "output_fields=id=version,name" not formatted correctly, wrong number of equal signs: parameter violation: error #100` ,
},
2023-06-06 16:13:44 -04:00
{
name : "bad output fields ids" ,
jsonInput : `{"output_fields":true}` ,
jsonErr : `perms.(Grant).unmarshalJSON: unable to interpret "output_fields" as array: parameter violation: error #100` ,
textInput : `output_fields=ids=version,name` ,
textErr : `perms.(Grant).unmarshalText: segment "output_fields=ids=version,name" not formatted correctly, wrong number of equal signs: parameter violation: error #100` ,
},
2023-09-06 09:11:56 -07:00
{
name : "bad output fields comma" ,
jsonInput : `{"output_fields":[","]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: output fields cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "output fields starting with comma" ,
jsonInput : `{"output_fields":[",something"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: output fields cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "output fields with comma" ,
jsonInput : `{"output_fields":["some,thing"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: output fields cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "output fields ending with comma" ,
jsonInput : `{"output_fields":["something,"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: output fields cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids semicolon" ,
jsonInput : `{"ids":[";"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids starting with semicolon" ,
jsonInput : `{"ids":[";something"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids with semicolon" ,
jsonInput : `{"ids":["some;thing"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids ending with semicolon" ,
jsonInput : `{"ids":["something;"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids equals sign" ,
jsonInput : `{"ids":["="]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids starting with equals sign" ,
jsonInput : `{"ids":["=something"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids with equals sign" ,
jsonInput : `{"ids":["some=thing"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment ids ending with equals sign" ,
jsonInput : `{"ids":["something="]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: ID cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
2020-06-10 17:58:52 -04:00
{
name : "good actions" ,
expected : Grant {
actionsBeingParsed : [] string { "create" , "read" },
},
jsonInput : `{"actions":["create","read"]}` ,
textInput : `actions=create,read` ,
},
{
name : "bad actions" ,
jsonInput : `{"actions":true}` ,
2021-01-13 15:50:07 -08:00
jsonErr : `perms.(Grant).unmarshalJSON: unable to interpret "actions" as array: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
textInput : `type=host-catalog=id` ,
2021-01-13 15:50:07 -08:00
textErr : `perms.(Grant).unmarshalText: segment "type=host-catalog=id" not formatted correctly, wrong number of equal signs: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
},
{
name : "empty actions" ,
jsonInput : `{"actions":[""]}` ,
2021-01-13 15:50:07 -08:00
jsonErr : `perms.(Grant).unmarshalJSON: empty action found: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
textInput : `actions=,` ,
2021-01-13 15:50:07 -08:00
textErr : `perms.(Grant).unmarshalText: empty action found: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
},
{
name : "bad json action" ,
jsonInput : `{"actions":[1, true]}` ,
2021-01-13 15:50:07 -08:00
jsonErr : `perms.(Grant).unmarshalJSON: unable to interpret 1 in actions array as string: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
},
2023-09-06 09:11:56 -07:00
{
name : "segment actions comma" ,
jsonInput : `{"actions":[","]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: action cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment actions starting with comma" ,
jsonInput : `{"actions":[",something"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: action cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment actions with comma" ,
jsonInput : `{"actions":["some,thing"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: action cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
{
name : "segment actions ending with comma" ,
jsonInput : `{"actions":["something,"]}` ,
jsonErr : `perms.(Grant).unmarshalJSON: action cannot contain a comma, semicolon or equals sign: parameter violation: error #100` ,
},
2020-06-10 17:58:52 -04:00
}
for _ , test := range tests {
t . Run ( test . name , func ( t * testing . T ) {
2020-06-26 11:00:14 -04:00
assert := assert . New ( t )
require := require . New ( t )
2020-06-10 17:58:52 -04:00
var g Grant
if test . jsonInput != "" {
2023-06-06 17:09:08 -04:00
err := g . unmarshalJSON ( ctx , [] byte ( test . jsonInput ))
2020-06-10 17:58:52 -04:00
if test . jsonErr != "" {
require . Error ( err )
assert . Equal ( test . jsonErr , err . Error ())
} else {
require . NoError ( err )
assert . Equal ( test . expected , g )
}
}
g = Grant {}
if test . textInput != "" {
2023-06-06 17:09:08 -04:00
err := g . unmarshalText ( ctx , test . textInput )
2020-06-10 17:58:52 -04:00
if test . textErr != "" {
require . Error ( err )
assert . Equal ( test . textErr , err . Error ())
} else {
require . NoError ( err )
assert . Equal ( test . expected , g )
}
}
})
}
}
func Test_Parse ( t * testing . T ) {
t . Parallel ()
2023-06-06 16:13:44 -04:00
ctx := context . Background ()
2020-06-10 17:58:52 -04:00
type input struct {
2020-07-10 17:42:47 -07:00
name string
input string
userId string
2020-10-01 10:51:54 -04:00
accountId string
2020-07-10 17:42:47 -07:00
err string
scopeOverride string
expected Grant
2020-06-10 17:58:52 -04:00
}
tests := [] input {
2021-05-04 19:57:35 -05:00
{
name : "empty output fields" ,
input : "id=*;type=*;actions=read,list;output_fields=" ,
2023-01-06 17:27:19 -06:00
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
id : "*" ,
typ : resource . All ,
2023-01-06 17:27:19 -06:00
actions : map [ action . Type ] bool {
action . Read : true ,
action . List : true ,
},
OutputFields : & OutputFields {
fields : make ( map [ string ] bool ),
},
},
2021-05-04 19:57:35 -05:00
},
{
name : "empty output fields json" ,
input : `{"id": "*", "type": "*", "actions": ["read", "list"], "output_fields": []}` ,
2023-01-06 17:27:19 -06:00
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
id : "*" ,
typ : resource . All ,
2023-01-06 17:27:19 -06:00
actions : map [ action . Type ] bool {
action . Read : true ,
action . List : true ,
},
OutputFields : & OutputFields {
fields : make ( map [ string ] bool ),
},
},
2021-05-04 19:57:35 -05:00
},
2021-02-05 12:39:55 -05:00
{
name : "wildcard id and type and actions with list" ,
input : "id=*;type=*;actions=read,list" ,
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
id : "*" ,
typ : resource . All ,
2021-02-05 12:39:55 -05:00
actions : map [ action . Type ] bool {
action . Read : true ,
action . List : true ,
},
},
2020-06-23 11:28:44 -04:00
},
2023-06-06 16:13:44 -04:00
{
name : "wildcard ids and type and actions with list" ,
input : "ids=*;type=*;actions=read,list" ,
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
ids : [] string { "*" },
typ : resource . All ,
2023-06-06 16:13:44 -04:00
actions : map [ action . Type ] bool {
action . Read : true ,
action . List : true ,
},
},
},
2020-06-10 17:58:52 -04:00
{
2020-10-01 01:49:20 -04:00
name : "good json type" ,
input : `{"type":"host-catalog","actions":["create"]}` ,
2020-06-10 17:58:52 -04:00
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
typ : resource . HostCatalog ,
2020-06-26 11:00:14 -04:00
actions : map [ action . Type ] bool {
action . Create : true ,
2020-06-10 17:58:52 -04:00
},
},
},
{
2020-10-01 01:49:20 -04:00
name : "good json id" ,
2023-03-16 10:11:55 -04:00
input : `{"id":"u_foobar","actions":["read"]}` ,
2020-06-10 17:58:52 -04:00
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
id : "u_foobar" ,
typ : resource . Unknown ,
2020-10-01 01:49:20 -04:00
actions : map [ action . Type ] bool {
action . Read : true ,
},
},
},
2021-05-04 19:57:35 -05:00
{
2023-06-06 16:13:44 -04:00
name : "good json ids" ,
input : `{"ids":["hcst_foobar", "hcst_foobaz"],"actions":["read"]}` ,
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
ids : [] string { "hcst_foobar" , "hcst_foobaz" },
typ : resource . Unknown ,
2023-06-06 16:13:44 -04:00
actions : map [ action . Type ] bool {
action . Read : true ,
},
},
},
{
name : "good json output fields id" ,
2023-03-16 10:11:55 -04:00
input : `{"id":"u_foobar","actions":["read"],"output_fields":["version","id","name"]}` ,
2021-05-04 19:57:35 -05:00
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
id : "u_foobar" ,
typ : resource . Unknown ,
2021-05-04 19:57:35 -05:00
actions : map [ action . Type ] bool {
action . Read : true ,
},
2023-01-06 17:27:19 -06:00
OutputFields : & OutputFields {
fields : map [ string ] bool {
"version" : true ,
"id" : true ,
"name" : true ,
},
2021-05-04 19:57:35 -05:00
},
},
},
2023-06-06 16:13:44 -04:00
{
name : "good json output fields ids" ,
input : `{"ids":["u_foobar"],"actions":["read"],"output_fields":["version","ids","name"]}` ,
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
ids : [] string { "u_foobar" },
typ : resource . Unknown ,
2023-06-06 16:13:44 -04:00
actions : map [ action . Type ] bool {
action . Read : true ,
},
OutputFields : & OutputFields {
fields : map [ string ] bool {
"version" : true ,
"ids" : true ,
"name" : true ,
},
},
},
},
2021-05-04 19:57:35 -05:00
{
name : "good json output fields no action" ,
2023-03-16 10:11:55 -04:00
input : `{"id":"u_foobar","output_fields":["version","id","name"]}` ,
2021-05-04 19:57:35 -05:00
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
id : "u_foobar" ,
typ : resource . Unknown ,
2023-01-06 17:27:19 -06:00
OutputFields : & OutputFields {
fields : map [ string ] bool {
"version" : true ,
"id" : true ,
"name" : true ,
},
2021-05-04 19:57:35 -05:00
},
},
},
2020-10-01 01:49:20 -04:00
{
name : "good text type" ,
input : `type=host-catalog;actions=create` ,
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
typ : resource . HostCatalog ,
2020-06-26 11:00:14 -04:00
actions : map [ action . Type ] bool {
action . Create : true ,
2020-10-01 01:49:20 -04:00
},
},
},
{
name : "good text id" ,
2023-03-16 10:11:55 -04:00
input : `id=u_foobar;actions=read` ,
2020-10-01 01:49:20 -04:00
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
id : "u_foobar" ,
typ : resource . Unknown ,
2020-10-01 01:49:20 -04:00
actions : map [ action . Type ] bool {
action . Read : true ,
2020-06-10 17:58:52 -04:00
},
},
},
2021-05-04 19:57:35 -05:00
{
2023-06-06 16:13:44 -04:00
name : "good text ids" ,
input : `ids=hcst_foobar,hcst_foobaz;actions=read` ,
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
ids : [] string { "hcst_foobar" , "hcst_foobaz" },
typ : resource . Unknown ,
2023-06-06 16:13:44 -04:00
actions : map [ action . Type ] bool {
action . Read : true ,
},
},
},
{
name : "good output fields id" ,
2023-03-16 10:11:55 -04:00
input : `id=u_foobar;actions=read;output_fields=version,id,name` ,
2021-05-04 19:57:35 -05:00
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
id : "u_foobar" ,
typ : resource . Unknown ,
2021-05-04 19:57:35 -05:00
actions : map [ action . Type ] bool {
action . Read : true ,
},
2023-01-06 17:27:19 -06:00
OutputFields : & OutputFields {
fields : map [ string ] bool {
"version" : true ,
"id" : true ,
"name" : true ,
},
2021-05-04 19:57:35 -05:00
},
},
},
2023-06-06 16:13:44 -04:00
{
name : "good output fields ids" ,
input : `ids=hcst_foobar,hcst_foobaz;actions=read;output_fields=version,ids,name` ,
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
ids : [] string { "hcst_foobar" , "hcst_foobaz" },
typ : resource . Unknown ,
2023-06-06 16:13:44 -04:00
actions : map [ action . Type ] bool {
action . Read : true ,
},
OutputFields : & OutputFields {
fields : map [ string ] bool {
"version" : true ,
"ids" : true ,
"name" : true ,
},
},
},
},
2020-07-10 17:42:47 -07:00
{
name : "default project scope" ,
2023-03-16 10:11:55 -04:00
input : `id=hcst_foobar;actions=read` ,
2020-07-10 17:42:47 -07:00
scopeOverride : "p_1234" ,
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "p_1234" ,
grantScopeId : "p_1234" ,
id : "hcst_foobar" ,
typ : resource . Unknown ,
2020-07-10 17:42:47 -07:00
actions : map [ action . Type ] bool {
2020-10-01 01:49:20 -04:00
action . Read : true ,
2020-07-10 17:42:47 -07:00
},
},
},
{
name : "default org scope" ,
2023-03-16 10:11:55 -04:00
input : `id=acctpw_foobar;actions=read` ,
2020-07-10 17:42:47 -07:00
scopeOverride : "o_1234" ,
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_1234" ,
grantScopeId : "o_1234" ,
id : "acctpw_foobar" ,
typ : resource . Unknown ,
2020-07-10 17:42:47 -07:00
actions : map [ action . Type ] bool {
2020-10-01 01:49:20 -04:00
action . Read : true ,
2020-07-10 17:42:47 -07:00
},
},
},
{
name : "default global scope" ,
2023-03-16 10:11:55 -04:00
input : `id=acctpw_foobar;actions=read` ,
2020-07-10 17:42:47 -07:00
scopeOverride : "global" ,
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "global" ,
grantScopeId : "global" ,
id : "acctpw_foobar" ,
typ : resource . Unknown ,
2020-07-10 17:42:47 -07:00
actions : map [ action . Type ] bool {
2020-10-01 01:49:20 -04:00
action . Read : true ,
2020-07-10 17:42:47 -07:00
},
},
},
2020-06-10 17:58:52 -04:00
{
name : "bad user id template" ,
input : `id= {{ superman }} ;actions=create,read` ,
userId : "u_abcd1234" ,
2021-01-13 15:50:07 -08:00
err : `perms.Parse: unknown template " {{ superman }} " in grant "id" value: parameter violation: error #100` ,
2020-06-10 17:58:52 -04:00
},
2023-06-06 16:13:44 -04:00
{
name : "bad user ids template" ,
input : `ids= {{ superman }} ;actions=create,read` ,
userId : "u_abcd1234" ,
err : `perms.Parse: unknown template " {{ superman }} " in grant "ids" value: parameter violation: error #100` ,
},
2020-06-10 17:58:52 -04:00
{
name : "good user id template" ,
2021-02-05 12:39:55 -05:00
input : `id= {{ user .id }} ;actions=read,update` ,
2020-06-10 17:58:52 -04:00
userId : "u_abcd1234" ,
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
id : "u_abcd1234" ,
2020-06-26 11:00:14 -04:00
actions : map [ action . Type ] bool {
2021-02-05 12:39:55 -05:00
action . Update : true ,
2020-06-26 11:00:14 -04:00
action . Read : true ,
2020-06-10 17:58:52 -04:00
},
},
},
2020-10-01 10:51:54 -04:00
{
2021-06-08 11:31:58 -05:00
name : "bad old account id template" ,
2021-02-05 12:39:55 -05:00
input : `id= {{ superman }} ;actions=read` ,
2023-03-10 15:06:39 -05:00
accountId : fmt . Sprintf ( "%s_1234567890" , globals . PasswordAccountPreviousPrefix ),
2021-01-13 15:50:07 -08:00
err : `perms.Parse: unknown template " {{ superman }} " in grant "id" value: parameter violation: error #100` ,
2020-10-01 10:51:54 -04:00
},
2023-06-06 16:13:44 -04:00
{
name : "bad old account ids template" ,
input : `ids= {{ superman }} ;actions=read` ,
accountId : fmt . Sprintf ( "%s_1234567890" , globals . PasswordAccountPreviousPrefix ),
err : `perms.Parse: unknown template " {{ superman }} " in grant "ids" value: parameter violation: error #100` ,
},
2020-10-01 10:51:54 -04:00
{
2021-06-08 11:31:58 -05:00
name : "bad new account id template" ,
input : `id= {{ superman }} ;actions=read` ,
2023-03-10 15:06:39 -05:00
accountId : fmt . Sprintf ( "%s_1234567890" , globals . PasswordAccountPrefix ),
2021-06-08 11:31:58 -05:00
err : `perms.Parse: unknown template " {{ superman }} " in grant "id" value: parameter violation: error #100` ,
},
{
name : "good old account id template" ,
input : `id= {{ account .id }} ;actions=update,read` ,
2023-03-10 15:06:39 -05:00
accountId : fmt . Sprintf ( "%s_1234567890" , globals . PasswordAccountPreviousPrefix ),
2021-06-08 11:31:58 -05:00
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
id : fmt . Sprintf ( "%s_1234567890" , globals . PasswordAccountPreviousPrefix ),
2021-06-08 11:31:58 -05:00
actions : map [ action . Type ] bool {
action . Update : true ,
action . Read : true ,
},
},
},
{
name : "good new account id template" ,
2021-02-05 12:39:55 -05:00
input : `id= {{ account .id }} ;actions=update,read` ,
2023-03-10 15:06:39 -05:00
accountId : fmt . Sprintf ( "%s_1234567890" , globals . PasswordAccountPrefix ),
2020-10-01 10:51:54 -04:00
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
id : fmt . Sprintf ( "%s_1234567890" , globals . PasswordAccountPrefix ),
2020-10-01 10:51:54 -04:00
actions : map [ action . Type ] bool {
2021-02-05 12:39:55 -05:00
action . Update : true ,
2020-10-01 10:51:54 -04:00
action . Read : true ,
},
},
},
2023-06-06 16:13:44 -04:00
{
name : "good ids template" ,
input : `ids= {{ user .id }} , {{ account .id }} ;actions=read,update` ,
userId : "u_abcd1234" ,
accountId : fmt . Sprintf ( "%s_1234567890" , globals . PasswordAccountPrefix ),
expected : Grant {
2024-09-17 10:07:43 -04:00
roleScopeId : "o_scope" ,
grantScopeId : "o_scope" ,
ids : [] string { "u_abcd1234" , "acctpw_1234567890" },
2023-06-06 16:13:44 -04:00
actions : map [ action . Type ] bool {
action . Update : true ,
action . Read : true ,
},
},
},
2020-06-10 17:58:52 -04:00
}
2024-09-17 10:07:43 -04:00
_ , err := Parse ( ctx , GrantTuple { RoleScopeId : "" , GrantScopeId : "" , Grant : "" })
2020-06-26 11:00:14 -04:00
require . Error ( t , err )
2021-01-13 15:50:07 -08:00
assert . Equal ( t , "perms.Parse: missing grant string: parameter violation: error #100" , err . Error ())
2020-06-10 17:58:52 -04:00
2024-09-17 10:07:43 -04:00
_ , err = Parse ( ctx , GrantTuple { RoleScopeId : "" , GrantScopeId : "" , Grant : "{}" })
require . Error ( t , err )
assert . Equal ( t , "perms.Parse: missing role scope id: parameter violation: error #100" , err . Error ())
_ , err = Parse ( ctx , GrantTuple { RoleScopeId : "p_abcd" , GrantScopeId : "" , Grant : "{}" })
2020-06-26 11:00:14 -04:00
require . Error ( t , err )
2024-09-17 10:07:43 -04:00
assert . Equal ( t , "perms.Parse: missing grant scope id: parameter violation: error #100" , err . Error ())
2020-06-10 17:58:52 -04:00
for _ , test := range tests {
t . Run ( test . name , func ( t * testing . T ) {
2020-06-26 11:00:14 -04:00
assert := assert . New ( t )
require := require . New ( t )
2020-07-10 17:42:47 -07:00
scope := "o_scope"
if test . scopeOverride != "" {
scope = test . scopeOverride
}
2024-09-17 10:07:43 -04:00
grant , err := Parse ( ctx , GrantTuple { RoleScopeId : scope , GrantScopeId : scope , Grant : test . input }, WithUserId ( test . userId ), WithAccountId ( test . accountId ))
2020-06-10 17:58:52 -04:00
if test . err != "" {
require . Error ( err )
2021-01-13 15:50:07 -08:00
assert . Equal ( test . err , err . Error ())
2020-06-10 17:58:52 -04:00
} else {
require . NoError ( err )
assert . Equal ( test . expected , grant )
}
})
}
}
2022-06-05 16:43:02 -04:00
func TestHasActionOrSubaction ( t * testing . T ) {
tests := [] struct {
name string
base [] action . Type
act action . Type
want bool
}{
{
name : "no actions" ,
base : [] action . Type {},
act : action . Read ,
},
{
name : "has direct action" ,
base : [] action . Type { action . Cancel , action . Read },
act : action . Read ,
want : true ,
},
{
name : "has parent action" ,
base : [] action . Type { action . Cancel , action . ReadSelf },
act : action . Read ,
want : true ,
},
{
name : "has direct sub action" ,
base : [] action . Type { action . Cancel , action . ReadSelf },
act : action . ReadSelf ,
want : true ,
},
{
name : "has sub action needs parent" ,
base : [] action . Type { action . Cancel , action . Read },
act : action . ReadSelf ,
},
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
g := Grant {
actions : make ( map [ action . Type ] bool ),
}
for _ , act := range tt . base {
g . actions [ act ] = true
}
assert . Equal ( t , tt . want , g . hasActionOrSubaction ( tt . act ))
})
}
}
2023-01-06 17:27:19 -06:00
2024-12-06 16:45:38 -05:00
func Test_HasNoGrants ( t * testing . T ) {
t . Parallel ()
ctx := context . Background ()
var gt GrantTuples
hash , err := gt . GrantHash ( ctx )
require . NoError ( t , err )
assert . Equal ( t , [] byte { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, hash )
}
2023-01-06 17:27:19 -06:00
func FuzzParse ( f * testing . F ) {
2023-06-06 16:13:44 -04:00
ctx := context . Background ()
2023-08-25 21:17:29 -04:00
tc := [] string {
"id=*;type=*;actions=read,list;output_fields=" ,
`{"id": "*", "type": "*", "actions": ["read", "list"], "output_fields": []}` ,
"id=*;type=*;actions=read,list" ,
"ids=*;type=*;actions=read,list" ,
`{"type":"host-catalog","actions":["create"]}` ,
`{"id":"u_foobar","actions":["read"]}` ,
`{"id":"u_foobar","actions":["read"],"output_fields":["version","id","name"]}` ,
`{"id":"u_foobar","output_fields":["version","id","name"]}` ,
`type=host-catalog;actions=create` ,
`ids=hcst_foobar,hcst_foobaz;actions=read;output_fields=version,ids,name` ,
`id=hcst_foobar;actions=read` ,
`id=acctpw_foobar;actions=read` ,
`id= {{ user .id }} ;actions=read,update` ,
"type=host-catalog;actions=create" ,
"type=*;actions=*" ,
"id=*;type=*;actions=*" ,
"ids=*;type=*;actions=*" ,
"id=*;type=*;actions=read,list" ,
"ids=*;type=*;actions=read,list" ,
"id=foobar;actions=read;output_fields=version,id,name" ,
"ids=foobar,foobaz;actions=read;output_fields=version,id,name" ,
"id={{account.id}};actions=update,read" ,
"ids={{account.id}},{{user.id}};actions=update,read" ,
`{"id":"foobar","type":"host-catalog","actions":["create"]}` ,
`{"ids":["foobar"],"type":"host-catalog","actions":["create"]}` ,
2023-09-06 09:11:56 -07:00
`{"ids":["\""]}` ,
2023-08-25 21:17:29 -04:00
}
for _ , tc := range tc {
f . Add ( tc )
}
2023-01-06 17:27:19 -06:00
f . Fuzz ( func ( t * testing . T , grant string ) {
2024-09-17 10:07:43 -04:00
g , err := Parse ( ctx , GrantTuple { GrantScopeId : "global" , Grant : grant }, WithSkipFinalValidation ( true ))
2023-01-06 17:27:19 -06:00
if err != nil {
return
}
2024-09-17 10:07:43 -04:00
g2 , err := Parse ( ctx , GrantTuple { GrantScopeId : "global" , Grant : g . CanonicalString ()}, WithSkipFinalValidation ( true ))
2023-01-06 17:27:19 -06:00
if err != nil {
t . Fatal ( "Failed to parse canonical string:" , err )
}
if g . CanonicalString () != g2 . CanonicalString () {
t . Errorf ( "grant roundtrip failed, input %q, output %q" , g . CanonicalString (), g2 . CanonicalString ())
}
2024-02-21 16:32:26 -05:00
jsonBytes , err := g . MarshalJSON ()
2023-01-06 17:27:19 -06:00
if err != nil {
t . Error ( "Failed to marshal JSON:" , err )
}
2024-09-17 10:07:43 -04:00
g3 , err := Parse ( ctx , GrantTuple { GrantScopeId : "global" , Grant : string ( jsonBytes )}, WithSkipFinalValidation ( true ))
2023-01-06 17:27:19 -06:00
if err != nil {
t . Fatal ( "Failed to parse json string:" , err )
}
if g . CanonicalString () != g3 . CanonicalString () {
t . Errorf ( "grant JSON roundtrip failed, input %q, output %q" , g . CanonicalString (), g3 . CanonicalString ())
}
})
}