[
https://issues.apache.org/jira/browse/QPID-2108?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12799230#action_12799230
]
Rajith Attapattu commented on QPID-2108:
----------------------------------------
Applied the patch at rev 819948 in Qpid trunk with minor modifications and
some added logging.
> ACL Enhancement to support queue limit policies
> -----------------------------------------------
>
> Key: QPID-2108
> URL: https://issues.apache.org/jira/browse/QPID-2108
> Project: Qpid
> Issue Type: Improvement
> Components: C++ Broker
> Affects Versions: 0.5
> Reporter: Tim Platten
> Assignee: Rajith Attapattu
>
> It is a requirement for us to be able to enforce queue limit policies using
> the ACL authorisation mechanism. I therefore propose the following
> enhancement:
> Add three new properties to the "create queue" rule: limitpolicy,
> maxqueuesize and maxqueuecount. The policy test can be implemented using
> existing code, but the numeric limits require a less-than-or-equal test. I.e.
> if a value for maxqueuesize is specified in the ACL file, an exception will
> be thrown if a value greater than this is specified in declareQueue. A value
> less than or equal would be acceptable. If maxqueuecount and/or maxqueuesize
> were omitted from the rule or specified as zero, the corresponding check
> would interpret the value as "unlimited".
> Proposed code changes follow (prefixed with change-bar "|").
> AclModule.h
> .
> .
> .
> enum Property {PROP_NAME, PROP_DURABLE, PROP_OWNER, PROP_ROUTINGKEY,
> PROP_PASSIVE, PROP_AUTODELETE, PROP_EXCLUSIVE, PROP_TYPE,
> PROP_ALTERNATE, PROP_QUEUENAME, PROP_SCHEMAPACKAGE,
> | PROP_SCHEMACLASS, PROP_LIMITPOLICY, PROP_MAXQUEUESIZE,
> PROP_MAXQUEUECOUNT};
> .
> .
> .
> static inline Property getProperty(const std::string& str) {
> if (str.compare("name") == 0) return PROP_NAME;
> if (str.compare("durable") == 0) return PROP_DURABLE;
> if (str.compare("owner") == 0) return PROP_OWNER;
> if (str.compare("routingkey") == 0) return PROP_ROUTINGKEY;
> if (str.compare("passive") == 0) return PROP_PASSIVE;
> if (str.compare("autodelete") == 0) return PROP_AUTODELETE;
> if (str.compare("exclusive") == 0) return PROP_EXCLUSIVE;
> if (str.compare("type") == 0) return PROP_TYPE;
> if (str.compare("alternate") == 0) return PROP_ALTERNATE;
> if (str.compare("queuename") == 0) return PROP_QUEUENAME;
> if (str.compare("schemapackage") == 0) return PROP_SCHEMAPACKAGE;
> if (str.compare("schemaclass") == 0) return PROP_SCHEMACLASS;
> | if (str.compare("limitpolicy") == 0) return PROP_LIMITPOLICY;
> | if (str.compare("maxqueuesize") == 0) return PROP_MAXQUEUESIZE;
> | if (str.compare("maxqueuecount") == 0) return PROP_MAXQUEUECOUNT;
> throw str;
> }
> static inline std::string getPropertyStr(const Property p) {
> switch (p) {
> case PROP_NAME: return "name";
> case PROP_DURABLE: return "durable";
> case PROP_OWNER: return "owner";
> case PROP_ROUTINGKEY: return "routingkey";
> case PROP_PASSIVE: return "passive";
> case PROP_AUTODELETE: return "autodelete";
> case PROP_EXCLUSIVE: return "exclusive";
> case PROP_TYPE: return "type";
> case PROP_ALTERNATE: return "alternate";
> case PROP_QUEUENAME: return "queuename";
> case PROP_SCHEMAPACKAGE: return "schemapackage";
> case PROP_SCHEMACLASS: return "schemaclass";
> | case PROP_LIMITPOLICY: return "limitpolicy";
> | case PROP_MAXQUEUESIZE: return "maxqueuesize";
> | case PROP_MAXQUEUECOUNT: return "maxqueuecount";
> default: assert(false); // should never get here
> }
> return "";
> }
> .
> .
> .
> // == Queues ==
> propSetPtr p4(new propSet);
> | p4->insert(PROP_ALTERNATE);
> | p4->insert(PROP_PASSIVE);
> | p4->insert(PROP_DURABLE);
> | p4->insert(PROP_EXCLUSIVE);
> | p4->insert(PROP_AUTODELETE);
> | p4->insert(PROP_LIMITPOLICY);
> | p4->insert(PROP_MAXQUEUESIZE);
> | p4->insert(PROP_MAXQUEUECOUNT);
> Note that currently (Qpid 0.5) this code appears to be incorrectly
> dereferencing p3 instead of p4.
> SessionAdapter.cpp
> .
> .
> .
> void SessionAdapter::QueueHandlerImpl::declare(const string& name, const
> string& alternateExchange,
> bool passive, bool durable,
> bool exclusive,
> bool autoDelete, const
> qpid::framing::FieldTable& arguments)
> {
> AclModule* acl = getBroker().getAcl();
> if (acl) {
> std::map<acl::Property, std::string> params;
> params.insert(make_pair(acl::PROP_ALTERNATE, alternateExchange));
> params.insert(make_pair(acl::PROP_PASSIVE, std::string(passive ?
> "true" : "false") ));
> params.insert(make_pair(acl::PROP_DURABLE, std::string(durable ?
> "true" : "false")));
> params.insert(make_pair(acl::PROP_EXCLUSIVE, std::string(exclusive ?
> "true" : "false")));
> params.insert(make_pair(acl::PROP_AUTODELETE, std::string(autoDelete
> ? "true" : "false")));
> | params.insert(make_pair(acl::PROP_LIMITPOLICY,
> arguments.getAsString("qpid.policy_type")));
> | params.insert(make_pair(acl::PROP_MAXQUEUECOUNT,
> boost::lexical_cast<string>(arguments.getAsInt("qpid.max_count"))));
> | params.insert(make_pair(acl::PROP_MAXQUEUESIZE,
> boost::lexical_cast<string>(arguments.getAsInt64("qpid.max_size"))));
> if
> (!acl->authorise(getConnection().getUserId(),acl::ACT_CREATE,acl::OBJ_QUEUE,name,¶ms)
> )
> throw NotAllowedException(QPID_MSG("ACL denied queue create
> request from " << getConnection().getUserId()));
> }
> AclData.cpp
> .
> .
> .
> |#include <boost/lexical_cast.hpp>
> .
> .
> .
> AclResult AclData::lookup(const std::string& id, const Action& action, const
> ObjectType& objType, const std::string& name, std::map<Property,
> std::string>* params)
> {
> AclResult aclresult = decisionMode;
> if (actionList[action] && actionList[action][objType]){
> AclData::actObjItr itrRule =
> actionList[action][objType]->find(id);
> if (itrRule == actionList[action][objType]->end())
> itrRule = actionList[action][objType]->find("*");
> if (itrRule != actionList[action][objType]->end() ) {
> //loop the vector
> for (ruleSetItr i=itrRule->second.begin();
> i<itrRule->second.end(); i++) {
> // loop the names looking for match
> bool match =true;
> for (propertyMapItr pMItr =
> i->props.begin(); (pMItr != i->props.end()) && match; pMItr++)
> {
> //match name is exists first
> if (pMItr->first ==
> acl::PROP_NAME){
> if
> (!matchProp(pMItr->second, name)){
> match= false;
> }
> }else if (params){ //match
> pMItr against params
> propertyMapItr
> paramItr = params->find (pMItr->first);
> if (paramItr ==
> params->end()){
> match = false;
> | }else if (
> pMItr->first == acl::PROP_MAXQUEUECOUNT || pMItr->first ==
> acl::PROP_MAXQUEUESIZE ) {
> | if ( pMItr->first
> == paramItr->first ) {
> | uint64_t
> aclMax = boost::lexical_cast<uint64_t>(pMItr->second);
> | uint64_t
> paramMax = boost::lexical_cast<uint64_t>(paramItr->second);
> | if (( aclMax
> ) && ( paramMax == 0 || paramMax > aclMax ))
> | match =
> false;
> | }
> }else if
> (!matchProp(pMItr->second, paramItr->second)){
> match = false;
> }
> }
> }
> if (match) return
> getACLResult(i->logOnly, i->log);
> }
> }
> }
> return aclresult;
> }
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project: http://qpid.apache.org
Use/Interact: mailto:[email protected]