This commit is contained in:
DNW 2011-08-29 21:58:32 +02:00
parent 0e4d963a5a
commit a8975fe6bc
8 changed files with 81 additions and 16 deletions

View File

@ -57,19 +57,20 @@ ChanACL::ChanACL(Channel *chan) : QObject(chan) {
#ifdef MURMUR
bool ChanACL::hasPermission(ServerUser *p, Channel *chan, QFlags<Perm> perm, ACLCache &cache) {
Permissions granted = effectivePermissions(p, chan, cache);
return ((granted & perm) != None);
}
// Return effective permissions.
QFlags<ChanACL::Perm> ChanACL::effectivePermissions(ServerUser *p, Channel *chan, ACLCache &cache) {
QStack<Channel *> chanstack;
Channel *ch;
ChanACL *acl;
// Superuser
if (p->iId == 0) {
switch (perm) {
case Speak:
case Whisper:
return false;
default:
return true;
}
return static_cast<Permissions>(All &~ (Speak|Whisper));
}
Permissions granted = 0;
@ -79,10 +80,7 @@ bool ChanACL::hasPermission(ServerUser *p, Channel *chan, QFlags<Perm> perm, ACL
granted = h->value(chan);
if (granted & Cached) {
if ((perm != Speak) && (perm != Whisper))
return ((granted & (perm | Write)) != None);
else
return ((granted & perm) != None);
return granted;
}
ch = chan;
@ -116,8 +114,18 @@ bool ChanACL::hasPermission(ServerUser *p, Channel *chan, QFlags<Perm> perm, ACL
write = true;
if (acl->pDeny & Write)
write = false;
if (ch->iId == 0 && chan == ch && acl->bApplyHere) {
if (acl->pAllow & Kick)
granted |= Kick;
if (acl->pAllow & Ban)
granted |= Ban;
if (acl->pAllow & Register)
granted |= Register;
if (acl->pAllow & SelfRegister)
granted |= SelfRegister;
}
if ((ch==chan && acl->bApplyHere) || (ch!=chan && acl->bApplySubs)) {
granted |= acl->pAllow;
granted |= (acl->pAllow & ~(Kick|Ban|Register|SelfRegister|Cached));
granted &= ~acl->pDeny;
}
}
@ -128,15 +136,19 @@ bool ChanACL::hasPermission(ServerUser *p, Channel *chan, QFlags<Perm> perm, ACL
}
}
if (granted & Write) {
granted |= Traverse|Enter|MuteDeafen|Move|MakeChannel|LinkChannel|TextMessage|MakeTempChannel;
if (chan->iId == 0)
granted |= Kick|Ban|Register|SelfRegister;
}
if (! cache.contains(p))
cache.insert(p, new QHash<Channel *, Permissions>);
cache.value(p)->insert(chan, granted | Cached);
if ((perm != Speak) && (perm != Whisper))
return ((granted & (perm | Write)) != None);
else
return ((granted & perm) != None);
return granted;
}
#else

View File

@ -85,6 +85,7 @@ class ChanACL : public QObject {
ChanACL(Channel *c);
#ifdef MURMUR
static bool hasPermission(ServerUser *p, Channel *c, QFlags<Perm> perm, ACLCache &cache);
static QFlags<Perm> effectivePermissions(ServerUser *p, Channel *c, ACLCache &cache);
#else
static QString whatsThis(Perm p);
#endif

View File

@ -575,6 +575,13 @@ module Murmur
* @return true if any of the permissions in perm were set for the user.
*/
bool hasPermission(int session, int channelid, int perm) throws ServerBootedException, InvalidSessionException, InvalidChannelException, InvalidSecretException;
/** Return users effective permissions
* @param session Connection ID of user. See {@link User.session}.
* @param channelid ID of Channel. See {@link Channel.id}.
* @return bitfield of allowed actions
*/
idempotent int effectivePermissions(int session, int channelid) throws ServerBootedException, InvalidSessionException, InvalidChannelException, InvalidSecretException;
/** Add a context callback. This is done per user, and will add a context menu action for the user.
*

View File

@ -83,6 +83,7 @@ namespace Murmur {
const Ice::Current&);
virtual void hasPermission_async(const ::Murmur::AMD_Server_hasPermissionPtr&, ::Ice::Int, ::Ice::Int, ::Ice::Int, const ::Ice::Current&);
virtual void effectivePermissions_async(const ::Murmur::AMD_Server_effectivePermissionsPtr&, ::Ice::Int, ::Ice::Int, const ::Ice::Current&);
virtual void addContextCallback_async(const ::Murmur::AMD_Server_addContextCallbackPtr&, ::Ice::Int, const ::std::string&, const ::std::string&, const ::Murmur::ServerContextCallbackPrx&, int, const ::Ice::Current&);
virtual void removeContextCallback_async(const ::Murmur::AMD_Server_removeContextCallbackPtr&, const ::Murmur::ServerContextCallbackPrx&, const ::Ice::Current&);

View File

@ -1019,6 +1019,14 @@ static void impl_Server_hasPermission(const ::Murmur::AMD_Server_hasPermissionPt
cb->ice_response(server->hasPermission(user, channel, static_cast<ChanACL::Perm>(perm)));
}
#define ACCESS_Server_effectivePermissions_READ
static void impl_Server_effectivePermissions(const ::Murmur::AMD_Server_effectivePermissionsPtr cb, int server_id, ::Ice::Int session, ::Ice::Int channelid) {
NEED_SERVER;
NEED_PLAYER;
NEED_CHANNEL;
cb->ice_response(server->effectivePermissions(user, channel));
}
static void impl_Server_addContextCallback(const Murmur::AMD_Server_addContextCallbackPtr cb, int server_id, ::Ice::Int session, const ::std::string& action, const ::std::string& text, const ::Murmur::ServerContextCallbackPrx& cbptr, int ctx) {
NEED_SERVER;
NEED_PLAYER;

View File

@ -749,6 +749,36 @@ void ::Murmur::ServerI::hasPermission_async(const ::Murmur::AMD_Server_hasPermis
QCoreApplication::instance()->postEvent(mi, ie);
}
void ::Murmur::ServerI::effectivePermissions_async(const ::Murmur::AMD_Server_effectivePermissionsPtr &cb, ::Ice::Int p1, ::Ice::Int p2, const ::Ice::Current &current) {
// qWarning() << effectivePermissions << meta->mp.qsIceSecretRead.isNull() << meta->mp.qsIceSecretRead.isEmpty();
#ifndef ACCESS_Server_effectivePermissions_ALL
#ifdef ACCESS_Server_effectivePermissions_READ
if ( !meta->mp.qsIceSecretRead.isNull()) {
bool ok = ! meta->mp.qsIceSecretRead.isEmpty();
#else
if (! meta->mp.qsIceSecretRead.isNull() ||! meta->mp.qsIceSecretWrite.isNull()) {
bool ok = ! meta->mp.qsIceSecretWrite.isEmpty();
#endif
::Ice::Context::const_iterator i = current.ctx.find("secret");
ok = ok && (i != current.ctx.end());
if (ok) {
const QString &secret = u8((*i).second);
#ifdef ACCESS_Server_effectivePermissions_READ
ok = ((secret == meta->mp.qsIceSecretRead) ||(secret == meta->mp.qsIceSecretWrite));
#else
ok = (secret == meta->mp.qsIceSecretWrite);
#endif
}
if (! ok) {
cb->ice_exception(InvalidSecretException());
return;
}
}
#endif
ExecEvent *ie = new ExecEvent(boost::bind(&impl_Server_effectivePermissions, cb, QString::fromStdString(current.id.name).toInt(), p1, p2));
QCoreApplication::instance()->postEvent(mi, ie);
}
void ::Murmur::ServerI::addContextCallback_async(const ::Murmur::AMD_Server_addContextCallbackPtr &cb, ::Ice::Int p1, const ::std::string& p2, const ::std::string& p3, const ::Murmur::ServerContextCallbackPrx& p4, ::Ice::Int p5, const ::Ice::Current &current) {
// qWarning() << "addContextCallback" << meta->mp.qsIceSecretRead.isNull() << meta->mp.qsIceSecretRead.isEmpty();
#ifndef ACCESS_Server_addContextCallback_ALL

View File

@ -1491,6 +1491,11 @@ bool Server::hasPermission(ServerUser *p, Channel *c, QFlags<ChanACL::Perm> perm
return ChanACL::hasPermission(p, c, perm, acCache);
}
QFlags<ChanACL::Perm> Server::effectivePermissions(ServerUser *p, Channel *c) {
QMutexLocker qml(&qmCache);
return ChanACL::effectivePermissions(p, c, acCache);
}
void Server::sendClientPermission(ServerUser *u, Channel *c, bool forceupdate) {
unsigned int perm;

View File

@ -220,6 +220,7 @@ class Server : public QThread {
bool checkDecrypt(ServerUser *u, const char *encrypted, char *plain, unsigned int cryptlen);
bool hasPermission(ServerUser *p, Channel *c, QFlags<ChanACL::Perm> perm);
QFlags<ChanACL::Perm> effectivePermissions(ServerUser *p, Channel *c);
void sendClientPermission(ServerUser *u, Channel *c, bool updatelast = false);
void flushClientPermissionCache(ServerUser *u, MumbleProto::PermissionQuery &mpqq);
void clearACLCache(User *p = NULL);