diff options
| author | Charles E. Rolke <chug@apache.org> | 2013-05-02 15:42:39 +0000 |
|---|---|---|
| committer | Charles E. Rolke <chug@apache.org> | 2013-05-02 15:42:39 +0000 |
| commit | 3d962f8a4c44cca0c9942fb3bab0a466caecf4ba (patch) | |
| tree | 41f5416e62dc4425b35318bb0a51566fca401c23 /cpp | |
| parent | 01b3863f6007b70df9ab4c226a0fccd135b72751 (diff) | |
| download | qpid-python-3d962f8a4c44cca0c9942fb3bab0a466caecf4ba.tar.gz | |
QPID-4775: C++ Broker add ACL property checks for delete queue and exchange.
0-18-based patch from Pavel Moravec was adjusted for trunk.
Removed size properties from list of queue deletion check parameters.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1478418 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp')
| -rw-r--r-- | cpp/src/qpid/broker/Broker.cpp | 34 | ||||
| -rwxr-xr-x | cpp/src/tests/acl.py | 246 |
2 files changed, 264 insertions, 16 deletions
diff --git a/cpp/src/qpid/broker/Broker.cpp b/cpp/src/qpid/broker/Broker.cpp index be69516072..bf296696cf 100644 --- a/cpp/src/qpid/broker/Broker.cpp +++ b/cpp/src/qpid/broker/Broker.cpp @@ -1193,12 +1193,21 @@ void Broker::deleteQueue(const std::string& name, const std::string& userId, << " user:" << userId << " rhost:" << connectionId ); - if (acl && !acl->authorise(userId,acl::ACT_DELETE,acl::OBJ_QUEUE,name,NULL)) { - throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied queue delete request from " << userId)); - } - Queue::shared_ptr queue = queues.find(name); if (queue) { + if (acl) { + std::map<acl::Property, std::string> params; + const qpid::broker::QueueSettings settings = queue->getSettings(); + boost::shared_ptr<Exchange> altEx = queue->getAlternateExchange(); + params.insert(make_pair(acl::PROP_ALTERNATE, (altEx) ? altEx->getName() : "" )); + params.insert(make_pair(acl::PROP_DURABLE, queue->isDurable() ? _TRUE : _FALSE)); + params.insert(make_pair(acl::PROP_EXCLUSIVE, queue->hasExclusiveOwner() ? _TRUE : _FALSE)); + params.insert(make_pair(acl::PROP_AUTODELETE, queue->isAutoDelete() ? _TRUE : _FALSE)); + params.insert(make_pair(acl::PROP_POLICYTYPE, settings.dropMessagesAtLimit ? "ring" : "reject")); + + if (!acl->authorise(userId,acl::ACT_DELETE,acl::OBJ_QUEUE,name,¶ms) ) + throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied queue delete request from " << userId)); + } if (check) check(queue); if (acl) acl->recordDestroyQueue(name); @@ -1256,16 +1265,23 @@ void Broker::deleteExchange(const std::string& name, const std::string& userId, QPID_LOG_CAT(debug, model, "Deleting exchange. name:" << name << " user:" << userId << " rhost:" << connectionId); - if (acl) { - if (!acl->authorise(userId,acl::ACT_DELETE,acl::OBJ_EXCHANGE,name,NULL) ) - throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied exchange delete request from " << userId)); - } - if (name.empty()) { throw framing::InvalidArgumentException(QPID_MSG("Delete not allowed for default exchange")); } Exchange::shared_ptr exchange(exchanges.get(name)); if (!exchange) throw framing::NotFoundException(QPID_MSG("Delete failed. No such exchange: " << name)); + + if (acl) { + std::map<acl::Property, std::string> params; + Exchange::shared_ptr altEx = exchange->getAlternate(); + params.insert(make_pair(acl::PROP_TYPE, exchange->getType())); + params.insert(make_pair(acl::PROP_ALTERNATE, (altEx) ? altEx->getName() : "" )); + params.insert(make_pair(acl::PROP_DURABLE, exchange->isDurable() ? _TRUE : _FALSE)); + + if (!acl->authorise(userId,acl::ACT_DELETE,acl::OBJ_EXCHANGE,name,¶ms) ) + throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied exchange delete request from " << userId)); + } + if (exchange->inUseAsAlternate()) throw framing::NotAllowedException(QPID_MSG("Cannot delete " << name <<", in use as alternate-exchange.")); if (exchange->isDurable()) store->destroy(*exchange); if (exchange->getAlternate()) exchange->getAlternate()->decAlternateUsers(); diff --git a/cpp/src/tests/acl.py b/cpp/src/tests/acl.py index 41f1e7a8cd..666ae46a39 100755 --- a/cpp/src/tests/acl.py +++ b/cpp/src/tests/acl.py @@ -1464,13 +1464,6 @@ class ACLTests(TestBase010): self.fail("ACL should allow exchange bound request for myEx with queuename=q1 and binding_key='rk1.*'"); try: - session.exchange_delete(exchange='myXml') - self.fail("ACL should deny exchange delete request for myXml"); - except qpid.session.SessionException, e: - self.assertEqual(403,e.args[0].error_code) - session = self.get_session('bob','bob') - - try: session.exchange_delete(exchange='myEx') except qpid.session.SessionException, e: if (403 == e.args[0].error_code): @@ -3112,6 +3105,245 @@ class ACLTests(TestBase010): # User not named in quotas is denied self.queue_quota('bilboGR', 'bilbo', 0) + def test_queue_delete_with_properties(self): + """ + Test cases for queue delete with properties + """ + aclf = self.get_acl_file() + aclf.write('acl allow bob@QPID access queue\n') + aclf.write('acl allow bob@QPID access exchange\n') + aclf.write('acl allow bob@QPID create queue name=qdaq1 durable=true\n') + aclf.write('acl allow bob@QPID create queue name=qdaq2 exclusive=true\n') + aclf.write('acl allow bob@QPID create queue name=qdaq3 policytype=ring\n') + aclf.write('acl allow bob@QPID create queue name=qdaq4 durable=false\n') + aclf.write('acl allow bob@QPID create queue name=qdaq5 exclusive=false\n') + aclf.write('acl allow bob@QPID create queue name=qdaq6 policytype=reject\n') + aclf.write('acl allow bob@QPID create queue name=qdaq7 autodelete=true\n') + aclf.write('acl allow bob@QPID create queue name=qdaq8 autodelete=false\n') + aclf.write('acl allow bob@QPID create queue name=qdaq9\n') + aclf.write('acl allow bob@QPID create exchange name=qdae9\n') + aclf.write('acl deny bob@QPID delete queue name=qdaq1 durable=true\n') + aclf.write('acl deny bob@QPID delete queue name=qdaq2 exclusive=true\n') + aclf.write('acl deny bob@QPID delete queue name=qdaq3 policytype=ring\n') + aclf.write('acl deny bob@QPID delete queue name=qdaq4 durable=false\n') + aclf.write('acl deny bob@QPID delete queue name=qdaq5 exclusive=false\n') + aclf.write('acl deny bob@QPID delete queue name=qdaq6 policytype=reject\n') + aclf.write('acl deny bob@QPID delete queue name=qdaq7 autodelete=true\n') + aclf.write('acl deny bob@QPID delete queue name=qdaq8 autodelete=false\n') + aclf.write('acl deny bob@QPID delete queue name=qdaq9 alternate=qdaq9a\n') + aclf.write('acl allow all access queue\n') + aclf.write('acl allow anonymous all all\n') + aclf.write('acl deny all all') + aclf.close() + + result = self.reload_acl() + if (result): + self.fail(result) + + session = self.get_session('bob','bob') + + try: + session.queue_declare(queue="qdaq1", durable=True) + except qpid.session.SessionException, e: + if (403 == e.args[0].error_code): + self.fail("ACL should allow queue create request with name=qdaq1 durable=true"); + + try: + session.queue_delete(queue="qdaq1") + self.fail("ACL should deny queue delete request for qdaq1"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + session.queue_declare(queue="qdaq2", exclusive=True) + except qpid.session.SessionException, e: + if (403 == e.args[0].error_code): + self.fail("ACL should allow queue create request with name=qdaq2 exclusive=true"); + + try: + session.queue_delete(queue="qdaq2") + self.fail("ACL should deny queue delete request for qdaq2"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + queue_options = {} + queue_options["qpid.policy_type"] = "ring" + session.queue_declare(queue="qdaq3", arguments=queue_options) + except qpid.session.SessionException, e: + if (403 == e.args[0].error_code): + self.fail("ACL should allow queue create request for qdaq3 with policytype=ring"); + + try: + session.queue_delete(queue="qdaq3") + self.fail("ACL should deny queue delete request for qdaq3"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + session.queue_declare(queue="qdaq4", durable=False) + except qpid.session.SessionException, e: + if (403 == e.args[0].error_code): + self.fail("ACL should allow queue create request with name=qdaq4 durable=false"); + + try: + session.queue_delete(queue="qdaq4") + self.fail("ACL should deny queue delete request for qdaq4"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + session.queue_declare(queue="qdaq5", exclusive=False) + except qpid.session.SessionException, e: + if (403 == e.args[0].error_code): + self.fail("ACL should allow queue create request with name=qdaq5 exclusive=false"); + + try: + session.queue_delete(queue="qdaq5") + self.fail("ACL should deny queue delete request for qdaq5"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + queue_options = {} + queue_options["qpid.policy_type"] = "reject" + session.queue_declare(queue="qdaq6", arguments=queue_options) + except qpid.session.SessionException, e: + if (403 == e.args[0].error_code): + self.fail("ACL should allow queue create request for qdaq6 with policytype=reject"); + + try: + session.queue_delete(queue="qdaq6") + self.fail("ACL should deny queue delete request for qdaq6"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + session.queue_declare(queue="qdaq7", auto_delete=True) + except qpid.session.SessionException, e: + if (403 == e.args[0].error_code): + self.fail("ACL should allow queue create request with name=qdaq7 autodelete=true"); + + try: + session.queue_delete(queue="qdaq7") + self.fail("ACL should deny queue delete request for qdaq7"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + session.queue_declare(queue="qdaq8", auto_delete=False) + except qpid.session.SessionException, e: + if (403 == e.args[0].error_code): + self.fail("ACL should allow queue create request with name=qdaq8 autodelete=false"); + + try: + session.queue_delete(queue="qdaq8") + self.fail("ACL should deny queue delete request for qdaq8"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + session.exchange_declare(exchange='qdae9', type='direct') + except qpid.session.SessionException, e: + self.fail("ACL should allow exchange create request with name=qdae9"); + + try: + session.queue_declare(queue="qdaq9", alternate_exchange="qdae9") + except qpid.session.SessionException, e: + if (403 == e.args[0].error_code): + self.fail("ACL should allow queue create request with name=qdaq9 alternate=qdaq9a"); + + try: + session.queue_delete(queue="qdaq9") + self.fail("ACL should deny queue delete request for qdaq9"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + + def test_exchange_delete_with_properties(self): + """ + Test cases for exchange delete with properties + """ + aclf = self.get_acl_file() + aclf.write('acl allow bob@QPID access exchange\n') + aclf.write('acl allow bob@QPID create exchange\n') + aclf.write('acl deny bob@QPID delete exchange name=edae1 durable=true\n') + aclf.write('acl deny bob@QPID delete exchange name=edae2 alternate=edae2a\n') + aclf.write('acl deny bob@QPID delete exchange type=direct\n') + aclf.write('acl allow bob@QPID delete exchange type=headers\n') + aclf.write('acl allow anonymous all all\n') + aclf.write('acl deny all all') + aclf.close() + + result = self.reload_acl() + if (result): + self.fail(result) + + session = self.get_session('bob','bob') + + try: + session.exchange_declare(exchange='edae1', type='direct', durable=True) + except qpid.session.SessionException, e: + self.fail("ACL should allow exchange create request with name=edae1"); + + try: + session.exchange_delete(exchange="edae1") + self.fail("ACL should deny exchange delete request for edae1"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + session.exchange_declare(exchange='edae2a', type='direct') + except qpid.session.SessionException, e: + self.fail("ACL should allow exchange create request with name=edae2a"); + + try: + session.exchange_declare(exchange='edae2', type='direct', alternate_exchange='edae2a') + except qpid.session.SessionException, e: + self.fail("ACL should allow exchange create request with name=edae2"); + + try: + session.exchange_delete(exchange="edae2") + self.fail("ACL should deny exchange delete request for edae2"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + session.exchange_declare(exchange='edae3d', type='direct') + except qpid.session.SessionException, e: + self.fail("ACL should allow exchange create request with name=edae3d"); + + try: + session.exchange_declare(exchange='edae3h', type='headers') + except qpid.session.SessionException, e: + self.fail("ACL should allow exchange create request with name=eda3h"); + + try: + session.exchange_delete(exchange="edae3d") + self.fail("ACL should deny exchange delete request for edae3d"); + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + session = self.get_session('bob','bob') + + try: + session.exchange_delete(exchange="edae3h") + except qpid.session.SessionException, e: + self.assertEqual(403,e.args[0].error_code) + self.fail("ACL should allow exchange delete request for edae3h"); + + + class BrokerAdmin: def __init__(self, broker, username=None, password=None): self.connection = qpid.messaging.Connection(broker) |
