You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@qpid.apache.org by "Tim Platten (JIRA)" <qp...@incubator.apache.org> on 2009/09/17 12:17:57 UTC

[jira] Created: (QPID-2108) ACL Enhancement to support queue limit policies

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


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,&params) )
            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:dev-subscribe@qpid.apache.org


[jira] Commented: (QPID-2108) ACL Enhancement to support queue limit policies

Posted by "Rajith Attapattu (JIRA)" <qp...@incubator.apache.org>.
    [ https://issues.apache.org/jira/browse/QPID-2108?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12799317#action_12799317 ] 

Rajith Attapattu commented on QPID-2108:
----------------------------------------

that's a good point.
I will ping Tim to attach the original patch and grant the necessary rights

> 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,&params) )
>             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:dev-subscribe@qpid.apache.org


[jira] Commented: (QPID-2108) ACL Enhancement to support queue limit policies

Posted by "Rajith Attapattu (JIRA)" <qp...@incubator.apache.org>.
    [ 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,&params) )
>             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:dev-subscribe@qpid.apache.org


[jira] Assigned: (QPID-2108) ACL Enhancement to support queue limit policies

Posted by "Rajith Attapattu (JIRA)" <qp...@incubator.apache.org>.
     [ https://issues.apache.org/jira/browse/QPID-2108?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Rajith Attapattu reassigned QPID-2108:
--------------------------------------

    Assignee: Rajith Attapattu

> 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,&params) )
>             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:dev-subscribe@qpid.apache.org


[jira] Commented: (QPID-2108) ACL Enhancement to support queue limit policies

Posted by "Rob Godfrey (JIRA)" <qp...@incubator.apache.org>.
    [ https://issues.apache.org/jira/browse/QPID-2108?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12799238#action_12799238 ] 

Rob Godfrey commented on QPID-2108:
-----------------------------------

Although this patch seems fairly trivial - should we not still have only accepted it if it was received as an attachment with an Apache IP assignment?

> 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,&params) )
>             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:dev-subscribe@qpid.apache.org