diff --git a/src/modules/imc/doc/imc.xml b/src/modules/imc/doc/imc.xml index 99f97a5eed3..f0f4a73d1b0 100644 --- a/src/modules/imc/doc/imc.xml +++ b/src/modules/imc/doc/imc.xml @@ -37,6 +37,13 @@ anca@voice-system.ro + + Joey + Golan +
+ joeygo@gmail.com +
+
2006 diff --git a/src/modules/imc/doc/imc_admin.xml b/src/modules/imc/doc/imc_admin.xml index 85a31a844a1..6f7f5a02582 100644 --- a/src/modules/imc/doc/imc_admin.xml +++ b/src/modules/imc/doc/imc_admin.xml @@ -453,6 +453,20 @@ if(is_method("MESSAGE) -eg: #add sip:john@kamailio.org sip:chat-000@kamailio.org or #add john@kamailio.org sent to sip:chat-000@kamailio.org -error case: return codes: -50 -- -59 + +11.modify + -modify user role in a room + -takes 3 parameters: + 1)the complete address of the user + 2)the role of the user + 3)the address of the room -if not present it will be considered + to be the address in the To header of the message + -only certain users have the right to invite other user: the owner + and the administrators + -roles: owner, admin, member + -eg: #invite sip:john@kamailio.org admin sip:chat-000@kamailio.org + or #invite john@kamailio.org admin sent to sip:chat-000@kamailio.org + -error case: return codes: -120 -- -129 ... diff --git a/src/modules/imc/imc_cmd.c b/src/modules/imc/imc_cmd.c index 8d9c6f3ea18..4f8a1501425 100644 --- a/src/modules/imc/imc_cmd.c +++ b/src/modules/imc/imc_cmd.c @@ -62,6 +62,7 @@ static str msg_join_attempt_bcast = STR_STATIC_INIT(PREFIX "%.*s attempted to jo static str msg_join_attempt_ucast = STR_STATIC_INIT(PREFIX "Private rooms are by invitation only. Room owners have been notified."); static str msg_invite = STR_STATIC_INIT(PREFIX "%.*s invites you to join the room (send '%.*saccept' or '%.*sreject')"); static str msg_add_reject = STR_STATIC_INIT(PREFIX "You don't have the permmission to add members to this room"); +static str msg_modify_reject = STR_STATIC_INIT(PREFIX "You don't have the permmission to modify members in this room"); #if 0 static str msg_rejected = STR_STATIC_INIT(PREFIX "%.*s has rejected invitation"); #endif @@ -289,6 +290,9 @@ int imc_parse_cmd(char *buf, int len, imc_cmd_p cmd) } else if(cmd->name.len==(sizeof("destroy")-1) && !strncasecmp(cmd->name.s, "destroy", cmd->name.len)) { cmd->type = IMC_CMDID_DESTROY; + } else if(cmd->name.len==(sizeof("modify")-1) + && !strncasecmp(cmd->name.s, "modify", cmd->name.len)) { + cmd->type = IMC_CMDID_MODIFY; } else if(cmd->name.len==(sizeof("help")-1) && !strncasecmp(cmd->name.s, "help", cmd->name.len)) { cmd->type = IMC_CMDID_HELP; @@ -1295,6 +1299,122 @@ int imc_handle_message(struct sip_msg* msg, str *msgbody, return rv; } +int imc_handle_modify(struct sip_msg* msg, imc_cmd_t *cmd, + struct imc_uri *src, struct imc_uri *dst) +{ + int rv = -1; + imc_room_p rm = 0; + imc_member_p member = 0; + int flag_member = 0; + str body; + struct imc_uri user, room; + int params = 0; + + memset(&user, '\0', sizeof(user)); + memset(&room, '\0', sizeof(room)); + + if (cmd->param[0].s) { + params++; + if (cmd->param[1].s) { + params++; + if (cmd->param[2].s) { + params++; + } + } + } + + switch(params) { + case 0: + LM_INFO("Modify command with missing argument from [%.*s]\n", STR_FMT(&src->uri)); + goto error; + case 1: + LM_INFO("Modify command with missing argument role\n"); + goto error; + case 2: + case 3: + /* identify the role */ + if(cmd->param[1].len==(sizeof(IMC_MEMBER_OWNER_STR)-1) + && !strncasecmp(cmd->param[1].s, IMC_MEMBER_OWNER_STR, cmd->param[1].len)) + { + flag_member |= IMC_MEMBER_OWNER; + } else if(cmd->param[1].len==(sizeof(IMC_MEMBER_ADMIN_STR)-1) + && !strncasecmp(cmd->param[1].s, IMC_MEMBER_ADMIN_STR, cmd->param[1].len)) + { + flag_member |= IMC_MEMBER_ADMIN; + } else if(cmd->param[1].len==(sizeof(IMC_MEMBER_INVITED_STR)-1) + && !strncasecmp(cmd->param[1].s, IMC_MEMBER_INVITED_STR, cmd->param[1].len)) + { + flag_member |= IMC_MEMBER_INVITED; + } else { + LM_INFO("Modify command with unknown argument role [%.*s]\n", STR_FMT(&cmd->param[1])); + goto error; + } + + if (build_imc_uri(&room, cmd->param[3].s ? cmd->param[3] : dst->parsed.user, &dst->parsed)) + goto error; + break; + default: + LM_ERR("Invalid number of parameters %d\n", params); + goto error; + } + + if (build_imc_uri(&user, cmd->param[0], &dst->parsed)) + goto error; + + rm = imc_get_room(&room.parsed.user, &room.parsed.host); + if (rm == NULL || (rm->flags & IMC_ROOM_DELETED)) { + LM_ERR("Room [%.*s] does not exist!\n", STR_FMT(&room.uri)); + goto error; + } + member = imc_get_member(rm, &src->parsed.user, &src->parsed.host); + + if (member == NULL) { + LM_ERR("User [%.*s] is not member of room [%.*s]!\n", STR_FMT(&src->uri), STR_FMT(&room.uri)); + goto error; + } + + if (!(member->flags & IMC_MEMBER_OWNER) && + !(member->flags & IMC_MEMBER_ADMIN)) { + LM_ERR("User [%.*s] has no right to modify others role!\n", STR_FMT(&member->uri)); + imc_send_message(&rm->uri, &member->uri, build_headers(msg), &msg_modify_reject); + goto done; + } + + member = imc_get_member(rm, &user.parsed.user, &user.parsed.host); + if (member == NULL) { + LM_ERR("User [%.*s] is not member of room [%.*s]!\n", STR_FMT(&member->uri), STR_FMT(&room.uri)); + goto error; + } + + rv = imc_modify_member(rm, &src->parsed.user, &src->parsed.host, flag_member); + + if (rv == -1) { + LM_ERR("Failed to modify member [%.*s] role [%.*s]\n", STR_FMT(&member->uri), STR_FMT(&cmd->param[1])); + goto error; + } + + body.s = imc_body_buf; + body.len = snprintf(body.s, sizeof(imc_body_buf), msg_user_joined.s, STR_FMT(format_uri(member->uri))); + + if (body.len < 0) { + LM_ERR("Error while building response\n"); + goto error; + } + + if (body.len > 0) + imc_room_broadcast(rm, build_headers(msg), &body); + + if (body.len >= sizeof(imc_body_buf)) + LM_ERR("Truncated message '%.*s'\n", STR_FMT(&body)); + +done: + rv = 0; +error: + if (user.uri.s != NULL) pkg_free(user.uri.s); + if (room.uri.s != NULL) pkg_free(room.uri.s); + if (rm != NULL) imc_release_room(rm); + return rv; +} int imc_room_broadcast(imc_room_p room, str *ctype, str *body) { diff --git a/src/modules/imc/imc_cmd.h b/src/modules/imc/imc_cmd.h index 64f444d715c..b35dfe7dcf6 100644 --- a/src/modules/imc/imc_cmd.h +++ b/src/modules/imc/imc_cmd.h @@ -48,6 +48,7 @@ #define IMC_CMDID_UNKNOWN 11 #define IMC_CMDID_ADD 12 #define IMC_CMDID_ROOMS 13 +#define IMC_CMDID_MODIFY 14 #define IMC_CMD_CREATE "create" @@ -61,10 +62,14 @@ #define IMC_CMD_MEMBERS "members" #define IMC_CMD_ADD "add" #define IMC_CMD_ROOMS "rooms" +#define IMC_CMD_MODIFY "modify" #define IMC_ROOM_PRIVATE "private" #define IMC_ROOM_PRIVATE_LEN (sizeof(IMC_ROOM_PRIVATE)-1) +#define IMC_ROOM_ROLE "role" +#define IMC_ROLE_LEN (sizeof(IMC_ROOM_ROLE)-1) + #define IMC_HELP_MSG "\r\n"IMC_CMD_START_STR IMC_CMD_CREATE" - \ create new conference room\r\n\ "IMC_CMD_START_STR IMC_CMD_JOIN" [] - \ @@ -73,6 +78,8 @@ join the conference room\r\n\ invite a user to join a conference room\r\n\ "IMC_CMD_START_STR IMC_CMD_ADD" [] - \ add a user to a conference room\r\n\ +"IMC_CMD_START_STR IMC_CMD_MODIFY" [] - \ +modify user role in a conference room\r\n\ "IMC_CMD_START_STR IMC_CMD_ACCEPT" - \ accept invitation to join a conference room\r\n\ "IMC_CMD_START_STR IMC_CMD_REJECT" - \ @@ -129,5 +136,7 @@ int imc_handle_help(struct sip_msg* msg, imc_cmd_t *cmd, struct imc_uri *src, struct imc_uri *dst); int imc_handle_message(struct sip_msg* msg, str *msgbody, struct imc_uri *src, struct imc_uri *dst); +int imc_handle_modify(struct sip_msg* msg, imc_cmd_t *cmd, + struct imc_uri *src, struct imc_uri *dst); #endif diff --git a/src/modules/imc/imc_mng.c b/src/modules/imc/imc_mng.c index dc65d060888..7740a74b681 100644 --- a/src/modules/imc/imc_mng.c +++ b/src/modules/imc/imc_mng.c @@ -344,8 +344,38 @@ imc_member_p imc_add_member(imc_room_p room, str* user, str* domain, int flags) return imp; } +imc_member_p imc_modify_member(imc_room_p room, str* user, str* domain, int flags) { + imc_member_p imp = NULL; + unsigned int hashid; + + if(room==NULL || user == NULL || user->s==NULL || user->len<=0 + || domain == NULL || domain->s==NULL || domain->len<=0) + { + LM_ERR("invalid parameters\n"); + return NULL; + } + + hashid = core_case_hash(user, domain, 0); + imp = room->members; + while(imp) + { + if(imp->hashid==hashid && imp->user.len==user->len + && imp->domain.len==domain->len + && !strncasecmp(imp->user.s, user->s, user->len) + && !strncasecmp(imp->domain.s, domain->s, domain->len)) + { + LM_DBG("member found. modify flags\n"); + imp->flags = flags; + return 0; + } + imp = imp->next; + } + + return -1; +} + /** - * search memeber + * search member */ imc_member_p imc_get_member(imc_room_p room, str* user, str* domain) { @@ -374,7 +404,7 @@ imc_member_p imc_get_member(imc_room_p room, str* user, str* domain) imp = imp->next; } - return NULL; + return 0; } /** diff --git a/src/modules/imc/imc_mng.h b/src/modules/imc/imc_mng.h index 206351e3cd3..866a1fa56dd 100644 --- a/src/modules/imc/imc_mng.h +++ b/src/modules/imc/imc_mng.h @@ -38,6 +38,10 @@ #define IMC_MEMBER_DELETED (1<<3) #define IMC_MEMBER_SKIP (1<<4) +#define IMC_MEMBER_OWNER_STR "owner" +#define IMC_MEMBER_ADMIN_STR "admin" +#define IMC_MEMBER_INVITED_STR "member" + typedef struct _imc_member { unsigned int hashid; @@ -81,6 +85,7 @@ typedef struct _imc_hentry } imc_hentry_t, *imc_hentry_p; imc_member_p imc_add_member(imc_room_p room, str* user, str* domain, int flags); +imc_member_p imc_modify_member(imc_room_p room, str* user, str* domain, int flags); imc_member_p imc_get_member(imc_room_p room, str* user, str* domain); int imc_del_member(imc_room_p room, str* user, str* domain);