Skip to content

[CLIENT-3161] Add client config option to validate keys passed into client config and policy dictionaries #729

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 99 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
68b6290
doc
juliannguyen4 Feb 20, 2025
c28a503
fix
juliannguyen4 Feb 20, 2025
d27d6a4
add more
juliannguyen4 Feb 20, 2025
5389751
test formatting
juliannguyen4 Feb 20, 2025
338deac
add code
juliannguyen4 Feb 20, 2025
2b5a713
add err msg
juliannguyen4 Feb 20, 2025
63775fb
add link
juliannguyen4 Feb 20, 2025
c9a0fb3
policy ex
juliannguyen4 Feb 20, 2025
5ab110a
add
juliannguyen4 Feb 20, 2025
e6d341d
fix
juliannguyen4 Feb 20, 2025
5ae575c
improve error msgs, fix
juliannguyen4 Feb 20, 2025
cfdf891
oops
juliannguyen4 Feb 20, 2025
3deefe3
Merge remote-tracking branch 'origin/dev' into CLIENT-3161-validate-d…
juliannguyen4 Apr 9, 2025
8049d4e
wip
juliannguyen4 Apr 9, 2025
af35ccd
fix
juliannguyen4 Apr 9, 2025
399aa5d
Merge remote-tracking branch 'origin/dev' into CLIENT-3161-validate-d…
juliannguyen4 Apr 10, 2025
03701fb
validate logic
juliannguyen4 Apr 10, 2025
9513e4f
dont need to
juliannguyen4 Apr 11, 2025
bcac0f7
fix
juliannguyen4 Apr 11, 2025
42c7fd9
wrong pointer type
juliannguyen4 Apr 11, 2025
6cd1143
fix
juliannguyen4 Apr 11, 2025
107f67b
fix
juliannguyen4 Apr 11, 2025
b0f93df
fix
juliannguyen4 Apr 11, 2025
82138f8
fix
juliannguyen4 Apr 11, 2025
8c78bd8
fix
juliannguyen4 Apr 14, 2025
07b7d8d
Merge remote-tracking branch 'origin/dev' into CLIENT-3161-validate-d…
juliannguyen4 Apr 23, 2025
0fa9f87
clear up
juliannguyen4 Apr 23, 2025
9316849
rename to str to make consistent
juliannguyen4 Apr 23, 2025
9adb09c
clear up
juliannguyen4 Apr 23, 2025
e4cff79
cleanup
juliannguyen4 Apr 23, 2025
8a523a6
make optional
juliannguyen4 Apr 23, 2025
bea8686
f
juliannguyen4 Apr 23, 2025
09aa9d3
Add basic test
juliannguyen4 Apr 23, 2025
1c39ac4
revert
juliannguyen4 Apr 23, 2025
de01c62
fix
juliannguyen4 Apr 23, 2025
72dae54
fix
juliannguyen4 Apr 23, 2025
333b249
doesnt match with docs
juliannguyen4 Apr 24, 2025
22b1ca5
wip
juliannguyen4 Apr 24, 2025
1f0daf8
Merge remote-tracking branch 'origin/dev' into CLIENT-3161-validate-d…
juliannguyen4 May 5, 2025
246d5a5
Revert "wip"
juliannguyen4 May 5, 2025
facd84d
remove policy documentation
juliannguyen4 May 5, 2025
1159a7c
Merge remote-tracking branch 'origin/dev' into CLIENT-3161-validate-d…
juliannguyen4 May 19, 2025
c7a3390
wip
juliannguyen4 May 19, 2025
7feb2cc
fix
juliannguyen4 May 19, 2025
807b058
wip. code needs to be refactored
juliannguyen4 May 19, 2025
1dce910
Merge remote-tracking branch 'origin/dev' into CLIENT-3161-validate-d…
juliannguyen4 May 29, 2025
6f47ef5
fix
juliannguyen4 May 29, 2025
791d91f
fix
juliannguyen4 May 29, 2025
db64aaa
make extern so we know it's not defined in that source file
juliannguyen4 May 29, 2025
ea9a402
just ignore err and throw code
juliannguyen4 May 29, 2025
6f61110
needs to be in header file so other source files can see
juliannguyen4 May 29, 2025
51a0f7b
add coverage
juliannguyen4 May 29, 2025
918bdb3
validate_keys should be at the beginning
juliannguyen4 May 29, 2025
1f9e738
comment
juliannguyen4 May 29, 2025
d0404fd
make extern as well
juliannguyen4 May 29, 2025
5315781
run all tests with this option enabled
juliannguyen4 May 29, 2025
5d94f27
merge base policy keys
juliannguyen4 May 29, 2025
2964b1b
fix
juliannguyen4 May 29, 2025
3415b76
move docs to header file
juliannguyen4 May 29, 2025
ab9e5a4
proofreading wip
juliannguyen4 May 29, 2025
360aa4b
need to raise exception with proper error msg for key validation
juliannguyen4 May 29, 2025
65567a3
do the rest of the policies
juliannguyen4 May 29, 2025
4d30bee
finish
juliannguyen4 May 29, 2025
4f5327f
remove finished todo
juliannguyen4 May 29, 2025
0d61acc
forgot
juliannguyen4 May 29, 2025
b37a0f9
full test coverage
juliannguyen4 May 29, 2025
e89fd63
reuse test case
juliannguyen4 May 29, 2025
2c37005
fix
juliannguyen4 May 29, 2025
e592ee7
fix
juliannguyen4 May 29, 2025
1259a1e
also fix
juliannguyen4 May 29, 2025
2c83c33
add missing
juliannguyen4 May 29, 2025
c729581
fix
juliannguyen4 May 29, 2025
393ec99
CI/CD: Get code coverage using unoptimized build for more accurate re…
juliannguyen4 May 30, 2025
02aa811
clear up what this does
juliannguyen4 May 30, 2025
863dfa7
add coverage
juliannguyen4 May 30, 2025
7d049c7
add coverage
juliannguyen4 May 30, 2025
7ef85bf
fix test
juliannguyen4 May 30, 2025
fc74318
also test tls
juliannguyen4 May 30, 2025
2be521a
fix tests
juliannguyen4 May 30, 2025
2998484
Merge remote-tracking branch 'origin/dev' into CLIENT-3161-validate-d…
juliannguyen4 May 30, 2025
9b95124
dont fail if client doesn't raise exception. add more coverage tests
juliannguyen4 May 30, 2025
2c4c103
validate txn level read policies.
juliannguyen4 Jun 2, 2025
236e12f
fix seg fault
juliannguyen4 Jun 2, 2025
a308f25
Revert "fix seg fault"
juliannguyen4 Jun 2, 2025
1f232ac
fix
juliannguyen4 Jun 2, 2025
d44bb15
Fix
juliannguyen4 Jun 2, 2025
890863e
fix test
juliannguyen4 Jun 2, 2025
fabcd05
fix
juliannguyen4 Jun 2, 2025
9637ffd
fix test
juliannguyen4 Jun 2, 2025
aed68ef
wip
juliannguyen4 Jun 2, 2025
19d56a5
wrong syntax
juliannguyen4 Jun 2, 2025
defb86e
fix
juliannguyen4 Jun 3, 2025
869a5fb
dont use write or scan policy as info policy
juliannguyen4 Jun 3, 2025
c259098
revert
juliannguyen4 Jun 3, 2025
a4c473e
fix wrong usage of api
juliannguyen4 Jun 3, 2025
7fbb19b
fix
juliannguyen4 Jun 3, 2025
7661deb
round up, or query may not finish
juliannguyen4 Jun 3, 2025
4a66ef7
fix test (this will seg fault)
juliannguyen4 Jun 5, 2025
08aa3b0
Merge remote-tracking branch 'origin/dev' into CLIENT-3161-validate-d…
juliannguyen4 Jun 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ max-line-length = 120
extend-ignore = E203
filename =
./aerospike_helpers/**/*.py,
./test/**/*.py
./test/new_tests/**/*.py
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ jobs:
# They will also contain .gcno files there
# and .gcda files will be generated there after running the tests
# The build frontend doesn't generate these .o files (may be wrong?)
run: COVERAGE=1 python3 setup.py build
run: COVERAGE=1 UNOPTIMIZED=1 python3 setup.py build

- name: Install client
# Install in user directory to prevent permission errors
Expand Down
55 changes: 55 additions & 0 deletions doc/aerospike.rst
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,61 @@ Only the `hosts` key is required; the rest of the keys are optional.
.. hlist::
:columns: 1

* **validate_keys** (:class:`bool`)
(Optional) Validate keys passed into this config dictionary as well as any policy dictionaries.

If a key that is undefined in this documentation gets passed to a config or policy dictionary:

* If this option is set to :py:obj:`True`, :py:class:`~aerospike.exception.ParamError` will be raised.
* If this option is set to :py:obj:`False`, the key will be ignored and the client does not raise an
exception in response to the invalid key.

Default: :py:obj:`False`

Invalid client config example:

.. code-block:: python

import aerospike

config = {
"validate_keys": True,
"hosts": [
("127.0.0.1", 3000)
],
# The correct key is "user", but "username" may be used by accident
"username": "user",
"password": "password"
}
# This call will raise a ParamError from aerospike.exception
# Exception message should be:
# "username" is an invalid client config dictionary key
client = aerospike.client(config)

Invalid policy example:

.. code-block:: python

import aerospike

config = {
"validate_keys": True,
"hosts": [
("127.0.0.1", 3000)
],
}
client = aerospike.client(config)

key = ("test", "demo", 1)
# "key_policy" is used instead of the correct key named "key"
policy = {
"key_policy": aerospike.POLICY_KEY_SEND
}
# This call will raise a ParamError from aerospike.exception
# Exception message should be:
# "key_policy" is an invalid policy dictionary key
client.get(key, policy=policy)

* **hosts** (:class:`list`)
A list of tuples identifying a node (or multiple nodes) in the cluster.

Expand Down
4 changes: 2 additions & 2 deletions src/include/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,8 @@ as_status pyobject_to_policy_apply(AerospikeClient *self, as_error *err,
as_policy_apply *config_apply_policy,
as_exp *exp_list, as_exp **exp_list_p);

as_status pyobject_to_policy_info(as_error *err, PyObject *py_policy,
as_policy_info *policy,
as_status pyobject_to_policy_info(AerospikeClient *self, as_error *err,
PyObject *py_policy, as_policy_info *policy,
as_policy_info **policy_p,
as_policy_info *config_info_policy);

Expand Down
52 changes: 33 additions & 19 deletions src/include/policy_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,36 @@ as_status set_optional_gen(as_policy_gen *target_ptr, PyObject *py_policy,
as_status set_optional_exists(as_policy_exists *target_ptr, PyObject *py_policy,
const char *name);

as_status set_subpolicies(as_config *config, PyObject *py_policies);
as_status set_read_policy(as_policy_read *read_policy, PyObject *py_policy);
as_status set_write_policy(as_policy_write *write_policy, PyObject *py_policy);
as_status set_apply_policy(as_policy_apply *apply_policy, PyObject *py_policy);
as_status set_remove_policy(as_policy_remove *remove_policy,
PyObject *py_policy);
as_status set_query_policy(as_policy_query *query_policy, PyObject *py_policy);
as_status set_scan_policy(as_policy_scan *scan_policy, PyObject *py_policy);
as_status set_operate_policy(as_policy_operate *operate_policy,
PyObject *py_policy);
as_status set_batch_policy(as_policy_batch *batch_policy, PyObject *py_policy);
as_status set_info_policy(as_policy_info *info_policy, PyObject *py_policy);
as_status set_admin_policy(as_policy_admin *admin_policy, PyObject *py_policy);
as_status set_batch_apply_policy(as_policy_batch_apply *batch_apply_policy,
PyObject *py_policy);
as_status set_batch_write_policy(as_policy_batch_write *batch_write_policy,
PyObject *py_policy);
as_status set_batch_remove_policy(as_policy_batch_remove *batch_remove_policy,
PyObject *py_policy);
// This only sets the err object if an invalid dictionary key is passed
// On error, return an error code
as_status set_subpolicies(as_error *err, as_config *config,
PyObject *py_policies, int validate_keys);
as_status set_read_policy(as_error *err, as_policy_read *read_policy,
PyObject *py_policy, int validate_keys);
as_status set_write_policy(as_error *err, as_policy_write *write_policy,
PyObject *py_policy, int validate_keys);
as_status set_apply_policy(as_error *err, as_policy_apply *apply_policy,
PyObject *py_policy, int validate_keys);
as_status set_remove_policy(as_error *err, as_policy_remove *remove_policy,
PyObject *py_policy, int validate_keys);
as_status set_query_policy(as_error *err, as_policy_query *query_policy,
PyObject *py_policy, int validate_keys);
as_status set_scan_policy(as_error *err, as_policy_scan *scan_policy,
PyObject *py_policy, int validate_keys);
as_status set_operate_policy(as_error *err, as_policy_operate *operate_policy,
PyObject *py_policy, int validate_keys);
as_status set_batch_policy(as_error *err, as_policy_batch *batch_policy,
PyObject *py_policy, int validate_keys);
as_status set_info_policy(as_error *err, as_policy_info *info_policy,
PyObject *py_policy, int validate_keys);
as_status set_admin_policy(as_error *err, as_policy_admin *admin_policy,
PyObject *py_policy, int validate_keys);
as_status set_batch_apply_policy(as_error *err,
as_policy_batch_apply *batch_apply_policy,
PyObject *py_policy, int validate_keys);
as_status set_batch_write_policy(as_error *err,
as_policy_batch_write *batch_write_policy,
PyObject *py_policy, int validate_keys);
as_status set_batch_remove_policy(as_error *err,
as_policy_batch_remove *batch_remove_policy,
PyObject *py_policy, int validate_keys);
35 changes: 35 additions & 0 deletions src/include/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ typedef struct {
bool has_connected;
bool use_shared_connection;
uint8_t send_bool_as;
bool validate_keys;
} AerospikeClient;

typedef struct {
Expand Down Expand Up @@ -117,3 +118,37 @@ typedef struct {
} AerospikeConfigProvider;

extern PyTypeObject AerospikeConfigProvider_Type;

// These are defined in aerospike.c
extern PyObject *py_client_config_valid_keys;
extern PyObject *py_client_config_shm_valid_keys;
extern PyObject *py_client_config_lua_valid_keys;
extern PyObject *py_client_config_policies_valid_keys;
extern PyObject *py_client_config_tls_valid_keys;
extern PyObject *py_apply_policy_valid_keys;
extern PyObject *py_admin_policy_valid_keys;
extern PyObject *py_info_policy_valid_keys;
extern PyObject *py_query_policy_valid_keys;
extern PyObject *py_read_policy_valid_keys;
extern PyObject *py_remove_policy_valid_keys;
extern PyObject *py_scan_policy_valid_keys;
extern PyObject *py_write_policy_valid_keys;
extern PyObject *py_operate_policy_valid_keys;
extern PyObject *py_batch_policy_valid_keys;
extern PyObject *py_batch_write_policy_valid_keys;
extern PyObject *py_batch_read_policy_valid_keys;
extern PyObject *py_batch_apply_policy_valid_keys;
extern PyObject *py_batch_remove_policy_valid_keys;
extern PyObject *py_bit_policy_valid_keys;
extern PyObject *py_map_policy_valid_keys;
extern PyObject *py_list_policy_valid_keys;
extern PyObject *py_hll_policy_valid_keys;

// py_set contains the valid keys
// Return -1 if we failed to validate dictionary
// Return 0 if dictionary has invalid keys
// Return 1 if dictionary's keys are all valid
// If validating_policy is false, we are validating a client config dictionary
extern int does_py_dict_contain_valid_keys(as_error *err, PyObject *py_dict,
PyObject *py_set,
bool validating_policy);
Loading
Loading