in python/qpid_dispatch_internal/policy/policy_local.py [0:0]
def compile_app_settings(self, vhostname, usergroup, policy_in, policy_out, warnings, errors):
"""
Compile a vhostUserGroupSettings schema from processed json format to local internal format.
@param[in] name vhost name
@param[in] policy_in user config settings
@param[out] policy_out validated Internal format
@param[out] warnings nonfatal irregularities observed
@param[out] errors descriptions of failure
@return - settings are usable. If True then warnings[] may contain useful
information about fields that are ignored. If False then
warnings[] may contain info and errors[0] will hold the
description of why the policy was rejected.
"""
# rulesets may not come through standard config so make nice defaults
policy_out[PolicyKeys.KW_USERS] = ''
policy_out[PolicyKeys.KW_REMOTE_HOSTS] = ''
# DISPATCH-2305: do not provide default values for max
# frame/window/sessions. The router already provides these. Setting
# zero here will cause the router to use configured values unless
# specifically overridden by policy:
policy_out[PolicyKeys.KW_MAX_FRAME_SIZE] = 0
policy_out[PolicyKeys.KW_MAX_SESSION_WINDOW] = 0
policy_out[PolicyKeys.KW_MAX_SESSIONS] = 0
policy_out[PolicyKeys.KW_MAX_MESSAGE_SIZE] = None
policy_out[PolicyKeys.KW_MAX_SENDERS] = 2147483647
policy_out[PolicyKeys.KW_MAX_RECEIVERS] = 2147483647
policy_out[PolicyKeys.KW_ALLOW_DYNAMIC_SRC] = False
policy_out[PolicyKeys.KW_ALLOW_ANONYMOUS_SENDER] = False
policy_out[PolicyKeys.KW_ALLOW_USERID_PROXY] = False
policy_out[PolicyKeys.KW_ALLOW_WAYPOINT_LINKS] = True
policy_out[PolicyKeys.KW_ALLOW_FALLBACK_LINKS] = True
policy_out[PolicyKeys.KW_ALLOW_DYNAMIC_LINK_ROUTES] = True
policy_out[PolicyKeys.KW_ALLOW_ADMIN_STATUS_UPDATE] = True
policy_out[PolicyKeys.KW_SOURCES] = ''
policy_out[PolicyKeys.KW_TARGETS] = ''
policy_out[PolicyKeys.KW_SOURCE_PATTERN] = ''
policy_out[PolicyKeys.KW_TARGET_PATTERN] = ''
policy_out[PolicyKeys.KW_MAXCONNPERHOST] = None # optional group limit
policy_out[PolicyKeys.KW_MAXCONNPERUSER] = None
cerror = []
user_sources = False
user_targets = False
user_src_pattern = False
user_tgt_pattern = False
for key, val in policy_in.items():
if key not in self.allowed_settings_options:
warnings.append("Policy vhost '%s' user group '%s' option '%s' is ignored." %
(vhostname, usergroup, key))
if key in [PolicyKeys.KW_MAXCONNPERHOST,
PolicyKeys.KW_MAXCONNPERUSER
]:
if not self.validateNumber(val, 0, 65535, cerror):
msg = ("Policy vhost '%s' user group '%s' option '%s' has error '%s'." %
(vhostname, usergroup, key, cerror[0]))
errors.append(msg)
return False
policy_out[key] = int(val)
elif key in [PolicyKeys.KW_MAX_FRAME_SIZE,
PolicyKeys.KW_MAX_MESSAGE_SIZE,
PolicyKeys.KW_MAX_RECEIVERS,
PolicyKeys.KW_MAX_SENDERS,
PolicyKeys.KW_MAX_SESSION_WINDOW,
PolicyKeys.KW_MAX_SESSIONS
]:
if not self.validateNumber(val, 0, 0, cerror):
errors.append("Policy vhost '%s' user group '%s' option '%s' has error '%s'." %
(vhostname, usergroup, key, cerror[0]))
return False
policy_out[key] = int(val)
elif key == PolicyKeys.KW_REMOTE_HOSTS:
# Conection groups are lists of IP addresses that need to be
# converted into binary structures for comparisons.
val_out = []
if not self.compile_connection_group(vhostname, usergroup, val, val_out, warnings, errors):
return False
policy_out[key] = val_out
elif key in [PolicyKeys.KW_ALLOW_ANONYMOUS_SENDER,
PolicyKeys.KW_ALLOW_DYNAMIC_SRC,
PolicyKeys.KW_ALLOW_USERID_PROXY,
PolicyKeys.KW_ALLOW_WAYPOINT_LINKS,
PolicyKeys.KW_ALLOW_FALLBACK_LINKS,
PolicyKeys.KW_ALLOW_DYNAMIC_LINK_ROUTES,
PolicyKeys.KW_ALLOW_ADMIN_STATUS_UPDATE
]:
if isinstance(val, str) and val.lower() in ['true', 'false']:
val = val == 'true'
if not isinstance(val, bool):
errors.append("Policy vhost '%s' user group '%s' option '%s' has illegal boolean value '%s'." %
(vhostname, usergroup, key, val))
return False
policy_out[key] = val
elif key in [PolicyKeys.KW_USERS,
PolicyKeys.KW_SOURCES,
PolicyKeys.KW_TARGETS,
PolicyKeys.KW_SOURCE_PATTERN,
PolicyKeys.KW_TARGET_PATTERN,
PolicyKeys.KW_VHOST_ALIASES
]:
# accept a string or list
if isinstance(val, list):
# ['abc', 'def', 'mytarget']
pass
elif isinstance(val, str):
# 'abc, def, mytarget'
val = [x.strip(' ') for x in val.split(PolicyKeys.KC_CONFIG_LIST_SEP)]
else:
errors.append("Policy vhost '%s' user group '%s' option '%s' has illegal value '%s'. Type must be 'str' or 'list' but is '%s;" %
(vhostname, usergroup, key, val, type(val)))
# deduplicate address lists
val = list(set(val))
# val is CSV string with no white space between values: 'abc,def,mytarget,tmp-${user}'
if key == PolicyKeys.KW_USERS:
# user name list items are literal strings and need no special handling
policy_out[key] = ','.join(val)
else:
# source and target names get special handling for the '${user}' substitution token
# The literal string is translated to a (key, prefix, suffix) set of three strings.
# C code does not have to search for the username token and knows with authority
# how to construct match strings.
# A wildcard is also signaled.
utoken = PolicyKeys.KC_TOKEN_USER
eVal = []
for v in val:
vcount = v.count(utoken)
if vcount > 1:
errors.append("Policy vhost '%s' user group '%s' policy key '%s' item '%s' contains multiple user subtitution tokens" %
(vhostname, usergroup, key, v))
return False
elif vcount == 1:
# a single token is present as a prefix, suffix, or embedded
# construct cChar, S1, S2 encodings to be added to eVal description
if v.startswith(utoken):
# prefix
eVal.append(PolicyKeys.KC_TUPLE_PREFIX)
eVal.append('')
eVal.append(v[v.find(utoken) + len(utoken):])
elif v.endswith(utoken):
# suffix
eVal.append(PolicyKeys.KC_TUPLE_SUFFIX)
eVal.append(v[0:v.find(utoken)])
eVal.append('')
else:
# embedded
if key in [PolicyKeys.KW_SOURCE_PATTERN,
PolicyKeys.KW_TARGET_PATTERN]:
errors.append("Policy vhost '%s' user group '%s' policy key '%s' item '%s' may contain match pattern '%s' as a prefix or a suffix only." %
(vhostname, usergroup, key, v, utoken))
return False
eVal.append(PolicyKeys.KC_TUPLE_EMBED)
eVal.append(v[0:v.find(utoken)])
eVal.append(v[v.find(utoken) + len(utoken):])
else:
# ${user} token is absent
if v == PolicyKeys.KC_TUPLE_WILDCARD:
eVal.append(PolicyKeys.KC_TUPLE_WILDCARD)
eVal.append('')
eVal.append('')
else:
eVal.append(PolicyKeys.KC_TUPLE_ABSENT)
eVal.append(v)
eVal.append('')
policy_out[key] = ','.join(eVal)
if key == PolicyKeys.KW_SOURCES:
user_sources = True
if key == PolicyKeys.KW_TARGETS:
user_targets = True
if key == PolicyKeys.KW_SOURCE_PATTERN:
user_src_pattern = True
if key == PolicyKeys.KW_TARGET_PATTERN:
user_tgt_pattern = True
if user_sources and user_src_pattern:
errors.append("Policy vhost '%s' user group '%s' specifies conflicting 'sources' and 'sourcePattern' attributes. Use only one or the other." % (vhostname, usergroup))
return False
if user_targets and user_tgt_pattern:
errors.append("Policy vhost '%s' user group '%s' specifies conflicting 'targets' and 'targetPattern' attributes. Use only one or the other." % (vhostname, usergroup))
return False
return True