mirror of
https://github.com/mumble-voip/mumble.git
synced 2025-10-26 11:19:16 +00:00
AccessTokens: Added support for temporary access tokens in the UserState message
This commit is contained in:
parent
61ee9ddf6d
commit
1c38b53fdf
@ -213,6 +213,8 @@ message UserState {
|
||||
optional bool priority_speaker = 18;
|
||||
// True if the user is currently recording.
|
||||
optional bool recording = 19;
|
||||
// a list of temporary acces tokens to be respected when processing this request
|
||||
repeated string temporary_access_tokens = 20;
|
||||
}
|
||||
|
||||
// Relays information on the bans. The client may send the BanList message to
|
||||
|
||||
@ -816,9 +816,20 @@ void ServerHandler::requestUserStats(unsigned int uiSession, bool statsOnly) {
|
||||
}
|
||||
|
||||
void ServerHandler::joinChannel(unsigned int uiSession, unsigned int channel) {
|
||||
static const QStringList EMPTY;
|
||||
|
||||
joinChannel(uiSession, channel, EMPTY);
|
||||
}
|
||||
|
||||
void ServerHandler::joinChannel(unsigned int uiSession, unsigned int channel, const QStringList &temporaryAccessTokens) {
|
||||
MumbleProto::UserState mpus;
|
||||
mpus.set_session(uiSession);
|
||||
mpus.set_channel_id(channel);
|
||||
|
||||
foreach(QString tmpToken, temporaryAccessTokens) {
|
||||
mpus.add_temporary_access_tokens(tmpToken.toUtf8().constData());
|
||||
}
|
||||
|
||||
sendMessage(mpus);
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtNetwork/QHostAddress>
|
||||
#include <QtNetwork/QSslCipher>
|
||||
#include <QtNetwork/QSslError>
|
||||
@ -117,6 +118,7 @@ class ServerHandler : public QThread {
|
||||
|
||||
void requestUserStats(unsigned int uiSession, bool statsOnly);
|
||||
void joinChannel(unsigned int uiSession, unsigned int channel);
|
||||
void joinChannel(unsigned int uiSession, unsigned int channel, const QStringList &temporaryAccessTokens);
|
||||
void createChannel(unsigned int parent_id, const QString &name, const QString &description, unsigned int position, bool temporary, unsigned int maxUsers);
|
||||
void requestBanList();
|
||||
void requestUserList();
|
||||
|
||||
@ -77,6 +77,59 @@
|
||||
sendMessage(uSource, mppd); \
|
||||
}
|
||||
|
||||
/// A helper class for managing temporary access tokens
|
||||
/// It will add the tokens in the comstructor and remove them again in the destructor effectively
|
||||
/// turning the tokens into a scope-based property
|
||||
class TemporaryAccessTokenHelper {
|
||||
protected:
|
||||
ServerUser *affectedUser;
|
||||
QStringList qslTemporaryTokens;
|
||||
Server *server;
|
||||
|
||||
public:
|
||||
TemporaryAccessTokenHelper(ServerUser *affectedUser, const QStringList &tokens, Server *server) : affectedUser(affectedUser),
|
||||
qslTemporaryTokens(tokens), server(server) {
|
||||
// Add the temporary tokens
|
||||
QMutableStringListIterator it(this->qslTemporaryTokens);
|
||||
|
||||
{
|
||||
QMutexLocker qml(&server->qmCache);
|
||||
|
||||
while (it.hasNext()) {
|
||||
QString token = it.next();
|
||||
if (!this->affectedUser->qslAccessTokens.contains(token)) {
|
||||
// Add token
|
||||
this->affectedUser->qslAccessTokens << token;
|
||||
} else {
|
||||
// It appears, as if the user already has this token set -> it's not a temporary one or a duplicate
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->qslTemporaryTokens.isEmpty()) {
|
||||
// Clear the cache in order for tokens to take effect
|
||||
server->clearACLCache(this->affectedUser);
|
||||
}
|
||||
}
|
||||
|
||||
~TemporaryAccessTokenHelper() {
|
||||
if (!this->qslTemporaryTokens.isEmpty()) {
|
||||
{
|
||||
QMutexLocker qml(&server->qmCache);
|
||||
|
||||
// remove the temporary tokens
|
||||
foreach(QString token, this->qslTemporaryTokens) {
|
||||
this->affectedUser->qslAccessTokens.removeOne(token);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear cache to actually get rid of the temporary tokens
|
||||
server->clearACLCache(this->affectedUser);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void Server::msgAuthenticate(ServerUser *uSource, MumbleProto::Authenticate &msg) {
|
||||
if ((msg.tokens_size() > 0) || (uSource->sState == ServerUser::Authenticated)) {
|
||||
QStringList qsl;
|
||||
@ -501,6 +554,7 @@ void Server::msgUserState(ServerUser *uSource, MumbleProto::UserState &msg) {
|
||||
First check all permissions involved
|
||||
*/
|
||||
if ((pDstServerUser->iId == 0) && (uSource->iId != 0)) {
|
||||
// Don't allow any action on the SuperUser except initiated directly by the SuperUser himself/herself
|
||||
PERM_DENIED_TYPE(SuperUser);
|
||||
return;
|
||||
}
|
||||
@ -516,6 +570,13 @@ void Server::msgUserState(ServerUser *uSource, MumbleProto::UserState &msg) {
|
||||
if (uSource == pDstServerUser) {
|
||||
RATELIMIT(uSource);
|
||||
}
|
||||
|
||||
// Handle potential temporary access tokens
|
||||
QStringList temporaryAccessTokens;
|
||||
for (int i=0; i < msg.temporary_access_tokens_size(); i++) {
|
||||
temporaryAccessTokens << u8(msg.temporary_access_tokens(i));
|
||||
}
|
||||
TemporaryAccessTokenHelper tempTokenHelper(uSource, temporaryAccessTokens, this);
|
||||
|
||||
if (msg.has_channel_id()) {
|
||||
Channel *c = qhChannels.value(msg.channel_id());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user