GUACAMOLE-1293: Add support for notifying owner of users joining and leaving.

This commit is contained in:
Virtually Nick 2021-12-25 19:15:21 -05:00
parent cb7ae25177
commit 6312e1720d
2 changed files with 164 additions and 0 deletions

View File

@ -303,6 +303,10 @@ int guac_client_add_user(guac_client* client, guac_user* user, int argc, char**
if (user->owner)
client->__owner = user;
/* Notify owner of user joining connection. */
else
guac_client_owner_notify_join(client, user);
}
pthread_rwlock_unlock(&(client->__users_lock));
@ -331,6 +335,10 @@ void guac_client_remove_user(guac_client* client, guac_user* user) {
if (user->owner)
client->__owner = NULL;
/* Update owner of user having left the connection. */
else
guac_client_owner_notify_leave(client, user);
pthread_rwlock_unlock(&(client->__users_lock));
/* Call handler, if defined */
@ -731,6 +739,126 @@ int guac_client_owner_supports_required(guac_client* client) {
}
/**
* A callback function that is invokved by guac_client_owner_notify_join() to
* notify the owner of a connection that another user has joined the
* connection, returning zero if the message is sent successfully, or non-zero
* if an error occurs.
*
* @param user
* The user to send the notification to, which will be the owner of the
* connection.
*
* @param data
* The data provided to the callback, which is the user that is joining the
* connection.
*
* @return
* Zero if the message is sent successfully to the owner, otherwise
* non-zero, cast as a void*.
*/
static void* guac_client_owner_notify_join_callback(guac_user* user, void* data) {
const guac_user* joiner = (const guac_user *) data;
int retval = 0;
char* owner = "owner";
if (user->info.name != NULL)
owner = strdup(user->info.name);
char* joinName = "anonymous";
if (joiner->info.name != NULL)
joinName = strdup(joiner->info.name);
guac_user_log(user, GUAC_LOG_DEBUG, "Notifying %s of %s joining.", owner, joinName);
size_t msg_size = snprintf(NULL, 0, "User %s has joined the connection.", joinName);
char* msg = malloc(msg_size + 1);
sprintf(msg, "User %s has joined the connection.", joinName);
/* Send required parameters to owner. */
if (user != NULL)
retval = guac_protocol_send_msg(user->socket, msg);
else
retval = -1;
free(owner);
free(joinName);
free(msg);
return (void*) ((intptr_t) retval);
}
int guac_client_owner_notify_join(guac_client* client, guac_user* joiner) {
/* Don't send msg instruction if client does not support it. */
if (!guac_client_owner_supports_msg(client))
return -1;
guac_client_log(client, GUAC_LOG_DEBUG, "Notifying owner of %s joining.", joiner->user_id);
return (int) ((intptr_t) guac_client_for_owner(client, guac_client_owner_notify_join_callback, joiner));
}
/**
* A callback function that is invokved by guac_client_owner_notify_leave() to
* notify the owner of a connection that another user has left the connection,
* returning zero if the message is sent successfully, or non-zero
* if an error occurs.
*
* @param user
* The user to send the notification to, which will be the owner of the
* connection.
*
* @param data
* The data provided to the callback, which is the user that is leaving the
* connection.
*
* @return
* Zero if the message is sent successfully to the owner, otherwise
* non-zero, cast as a void*.
*/
static void* guac_client_owner_notify_leave_callback(guac_user* user, void* data) {
const guac_user* quitter = (const guac_user *) data;
char* owner = "owner";
if (user->info.name != NULL)
owner = strdup(user->info.name);
char* quitterName = "anonymous";
if (quitter->info.name != NULL)
quitterName = strdup(quitter->info.name);
guac_user_log(user, GUAC_LOG_DEBUG, "Notifying %s of %s leaving.", owner, quitterName);
size_t msg_size = snprintf(NULL, 0, "User %s has left the connection.", quitterName);
char* msg = malloc(msg_size + 1);
sprintf(msg, "User %s has left the connection.", quitterName);
/* Send required parameters to owner. */
if (user != NULL)
return (void*) ((intptr_t) guac_protocol_send_msg(user->socket, msg));
return (void*) ((intptr_t) -1);
}
int guac_client_owner_notify_leave(guac_client* client, guac_user* quitter) {
/* Don't send msg instruction if client does not support it. */
if (!guac_client_owner_supports_msg(client))
return -1;
guac_client_log(client, GUAC_LOG_DEBUG, "Notifying owner of %s leaving.", quitter->user_id);
return (int) ((intptr_t) guac_client_for_owner(client, guac_client_owner_notify_leave_callback, quitter));
}
int guac_client_supports_webp(guac_client* client) {
#ifdef ENABLE_WEBP

View File

@ -738,6 +738,42 @@ int guac_client_owner_supports_msg(guac_client* client);
*/
int guac_client_owner_supports_required(guac_client* client);
/**
* Notifies the owner of the given client that a user has joined the connection,
* and returns zero if the message was sent successfully, or non-zero if the
* notification failed.
*
* @param client
* The Guacamole Client whose owner should be notified of a user joining
* the connection.
*
* @param joiner
* The Guacamole User who joined the connection.
*
* @return
* Zero if the notification to the owner was sent successfully, or non-zero
* if an error occurred.
*/
int guac_client_owner_notify_join(guac_client* client, guac_user* joiner);
/**
* Notifies the owner of the given client that a user has left the connection,
* and returns zero if the message was sent successfully, or non-zero if the
* notification failed.
*
* @param client
* The Guacamole Client whose owner should be notified of a user leaving
* the connection.
*
* @param quitter
* The Guacamole User who left the connection.
*
* @return
* Zero if the notification to the owner was sent successfully, or non-zero
* if an error occurred.
*/
int guac_client_owner_notify_leave(guac_client* client, guac_user* quitter);
/**
* Returns whether all users of the given client support WebP. If any user does
* not support WebP, or the server cannot encode WebP images, zero is returned.