add group concept

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10917 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2008-12-23 17:36:50 +00:00
parent d5100bc5fe
commit ed100f44ea
8 changed files with 603 additions and 38 deletions

View File

@ -142,6 +142,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_child(switch_xml_t xml, const char *name
///\param value the value
///\return an xml node or NULL
SWITCH_DECLARE(switch_xml_t) switch_xml_find_child(switch_xml_t node, const char *childname, const char *attrname, const char *value);
SWITCH_DECLARE(switch_xml_t) switch_xml_find_child_multi(switch_xml_t node, const char *childname, ...);
///\brief returns the next tag of the same name in the same section and depth or NULL
///\ if not found
@ -334,11 +335,20 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate(const char *section,
switch_event_t *params);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_domain(const char *domain_name, switch_event_t *params, switch_xml_t *root, switch_xml_t *domain);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_group(const char *group_name,
const char *domain_name,
switch_xml_t *root,
switch_xml_t *domain,
switch_xml_t *group,
switch_event_t *params);
SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key,
const char *user_name,
const char *domain_name,
const char *ip,
switch_xml_t *root, switch_xml_t *domain, switch_xml_t *user, switch_event_t *params);
switch_xml_t *root, switch_xml_t *domain, switch_xml_t *user, switch_xml_t *ingroup,
switch_event_t *params);
///\brief open a config in the core registry
///\param file_path the name of the config section e.g. modules.conf

View File

@ -77,6 +77,245 @@ SWITCH_STANDARD_API(time_test_function)
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(group_call_function)
{
char *domain;
char *group_name = NULL;
char *flags;
int ok = 0;
switch_channel_t *channel = NULL;
char *fp = NULL;
const char *call_delim = ",";
if (switch_strlen_zero(cmd)) {
goto end;
}
if (session) {
channel = switch_core_session_get_channel(session);
}
group_name = strdup(cmd);
switch_assert(group_name);
if ((flags = strchr(group_name, '+'))) {
*flags++ = '\0';
for (fp = flags; fp && *fp; fp++) {
switch(*fp) {
case 'F':
call_delim = "|";
break;
case 'A':
call_delim = ",";
break;
default:
break;
}
}
}
domain = strchr(group_name, '@');
if (domain) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
if (!switch_strlen_zero(domain)) {
switch_xml_t xml, x_domain, x_group;
switch_event_t *params;
switch_stream_handle_t dstream = { 0 };
SWITCH_STANDARD_STREAM(dstream);
switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "group", group_name);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "action", "group_call");
if (switch_xml_locate_group(group_name, domain, &xml, &x_domain, &x_group, params) == SWITCH_STATUS_SUCCESS) {
switch_xml_t x_user, x_users, x_param, x_params;
if ((x_users = switch_xml_child(x_group, "users"))) {
ok++;
for(x_user = switch_xml_child(x_users, "user"); x_user; x_user = x_user->next) {
const char *id = switch_xml_attr_soft(x_user, "id");
const char *dest = NULL;
char *d_dest = NULL;
if ((x_params = switch_xml_child(x_domain, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (!strcasecmp(var, "group-dial-string")) {
dest = val;
break;
}
if (!strcasecmp(var, "dial-string")) {
dest = val;
}
}
}
if ((x_params = switch_xml_child(x_group, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (!strcasecmp(var, "group-dial-string")) {
dest = val;
break;
}
if (!strcasecmp(var, "dial-string")) {
dest = val;
}
}
}
if ((x_params = switch_xml_child(x_user, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (!strcasecmp(var, "group-dial-string")) {
dest = val;
break;
}
if (!strcasecmp(var, "dial-string")) {
dest = val;
}
}
}
if (dest) {
if (channel) {
switch_channel_set_variable(channel, "dialed_group", group_name);
switch_channel_set_variable(channel, "dialed_user", id);
switch_channel_set_variable(channel, "dialed_domain", domain);
d_dest = switch_channel_expand_variables(channel, dest);
} else {
switch_event_del_header(params, "dialed_user");
switch_event_del_header(params, "dialed_group");
switch_event_del_header(params, "dialed_domain");
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "dialed_user", id);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "dialed_group", group_name);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "dialed_domain", domain);
d_dest = switch_event_expand_headers(params, dest);
}
} else {
d_dest = switch_mprintf("user/%s@%s", id, domain);
}
if (d_dest) {
if (!switch_stristr("error/", d_dest)) {
dstream.write_function(&dstream, "%s%s", d_dest, call_delim);
}
if (d_dest != dest) {
free(d_dest);
}
}
}
if (ok && dstream.data) {
char *data = (char *) dstream.data;
char c = end_of(data);
char *p;
if (c == ',' || c == '|') {
end_of(data) = '\0';
}
for (p = data; p && *p; p++) {
if (*p == '{') {
*p = '[';
} else if (*p == '}') {
*p = ']';
}
}
stream->write_function(stream, "%s", data);
free(dstream.data);
} else {
ok = 0;
}
}
switch_xml_free(xml);
}
switch_event_destroy(&params);
}
end:
switch_safe_free(group_name);
if (!ok) {
stream->write_function(stream, "error/NO_ROUTE_DESTINATION");
}
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(in_group_function)
{
switch_xml_t x_domain, xml = NULL, x_user = NULL, x_group;
int argc;
char *mydata = NULL, *argv[2], *user, *domain;
char delim = ',';
switch_event_t *params = NULL;
const char *rval = "false";
char *group;
if (switch_strlen_zero(cmd) || !(mydata = strdup(cmd))) {
goto end;
}
if ((argc = switch_separate_string(mydata, delim, argv, (sizeof(argv) / sizeof(argv[0])))) < 2) {
goto end;
}
user = argv[0];
group = argv[1];
if ((domain = strchr(user, '@'))) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "user", user);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain);
if (switch_xml_locate_group(group, domain, &xml, &x_domain, &x_group, params) == SWITCH_STATUS_SUCCESS) {
switch_xml_t x_users;
if ((x_users = switch_xml_child(x_group, "users"))) {
if ((x_user = switch_xml_find_child(x_users, "user", "id", user))) {
rval = "true";
}
}
}
end:
stream->write_function(stream, "%s", rval);
switch_xml_free(xml);
free(mydata);
switch_event_destroy(&params);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_API(user_data_function)
{
switch_xml_t x_domain, xml = NULL, x_user = NULL, x_param, x_params;
@ -111,7 +350,7 @@ SWITCH_STANDARD_API(user_data_function)
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "type", type);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "key", key);
if (key && type && switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, params) == SWITCH_STATUS_SUCCESS) {
if (key && type && switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, NULL, params) == SWITCH_STATUS_SUCCESS) {
if (!strcmp(type, "attr")) {
const char *attr = switch_xml_attr_soft(x_user, key);
stream->write_function(stream, "%s", attr);
@ -201,7 +440,7 @@ static switch_status_t _find_user(const char *cmd, switch_core_session_t *sessio
goto end;
}
if (switch_xml_locate_user(key, user, domain, NULL, &xml, &x_domain, &x_user, NULL) != SWITCH_STATUS_SUCCESS) {
if (switch_xml_locate_user(key, user, domain, NULL, &xml, &x_domain, &x_user, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
err = "can't find user";
goto end;
}
@ -2940,6 +3179,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
switch_api_interface_t *commands_api_interface;
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_API(commands_api_interface, "group_call", "Generate a dial string to call a group", group_call_function, "<group>[@<domain>]");
SWITCH_ADD_API(commands_api_interface, "in_group", "determine if a user is in a group", in_group_function, "<user>[@<domain>] <group_name>");
SWITCH_ADD_API(commands_api_interface, "uuid_flush_dtmf", "Flush dtmf on a given uuid", uuid_flush_dtmf_function, "<uuid>");
SWITCH_ADD_API(commands_api_interface, "md5", "md5", md5_function, "<data>");
SWITCH_ADD_API(commands_api_interface, "hupall", "hupall", hupall_api_function, "<cause> [<var> <value>]");

View File

@ -2002,6 +2002,108 @@ static switch_call_cause_t error_outgoing_channel(switch_core_session_t *session
return cause;
}
/* fake chan_group */
switch_endpoint_interface_t *group_endpoint_interface;
static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags);
switch_io_routines_t group_io_routines = {
/*.outgoing_channel */ group_outgoing_channel
};
static switch_call_cause_t group_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags)
{
char *group;
switch_call_cause_t cause;
char *template = NULL, *dest = NULL;
switch_originate_flag_t myflags = SOF_NONE;
char *cid_name_override = NULL;
char *cid_num_override = NULL;
const char *var;
unsigned int timelimit = 60;
char *domain = NULL;
switch_channel_t *new_channel = NULL;
group = strdup(outbound_profile->destination_number);
if (!group) goto done;
if ((domain = strchr(group, '@'))) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
if (!domain) {
goto done;
}
template = switch_mprintf("${group_call(%s@%s)}", group, domain);
if (session) {
switch_channel_t *channel = switch_core_session_get_channel(session);
dest = switch_channel_expand_variables(channel, template);
if ((var = switch_channel_get_variable(channel, SWITCH_CALL_TIMEOUT_VARIABLE))) {
timelimit = atoi(var);
}
} else if (var_event) {
dest = switch_event_expand_headers(var_event, template);
}
if (!dest) {
goto done;
}
if (var_event) {
cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name");
cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number");
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE))) {
timelimit = atoi(var);
}
}
if ((flags & SOF_FORKED_DIAL)) {
myflags |= SOF_NOBLOCK;
}
if (switch_ivr_originate(session, new_session, &cause, dest, timelimit, NULL,
cid_name_override, cid_num_override, NULL, var_event, myflags) == SWITCH_STATUS_SUCCESS) {
const char *context;
switch_caller_profile_t *cp;
new_channel = switch_core_session_get_channel(*new_session);
if ((context = switch_channel_get_variable(new_channel, "group_context"))) {
if ((cp = switch_channel_get_caller_profile(new_channel))) {
cp->context = switch_core_strdup(cp->pool, context);
}
}
switch_core_session_rwunlock(*new_session);
}
done:
if (dest && dest != template) {
switch_safe_free(dest);
}
switch_safe_free(template);
if (cause == SWITCH_CAUSE_NONE) {
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
return cause;
}
/* fake chan_user */
switch_endpoint_interface_t *user_endpoint_interface;
static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
@ -2017,7 +2119,7 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags)
{
switch_xml_t x_domain = NULL, xml = NULL, x_user = NULL, x_param, x_params;
switch_xml_t x_domain = NULL, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params;
char *user = NULL, *domain = NULL;
const char *dest = NULL;
static switch_call_cause_t cause = SWITCH_CAUSE_NONE;
@ -2030,20 +2132,24 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
user = strdup(outbound_profile->destination_number);
if (!user)
goto done;
if (!user) goto done;
if (!(domain = strchr(user, '@'))) {
if ((domain = strchr(user, '@'))) {
*domain++ = '\0';
} else {
domain = switch_core_get_variable("domain");
}
if (!domain) {
goto done;
}
*domain++ = '\0';
switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(params);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "as_channel", "true");
if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, params) != SWITCH_STATUS_SUCCESS) {
if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, &x_group, params) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", user, domain);
cause = SWITCH_CAUSE_SUBSCRIBER_ABSENT;
goto done;
@ -2061,6 +2167,18 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
}
}
if ((x_params = switch_xml_child(x_group, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (!strcasecmp(var, "dial-string")) {
dest = val;
break;
}
}
}
if ((x_params = switch_xml_child(x_user, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
@ -2107,6 +2225,9 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session,
switch_event_dup(&event, var_event);
switch_event_del_header(event, "dialer_user");
switch_event_del_header(event, "dialer_domain");
if ((var = switch_event_get_header(var_event, SWITCH_CALL_TIMEOUT_VARIABLE))) {
timelimit = atoi(var);
}
} else {
switch_event_create(&event, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(event);
@ -2318,6 +2439,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
error_endpoint_interface->interface_name = "error";
error_endpoint_interface->io_routines = &error_io_routines;
group_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
group_endpoint_interface->interface_name = "group";
group_endpoint_interface->io_routines = &group_io_routines;
user_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
user_endpoint_interface->interface_name = "user";
user_endpoint_interface->io_routines = &user_io_routines;

View File

@ -1888,7 +1888,7 @@ static void voicemail_check_main(switch_core_session_t *session, const char *pro
switch_channel_event_set_data(channel, params);
if (switch_xml_locate_user("id", myid, domain_name, switch_channel_get_variable(channel, "network_addr"),
&xx_domain_root, &xx_domain, &xx_user, params) == SWITCH_STATUS_SUCCESS) {
&xx_domain_root, &xx_domain, &xx_user, NULL, params) == SWITCH_STATUS_SUCCESS) {
switch_xml_free(xx_domain_root);
}
@ -1981,7 +1981,7 @@ static void voicemail_check_main(switch_core_session_t *session, const char *pro
if (switch_xml_locate_user("id", myid, domain_name, switch_channel_get_variable(channel, "network_addr"),
&x_domain_root, &x_domain, &x_user, params) != SWITCH_STATUS_SUCCESS) {
&x_domain_root, &x_domain, &x_user, NULL, params) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", myid, domain_name);
ok = 0;
}
@ -2679,7 +2679,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "mailbox", id);
if (switch_xml_locate_user("id", id, domain_name, switch_channel_get_variable(channel, "network_addr"),
&x_domain_root, &x_domain, &x_user, params) == SWITCH_STATUS_SUCCESS) {
&x_domain_root, &x_domain, &x_user, NULL, params) == SWITCH_STATUS_SUCCESS) {
if ((x_params = switch_xml_child(x_user, "params"))) {
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr_soft(x_param, "name");

View File

@ -1394,7 +1394,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
const char *a1_hash = NULL;
char *sql;
char *mailbox = NULL;
switch_xml_t domain, xml = NULL, user, param, uparams, dparams;
switch_xml_t domain, xml = NULL, user, param, uparams, dparams, group, gparams = NULL;
char hexdigest[2 * SU_MD5_DIGEST_SIZE + 1] = "";
char *domain_name = NULL;
switch_event_t *params = NULL;
@ -1529,7 +1529,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
}
if (switch_xml_locate_user("id", switch_strlen_zero(username) ? "nobody" : username,
domain_name, ip, &xml, &domain, &user, params) != SWITCH_STATUS_SUCCESS) {
domain_name, ip, &xml, &domain, &user, &group, params) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n"
"You must define a domain called '%s' in your directory and add a user with the id=\"%s\" attribute\n"
"and you must configure your device to use the proper domain in it's authentication credentials.\n"
@ -1545,6 +1545,9 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
dparams = switch_xml_child(domain, "params");
uparams = switch_xml_child(user, "params");
if (group) {
gparams = switch_xml_child(group, "params");
}
if (!(dparams || uparams)) {
ret = AUTH_OK;
@ -1575,6 +1578,30 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
}
}
if (gparams) {
for (param = switch_xml_child(gparams, "param"); param; param = param->next) {
const char *var = switch_xml_attr_soft(param, "name");
const char *val = switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "sip-forbid-register") && switch_true(val)) {
ret = AUTH_FORBIDDEN;
goto end;
}
if (!strcasecmp(var, "password")) {
passwd = val;
}
if (!strcasecmp(var, "auth-acl")) {
auth_acl = val;
}
if (!strcasecmp(var, "a1-hash")) {
a1_hash = val;
}
}
}
if (uparams) {
for (param = switch_xml_child(uparams, "param"); param; param = param->next) {
const char *var = switch_xml_attr_soft(param, "name");
@ -1670,7 +1697,7 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
switch_event_create(v_event, SWITCH_EVENT_REQUEST_PARAMS);
}
if (v_event && *v_event) {
switch_xml_t xparams[2];
switch_xml_t xparams[3];
int i = 0;
switch_event_add_header_string(*v_event, SWITCH_STACK_BOTTOM, "sip_mailbox", mailbox);
@ -1684,11 +1711,15 @@ auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t co
xparams[i++] = dparams;
}
if (group && (gparams = switch_xml_child(group, "variables"))) {
xparams[i++] = gparams;
}
if ((uparams = switch_xml_child(user, "variables"))) {
xparams[i++] = uparams;
}
if (dparams || uparams) {
if (i <= 3) {
int j = 0;
for (j = 0; j < i; j++) {

View File

@ -206,7 +206,7 @@ static abyss_bool http_directory_auth(TSession * r, char *domain_name)
switch_assert(params);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "mailbox", "check");
if (switch_xml_locate_user("id", user, domain_name, NULL, &x_domain_root, &x_domain, &x_user, params) != SWITCH_STATUS_SUCCESS) {
if (switch_xml_locate_user("id", user, domain_name, NULL, &x_domain_root, &x_domain, &x_user, NULL, params) != SWITCH_STATUS_SUCCESS) {
switch_event_destroy(&params);
goto fail;
}

View File

@ -1920,7 +1920,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, c
SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *session, const char *data)
{
switch_xml_t x_domain, xml = NULL, x_user, x_param, x_params;
switch_xml_t x_domain, xml = NULL, x_user, x_param, x_params, x_group = NULL;
char *user, *mailbox, *domain;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_status_t status = SWITCH_STATUS_FALSE;
@ -1937,7 +1937,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *sessi
*domain++ = '\0';
if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, NULL) != SWITCH_STATUS_SUCCESS) {
if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, &x_group, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain);
goto done;
}
@ -1959,6 +1959,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_user(switch_core_session_t *sessi
}
}
if (x_group && (x_params = switch_xml_child(x_group, "variables"))) {
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");
const char *val = switch_xml_attr(x_param, "value");
if (var && val) {
switch_channel_set_variable(channel, var, val);
}
}
}
if ((x_params = switch_xml_child(x_user, "variables"))) {
for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr(x_param, "name");

View File

@ -300,6 +300,62 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_find_child(switch_xml_t node, const char
return p;
}
SWITCH_DECLARE(switch_xml_t) switch_xml_find_child_multi(switch_xml_t node, const char *childname, ...)
{
switch_xml_t p = NULL;
const char *names[256] = {0};
const char *vals[256] = {0};
int x, i = 0;
va_list ap;
const char *attrname, *value;
va_start(ap, childname);
while(i < 255) {
if ((attrname = va_arg(ap, const char *))) {
value = va_arg(ap, const char *);
}
if (attrname && value) {
names[i] = attrname;
vals[i] = value;
} else {
break;
}
i++;
}
va_end(ap);
if (!(childname && i)) {
return node;
}
for (p = switch_xml_child(node, childname); p; p = p->next) {
for (x = 0; x < i; x++) {
if (names[x] && vals[x]) {
const char *aname = switch_xml_attr(p, names[x]);
if (aname) {
if (*vals[x] == '!') {
const char *sval = vals[x] + 1;
if (sval && strcasecmp(aname, sval)) {
goto done;
}
} else {
if (!strcasecmp(aname, vals[x])) {
goto done;
}
}
}
}
}
}
done:
return p;
}
// returns the first child tag with the given name or NULL if not found
SWITCH_DECLARE(switch_xml_t) switch_xml_child(switch_xml_t xml, const char *name)
{
@ -1528,6 +1584,93 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_domain(const char *domain_name
return status;
}
SWITCH_DECLARE(switch_status_t) switch_xml_locate_group(const char *group_name,
const char *domain_name,
switch_xml_t *root,
switch_xml_t *domain,
switch_xml_t *group,
switch_event_t *params)
{
switch_status_t status = SWITCH_STATUS_FALSE;
switch_event_t *my_params = NULL;
switch_xml_t groups = NULL;
*root = NULL;
*group = NULL;
*domain = NULL;
if (!params) {
switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(my_params);
params = my_params;
}
if (group_name) {
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "group_name", group_name);
}
if (domain_name) {
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
}
if ((status = switch_xml_locate_domain(domain_name, params, root, domain)) != SWITCH_STATUS_SUCCESS) {
goto end;
}
status = SWITCH_STATUS_FALSE;
if ((groups = switch_xml_child(*domain, "groups"))) {
if ((*group = switch_xml_find_child(groups, "group", "name", group_name))) {
status = SWITCH_STATUS_SUCCESS;
}
}
end:
if (my_params) {
switch_event_destroy(&my_params);
}
return status;
}
static switch_status_t find_user_in_tag(switch_xml_t tag, const char *ip, const char *user_name, const char *key, switch_event_t *params, switch_xml_t *user)
{
const char *type = "!pointer";
const char *val;
if (params && (val = switch_event_get_header(params, "user_type"))) {
if (!strcasecmp(val, "any")) {
type = NULL;
} else {
type = val;
}
}
if (ip) {
if ((*user = switch_xml_find_child_multi(tag, "user", "ip", ip, "type", type, NULL))) {
return SWITCH_STATUS_SUCCESS;
}
}
if (user_name) {
if (params && switch_event_get_header(params, (char *) "mailbox")) {
if ((*user = switch_xml_find_child_multi(tag, "user", "mailbox", user_name, "type", type, NULL))) {
return SWITCH_STATUS_SUCCESS;
}
}
if ((*user = switch_xml_find_child_multi(tag, "user", key, user_name, "type", type, NULL))) {
return SWITCH_STATUS_SUCCESS;
}
}
return SWITCH_STATUS_FALSE;
}
SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key,
const char *user_name,
const char *domain_name,
@ -1535,11 +1678,13 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key,
switch_xml_t *root,
switch_xml_t *domain,
switch_xml_t *user,
switch_xml_t *ingroup,
switch_event_t *params)
{
switch_status_t status = SWITCH_STATUS_FALSE;
switch_event_t *my_params = NULL;
switch_event_t *my_params = NULL, *search_params = NULL;
switch_xml_t group = NULL, groups = NULL, users = NULL;
*root = NULL;
*user = NULL;
*domain = NULL;
@ -1570,27 +1715,28 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key,
status = SWITCH_STATUS_FALSE;
if (ip) {
if ((*user = switch_xml_find_child(*domain, "user", "ip", ip))) {
status = SWITCH_STATUS_SUCCESS;
goto end;
}
}
if (params != my_params) {
search_params = params;
}
if (user_name) {
if (params != my_params && switch_event_get_header(params, (char *) "mailbox")) {
if ((*user = switch_xml_find_child(*domain, "user", "mailbox", user_name))) {
status = SWITCH_STATUS_SUCCESS;
goto end;
if ((groups = switch_xml_child(*domain, "groups"))) {
for (group = switch_xml_child(groups, "group"); group; group = group->next) {
if ((users = switch_xml_child(group, "users"))) {
if ((status = find_user_in_tag(users, ip, user_name, key, params, user)) == SWITCH_STATUS_SUCCESS) {
if (ingroup) {
*ingroup = group;
}
break;
}
}
}
if ((*user = switch_xml_find_child(*domain, "user", key, user_name))) {
status = SWITCH_STATUS_SUCCESS;
goto end;
}
}
if (status != SWITCH_STATUS_SUCCESS) {
status = find_user_in_tag(*domain, ip, user_name, key, params, user);
}
end:
if (my_params) {