diff --git a/protocol/go/authorization/v2/authorization.pb.go b/protocol/go/authorization/v2/authorization.pb.go index cecabe0934..7cc05f4f33 100644 --- a/protocol/go/authorization/v2/authorization.pb.go +++ b/protocol/go/authorization/v2/authorization.pb.go @@ -988,174 +988,184 @@ var file_authorization_v2_authorization_proto_rawDesc = []byte{ 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0xfe, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x21, + 0x01, 0x22, 0xa6, 0x03, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x49, - 0x64, 0x12, 0x57, 0x0a, 0x10, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x1d, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x1a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x71, 0x6e, 0x1a, - 0x25, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x04, 0x66, 0x71, 0x6e, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x22, 0x7e, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, - 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, - 0x72, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x08, 0x64, 0x65, - 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x61, + 0x64, 0x12, 0xf2, 0x01, 0x0a, 0x10, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, - 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x22, 0xc4, 0x02, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, - 0x52, 0x10, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x3a, 0x65, 0xba, 0x48, 0x62, 0x1a, 0x60, 0x0a, 0x29, 0x67, 0x65, 0x74, 0x5f, 0x64, - 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x64, 0x12, 0x1c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x64, 0x1a, 0x15, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x22, 0x55, 0x0a, 0x13, 0x47, 0x65, 0x74, - 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x3e, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, - 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x22, 0xde, 0x02, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x32, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x2e, 0x0a, - 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x06, 0xba, - 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, - 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x0b, 0xba, 0x48, - 0x08, 0xc8, 0x01, 0x01, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x3a, 0x6b, 0xba, 0x48, 0x68, 0x1a, 0x66, 0x0a, 0x2f, 0x67, 0x65, 0x74, - 0x5f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x98, 0x01, 0xba, 0x48, 0x94, 0x01, 0xba, + 0x01, 0x90, 0x01, 0x0a, 0x19, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x38, + 0x69, 0x66, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x2c, 0x20, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x62, 0x65, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x39, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, + 0x71, 0x6e, 0x73, 0x2e, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x20, 0x26, + 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x71, 0x6e, 0x73, 0x2e, 0x61, 0x6c, 0x6c, 0x28, + 0x69, 0x74, 0x65, 0x6d, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, + 0x28, 0x29, 0x29, 0x48, 0x00, 0x52, 0x0f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x1d, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, + 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, 0x1a, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x46, 0x71, 0x6e, 0x1a, 0x25, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, + 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x6e, 0x73, 0x42, 0x0a, + 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x7e, 0x0a, 0x10, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, + 0x0a, 0x15, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, + 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x49, 0x64, 0x12, 0x36, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xc4, 0x02, 0x0a, 0x12, 0x47, + 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x57, 0x0a, 0x11, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, + 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, + 0x01, 0x01, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x08, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, + 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x65, 0xba, 0x48, 0x62, 0x1a, + 0x60, 0x0a, 0x29, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x1c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x1a, 0x15, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, - 0x29, 0x22, 0xb6, 0x01, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x65, - 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x5f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, - 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x78, 0x0a, 0x16, 0x47, 0x65, - 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x5e, 0x0a, 0x11, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x31, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x52, 0x10, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x73, 0x22, 0x7c, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x61, 0x0a, 0x12, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, - 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, - 0x11, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x73, 0x22, 0xd9, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, - 0x11, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x06, 0xba, 0x48, - 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x1c, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, - 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x68, 0x69, 0x65, - 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x1a, - 0x77, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76, - 0x65, 0x48, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x88, 0x01, 0x01, 0x42, 0x1f, 0x0a, - 0x1d, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, - 0x73, 0x69, 0x76, 0x65, 0x5f, 0x68, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x22, 0x63, - 0x0a, 0x17, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0c, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x24, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x32, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0c, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x2a, 0x4c, 0x0a, 0x08, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x18, 0x0a, 0x14, 0x44, 0x45, 0x43, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x45, 0x43, - 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, - 0x44, 0x45, 0x43, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x54, 0x10, - 0x02, 0x32, 0xce, 0x03, 0x0a, 0x14, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5c, 0x0a, 0x0b, 0x47, 0x65, - 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x2e, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, - 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x25, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x83, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, + 0x29, 0x22, 0x55, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, + 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xde, 0x02, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x31, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x44, - 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, - 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6c, - 0x6b, 0x12, 0x28, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, - 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x45, - 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x06, 0xba, 0x48, 0x03, + 0xc8, 0x01, 0x01, 0x52, 0x10, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0x92, 0x01, 0x02, 0x08, + 0x01, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x3a, 0x6b, 0xba, 0x48, + 0x68, 0x1a, 0x66, 0x0a, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x64, 0x12, 0x1c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x64, 0x1a, 0x15, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x22, 0xb6, 0x01, 0x0a, 0x20, 0x47, 0x65, + 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, + 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x12, + 0x51, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x64, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x11, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0x78, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5e, 0x0a, 0x11, + 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, + 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x10, 0x64, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x7c, 0x0a, 0x17, + 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6c, 0x6b, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x12, 0x64, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x11, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, 0xd9, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, - 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0xd5, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x42, 0x12, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, - 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x41, 0x58, - 0x58, 0xaa, 0x02, 0x10, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x10, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x1c, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x10, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x45, + 0x0a, 0x1c, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, + 0x73, 0x69, 0x76, 0x65, 0x5f, 0x68, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x1a, 0x77, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6d, 0x70, + 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x48, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, + 0x68, 0x79, 0x88, 0x01, 0x01, 0x42, 0x1f, 0x0a, 0x1d, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, + 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x68, 0x69, 0x65, + 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x22, 0x63, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, + 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x48, 0x0a, 0x0c, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0c, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2a, 0x4c, 0x0a, 0x08, 0x44, + 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x14, 0x44, 0x45, 0x43, 0x49, 0x53, + 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x45, 0x43, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, + 0x4e, 0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x45, 0x43, 0x49, 0x53, 0x49, 0x4f, 0x4e, + 0x5f, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x54, 0x10, 0x02, 0x32, 0xce, 0x03, 0x0a, 0x14, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x5c, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x24, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, + 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x83, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x31, 0x2e, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, + 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x75, 0x6c, 0x74, + 0x69, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x32, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4d, + 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6c, 0x6b, 0x12, 0x28, 0x2e, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, + 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x68, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x12, 0x28, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x32, + 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xd5, 0x01, 0x0a, 0x14, 0x63, + 0x6f, 0x6d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x32, 0x42, 0x12, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, + 0x67, 0x6f, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x10, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x10, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x32, 0xe2, + 0x02, 0x1c, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5c, + 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x11, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, + 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/service/authorization/v2/authorization.proto b/service/authorization/v2/authorization.proto index 4eba195ad5..73453341ed 100644 --- a/service/authorization/v2/authorization.proto +++ b/service/authorization/v2/authorization.proto @@ -30,12 +30,10 @@ message EntityIdentifier { // fully qualified name of the registered resource value stored in platform policy, where in // this case the resource acts as and represents a single entity for authorization/entitlement decisioning - string registered_resource_value_fqn = 2 [ - (buf.validate.field).string = { - min_len: 1 - uri: true - } - ]; + string registered_resource_value_fqn = 2 [(buf.validate.field).string = { + min_len: 1 + uri: true + }]; // access token (JWT), which is used to create an entity chain (comprising one or more entities) entity.Token token = 3 [(buf.validate.field).cel = { @@ -67,8 +65,15 @@ message Resource { } oneof resource { - AttributeValues attribute_values = 2; - string registered_resource_value_fqn = 3; + AttributeValues attribute_values = 2 [(buf.validate.field).cel = { + id: "attribute_values_required" + message: "if provided, resource.attribute_values must not be empty" + expression: "this.fqns.size() > 0 && this.fqns.all(item, item.isUri())" + }]; + string registered_resource_value_fqn = 3 [(buf.validate.field).string = { + min_len: 1 + uri: true + }]; } } diff --git a/service/authorization/v2/authorization_test.go b/service/authorization/v2/authorization_test.go index 46cfaa3c17..110638c5a6 100644 --- a/service/authorization/v2/authorization_test.go +++ b/service/authorization/v2/authorization_test.go @@ -4,12 +4,933 @@ import ( "errors" "testing" + "buf.build/go/protovalidate" authzV2 "github.com/opentdf/platform/protocol/go/authorization/v2" + "github.com/opentdf/platform/protocol/go/entity" + "github.com/opentdf/platform/protocol/go/policy" access "github.com/opentdf/platform/service/internal/access/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +var ( + sampleActionCreate = &policy.Action{ + Name: "create", + } + sampleResourceFQN = "https://example.com/attr/hier/value/highest" + sampleResourceFQN2 = "https://example.com/attr/hier/value/lowest" + sampleRegisteredResourceFQN = "https://example.com/reg_res/system/value/internal" +) + +func getValidator() protovalidate.Validator { + v, err := protovalidate.New() + if err != nil { + panic(err) + } + return v +} + +func Test_GetDecisionRequest_Succeeds(t *testing.T) { + v := getValidator() + + cases := []struct { + name string + request *authzV2.GetDecisionRequest + }{ + { + name: "entity: token, action: create, resource: attribute values", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + }, + { + name: "entity: token, action: create, resource: registered", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: sampleRegisteredResourceFQN, + }, + }, + }, + }, + { + name: "entity: chain, action: create, resource: attribute values", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_EntityChain{ + EntityChain: &entity.EntityChain{ + EphemeralId: "1234", + Entities: []*entity.Entity{ + { + EphemeralId: "chained-1", + EntityType: &entity.Entity_EmailAddress{EmailAddress: "test@test.com"}, + Category: entity.Entity_CATEGORY_SUBJECT, + }, + { + EphemeralId: "chained-2", + EntityType: &entity.Entity_ClientId{ + ClientId: "client-123", + }, + Category: entity.Entity_CATEGORY_ENVIRONMENT, + }, + }, + }, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN, sampleResourceFQN2}, + }, + }, + }, + }, + }, + { + name: "entity: chain, action: create, resource: registered", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_EntityChain{ + EntityChain: &entity.EntityChain{ + EphemeralId: "1234", + Entities: []*entity.Entity{ + { + EphemeralId: "chained-1", + EntityType: &entity.Entity_ClientId{ + ClientId: "client-123", + }, + Category: entity.Entity_CATEGORY_ENVIRONMENT, + }, + }, + }, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: sampleRegisteredResourceFQN, + }, + }, + }, + }, + { + name: "entity: registered resource, action: create, resource: attribute values", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: sampleRegisteredResourceFQN, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN2}, + }, + }, + }, + }, + }, + { + name: "entity: registered resource, action: create, resource: registered", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: sampleRegisteredResourceFQN, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: sampleRegisteredResourceFQN, + }, + }, + }, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + err := v.Validate(tc.request) + require.NoError(t, err, "validation should succeed for request: %s", tc.name) + }) + } +} + +func Test_GetDecisionRequest_Fails(t *testing.T) { + v := getValidator() + cases := []struct { + name string + request *authzV2.GetDecisionRequest + expectedValidationError string + }{ + { + name: "missing entity identifier", + request: &authzV2.GetDecisionRequest{ + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + expectedValidationError: "entity_identifier", + }, + { + name: "missing action", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + expectedValidationError: "action", + }, + { + name: "missing resource", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + }, + expectedValidationError: "resource", + }, + { + name: "action missing name", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: &policy.Action{}, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + expectedValidationError: "name", + }, + { + name: "registered resource FQN is empty", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_RegisteredResourceValueFqn{}, + }, + }, + expectedValidationError: "resource", + }, + { + name: "registered resource FQN is invalid", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: "invalid format", + }, + }, + }, + expectedValidationError: "resource", + }, + { + name: "resource attribute value FQNs are empty", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{}, + }, + }, + }, + }, + expectedValidationError: "resource", + }, + { + name: "resource attribute value FQNs are invalid", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{"invalid-format"}, + }, + }, + }, + }, + expectedValidationError: "resource", + }, + { + name: "token entity with empty JWT", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + }, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + expectedValidationError: "jwt", + }, + { + name: "entity chain with no entities", + request: &authzV2.GetDecisionRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_EntityChain{ + EntityChain: &entity.EntityChain{ + EphemeralId: "1234", + }, + }, + }, + Action: sampleActionCreate, + Resource: &authzV2.Resource{ + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + expectedValidationError: "entities", + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + err := v.Validate(tc.request) + if err == nil { + t.Errorf("expected validation error for request: %s, but got none", tc.name) + } else { + assert.Contains(t, err.Error(), tc.expectedValidationError, "validation error should contain expected message") + } + }) + } +} + +func Test_GetDecisionMultiResourceRequest_Succeeds(t *testing.T) { + v := getValidator() + + cases := []struct { + name string + request *authzV2.GetDecisionMultiResourceRequest + }{ + { + name: "entity: token, action: create, multiple resources: attribute values", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + { + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN2}, + }, + }, + }, + }, + }, + }, + { + name: "entity: chain, action: create, multiple resources: mixed types", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_EntityChain{ + EntityChain: &entity.EntityChain{ + EphemeralId: "1234", + Entities: []*entity.Entity{ + { + EphemeralId: "chained-1", + EntityType: &entity.Entity_EmailAddress{EmailAddress: "test@test.com"}, + Category: entity.Entity_CATEGORY_SUBJECT, + }, + }, + }, + }, + }, + Action: sampleActionCreate, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + { + Resource: &authzV2.Resource_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: sampleRegisteredResourceFQN, + }, + }, + }, + }, + }, + { + name: "entity: registered resource, action: create, multiple resources: registered", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: sampleRegisteredResourceFQN, + }, + }, + Action: sampleActionCreate, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: sampleRegisteredResourceFQN, + }, + }, + { + Resource: &authzV2.Resource_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: "https://example.com/another/registered/resource", + }, + }, + }, + }, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + err := v.Validate(tc.request) + require.NoError(t, err, "validation should succeed for request: %s", tc.name) + }) + } +} + +func Test_GetDecisionMultiResourceRequest_Fails(t *testing.T) { + v := getValidator() + + cases := []struct { + name string + request *authzV2.GetDecisionMultiResourceRequest + expectedValidationError string + }{ + { + name: "missing entity identifier", + request: &authzV2.GetDecisionMultiResourceRequest{ + Action: sampleActionCreate, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + }, + expectedValidationError: "entity_identifier", + }, + { + name: "missing action", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + }, + expectedValidationError: "action", + }, + { + name: "action missing name", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: &policy.Action{}, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + }, + expectedValidationError: "name", + }, + { + name: "missing resources", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + }, + expectedValidationError: "resources", + }, + { + name: "empty resources array", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + Resources: []*authzV2.Resource{}, + }, + expectedValidationError: "resources", + }, + { + name: "invalid resource - registered resource FQN is empty", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_RegisteredResourceValueFqn{}, + }, + }, + }, + expectedValidationError: "resource", + }, + { + name: "invalid resource - empty attribute values", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{}, + }, + }, + }, + }, + }, + expectedValidationError: "resource", + }, + { + name: "invalid resource - invalid attribute values", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + Action: sampleActionCreate, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{"invalid-format"}, + }, + }, + }, + }, + }, + expectedValidationError: "resource", + }, + { + name: "token entity with empty JWT", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + }, + }, + }, + Action: sampleActionCreate, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + }, + expectedValidationError: "jwt", + }, + { + name: "entity chain with no entities", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_EntityChain{ + EntityChain: &entity.EntityChain{ + EphemeralId: "1234", + }, + }, + }, + Action: sampleActionCreate, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + }, + expectedValidationError: "entities", + }, + { + name: "registered resource as entity with invalid URI", + request: &authzV2.GetDecisionMultiResourceRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: "invalid uri", + }, + }, + Action: sampleActionCreate, + Resources: []*authzV2.Resource{ + { + Resource: &authzV2.Resource_AttributeValues_{ + AttributeValues: &authzV2.Resource_AttributeValues{ + Fqns: []string{sampleResourceFQN}, + }, + }, + }, + }, + }, + expectedValidationError: "registered_resource_value_fqn", + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + err := v.Validate(tc.request) + if err == nil { + t.Errorf("expected validation error for request: %s, but got none", tc.name) + } else { + assert.Contains(t, err.Error(), tc.expectedValidationError, "validation error should contain expected message") + } + }) + } +} + +func Test_GetEntitlementsRequest_Succeeds(t *testing.T) { + v := getValidator() + + cases := []struct { + name string + request *authzV2.GetEntitlementsRequest + }{ + { + name: "entity: token, with comprehensive hierarchy", + request: &authzV2.GetEntitlementsRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + WithComprehensiveHierarchy: &[]bool{true}[0], + }, + }, + { + name: "entity: token, without comprehensive hierarchy", + request: &authzV2.GetEntitlementsRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + WithComprehensiveHierarchy: &[]bool{false}[0], + }, + }, + { + name: "entity: token, hierarchy option not specified", + request: &authzV2.GetEntitlementsRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + Jwt: "sample-jwt-token", + }, + }, + }, + }, + }, + { + name: "entity: chain of multiple entities", + request: &authzV2.GetEntitlementsRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_EntityChain{ + EntityChain: &entity.EntityChain{ + EphemeralId: "1234", + Entities: []*entity.Entity{ + { + EphemeralId: "chained-1", + EntityType: &entity.Entity_EmailAddress{EmailAddress: "test@test.com"}, + Category: entity.Entity_CATEGORY_SUBJECT, + }, + { + EphemeralId: "chained-2", + EntityType: &entity.Entity_ClientId{ + ClientId: "client-123", + }, + Category: entity.Entity_CATEGORY_ENVIRONMENT, + }, + }, + }, + }, + }, + WithComprehensiveHierarchy: &[]bool{true}[0], + }, + }, + { + name: "entity: registered resource", + request: &authzV2.GetEntitlementsRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: sampleRegisteredResourceFQN, + }, + }, + }, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + err := v.Validate(tc.request) + require.NoError(t, err, "validation should succeed for request: %s", tc.name) + }) + } +} + +func Test_GetEntitlementsRequest_Fails(t *testing.T) { + v := getValidator() + + cases := []struct { + name string + request *authzV2.GetEntitlementsRequest + expectedValidationError string + }{ + { + name: "missing entity identifier", + request: &authzV2.GetEntitlementsRequest{}, + expectedValidationError: "entity_identifier", + }, + { + name: "token entity with empty JWT", + request: &authzV2.GetEntitlementsRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_Token{ + Token: &entity.Token{ + EphemeralId: "123", + }, + }, + }, + }, + expectedValidationError: "jwt", + }, + { + name: "entity chain with no entities", + request: &authzV2.GetEntitlementsRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_EntityChain{ + EntityChain: &entity.EntityChain{ + EphemeralId: "1234", + }, + }, + }, + }, + expectedValidationError: "entities", + }, + { + name: "registered resource FQN is empty", + request: &authzV2.GetEntitlementsRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: "", + }, + }, + }, + expectedValidationError: "registered_resource_value_fqn", + }, + { + name: "registered resource FQN is invalid URI", + request: &authzV2.GetEntitlementsRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{ + Identifier: &authzV2.EntityIdentifier_RegisteredResourceValueFqn{ + RegisteredResourceValueFqn: "invalid uri", + }, + }, + }, + expectedValidationError: "registered_resource_value_fqn", + }, + { + name: "no identifier specified", + request: &authzV2.GetEntitlementsRequest{ + EntityIdentifier: &authzV2.EntityIdentifier{}, + }, + expectedValidationError: "identifier", + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + err := v.Validate(tc.request) + if err == nil { + t.Errorf("expected validation error for request: %s, but got none", tc.name) + } else { + assert.Contains(t, err.Error(), tc.expectedValidationError, "validation error should contain expected message") + } + }) + } +} + func Test_RollupSingleResourceDecision(t *testing.T) { tests := []struct { name string