Przeglądaj źródła

imc: add support to modify member role

Joey Golan 2 lat temu
rodzic
commit
7d3d94b19f

+ 7 - 0
src/modules/imc/doc/imc.xml

@@ -37,6 +37,13 @@
 		    <email>[email protected]</email>
 		</address>
 	    </editor>
+		<editor>
+		<firstname>Joey</firstname>
+		<surname>Golan</surname>
+		<address>
+		    <email>[email protected]</email>
+		</address>
+	    </editor>
 	</authorgroup>
 	<copyright>
 	    <year>2006</year>

+ 14 - 0
src/modules/imc/doc/imc_admin.xml

@@ -453,6 +453,20 @@ if(is_method("MESSAGE)
   -eg: #add sip:[email protected] sip:[email protected]
     or  #add [email protected] sent to sip:[email protected]
   -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:[email protected] admin sip:[email protected]
+    or  #invite [email protected] admin sent to sip:[email protected]
+  -error case: return codes: -120 -- -129
 ...
 </programlisting>
 		</example>

+ 120 - 0
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 @@ error:
 	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)
 {

+ 9 - 0
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" <room_name> - \
 create new conference room\r\n\
 "IMC_CMD_START_STR IMC_CMD_JOIN" [<room_name>] - \
@@ -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" <user_name> [<room_name>] - \
 add a user to a conference room\r\n\
+"IMC_CMD_START_STR IMC_CMD_MODIFY" <user_name> <role> [<room_name>] - \
+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

+ 32 - 2
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;
 }
 
 /**

+ 5 - 0
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);