diff --git a/pubsignals/common.go b/pubsignals/common.go index 8ecb6f1..9aff789 100644 --- a/pubsignals/common.go +++ b/pubsignals/common.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "math/big" + "reflect" "strconv" "github.com/iden3/go-circuits/v2" @@ -159,7 +160,7 @@ func ParseQueryMetadata(ctx context.Context, propertyQuery PropertyQuery, ldCont } } if propertyQuery.Operator == circuits.EXISTS { - query.Values, err = transformQueryValueToBigInts(ctx, propertyQuery.OperatorValue, ld.XSDBoolean) // TODO: refactor + query.Values, err = transformExistsOperatorValueToBigInt(ctx, propertyQuery.OperatorValue) } else { query.Values, err = transformQueryValueToBigInts(ctx, propertyQuery.OperatorValue, query.Datatype) } @@ -221,6 +222,17 @@ func transformQueryValueToBigInts(_ context.Context, value any, ldType string) ( return []*big.Int{hashValue}, err } +func transformExistsOperatorValueToBigInt(_ context.Context, value any) (out []*big.Int, err error) { + t := reflect.TypeOf(value).Kind() + if t != reflect.Bool { + return nil, errors.New("only boolean value is supported for operator $exists") + } + val := new(big.Int) + if value == true { + val.SetInt64(1) + } + return []*big.Int{val}, err +} func isPositiveInteger(v interface{}) bool { number, err := strconv.ParseFloat(fmt.Sprintf("%v", v), 64) if err != nil { diff --git a/pubsignals/query_test.go b/pubsignals/query_test.go index 39ca4cf..2e4a806 100644 --- a/pubsignals/query_test.go +++ b/pubsignals/query_test.go @@ -310,7 +310,60 @@ func TestCheckRequest_Success(t *testing.T) { }) } } +func TestCheckRequestV3_Success(t *testing.T) { + now := time.Now().Unix() + tests := []struct { + name string + query Query + pubSig *CircuitOutputs + vp json.RawMessage + loader *mockJSONLDSchemaLoader + }{ + { + name: "Check merklized query, exists operator", + query: Query{ + AllowedIssuers: []string{"*"}, + CredentialSubject: map[string]interface{}{ + "countryCode": map[string]interface{}{ + "$exists": true, + }, + }, + Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld", + Type: "KYCCountryOfResidenceCredential", + }, + pubSig: &CircuitOutputs{ + IssuerID: &issuerID, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), + ClaimPathKey: func() *big.Int { + v, _ := big.NewInt(0).SetString("17002437119434618783545694633038537380726339994244684348913844923422470806844", 10) + return v + }(), + Operator: 11, + Value: func() []*big.Int { + v, _ := circuits.PrepareCircuitArrayValues([]*big.Int{big.NewInt(1)}, 64) + return v + }(), + Merklized: 1, + IsRevocationChecked: 1, + ValueArraySize: 1, + Timestamp: now, + }, + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.query.Check(context.Background(), tt.loader, tt.pubSig, tt.vp, circuits.AtomicQueryV3CircuitID) + require.NoError(t, err) + tt.loader.assert(t) + }) + } +} func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { now := time.Now().Unix() durationMin, _ := time.ParseDuration("-1m")