diff --git a/entc/gen/internal/bindata.go b/entc/gen/internal/bindata.go index c3a9afc72..64d3997ac 100644 --- a/entc/gen/internal/bindata.go +++ b/entc/gen/internal/bindata.go @@ -1046,7 +1046,7 @@ func templatePredicateTmpl() (*asset, error) { return a, nil } -var _templatePrivacyTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x58\x41\x6f\xdb\xb8\x12\x3e\x4b\xbf\x62\x20\x38\x80\xd5\xe7\x2a\x7d\xbd\xbd\x14\x39\x14\x6d\x0a\x14\x78\x9b\x76\xb7\xbd\x15\x45\xc1\x48\x23\x9b\x88\x44\x2a\x24\x15\xc7\x70\xf5\xdf\x17\x43\x91\x32\x25\xc7\x6e\xb2\x49\x81\x3d\x05\x26\x87\x33\x1f\x67\xbe\x6f\x86\xca\x76\x7b\xfa\x22\x7e\x27\x9b\x8d\xe2\xcb\x95\x81\xd7\xaf\xfe\xfb\xbf\x97\x8d\x42\x8d\xc2\xc0\x07\x96\xe3\x95\x94\xd7\xf0\x51\xe4\x19\xbc\xad\x2a\xb0\x46\x1a\x68\x5f\xdd\x62\x91\xc5\x5f\x57\x5c\x83\x96\xad\xca\x11\x72\x59\x20\x70\x0d\x15\xcf\x51\x68\x2c\xa0\x15\x05\x2a\x30\x2b\x84\xb7\x0d\xcb\x57\x08\xaf\xb3\x57\x7e\x17\x4a\xd9\x8a\x22\xe6\xc2\xee\xff\xff\xe3\xbb\x8b\xcb\x2f\x17\x50\xf2\x0a\xc1\xad\x29\x29\x0d\x14\x5c\x61\x6e\xa4\xda\x80\x2c\xc1\x04\xc1\x8c\x42\xcc\xe2\x17\xa7\x5d\x17\xc7\xdb\x2d\x14\x58\x72\x81\x90\x34\x8a\xdf\xb2\x7c\x93\x40\xbf\xfe\x12\xd6\xdc\xac\x00\xef\x0c\x8a\x02\x66\x90\x7c\x66\xf9\x35\x5b\x62\x12\x58\xbe\xec\xba\x38\xda\x6e\xc1\x60\xdd\x54\xcc\x20\x24\x2b\x64\x05\xaa\x04\x32\xf2\xb2\xdd\x02\x9d\x25\x7f\xbc\x6e\xa4\x32\x90\x6c\xb7\x30\xcb\xde\x49\x51\xf2\x65\xe6\x1c\x42\xd7\x25\x16\xc8\xac\xb9\x5e\xc2\xd9\x39\x5c\x31\x8d\xf7\x59\xc5\xf1\x2d\x53\x30\x8f\xa3\xd3\x53\xca\xa8\x5c\x43\xcd\x36\x70\x85\xa0\xd0\xb4\x4a\x60\x01\x57\x1b\x50\x6d\x85\x1a\x8c\x04\x2e\x0a\x9e\x13\x26\xb3\x62\xc6\x66\xa5\x91\x15\xcf\x37\xf6\x38\xde\xb2\xaa\x65\x86\x4b\x01\x7a\x25\xdb\xaa\x00\x83\xaa\xe6\x82\xec\xed\xb5\x99\x00\x66\x43\x14\x98\x73\xcd\xa5\xc8\xe2\xa8\x8f\x79\x0e\xa8\x94\x54\x3a\xbb\xc4\xf5\x3c\x41\x61\x4e\x5d\x3a\xce\xdc\x09\x42\x90\xa4\xb1\x8d\xf3\x1e\xc5\xe6\xf7\xa2\x2c\x28\x42\x00\xd2\x46\x3c\x82\xd1\xda\x87\x10\xbf\x5c\xf3\xe6\x39\x21\xe6\x52\x18\x2e\x5a\xa4\xa3\x64\x2c\xf0\xce\x58\x67\x59\x1c\xd9\x58\x47\xc0\x69\xda\x77\xe0\xd2\x9e\x84\x8a\x89\x25\xc2\xcc\xdf\x90\xf8\x51\x71\x6d\x20\xb1\xd5\x48\x20\xa1\x0b\x27\x90\x90\x6b\x4b\x5d\x42\x45\x64\x1a\x4e\x74\x5d\xe9\x2e\xa6\x29\x61\xa5\x54\x35\x33\x06\x0b\x58\x2b\xd6\x34\x58\x4c\xad\xc3\x6c\x96\xad\xc8\xf7\xbc\xcd\x7b\x17\xa0\x8d\xe2\x62\xb9\x00\x06\x59\x96\x71\x61\x50\x95\x2c\xc7\x6d\x97\xf6\x17\x84\x6d\x1c\x45\x7d\x60\x28\x6b\x93\x5d\xd0\xa2\x3f\xfc\x9f\xe4\x0c\x4e\xd6\xc9\x02\x08\x82\x28\xe6\x6c\x31\x0d\x93\x66\x59\x96\xc6\x51\x67\xb3\xe0\x65\x64\x36\x0d\x3a\x05\xfc\xd9\xa2\xda\x7c\xb6\x95\x80\x5c\xd6\x57\x5c\xa0\x86\xba\xad\x0c\x6f\x2a\x84\x1b\xda\x75\x35\xe4\xc2\x48\x60\xa0\xb9\x58\x56\xbe\x78\x59\x1c\x85\x0e\xbe\x7d\xb7\xbf\xfe\x6a\x2b\x8c\x77\xde\xe9\xa7\x6b\x0f\xda\xd6\x72\xb8\xa4\xcd\x51\xc1\xc5\x12\xd6\x2b\x34\x2b\x54\xc0\xec\xb1\x3e\x2c\xd7\xbd\x14\xb0\x00\x26\x0a\x90\x0d\xf1\x83\x55\xd5\x06\x6a\x59\xf0\x72\x03\xdc\xf8\xf8\x36\xc4\xce\x2d\xa5\xec\xe2\x96\x55\x76\x6f\x4e\x54\xc2\x3b\x43\x9d\x80\xfe\xf6\x29\xa2\x26\xd1\x75\x99\xb5\x70\x99\xa6\x2c\xa5\x71\x7c\x7a\x0a\xc3\x59\x4f\x4c\xd4\xc0\x1c\x2a\xb6\x64\x5c\x68\x33\xfc\xf6\x89\xb0\x35\x9e\xf7\xbf\xc2\xac\xa6\x10\x20\x31\x77\xb0\x87\xe6\xe6\x10\x1e\xba\x46\x29\x15\xfc\x58\xd8\x0a\x10\x67\x7b\x1a\xbb\x20\x74\x4b\xbd\xe6\x26\x5f\x91\xbd\xdd\x26\x7d\x8c\xc2\x2d\xe0\x26\x7d\x63\x2d\x73\x6a\x87\x64\x77\x7e\x0e\x82\x57\xf0\xf3\xa7\x17\xd0\x47\x3d\x47\xa5\x16\x56\xc2\xe9\x59\x60\x1a\x6e\x5a\x9d\xd8\x5d\x4f\x46\xc1\xab\x38\x8a\x0a\x2c\x59\x5b\x99\x70\x03\x95\x8a\xa3\xa8\xa3\x74\x86\xb6\x9d\x4d\xed\x50\xae\x0f\x94\x2f\x4b\x44\x6e\x05\xc5\x0a\xd6\x18\x1a\x56\xd2\x35\x40\x62\x4a\xab\x11\x64\x49\xe7\xa4\x2a\xb8\x60\x6a\x03\x94\x67\x22\x82\x06\xa6\x43\x7e\x66\x3d\xab\xc7\xfe\xc9\xf8\xe1\xf5\xf7\xa5\x1f\x74\x5e\xfa\x14\xfa\xf2\x96\x63\xff\x4f\xab\xad\x17\xb5\x0f\x12\x8f\x95\xf9\x47\x6b\x6c\x47\x3c\x28\xce\xda\x19\x1c\xd7\xe7\xc4\xcd\xb7\xef\x7e\x61\xa7\xd2\x70\xe5\x71\x42\x1d\x20\x3c\x4c\xab\xa3\x40\xfb\x72\xf5\xdb\x47\x2b\xe6\x8d\xee\x15\xad\xdf\x1c\xe9\x76\x00\xb9\x93\xee\xb0\x74\xaf\x7a\xc7\x29\x4b\x61\x8c\xed\xbe\x3a\xd7\x47\x10\x3e\x41\xc6\x61\xd0\x05\xd4\xff\x2e\x25\x87\xc5\x7c\x16\x31\x8f\xf9\xec\xf4\xbc\x17\xe5\x97\x92\x9e\x12\x64\x8f\x1b\x13\x75\xd7\x81\xba\xa7\xd1\x9e\xa3\xf6\x63\x99\xd7\xa9\x4b\x9f\xd3\xe3\x52\xc9\xb6\xf1\x8d\x8c\xa4\x33\xa6\x26\x1f\x12\xe1\xec\xb5\x51\x6d\x6e\xc8\x6f\x3f\xa0\x82\x49\xb3\xd3\xd7\x84\xc1\x2e\xe2\x6e\xaa\x95\x52\xad\x99\x2a\x74\xf8\xee\x32\xf2\xd8\x40\x7b\x8e\x59\xe6\x12\xe1\xfc\xdb\xdd\xfd\x61\x15\x60\x1d\x6e\x73\x00\xee\x71\x11\x3f\x9f\x78\xc7\xb8\xbd\xc1\xbd\x02\x0d\x87\xdc\xb8\xd9\x4d\x1b\xaa\x7d\x05\x1f\x2e\xfe\xde\x48\x3b\xdc\x3a\x77\x4f\xae\x51\x7f\x75\x50\xde\x56\x6b\xb6\xd1\x56\xf3\xf6\xe8\xf0\x84\xed\x9b\x91\x85\x11\x3c\x6b\xa7\x5f\x2b\x36\xa5\x13\x1f\xf3\xf4\x1e\x48\x01\xd1\xf9\x1d\x16\xef\x9d\x07\xda\xdb\xda\x93\xdd\x08\x10\x3d\xb7\x7f\x8d\x67\xfa\x59\x12\xa0\xf1\x0e\x1e\x0d\x86\x0e\x76\xc3\xa8\xdd\xdb\x1f\x04\x66\x3b\x6c\xcf\x81\x2e\x1e\x1a\xc4\x9e\xfd\x48\x12\x0f\x7c\x68\xc0\x16\x3c\xbc\x8c\xa2\x74\xbf\x72\xff\x4f\x06\xe3\x7e\x90\xd8\x7d\x49\x7a\xc3\x4f\x0d\xaa\x5d\xce\x26\x85\xa0\xcc\xd3\xbc\xd7\x0d\xe6\xbc\xe4\x18\x70\x53\xfa\x73\xae\x20\x07\x7d\xce\x65\x13\x02\xfc\xd4\xa4\x70\xa0\x4c\xd3\xbe\x3b\xb7\x5d\xfe\xc7\xe3\xb5\x1a\xf1\x12\xea\xec\x53\x33\x4f\x69\xde\xc9\x26\xb5\x8b\x3e\x0c\x21\x2d\x27\x1f\x8b\xc3\x6d\xe0\x44\x93\x4c\x85\x34\xfe\x29\x93\x2c\x9c\xaf\xb4\x9f\x82\xde\x0d\x8d\xd7\x38\xea\xac\xda\x83\x8f\x4b\xfb\x55\x39\xcb\x2e\x65\x81\x1a\xdc\xbf\x34\x66\x82\xd5\x76\xe4\x37\x8a\x0b\x03\x33\x91\x5d\xd2\x42\x32\x7a\x46\x26\x83\xb5\xe5\xa4\xb7\x2e\x21\x79\x71\xa2\xb3\x13\x9d\xf4\x37\x9e\x89\x9e\x45\xd6\x83\xfb\x44\xfd\xba\x42\x18\xc2\x74\xdd\x03\x67\xf0\x30\x80\xad\x8f\xd1\x10\x66\xc1\x9b\x3a\x8b\x23\xeb\x2f\x0c\x70\x78\xfc\x5a\xd3\xae\x1b\xc6\x6e\x34\x1a\x39\xd3\xc7\xae\xff\x2a\x9e\x97\xa1\xfb\xa7\x0d\x18\x2a\xfe\xcd\x02\xe4\x35\xa5\xf0\x26\x9b\x87\xa8\xde\xd0\x72\xc8\x85\xdd\xb3\x7b\x54\xdb\xfb\x28\xd2\x0a\xbc\x6b\x30\xa7\x8f\xfd\x3e\x39\xd6\xe9\xc9\xd7\x05\xf4\xeb\xe1\xf5\x93\xde\x65\x17\x07\xe5\xdf\xab\xfe\x94\xee\x13\x02\x1c\xae\xbf\x3f\xf8\x9b\x29\x30\x1a\x43\xcf\xc3\x82\x61\x98\xe7\xac\xaa\x46\x6f\xaf\xc3\x3c\x78\xda\xd8\xb6\xad\xc0\xb3\xa1\x7e\x18\x1b\xea\xc7\xb1\x61\xc8\xd3\x71\x42\xd4\x7b\xff\x80\xd9\xfd\x4b\xf3\xef\x00\x00\x00\xff\xff\x6d\x2f\x50\x5f\xfe\x15\x00\x00") +var _templatePrivacyTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x58\x4d\x6f\xdc\xbc\x11\x3e\xaf\x7e\xc5\x40\x58\x07\x52\xba\x91\xd3\xdc\xea\xc0\x87\xc0\x75\x80\xa0\xad\x93\x36\x41\x7b\x08\x82\x80\x96\x46\xbb\x84\x25\x52\x26\x29\xef\x2e\x14\xfd\xf7\x82\x23\x51\x4b\x69\x3f\x62\x37\x0e\xfa\x1e\x45\xce\xc7\x33\xc3\x67\x66\x48\x35\xcd\xf9\xcb\xe0\x4a\x56\x5b\xc5\x97\x2b\x03\x6f\x5e\xff\xf9\x2f\xaf\x2a\x85\x1a\x85\x81\xf7\x2c\xc5\x5b\x29\xef\xe0\x83\x48\x13\x78\x57\x14\x40\x42\x1a\xec\xbe\x7a\xc0\x2c\x09\xbe\xac\xb8\x06\x2d\x6b\x95\x22\xa4\x32\x43\xe0\x1a\x0a\x9e\xa2\xd0\x98\x41\x2d\x32\x54\x60\x56\x08\xef\x2a\x96\xae\x10\xde\x24\xaf\xdd\x2e\xe4\xb2\x16\x59\xc0\x05\xed\xff\xfd\xc3\xd5\xf5\xcd\xe7\x6b\xc8\x79\x81\xd0\xaf\x29\x29\x0d\x64\x5c\x61\x6a\xa4\xda\x82\xcc\xc1\x78\xce\x8c\x42\x4c\x82\x97\xe7\x6d\x1b\x04\x4d\x03\x19\xe6\x5c\x20\x84\x95\xe2\x0f\x2c\xdd\x86\xd0\xad\xbf\x82\x35\x37\x2b\xc0\x8d\x41\x91\xc1\x1c\xc2\x4f\x2c\xbd\x63\x4b\x0c\x3d\xc9\x57\x6d\x1b\xcc\x9a\x06\x0c\x96\x55\xc1\x0c\x42\xb8\x42\x96\xa1\x0a\x21\xb1\x56\x9a\x06\xac\xae\xb5\xc7\xcb\x4a\x2a\x03\x61\xd3\xc0\x3c\xb9\x92\x22\xe7\xcb\xa4\x37\x08\x6d\x1b\x12\x90\x79\x75\xb7\x84\x8b\x4b\xb8\x65\x1a\x0f\x49\x05\xc1\x03\x53\x10\x05\xb3\xf3\x73\x9b\x51\xb9\x86\x92\x6d\xe1\x16\x41\xa1\xa9\x95\xc0\x0c\x6e\xb7\xa0\xea\x02\x35\x18\x09\x5c\x64\x3c\xb5\x98\xcc\x8a\x19\xca\x4a\x25\x0b\x9e\x6e\x49\x1d\x1f\x58\x51\x33\xc3\xa5\x00\xbd\x92\x75\x91\x81\x41\x55\x72\x61\xe5\x29\x6c\x26\x80\x91\x8b\x0c\x53\xae\xb9\x14\x49\x30\xeb\x7c\x5e\x02\x2a\x25\x95\x4e\x6e\x70\x1d\x85\x28\xcc\x79\x9f\x8e\x8b\x5e\xc3\x22\x08\xe3\x80\xfc\xfc\x15\xc5\xf6\xf7\xa2\xcc\xac\x07\x0f\x24\x79\x3c\x81\x91\xe4\x7d\x88\x9f\xef\x78\xf5\x9c\x10\x53\x29\x0c\x17\x35\x5a\x55\x2b\x2c\x70\x63\xc8\x58\x12\xcc\xc8\xd7\x09\x70\xda\xee\xf7\xe0\xe2\x8e\x84\x8a\x89\x25\xc2\xdc\x45\x68\xf9\x51\x70\x6d\x20\xa4\xd3\x08\x21\xb4\x01\x87\x10\x5a\xd3\x44\x5d\x8b\xca\x92\x69\xd0\x68\xdb\xbc\x0f\x4c\xdb\x84\xe5\x52\x95\xcc\x18\xcc\x60\xad\x58\x55\x61\x36\x95\xf6\xb3\x99\xd7\x22\xdd\xb3\x16\x75\x26\x40\x1b\xc5\xc5\x72\x01\x0c\x92\x24\xe1\xc2\xa0\xca\x59\x8a\x4d\x1b\x77\x01\x42\x13\xcc\x66\x9d\x63\xc8\x4b\x93\x5c\xdb\x45\xa7\xfc\xa7\xf0\x02\xce\xd6\xe1\x02\x2c\x04\x91\x45\x6c\x31\x75\x13\x27\x49\x12\x07\xb3\x96\xb2\xe0\xca\xc8\x6c\x2b\x1c\xf0\x5d\x99\xcd\xdf\x70\x6b\x61\xd4\xa9\x81\xa6\x0d\x02\x62\x5c\xbf\x29\x85\xb1\x99\x4f\x15\x32\x83\x1a\xd8\xa0\x46\x27\x84\x1b\x93\x04\x14\xdd\x44\x21\xaa\x98\xb2\x0d\xcc\x09\xf5\xcb\x8b\x9d\x3a\x05\x17\x4f\x05\x6c\xb4\x3c\xdf\x49\x5d\x5e\x82\xe0\x05\xfc\xf8\xe1\x4e\xfb\x83\x8e\xdc\xe6\x82\x48\x17\xfb\x09\xea\xbc\xda\x70\xdd\x8a\xb3\xff\x1f\x6e\x56\xff\x66\x45\x8d\x3d\xb2\xc5\x24\xfe\xa6\xdd\xad\xc4\x41\x1b\x74\x51\xb9\x95\xf7\x4a\x96\x2e\xb2\xd4\x6c\xa6\xa8\x63\x88\x08\xde\x02\x6e\xa5\x2c\x08\x11\x2a\xb5\x00\x79\x67\x89\x96\x9a\x4d\xd2\xb9\x9e\xba\x8c\x93\x4e\x2f\xa6\xa0\xe5\x1d\xbc\x78\xe1\xc5\x49\x26\x88\x9f\x5d\x8c\xa8\x14\x50\x3a\xfc\xf8\x7a\x3f\x81\x3b\xd5\xae\xaf\xfd\xb3\x46\xb5\xfd\x44\xf5\x05\xa9\x2c\x6f\xb9\x40\x0d\x65\x5d\x18\x5e\x15\x08\xf7\x76\xb7\xaf\x4c\x2e\x8c\x04\x06\x9a\x8b\x65\xe1\x4a\x32\x09\x66\xbe\x81\xaf\xdf\xe8\xeb\x5f\x75\x81\xc1\xce\xba\xfd\xec\x9b\xbe\xa6\x0a\x1d\xa8\x4b\x59\xcb\xb8\x58\xc2\x7a\x85\x66\x85\x0a\x18\xa9\x75\x6e\xb9\xee\x1a\x1c\x66\xc0\x44\x06\xb2\xb2\x55\xcf\x8a\x62\x0b\xa5\xcc\x78\xbe\x05\x6e\x9c\x7f\x72\xb1\x33\x6b\x73\x70\xfd\xc0\x0a\xda\x8b\xf6\x98\xe5\x5a\x7f\xdb\x26\x24\xd1\xd7\x8f\x4d\x56\x4c\x9c\x1e\x74\x5d\xbb\x21\x3e\x77\xa8\xd8\x92\x71\xa1\xcd\xf0\xed\x12\x41\x2c\x88\xba\x2f\x3f\xab\x31\x78\x48\xf6\x09\xb1\x80\xfb\x63\x78\x7a\x86\x7b\xfc\x38\x42\xb2\xf8\xad\xdd\xf7\xc8\x8d\x8a\x82\x99\xe5\x52\xc1\xf7\x05\x9d\x9f\x55\xef\x5a\x5b\x0f\xd1\x8a\xeb\x35\x37\xe9\xca\x8a\xd3\xb6\xed\x99\x23\xb0\x0b\xb8\x8f\xdf\x92\x64\x6a\x47\x24\xd1\xea\x40\x99\x11\x42\xaa\xb0\x0b\x4f\x74\x9f\x9b\x76\xd7\x41\x24\x72\xce\x32\xcc\x59\x5d\x18\x7f\x83\xb0\x5b\xf0\x3b\xe6\x5a\xd9\xae\xd9\x0c\x87\xfd\xde\x66\x9b\x68\xcc\xa9\xc9\xb2\x8c\x55\xc6\x5e\x60\x64\x3f\x14\x2d\xcf\x6a\x8d\x20\x73\xab\x27\x55\xc6\x05\x53\x5b\xb0\xa7\x64\x69\xa4\x81\x69\x9f\xdd\x49\x57\x13\x63\xfb\x56\xf8\xf1\xec\x71\xc4\x19\x7a\x7f\xee\x52\xe8\xc8\x91\x8f\xed\xff\x1a\x33\x5c\xa3\x77\x4e\x26\x75\xfd\x8f\xda\xd0\x94\x3c\x5a\xda\x65\x2f\x70\xba\xba\x27\x66\xbe\x7e\x73\x0b\xbb\x1a\xf7\x57\x9e\x56\xe6\x03\x84\xc7\x55\xfa\xc8\xd1\x7e\xb1\xbb\xed\x93\x27\xe6\x84\x0e\x96\xbc\xdb\x1c\x55\xfd\x00\x72\x57\xf8\xc3\xd2\xc1\xda\x1f\xa7\x2c\x86\x31\xb6\x43\xe7\x5c\x9e\x40\xf8\x7f\x6b\x02\x3e\xe4\x05\x94\x7f\xac\x3e\xe0\x53\xe1\x59\x5a\xc1\xb8\x1a\xfa\x6e\xb0\xe7\xe5\xa7\x0d\x61\x4a\xaf\x3d\x66\x4d\x7a\x43\xe9\xf5\x86\xa9\xb7\xe7\x60\xce\xb8\x49\x94\x71\x9f\xbe\xbe\x9a\x97\x4a\xd6\x95\x6b\x83\xb6\xf0\xc6\xc4\xe6\x43\x22\x7a\x79\x77\xf1\xeb\x87\xae\x3f\xe5\x76\xd5\x39\xe1\x7f\xef\x71\x37\x51\x73\xa9\xd6\x4c\x65\xda\xbf\xc9\x1b\x79\x6a\x98\x3e\xc7\x1c\x75\xb7\xbe\xce\x3e\xed\xee\x8f\x3a\x0f\xeb\x10\xcd\x11\xb8\xa7\x5b\xc0\xf3\x95\xfe\x18\xb7\x13\x38\x58\xa0\xfe\x88\x1c\xb7\xca\x69\x3b\xa6\x77\xd5\xf1\xc3\xdf\x1b\x88\xc7\x1b\xef\xee\xba\x37\xea\xce\x3d\x94\x77\xc5\x9a\x6d\x35\xd5\x3c\xa9\x0e\x8f\xa2\xae\x19\x11\x0c\xef\xa1\x34\x7d\xff\x52\x4a\x27\x36\xa2\xf8\x00\x24\x8f\xe8\x7c\x83\x99\x7b\x60\xd8\xbd\x86\x34\xdb\x11\x20\xfb\x80\xfb\x39\x9e\xe9\x43\xd7\x43\xe3\x0c\x3c\x19\x8c\x55\x6c\x87\x41\xbd\xb7\x3f\x14\x18\x75\xd8\x8e\x03\xee\x7d\x11\xe5\xfb\xf2\xa3\x92\x78\xe4\x35\x05\x1a\x70\xf0\x12\xeb\xa5\xfd\x99\xf9\xff\x65\xac\xee\x3b\x09\xfa\x7f\x13\x4e\xf0\x63\x85\x6a\x97\xb3\xc9\x41\xd8\xcc\xdb\xdb\x82\xae\x30\xe5\x39\x47\x8f\x9b\xd2\xe9\x0d\x8f\xc9\x23\x36\x23\x59\xf9\x00\x3f\x56\x31\x1c\x39\xa6\x69\xdf\x8d\xa8\xcb\x7f\x7f\x7a\xad\xda\x39\x5d\x26\x1f\xab\x28\xb6\xf3\x4e\xf6\xef\x4d\xe7\xc6\x22\xcd\x27\xbf\x1f\x86\x68\xe0\x4c\xdb\x32\x15\xd2\xb8\x8b\x50\xb8\xe8\x6d\xc5\xdd\x14\x74\x66\xec\x78\x0d\x66\x2d\x55\xbb\xf7\xbb\x82\xfe\x53\xcc\x93\x1b\x99\xa1\x86\xfe\x27\xd9\x5c\xb0\x92\x46\x7e\xa5\xb8\x30\x30\x17\xc9\x8d\x5d\x08\x47\x97\xd0\x70\x90\x26\x4e\x3a\xe9\x1c\xc2\x97\x67\x3a\x39\xd3\x61\x17\xf1\x5c\x74\x2c\x22\x0b\xfd\x4f\x8f\x2f\x2b\x84\xc1\x4d\xdb\x3e\x72\x06\x0f\x03\x98\x6c\x8c\x86\x30\xf3\x6e\xe4\x49\x30\x23\x7b\xbe\x83\xe3\xe3\x97\x44\xdb\x76\x18\xbb\xb3\xd1\xc8\x99\x5e\x95\xdd\x7f\x96\x28\xf7\xcd\xff\xda\x80\xb1\x87\x7f\xef\xae\x68\xf7\x49\xe4\xa3\x1a\x6e\x66\xfb\x97\xf6\xd1\xd9\x1e\xa2\x48\x2d\x70\x53\x61\x6a\x30\xeb\x93\x43\x46\xcf\xbe\x2c\xa0\x5b\xf7\xc3\x0f\x3b\x93\x6d\xe0\x1d\xff\xde\xe9\x4f\xe9\x3e\x21\xc0\xf1\xf3\x77\x8a\xbf\x99\x02\xa3\x31\xf4\x3c\x2c\x18\x86\x79\xca\x8a\x62\x74\xf7\x3a\xce\x83\x5f\x1b\xdb\xd4\x0a\x1c\x1b\xca\xc7\xb1\xa1\x7c\x1a\x1b\x86\x3c\x9d\x26\x44\xb9\xf7\x4b\x6f\xf7\x93\xfc\xbf\x01\x00\x00\xff\xff\xb6\x14\xf1\xd5\x50\x18\x00\x00") func templatePrivacyTmplBytes() ([]byte, error) { return bindataRead( @@ -1061,7 +1061,7 @@ func templatePrivacyTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/privacy.tmpl", size: 5630, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/privacy.tmpl", size: 6224, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/entc/gen/template/privacy.tmpl b/entc/gen/template/privacy.tmpl index cb7d0c061..1c0649895 100644 --- a/entc/gen/template/privacy.tmpl +++ b/entc/gen/template/privacy.tmpl @@ -35,6 +35,24 @@ var ( } {{- end }} +type decisionCtxKey struct {} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -48,6 +66,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q {{ $pkg }}.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -82,6 +103,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m {{ $pkg }}.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/entc/integration/config/ent/privacy/privacy.go b/entc/integration/config/ent/privacy/privacy.go index 4080760a7..b03484535 100644 --- a/entc/integration/config/ent/privacy/privacy.go +++ b/entc/integration/config/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/entc/integration/customid/ent/privacy/privacy.go b/entc/integration/customid/ent/privacy/privacy.go index de10bff8d..81cdbde55 100644 --- a/entc/integration/customid/ent/privacy/privacy.go +++ b/entc/integration/customid/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/entc/integration/ent/privacy/privacy.go b/entc/integration/ent/privacy/privacy.go index e3d721965..db41eda91 100644 --- a/entc/integration/ent/privacy/privacy.go +++ b/entc/integration/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/entc/integration/gremlin/ent/privacy/privacy.go b/entc/integration/gremlin/ent/privacy/privacy.go index 88c659404..c08d38585 100644 --- a/entc/integration/gremlin/ent/privacy/privacy.go +++ b/entc/integration/gremlin/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/entc/integration/hooks/ent/privacy/privacy.go b/entc/integration/hooks/ent/privacy/privacy.go index 091a28a80..7d08bc706 100644 --- a/entc/integration/hooks/ent/privacy/privacy.go +++ b/entc/integration/hooks/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/entc/integration/idtype/ent/privacy/privacy.go b/entc/integration/idtype/ent/privacy/privacy.go index 4dc3780bf..92c9a74b2 100644 --- a/entc/integration/idtype/ent/privacy/privacy.go +++ b/entc/integration/idtype/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/entc/integration/json/ent/privacy/privacy.go b/entc/integration/json/ent/privacy/privacy.go index 6485dcd82..a5cd821c2 100644 --- a/entc/integration/json/ent/privacy/privacy.go +++ b/entc/integration/json/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/entc/integration/migrate/entv1/privacy/privacy.go b/entc/integration/migrate/entv1/privacy/privacy.go index 75cc5f1e6..9613c989c 100644 --- a/entc/integration/migrate/entv1/privacy/privacy.go +++ b/entc/integration/migrate/entv1/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q entv1.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m entv1.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/entc/integration/migrate/entv2/privacy/privacy.go b/entc/integration/migrate/entv2/privacy/privacy.go index dad8eaac2..325b0b2cd 100644 --- a/entc/integration/migrate/entv2/privacy/privacy.go +++ b/entc/integration/migrate/entv2/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q entv2.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m entv2.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/entc/integration/privacy/ent/privacy/privacy.go b/entc/integration/privacy/ent/privacy/privacy.go index a4e18dfc4..ee7687846 100644 --- a/entc/integration/privacy/ent/privacy/privacy.go +++ b/entc/integration/privacy/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/entc/integration/privacy/privacy_test.go b/entc/integration/privacy/privacy_test.go index 0bb3ddbe6..0112edffe 100644 --- a/entc/integration/privacy/privacy_test.go +++ b/entc/integration/privacy/privacy_test.go @@ -9,11 +9,10 @@ import ( "errors" "testing" - "github.com/facebookincubator/ent/entc/integration/privacy/ent" + "github.com/facebookincubator/ent/entc/integration/privacy/ent/enttest" "github.com/facebookincubator/ent/entc/integration/privacy/ent/galaxy" "github.com/facebookincubator/ent/entc/integration/privacy/ent/planet" "github.com/facebookincubator/ent/entc/integration/privacy/ent/privacy" - _ "github.com/facebookincubator/ent/entc/integration/privacy/ent/runtime" "github.com/facebookincubator/ent/entc/integration/privacy/rule" _ "github.com/mattn/go-sqlite3" @@ -21,38 +20,62 @@ import ( ) func TestPrivacyRules(t *testing.T) { - client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1") - require.NoError(t, err) + client := enttest.Open(t, "sqlite3", + "file:ent?mode=memory&cache=shared&_fk=1", + ) defer client.Close() - ctx := context.Background() - err = client.Schema.Create(ctx) - require.NoError(t, err) logf := rule.SetMutationLogFunc(t.Logf) defer rule.SetMutationLogFunc(logf) - earth, err := client.Planet.Create().SetName("Earth").SetAge(4_540_000_000).Save(ctx) + ctx := context.Background() + earth, err := client.Planet.Create(). + SetName("Earth"). + SetAge(4_540_000_000). + Save(ctx) require.NoError(t, err) - mars := client.Planet.Create().SetName("Mars").SaveX(ctx) - err = earth.Update().AddNeighbors(mars).Exec(ctx) + mars := client.Planet.Create(). + SetName("Mars"). + SaveX(ctx) + err = earth.Update(). + AddNeighbors(mars). + Exec(ctx) require.NoError(t, err) logf = rule.SetMutationLogFunc(func(string, ...interface{}) { require.FailNow(t, "hook called on privacy deny") }) - err = client.Planet.Update().Where(planet.ID(earth.ID)).SetAge(4_600_000_000).Exec(ctx) + err = client.Planet.Update(). + Where(planet.ID(earth.ID)). + SetAge(4_600_000_000). + Exec(ctx) require.True(t, errors.Is(err, privacy.Deny)) - err = earth.Update().AddNeighbors(earth).Exec(ctx) + err = earth.Update(). + AddNeighbors(earth). + Exec(ctx) require.True(t, errors.Is(err, privacy.Deny)) rule.SetMutationLogFunc(logf) + err = client.Planet.Update(). + Where(planet.ID(earth.ID)). + SetAge(4_600_000_000). + Exec(privacy.DecisionContext(ctx, privacy.Allow)) + require.NoError(t, err) + count := client.Planet.Query().CountX(ctx) require.Equal(t, 1, count) mars.Update().SetAge(6_000_000_000).ExecX(ctx) count = client.Planet.Query().CountX(ctx) require.Equal(t, 2, count) - client.Galaxy.Create().SetName("Milky Way").SetType(galaxy.TypeBarredSpiral).AddPlanets(earth, mars).SaveX(ctx) - client.Galaxy.Create().SetName("IC 3583").SetType(galaxy.TypeIrregular).SaveX(ctx) + client.Galaxy.Create(). + SetName("Milky Way"). + SetType(galaxy.TypeBarredSpiral). + AddPlanets(earth, mars). + SaveX(ctx) + client.Galaxy.Create(). + SetName("IC 3583"). + SetType(galaxy.TypeIrregular). + SaveX(ctx) count = client.Galaxy.Query().CountX(ctx) require.Equal(t, 1, count) } diff --git a/entc/integration/template/ent/privacy/privacy.go b/entc/integration/template/ent/privacy/privacy.go index d3c4554f4..37c95f8b5 100644 --- a/entc/integration/template/ent/privacy/privacy.go +++ b/entc/integration/template/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/edgeindex/ent/privacy/privacy.go b/examples/edgeindex/ent/privacy/privacy.go index 126e9accc..423c06c46 100644 --- a/examples/edgeindex/ent/privacy/privacy.go +++ b/examples/edgeindex/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/entcpkg/ent/privacy/privacy.go b/examples/entcpkg/ent/privacy/privacy.go index aa5296005..099a4b175 100644 --- a/examples/entcpkg/ent/privacy/privacy.go +++ b/examples/entcpkg/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/m2m2types/ent/privacy/privacy.go b/examples/m2m2types/ent/privacy/privacy.go index 57ac12574..5cfc4ef7e 100644 --- a/examples/m2m2types/ent/privacy/privacy.go +++ b/examples/m2m2types/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/m2mbidi/ent/privacy/privacy.go b/examples/m2mbidi/ent/privacy/privacy.go index 654453c52..6bd2252a7 100644 --- a/examples/m2mbidi/ent/privacy/privacy.go +++ b/examples/m2mbidi/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/m2mrecur/ent/privacy/privacy.go b/examples/m2mrecur/ent/privacy/privacy.go index 9a748e444..719975e81 100644 --- a/examples/m2mrecur/ent/privacy/privacy.go +++ b/examples/m2mrecur/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/o2m2types/ent/privacy/privacy.go b/examples/o2m2types/ent/privacy/privacy.go index 28982c646..1e01229d1 100644 --- a/examples/o2m2types/ent/privacy/privacy.go +++ b/examples/o2m2types/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/o2mrecur/ent/privacy/privacy.go b/examples/o2mrecur/ent/privacy/privacy.go index 06ef385d7..6cf873a9f 100644 --- a/examples/o2mrecur/ent/privacy/privacy.go +++ b/examples/o2mrecur/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/o2o2types/ent/privacy/privacy.go b/examples/o2o2types/ent/privacy/privacy.go index 063a4773c..6e234d14c 100644 --- a/examples/o2o2types/ent/privacy/privacy.go +++ b/examples/o2o2types/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/o2obidi/ent/privacy/privacy.go b/examples/o2obidi/ent/privacy/privacy.go index 54bff12ac..ebbe84d6c 100644 --- a/examples/o2obidi/ent/privacy/privacy.go +++ b/examples/o2obidi/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/o2orecur/ent/privacy/privacy.go b/examples/o2orecur/ent/privacy/privacy.go index db8be12cb..08ad26b32 100644 --- a/examples/o2orecur/ent/privacy/privacy.go +++ b/examples/o2orecur/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/start/ent/privacy/privacy.go b/examples/start/ent/privacy/privacy.go index 433b8431b..3e4e1f6cd 100644 --- a/examples/start/ent/privacy/privacy.go +++ b/examples/start/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip): diff --git a/examples/traversal/ent/privacy/privacy.go b/examples/traversal/ent/privacy/privacy.go index fd7769d59..5b558ec47 100644 --- a/examples/traversal/ent/privacy/privacy.go +++ b/examples/traversal/ent/privacy/privacy.go @@ -43,6 +43,24 @@ func Skipf(format string, a ...interface{}) error { return fmt.Errorf(format+": %w", append(a, Skip)...) } +type decisionCtxKey struct{} + +// DecisionContext creates a decision context. +func DecisionContext(parent context.Context, decision error) context.Context { + if decision == nil || errors.Is(decision, Skip) { + return parent + } + return context.WithValue(parent, decisionCtxKey{}, decision) +} + +func decisionFromContext(ctx context.Context) (error, bool) { + err, ok := ctx.Value(decisionCtxKey{}).(error) + if ok && errors.Is(err, Allow) { + err = nil + } + return err, ok +} + type ( // QueryPolicy combines multiple query rules into a single policy. QueryPolicy []QueryRule @@ -56,6 +74,9 @@ type ( // EvalQuery evaluates a query against a query policy. func (policy QueryPolicy) EvalQuery(ctx context.Context, q ent.Query) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalQuery(ctx, q); { case err == nil || errors.Is(err, Skip): @@ -90,6 +111,9 @@ type ( // EvalMutation evaluates a mutation against a mutation policy. func (policy MutationPolicy) EvalMutation(ctx context.Context, m ent.Mutation) error { + if err, ok := decisionFromContext(ctx); ok { + return err + } for _, rule := range policy { switch err := rule.EvalMutation(ctx, m); { case err == nil || errors.Is(err, Skip):