Explorar o código

Merge pull request #13010 from rpastrana/HPCC-22705

HPCC 22705 Enforce max value size configuration

Reviewed-By: Kevin Wang <kevin.wang@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman %!s(int64=5) %!d(string=hai) anos
pai
achega
b34dc09d76

+ 3 - 0
esp/scm/ws_store.ecm

@@ -35,6 +35,8 @@ ESPStruct StoreInfo
     string Description;
     string Owner;
     string CreateTime;
+    string MaxValSize;
+    bool   IsDefault(false);
 };
 
 ESPrequest ListKeysRequest
@@ -164,6 +166,7 @@ ESPrequest CreateStoreRequest
     string Type;
     string Description;
     [depr_ver("1.01")] bool UserSpecific(false);
+    [min_ver("1.02")] int MaxValueSize(1024);
 };
 
 ESPresponse [exceptions_inline] CreateStoreResponse

+ 12 - 5
esp/services/ws_store/espstorelib/daliKVStore.cpp

@@ -17,7 +17,7 @@
 
 #include "daliKVStore.hpp"
 
-bool CDALIKVStore::createStore(const char * apptype, const char * storename, const char * description, ISecUser * owner)
+bool CDALIKVStore::createStore(const char * apptype, const char * storename, const char * description, ISecUser * owner, unsigned int maxvalsize=DALI_KVSTORE_MAXVALSIZE_DEFAULT)
 {
     if (!storename || !*storename)
         throw MakeStringException(-1, "DALI Keystore createStore(): Store name not provided");
@@ -48,7 +48,7 @@ bool CDALIKVStore::createStore(const char * apptype, const char * storename, con
     apptree->setProp(DALI_KVSTORE_CREATEDTIME_ATT,dt.getString(str).str());
 
     if (apptype && *apptype)
-        apptree->setProp("@type", apptype);
+        apptree->setProp(DALI_KVSTORE_TYPE_ATT, apptype);
 
     if (description && *description)
         apptree->setProp(DALI_KVSTORE_DESCRIPTION_ATT, description);
@@ -56,6 +56,9 @@ bool CDALIKVStore::createStore(const char * apptype, const char * storename, con
     if (owner && !isEmptyString(owner->getName()))
         apptree->setProp(DALI_KVSTORE_CREATEDBY_ATT, owner->getName());
 
+    if (maxvalsize != 0)
+        apptree->setPropInt(DALI_KVSTORE_MAXVALSIZE_ATT, maxvalsize);
+
     root->addPropTree("Store", LINK(apptree));
 
     conn->commit();
@@ -90,6 +93,10 @@ bool CDALIKVStore::set(const char * storename, const char * thenamespace, const
     if (!storetree.get())
         throw MakeStringException(-1, "DALI KV Store set(): Unable to access store '%s'", storename); //this store doesn't exist
 
+    int maxval = storetree->getPropInt(DALI_KVSTORE_MAXVALSIZE_ATT, 0);
+    if (maxval > 0 && strlen(value) > maxval)
+        throw MakeStringException(-1, "DALI Keystore set(): Size of the value exceeds maximum size allowed (%i)", maxval);
+
     if (global)
         xpath.set(DALI_KVSTORE_GLOBAL);
     else
@@ -487,19 +494,19 @@ IPropertyTree * CDALIKVStore::getStores(const char * namefilter, const char * ow
       Owned<IPropertyTreeIterator> iter = storetree->getElements("*");
       ForEach(*iter)
       {
-          name.set(iter->query().queryProp("@name"));
+          name.set(iter->query().queryProp(DALI_KVSTORE_NAME_ATT));
           if (name.length() == 0 || !wildcardmatch(namefilter, name.str()))
               continue;
 
           if (!isEmptyString(ownerfilter))
           {
-              const char * owner = iter->query().queryProp("@createUser");
+              const char * owner = iter->query().queryProp(DALI_KVSTORE_CREATEDBY_ATT);
               if (!isEmptyString(owner) && !wildcardmatch(ownerfilter, owner))
                   continue;
           }
           if (!isEmptyString(typefilter))
           {
-              const char * type = iter->query().queryProp("@type");
+              const char * type = iter->query().queryProp(DALI_KVSTORE_TYPE_ATT);
               if (!isEmptyString(type) && !wildcardmatch(typefilter, type))
                   continue;
           }

+ 5 - 2
esp/services/ws_store/espstorelib/daliKVStore.hpp

@@ -38,9 +38,13 @@ static const char* DALI_KVSTORE_GLOBAL="GLOBAL";
 static const char* DALI_KVSTORE_NAME_ATT="@name";
 static const char* DALI_KVSTORE_DESCRIPTION_ATT="@description";
 static const char* DALI_KVSTORE_CREATEDBY_ATT="@createUser";
+static const char* DALI_KVSTORE_TYPE_ATT="@type";
 static const char* DALI_KVSTORE_CREATEDTIME_ATT="@createTime";
 static const char* DALI_KVSTORE_EDITEDBY_ATT="@editBy";
 static const char* DALI_KVSTORE_EDITEDTIME_ATT="@editTime";
+static const char* DALI_KVSTORE_MAXVALSIZE_ATT="@maxValSize";
+
+static unsigned int DALI_KVSTORE_MAXVALSIZE_DEFAULT=1024;
 
 class DALIKVSTORE_API CDALIKVStore : public CInterface, implements IEspStore
 {
@@ -58,7 +62,7 @@ public:
 
     IPropertyTree * getStores(const char * namefilter, const char * ownerfilter, const char * typefilter, ISecUser * user);
     bool fetchAllNamespaces(StringArray & namespaces, const char * storename, ISecUser * user, bool global);
-    bool createStore(const char * apptype, const char * storename, const char * description, ISecUser * owner);
+    bool createStore(const char * apptype, const char * storename, const char * description, ISecUser * owner, unsigned int maxvalsize);
     bool addNamespace(const char * storename, const char * thenamespace, ISecUser * owner, bool global);
     bool set(const char * storename, const char * thenamespace, const char * key, const char * value, ISecUser * owner, bool global);
     bool fetchKeySet(StringArray & keyset, const char * storename, const char * ns, ISecUser * user, bool global);
@@ -88,7 +92,6 @@ public:
 
 private:
     bool m_isDetachedFromDali = false;
-
 };
 
 #endif /* DALIKVSTORE_HPP_ */

+ 1 - 1
esp/services/ws_store/espstorelib/espStoreShare.hpp

@@ -34,7 +34,7 @@ interface IEspStore : extends IInterface
     virtual bool deletekey(const char * storename, const char * thenamespace, const char * key, ISecUser * user, bool global) = 0;
     virtual bool deleteNamespace(const char * storename, const char * thenamespace, ISecUser * user, bool global) = 0;
     virtual bool addNamespace(const char * storename, const char * thenamespace, ISecUser * owner, bool global) = 0;
-    virtual bool createStore(const char * apptype, const char * storename, const char * description, ISecUser * owner) = 0;
+    virtual bool createStore(const char * apptype, const char * storename, const char * description, ISecUser * owner, unsigned int maxvalsize) = 0;
     virtual bool setOfflineMode(bool offline) = 0 ;
     virtual bool fetchKeyProperty(StringBuffer & propval , const char * storename, const char * ns, const char * key, const char * property, ISecUser * username, bool global) = 0;
     virtual IPropertyTree * getAllKeyProperties(const char * storename, const char * ns, const char * key, ISecUser * username, bool global) =0;

+ 30 - 12
esp/services/ws_store/ws_storeService.cpp

@@ -20,6 +20,12 @@ limitations under the License.
 
 #define SDS_LOCK_TIMEOUT_ESPSTORE (30*1000)
 #define DEFAULT_ESP_STORE_FACTORY_METHOD "newEspStore"
+#define DEFAULT_ESP_STORE_MAX_VAL_SIZE 1024
+#define ESP_STORE_NAME_ATT "@name"
+#define ESP_STORE_TYPE_ATT "@type"
+#define ESP_STORE_DESCRIPTION_ATT "@description"
+#define ESP_STORE_MAXVALSIZE_ATT "@maxvalsize"
+#define ESP_STORE_DEFAULT_ATT "@default"
 
 typedef IEspStore* (*newEspStore_t_)();
 
@@ -76,13 +82,14 @@ void CwsstoreEx::init(IPropertyTree *_cfg, const char *_process, const char *_se
             StringBuffer description;
             bool isDefault = false;
 
-            iter->query().getProp("@name", id);
-            iter->query().getProp("@type", type);
-            iter->query().getProp("@description", description);
-            isDefault = iter->query().getPropBool("@default", false);
+            iter->query().getProp(ESP_STORE_NAME_ATT, id);
+            iter->query().getProp(ESP_STORE_TYPE_ATT, type);
+            iter->query().getProp(ESP_STORE_DESCRIPTION_ATT, description);
+            unsigned int maxvalsize = iter->query().getPropInt(ESP_STORE_MAXVALSIZE_ATT, DEFAULT_ESP_STORE_MAX_VAL_SIZE);
+            isDefault = iter->query().getPropBool(ESP_STORE_DEFAULT_ATT, false);
 
             ESPLOG(LogMin, "CwsstoreEx: Creating Store: '%s'%s", id.str(), isDefault ? " - as Default" : "");
-            m_storeProvider->createStore(type.str(), id.str(), description.str(), new CSecureUser(owner.str(), nullptr));
+            m_storeProvider->createStore(type.str(), id.str(), description.str(), new CSecureUser(owner.str(), nullptr), maxvalsize);
             if (isDefault)
             {
                 if (!m_defaultStore.isEmpty())
@@ -133,17 +140,20 @@ bool CwsstoreEx::onListStores(IEspContext &context, IEspListStoresRequest &req,
         Owned<IPropertyTreeIterator> iter = stores->getElements("Store");
         ForEach(*iter)
         {
+            IPropertyTree * tree = &iter->query();
             Owned<IEspStoreInfo> store = createStoreInfo();
-            store->setOwner(iter->query().queryProp("@createUser"));
-            store->setName(iter->query().queryProp("@name"));
-            store->setCreateTime(iter->query().queryProp("@createTime"));
-            store->setType(iter->query().queryProp("@type"));
-            store->setDescription(iter->query().queryProp("@description"));
+            store->setOwner(tree->queryProp("@createUser"));
+            store->setName(tree->queryProp("@name"));
+            store->setCreateTime(tree->queryProp("@createTime"));
+            store->setType(tree->queryProp("@type"));
+            store->setDescription(tree->queryProp("@description"));
+            store->setMaxValSize(tree->queryProp("@maxValSize"));
+            store->setIsDefault (!m_defaultStore.isEmpty() && strcasecmp(m_defaultStore.str(), tree->queryProp("@name"))==0);
+
             storeinfos.append(*store.getClear());
         }
         resp.setStores(storeinfos);
     }
-
     return true;
 }
 
@@ -151,7 +161,15 @@ bool CwsstoreEx::onCreateStore(IEspContext &context, IEspCreateStoreRequest &req
 {
     const char *user = context.queryUserId();
     double version = context.getClientVersion();
-    bool success = m_storeProvider->createStore(req.getType(), req.getName(), req.getDescription(), new CSecureUser(user, nullptr));
+    unsigned int maxvalsize = DEFAULT_ESP_STORE_MAX_VAL_SIZE;
+
+    if (version >= 1.02)
+    {
+        maxvalsize = req.getMaxValueSize();
+    }
+
+    bool success = m_storeProvider->createStore(req.getType(), req.getName(), req.getDescription(), new CSecureUser(user, nullptr), maxvalsize);
+
     if (version > 1)
       resp.setSuccess(success);
 

+ 8 - 0
initfiles/componentfiles/configxml/esp_service_wsstore.xsd

@@ -72,6 +72,14 @@
                           </xs:restriction>
                       </xs:simpleType>
                   </xs:attribute>
+                  <xs:attribute name="maxvalsize" type="xs:string" default="1024">
+                    <xs:annotation>
+                      <xs:appinfo>
+                        <colIndex>5</colIndex>
+                        <tooltip>Max size of the value entries</tooltip>
+                      </xs:appinfo>
+                    </xs:annotation>
+                  </xs:attribute>
                 </xs:complexType>
               </xs:element>
             </xs:sequence>