Ver código fonte

HPCC-15375 Add default feature level authorization

- Adds ESPService attribute "requiredaccess"
   If requiredaccess is not declared, build process will fail
   with message to developer
   All methods will require authorization of the feature:level specified

- Adds ESPmethod attribute "requiredaccess" which can overwrite service
    level requiredaccess
- User can specify requiredaccss levels: (NONE|INMETHOD|ACCESS|READ|WRITE|FULL)
   Default is READ

Signed-off-by: rpastrana <rodrigo.pastrana@lexisnexis.com>
rpastrana 8 anos atrás
pai
commit
a97ae9e190

+ 1 - 0
esp/bindings/bind_ng.hpp

@@ -108,6 +108,7 @@ public:
     bool authorizeFeature(const char * pszFeatureUrl, const char* UserID, const char* CompanyID, SecAccessFlags & access,bool bCheckTrial , SecUserStatus& user_status){return true;}
     bool authorizeFeature(const char * pszFeatureUrl, const char* UserID, const char* CompanyID, SecAccessFlags & access,bool bCheckTrial ,int DebitUnits,  SecUserStatus& user_status) {return true;}
 
+    bool validateFeaturesAccess(MapStringTo<SecAccessFlags> & pmap, bool throwExcpt) {return true;}
     bool validateFeatureAccess(const char * pszFeatureUrl, unsigned required, bool throwExcpt){return true;}
     void setServAddress(const char * host, short port){}
     void getServAddress(StringBuffer & host, short & port){}

+ 7 - 0
esp/bindings/http/platform/httpbinding.cpp

@@ -964,6 +964,13 @@ int EspHttpBinding::onGetSoapBuilder(IEspContext &context, CHttpRequest* request
     return 0;
 }
 
+int EspHttpBinding::onFeaturesAuthorize(IEspContext &context, MapStringTo<SecAccessFlags> & pmap, const char *serviceName, const char *methodName)
+{
+    if (!context.validateFeaturesAccess(pmap, false))
+        throw MakeStringException(-1, "%s::%s access denied.", serviceName, methodName);
+    return 0;
+}
+
 int EspHttpBinding::onGetInstantQuery(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *serv, const char *method)
 {
     return onGetNotFound(context, request,  response, serv);

+ 4 - 1
esp/bindings/http/platform/httpbinding.hpp

@@ -82,6 +82,8 @@ interface IEspHttpBinding
     virtual int onGetForm(IEspContext &context, CHttpRequest* request,   CHttpResponse* response, const char *servName, const char *methodName)=0;
     virtual int onGetXForm(IEspContext &context, CHttpRequest* request,   CHttpResponse* response, const char *servName, const char *methodName)=0;
     virtual int onGetInstantQuery(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *serviceName, const char *methodName)=0;
+    virtual int onFeaturesAuthorize(IEspContext &context, MapStringTo<SecAccessFlags> & pmap, const char *serviceName, const char *methodName)=0;
+
     virtual int onGetQuery(IEspContext &context, CHttpRequest* request,  CHttpResponse* response, const char *servName, const char *methodName)=0;
     virtual int onGetResult(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *servName, const char *methodName, const char *resultPath)=0;
     virtual int onGetResultPresentation(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *serviceName, const char *methodName, StringBuffer &xmlResult)=0;
@@ -94,7 +96,7 @@ interface IEspHttpBinding
     virtual int onGetRespSampleXml(IEspContext &context, CHttpRequest* request, CHttpResponse* response,    const char *serv, const char *method)=0;
     virtual int onStartUpload(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *serv, const char *method)=0;
     virtual int onFinishUpload(IEspContext &context, CHttpRequest* request, CHttpResponse* response,    const char *serv, const char *method,
-        StringArray& fileNames, StringArray& files, IMultiException *me)=0;
+    StringArray& fileNames, StringArray& files, IMultiException *me)=0;
 };
 
 typedef MapStringTo<int> wsdlIncludedTable;
@@ -217,6 +219,7 @@ public:
     virtual int onGetForm(IEspContext &context, CHttpRequest* request,   CHttpResponse* response, const char *serv, const char *method);
     virtual int onGetXForm(IEspContext &context, CHttpRequest* request,   CHttpResponse* response, const char *serv, const char *method);
     virtual int onGetInstantQuery(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *serv, const char *method);
+    virtual int onFeaturesAuthorize(IEspContext &context, MapStringTo<SecAccessFlags> & pmap, const char *serviceName, const char *methodName);
     virtual int onGetResult(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *serv, const char *method, const char *pathex);
     virtual int onGetResultPresentation(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *serv, const char *method, StringBuffer &xmlResult);
     virtual int onGetFile(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *path);

+ 5 - 0
esp/platform/espcontext.cpp

@@ -398,6 +398,11 @@ public:
         return m_SecurityHandler.authorizeSecFeature(pszFeatureUrl, access);
     }
 
+    virtual bool validateFeaturesAccess(MapStringTo<SecAccessFlags> & pmap, bool throwExcpt)
+    {
+        return m_SecurityHandler.validateSecFeaturesAccess(pmap, throwExcpt);
+    }
+
     virtual bool validateFeatureAccess(const char* pszFeatureUrl, unsigned required, bool throwExcpt)
     {
         return m_SecurityHandler.validateSecFeatureAccess(pszFeatureUrl, required, throwExcpt);

+ 42 - 3
esp/platform/sechandler.cpp

@@ -163,6 +163,48 @@ bool SecHandler::authorizeSecFeatures(StringArray & features, IEspStringIntMap &
     return authorizeSecReqFeatures(features, pmap, NULL);
 }
 
+bool SecHandler::validateSecFeaturesAccess(MapStringTo<SecAccessFlags> & accessmap, bool throwExcpt)
+{
+    StringArray features;
+    unsigned reqarray[accessmap.ordinality()];
+
+    HashIterator iter(accessmap);
+    int index = 0;
+    ForEach(iter)
+    {
+        IMapping &cur = iter.query();
+
+        const char * key = (const char *)cur.getKey();
+        SecAccessFlags val = *accessmap.getValue(key);
+        features.append((const char *)cur.getKey());
+        reqarray[index++] = *accessmap.getValue(key);
+
+        DBGLOG("ITERATING: key: %s val: %d", key, val);
+        DBGLOG("reqarray[%d]: val: %d", index-1, reqarray[index-1]);
+    }
+
+    Owned<IEspStringIntMap> pmap=createStringIntMap();
+
+    if (authorizeSecReqFeatures(features, *pmap, reqarray))
+    {
+        for(unsigned i = 0; i < features.length(); i++)
+        {
+            int accessAllowed = pmap->queryValue(features.item(i));
+            if ((accessAllowed == -1) || (reqarray[i] && (accessAllowed < reqarray[i])))
+            {
+                if (throwExcpt)
+                    throw MakeStringException(-1, "Access Denied!");
+                return false;
+            }
+        }
+
+        return true;
+    }
+    if (throwExcpt)
+        throw MakeStringException(-1, "Access Denied!");
+
+    return false;
+}
 
 bool SecHandler::authorizeSecReqFeatures(StringArray & features, IEspStringIntMap & pmap, unsigned *required)
 {
@@ -260,11 +302,8 @@ bool SecHandler::authorizeSecReqFeatures(StringArray & features, IEspStringIntMa
     return auth_ok;
 }
 
-
 bool SecHandler::validateSecFeatureAccess(const char* pszFeatureUrl, unsigned required, bool throwExcpt)
 {
-
-    
     StringArray features;
     features.append(pszFeatureUrl);
     unsigned reqarray[1];

+ 1 - 2
esp/platform/sechandler.hpp

@@ -44,9 +44,8 @@ public:
     bool authorizeSecFeature(const char* pszFeatureUrl, SecAccessFlags& access);
     bool authorizeSecFeatures(StringArray & features, IEspStringIntMap & pmap);
     bool validateSecFeatureAccess(const char* pszFeatureUrl, unsigned required, bool throwExcpt);
+    bool validateSecFeaturesAccess(MapStringTo<SecAccessFlags> & accessmap, bool throwExcpt);
     bool authorizeSecReqFeatures(StringArray & features, IEspStringIntMap & pmap, unsigned *required);
-
-
     bool authorizeSecFeature(const char * pszFeatureUrl, const char* UserID, const char* CompanyID, SecAccessFlags & access,bool bCheckTrial,int DebitUnits, SecUserStatus & user_status);
 
     void setSecManger(ISecManager* mgr);

+ 1 - 1
esp/scm/WsDeploy.ecm

@@ -568,7 +568,7 @@ ESPresponse [exceptions_inline, encode(0)] GetSummaryResponse
     string XmlStr;
 };
 
-ESPservice [exceptions_inline("xslt/exceptions.xslt")] WsDeploy
+ESPservice [requiredaccess("NONE"), exceptions_inline("xslt/exceptions.xslt")] WsDeploy
 {
     ESPuses ESPstruct Task;
     ESPuses ESPstruct Component;

+ 1 - 1
esp/scm/ecldirect.ecm

@@ -72,7 +72,7 @@ ESPresponse [nil_remove] RunEclExResponse
 };
 
 
-ESPservice EclDirect
+ESPservice [requiredaccess("NONE")]EclDirect
 {
     ESPmethod RunEcl(RunEclRequest, RunEclResponse);
     ESPmethod RunEclEx(RunEclExRequest, RunEclExResponse);

+ 1 - 0
esp/scm/esp.ecm

@@ -105,6 +105,7 @@ interface IEspContext : extends IInterface
 
     virtual bool authorizeFeature(const char * pszFeatureUrl, const char* UserID, const char* CompanyID, SecAccessFlags & access,bool bCheckTrial ,int DebitUnits,  SecUserStatus& user_status) = 0;
 
+    virtual bool validateFeaturesAccess(MapStringTo<SecAccessFlags> & pmap, bool throwExcpt) = 0;
     virtual bool validateFeatureAccess(const char * pszFeatureUrl, unsigned required, bool throwExcpt) = 0;
     virtual void setServAddress(const char * host, short port) = 0;
     virtual void getServAddress(StringBuffer & host, short & port) = 0;

+ 1 - 1
esp/scm/esploggingservice.ecm

@@ -115,7 +115,7 @@ TransactionSeedResponse
     bool SeedAvailable;
 };
 
-ESPService [noforms] WsLogService
+ESPService [requiredaccess("NONE"),noforms] WsLogService
 {
     ESPuses ESPStruct LogInfo;
     ESPmethod UpdateLogService(LOGServiceUpdateRequest, LOGServiceUpdateResponse);

+ 1 - 1
esp/scm/ws_access.ecm

@@ -792,7 +792,7 @@ ESPresponse [nil_remove] UserAccountExportResponse
 };
 
 
-ESPservice [version("1.10"), exceptions_inline("./smc_xslt/exceptions.xslt")] ws_access
+ESPservice [version("1.10"), requiredaccess("NONE"), exceptions_inline("./smc_xslt/exceptions.xslt")] ws_access
 {
     ESPmethod [client_xslt("/esp/xslt/access_users.xslt")] Users(UserRequest, UserResponse);
     ESPmethod [client_xslt("/esp/xslt/access_useredit.xslt")] UserEdit(UserEditRequest, UserEditResponse);

+ 1 - 1
esp/scm/ws_account.ecm

@@ -67,7 +67,7 @@ ESPresponse [exceptions_inline] VerifyUserResponse
 	int retcode;
 };
 
-ESPservice [version("1.01"), default_client_version("1.01"), exceptions_inline("./smc_xslt/exceptions.xslt")] ws_account
+ESPservice [requiredaccess("NONE"), version("1.01"), default_client_version("1.01"), exceptions_inline("./smc_xslt/exceptions.xslt")] ws_account
 {
     ESPmethod [client_xslt("/esp/xslt/account_myaccount.xslt")] MyAccount(MyAccountRequest, MyAccountResponse);
     ESPmethod [client_xslt("/esp/xslt/account_input.xslt")] UpdateUserInput(UpdateUserInputRequest, UpdateUserInputResponse);

+ 1 - 1
esp/scm/ws_config.ecm

@@ -26,7 +26,7 @@ ESPresponse [exceptions_inline, encode(0)] ConfigAccessResponse
 };
 
 
-ESPservice [exceptions_inline] ws_config
+ESPservice [requiredaccess("NONE"), exceptions_inline] ws_config
 {
     ESPmethod[description("Initial display"), help(""), noform] 
         GetConfigAccess(ConfigAccessRequest, ConfigAccessResponse);

+ 1 - 0
esp/scm/ws_dfu.ecm

@@ -709,6 +709,7 @@ ESPresponse [exceptions_inline, nil_remove, http_encode(0)] DFUGetFileMetaDataRe
 
 //  ===========================================================================
 ESPservice [
+	requiredaccess("NONE"),
     version("1.34"),
     noforms, 
     exceptions_inline("./smc_xslt/exceptions.xslt")] WsDfu

+ 1 - 1
esp/scm/ws_dfuXref.ecm

@@ -221,7 +221,7 @@ ESPresponse [exceptions_inline] DFUXRefUnusedFilesResponse
 
 
 //  ===========================================================================
-ESPservice [exceptions_inline("./smc_xslt/exceptions.xslt")] WsDFUXRef
+ESPservice [requiredaccess("NONE"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsDFUXRef
 {
     ///ESPmethod [resp_xsl_default("./smc_xslt/xref_main.xslt")] DFUXRefList(DFUXRefListRequest, DFUXRefListResponse);
     ESPmethod [resp_xsl_default("/esp/xslt/xref_main.xslt")] DFUXRefList(DFUXRefListRequest, DFUXRefListResponse);

+ 13 - 12
esp/scm/ws_esdlconfig.ecm

@@ -240,19 +240,20 @@ ESPresponse [exceptions_inline] ListESDLBindingsResponse
     ESParray<ESPstruct ESDLBinding, Binding> Bindings;
 };
 
-ESPservice [version("1.2"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsESDLConfig
+ESPservice [requiredaccess("ESDLConfigAccess:ACCESS"), version("1.2"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsESDLConfig
 {
-    ESPmethod Echo(EchoRequest, EchoResponse);
-    ESPmethod PublishESDLDefinition(PublishESDLDefinitionRequest, PublishESDLDefinitionResponse);
-    ESPmethod PublishESDLBinding(PublishESDLBindingRequest, PublishESDLBindingResponse);
-    ESPmethod ConfigureESDLBindingMethod(ConfigureESDLBindingMethodRequest, ConfigureESDLBindingMethodResponse);
-    ESPmethod GetESDLBinding(GetESDLBindingRequest, GetESDLBindingResponse);
-    ESPmethod DeleteESDLBinding(DeleteESDLBindingRequest, DeleteESDLRegistryEntryResponse);
-    ESPmethod DeleteESDLDefinition(DeleteESDLDefinitionRequest, DeleteESDLRegistryEntryResponse);
-    ESPmethod GetESDLDefinition(GetESDLDefinitionRequest, GetESDLDefinitionResponse);
-    ESPmethod ListESDLDefinitions(ListESDLDefinitionsRequest, ListESDLDefinitionsResponse);
-    ESPmethod ListESDLBindings(ListESDLBindingsRequest, ListESDLBindingsResponse);
-    ESPmethod [min_ver("1.2")] ListDESDLEspBindings(ListDESDLEspBindingsReq, ListDESDLEspBindingsResp);
+	//ESPmethod [featureauth("NONE", "Failed to Echo your request. Permission denied", 20)]   Echo(EchoRequest, EchoResponse);
+    ESPmethod []  Echo(EchoRequest, EchoResponse);
+    ESPmethod [] PublishESDLDefinition(PublishESDLDefinitionRequest, PublishESDLDefinitionResponse);
+    ESPmethod [] PublishESDLBinding(PublishESDLBindingRequest, PublishESDLBindingResponse);
+    ESPmethod [requiredaccess("ESDLConfigAccess:WRITE")] ConfigureESDLBindingMethod(ConfigureESDLBindingMethodRequest, ConfigureESDLBindingMethodResponse);
+    ESPmethod [requiredaccess("ESDLConfigAccess:READ")]  GetESDLBinding(GetESDLBindingRequest, GetESDLBindingResponse);
+    ESPmethod [requiredaccess("ESDLConfigAccess:FULL")]  DeleteESDLBinding(DeleteESDLBindingRequest, DeleteESDLRegistryEntryResponse);
+    ESPmethod [requiredaccess("ESDLConfigAccess:FULL")]  DeleteESDLDefinition(DeleteESDLDefinitionRequest, DeleteESDLRegistryEntryResponse);
+    ESPmethod [requiredaccess("ESDLConfigAccess:READ")]  GetESDLDefinition(GetESDLDefinitionRequest, GetESDLDefinitionResponse);
+    ESPmethod [requiredaccess("ESDLConfigAccess:READ")]  ListESDLDefinitions(ListESDLDefinitionsRequest, ListESDLDefinitionsResponse);
+    ESPmethod [requiredaccess("ESDLConfigAccess:READ")]  ListESDLBindings(ListESDLBindingsRequest, ListESDLBindingsResponse);
+    ESPmethod [requiredaccess("ESDLConfigAccess:READ,ClusterTopologyAccess:READ"), min_ver("1.2")] ListDESDLEspBindings(ListDESDLEspBindingsReq, ListDESDLEspBindingsResp);
 };
 
 SCMexportdef(WsESDLConfig);

+ 1 - 1
esp/scm/ws_espcontrol.ecm

@@ -30,7 +30,7 @@ ESPresponse [exceptions_inline, nil_remove, http_encode(0)] SetLoggingResponse
     string Message;
 };
 
-ESPservice [ version("1.00"), default_client_version("1.00"), exceptions_inline("./smc_xslt/exceptions.xslt")] WSESPControl
+ESPservice [ requiredaccess("NONE"), version("1.00"), default_client_version("1.00"), exceptions_inline("./smc_xslt/exceptions.xslt")] WSESPControl
 {
     ESPmethod SetLogging(SetLoggingRequest, SetLoggingResponse);
 };

+ 1 - 1
esp/scm/ws_fileio.ecm

@@ -72,7 +72,7 @@ ReadFileDataResponse
 };
 
 
-ESPservice [exceptions_inline("./smc_xslt/exceptions.xslt")] WsFileIO
+ESPservice [requiredaccess("NONE"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsFileIO
 {
     //ESPuses ESPstruct DFUException;
     ESPmethod CreateFile(CreateFileRequest, CreateFileResponse);

+ 1 - 0
esp/scm/ws_fs.ecm

@@ -651,6 +651,7 @@ ESPresponse [exceptions_inline, nil_remove] GetSprayTargetsResponse
 };
 
 ESPservice [
+	requiredaccess("NONE"),
     version("1.13"),
     exceptions_inline("./smc_xslt/exceptions.xslt")] FileSpray
 {

+ 1 - 1
esp/scm/ws_loggingservice.ecm

@@ -52,7 +52,7 @@ ESPresponse [exceptions_inline] UpdateLogResponse
     string StatusMessage;
 };
 
-ESPService [version("1.0"), noforms, use_method_name] WsLoggingService
+ESPService [requiredaccess("NONE"), version("1.0"), noforms, use_method_name] WsLoggingService
 {
     ESPmethod GetTransactionSeed(GetTransactionSeedRequest, GetTransactionSeedResponse);
     ESPmethod UpdateLog(UpdateLogRequest, UpdateLogResponse);

+ 1 - 1
esp/scm/ws_machine.ecm

@@ -368,7 +368,7 @@ ESPresponse [encode(0), nil_remove, exceptions_inline] UpdateComponentStatusResp
 };
 
 //-------- service ---------
-ESPservice [version("1.13")] ws_machine
+ESPservice [requiredaccess("NONE"), version("1.13")] ws_machine
 {
     ESPuses ESPstruct RequestInfoStruct;
     ESPuses ESPstruct MachineInfoEx;

+ 1 - 1
esp/scm/ws_packageprocess.ecm

@@ -288,7 +288,7 @@ ESPresponse [exceptions_inline] GetPartFromPackageMapResponse
     string Content;
 };
 
-ESPservice [version("1.02"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsPackageProcess
+ESPservice [requiredaccess("NONE"), version("1.02"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsPackageProcess
 {
     ESPmethod Echo(EchoRequest, EchoResponse);
     ESPmethod AddPackage(AddPackageRequest, AddPackageResponse);

+ 1 - 1
esp/scm/ws_roxie.ecm

@@ -43,7 +43,7 @@
 //  ===========================================================================
 //  ===========================================================================
 //  ===========================================================================
-ESPservice Roxie
+ESPservice [requiredaccess("NONE")] Roxie
 {
 };
 

+ 1 - 1
esp/scm/ws_sciab.ecm

@@ -44,7 +44,7 @@ ESPresponse [exceptions_inline] BoolResponse
     string Status;
 };
 
-ESPservice [exceptions_inline("./smc_xslt/exceptions.xslt")] WsSciab
+ESPservice [requiredaccess("NONE"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsSciab
 {
 
     ESPmethod [resp_xsl_default("./smc_xslt/BoolResponse.xslt")] Index(IndexRequest, BoolResponse);

+ 23 - 19
esp/scm/ws_smc.ecm

@@ -397,32 +397,36 @@ ESPresponse [exceptions_inline] LockQueryResponse
     int NumLocks;
 };
 
-ESPservice [noforms, version("1.19"), exceptions_inline("./smc_xslt/exceptions.xslt"), use_method_name] WsSMC
+ESPservice [requiredaccess("NONE"), noforms, version("1.19"), exceptions_inline("./smc_xslt/exceptions.xslt"), use_method_name] WsSMC
 {
-    ESPmethod Index(SMCIndexRequest, SMCIndexResponse);
-    ESPmethod [resp_xsl_default("/esp/xslt/index.xslt")] Activity(ActivityRequest, ActivityResponse);
+    ESPmethod [requiredaccess("NONE")] Index(SMCIndexRequest, SMCIndexResponse);
+    ESPmethod [requiredaccess("INMETHOD"), resp_xsl_default("/esp/xslt/index.xslt")] Activity(ActivityRequest, ActivityResponse);
 
-    ESPmethod ClearQueue(SMCQueueRequest, SMCQueueResponse);
-    ESPmethod PauseQueue(SMCQueueRequest, SMCQueueResponse);
-    ESPmethod ResumeQueue(SMCQueueRequest, SMCQueueResponse);
-    ESPmethod StopQueue(SMCQueueRequest, SMCQueueResponse);
+    ESPmethod [requiredaccess("INMETHOD")] ClearQueue(SMCQueueRequest, SMCQueueResponse);
+    ESPmethod [requiredaccess("INMETHOD")] PauseQueue(SMCQueueRequest, SMCQueueResponse);
+    ESPmethod [requiredaccess("INMETHOD")] ResumeQueue(SMCQueueRequest, SMCQueueResponse);
+    ESPmethod [requiredaccess("INMETHOD")] StopQueue(SMCQueueRequest, SMCQueueResponse);
 
-    ESPmethod RemoveJob(SMCJobRequest, SMCJobResponse);
-    ESPmethod MoveJobFront(SMCJobRequest, SMCJobResponse);
-    ESPmethod MoveJobBack(SMCJobRequest, SMCJobResponse);
-    ESPmethod MoveJobUp(SMCJobRequest, SMCJobResponse);
-    ESPmethod MoveJobDown(SMCJobRequest, SMCJobResponse);
+    ESPmethod [requiredaccess("INMETHOD")] RemoveJob(SMCJobRequest, SMCJobResponse);
+    ESPmethod [requiredaccess("INMETHOD")] MoveJobFront(SMCJobRequest, SMCJobResponse);
+    ESPmethod [requiredaccess("INMETHOD")] MoveJobBack(SMCJobRequest, SMCJobResponse);
+    ESPmethod [requiredaccess("INMETHOD")] MoveJobUp(SMCJobRequest, SMCJobResponse);
+    ESPmethod [requiredaccess("INMETHOD")] MoveJobDown(SMCJobRequest, SMCJobResponse);
 
-    ESPmethod SetJobPriority(SMCPriorityRequest, SMCPriorityResponse);
-    ESPmethod GetThorQueueAvailability(GetThorQueueAvailabilityRequest, GetThorQueueAvailabilityResponse);
-    ESPmethod SetBanner(SetBannerRequest, SetBannerResponse);
+//this one doesn't seem to do any feature level check, Kevin/Tony?
+    ESPmethod [requiredaccess("NONE")] SetJobPriority(SMCPriorityRequest, SMCPriorityResponse);
+    ESPmethod [requiredaccess("INMETHOD")] GetThorQueueAvailability(GetThorQueueAvailabilityRequest, GetThorQueueAvailabilityResponse);
+//this one ensures superuser, but no feature check is done, Kevin/Tony?
+    ESPmethod [requiredaccess("INMETHOD")] SetBanner(SetBannerRequest, SetBannerResponse);
 
-    ESPmethod NotInCommunityEdition(NotInCommunityEditionRequest, NotInCommunityEditionResponse);
+    ESPmethod [requiredaccess("NONE")] NotInCommunityEdition(NotInCommunityEditionRequest, NotInCommunityEditionResponse);
 
-    ESPmethod [resp_xsl_default("/esp/xslt/hpccresourcelist.xslt")] BrowseResources(BrowseResourcesRequest, BrowseResourcesResponse);
+    ESPmethod [requiredaccess("INMETHOD"), resp_xsl_default("/esp/xslt/hpccresourcelist.xslt")] BrowseResources(BrowseResourcesRequest, BrowseResourcesResponse);
 
-    ESPmethod RoxieControlCmd(RoxieControlCmdRequest, RoxieControlCmdResponse);
-    ESPmethod GetStatusServerInfo(GetStatusServerInfoRequest, GetStatusServerInfoResponse);
+    ESPmethod [requiredaccess("INMETHOD")] RoxieControlCmd(RoxieControlCmdRequest, RoxieControlCmdResponse);
+//this one doesn't seem to do any feature level check, Kevin/Tony?
+    ESPmethod [requiredaccess("NONE")] GetStatusServerInfo(GetStatusServerInfoRequest, GetStatusServerInfoResponse);
+//this one doesn't seem to do any feature level check, Kevin/Tony?
     ESPmethod LockQuery(LockQueryRequest, LockQueryResponse);
 };
 

+ 34 - 23
esp/scm/ws_topology.ecm

@@ -598,7 +598,7 @@ ESPresponse [exceptions_inline,encode(0)] TpGetServicePluginsResponse
     ESParray<ESPstruct TpEspServicePlugin, Plugin> Plugins;
 };
 
-ESPservice [noforms, version("1.25"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsTopology
+ESPservice [requiredaccess("ClusterTopologyAccess:FULL,MachineInfoAccess:FULL"), noforms, version("1.25"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsTopology
 {
     ESPuses ESPStruct TpBinding;
     ESPuses ESPstruct TpCluster;
@@ -620,30 +620,41 @@ ESPservice [noforms, version("1.25"), exceptions_inline("./smc_xslt/exceptions.x
     ESPuses ESPstruct TpServices;
     ESPuses ESPstruct TpTargetCluster;
 
-    ESPmethod [resp_xsl_default("/esp/xslt/targetclusters.xslt")]TpTargetClusterQuery(TpTargetClusterQueryRequest, TpTargetClusterQueryResponse);
-    ///ESPmethod TpTargetClusterQuery(TpTargetClusterQueryRequest, TpTargetClusterQueryResponse);
-    ESPmethod [resp_xsl_default("/esp/xslt/topology.xslt")] TpClusterQuery(TpClusterQueryRequest, TpClusterQueryResponse);
-    ESPmethod TpLogicalClusterQuery(TpLogicalClusterQueryRequest, TpLogicalClusterQueryResponse);
-    ESPmethod TpGroupQuery(TpGroupQueryRequest, TpGroupQueryResponse);
-    ESPmethod [resp_xsl_default("/esp/xslt/machines.xslt")] TpMachineQuery(TpMachineQueryRequest, TpMachineQueryResponse);
-    ESPmethod [resp_xsl_default("/esp/xslt/cluster_info.xslt")] TpClusterInfo(TpClusterInfoRequest, TpClusterInfoResponse);
-    ESPmethod [resp_xsl_default("/esp/xslt/thor_status.xslt")] TpThorStatus(TpThorStatusRequest, TpThorStatusResponse);
-
-    ESPmethod [resp_xsl_default("/esp/xslt/services.xslt")] TpServiceQuery(TpServiceQueryRequest, TpServiceQueryResponse);
-    ESPmethod TpSetMachineStatus(TpSetMachineStatusRequest, TpSetMachineStatusResponse);
-    ESPmethod TpSwapNode(TpSwapNodeRequest, TpSwapNodeResponse);
-    ESPmethod TpXMLFile(TpXMLFileRequest, TpXMLFileResponse);
-    ESPmethod [resp_xsl_default("/esp/xslt/tplog.xslt")] TpLogFile(TpLogFileRequest, TpLogFileResponse);
-    ESPmethod [resp_xsl_default("/esp/xslt/tplogdisplay.xslt")] TpLogFileDisplay(TpLogFileRequest, TpLogFileResponse);
-    ESPmethod TpGetComponentFile(TpGetComponentFileRequest, TpGetComponentFileResponse);
-    ESPmethod TpGetServicePlugins(TpGetServicePluginsRequest, TpGetServicePluginsResponse);
-    ESPmethod TpListTargetClusters(TpListTargetClustersRequest, TpListTargetClustersResponse);
-    ESPmethod [min_ver(1.25)] TpMachineInfo(TpMachineInfoRequest, TpMachineInfoResponse);
-
-    ESPmethod SystemLog(SystemLogRequest, SystemLogResponse);
+    ESPmethod [requiredaccess("INMETHOD"), resp_xsl_default("/esp/xslt/targetclusters.xslt")] TpTargetClusterQuery(TpTargetClusterQueryRequest, TpTargetClusterQueryResponse);
+    ESPmethod [requiredaccess("INMETHOD"), resp_xsl_default("/esp/xslt/topology.xslt")] TpClusterQuery(TpClusterQueryRequest, TpClusterQueryResponse);
+    ESPmethod [requiredaccess("INMETHOD")] TpLogicalClusterQuery(TpLogicalClusterQueryRequest, TpLogicalClusterQueryResponse);
+    ESPmethod [requiredaccess("INMETHOD")] TpGroupQuery(TpGroupQueryRequest, TpGroupQueryResponse);
+    ESPmethod [requiredaccess("INMETHOD"), resp_xsl_default("/esp/xslt/machines.xslt")] TpMachineQuery(TpMachineQueryRequest, TpMachineQueryResponse);
+    ESPmethod [requiredaccess("INMETHOD"), resp_xsl_default("/esp/xslt/cluster_info.xslt")] TpClusterInfo(TpClusterInfoRequest, TpClusterInfoResponse);
+    ESPmethod [requiredaccess("INMETHOD"), resp_xsl_default("/esp/xslt/thor_status.xslt")] TpThorStatus(TpThorStatusRequest, TpThorStatusResponse);
+
+    ESPmethod [requiredaccess("INMETHOD"), resp_xsl_default("/esp/xslt/services.xslt")] TpServiceQuery(TpServiceQueryRequest, TpServiceQueryResponse);
+    ESPmethod [requiredaccess("INMETHOD")] TpSetMachineStatus(TpSetMachineStatusRequest, TpSetMachineStatusResponse);
+    ESPmethod [requiredaccess("INMETHOD")] TpSwapNode(TpSwapNodeRequest, TpSwapNodeResponse);
+    ESPmethod [requiredaccess("INMETHOD")] TpXMLFile(TpXMLFileRequest, TpXMLFileResponse);
+    ESPmethod [requiredaccess("INMETHOD"), resp_xsl_default("/esp/xslt/tplog.xslt")] TpLogFile(TpLogFileRequest, TpLogFileResponse);
+    ESPmethod [requiredaccess("INMETHOD"), resp_xsl_default("/esp/xslt/tplogdisplay.xslt")] TpLogFileDisplay(TpLogFileRequest, TpLogFileResponse);
+    ESPmethod [requiredaccess("INMETHOD")] TpGetComponentFile(TpGetComponentFileRequest, TpGetComponentFileResponse);
+    ESPmethod [requiredaccess("INMETHOD")] TpGetServicePlugins(TpGetServicePluginsRequest, TpGetServicePluginsResponse);
+    ESPmethod [requiredaccess("INMETHOD")] TpListTargetClusters(TpListTargetClustersRequest, TpListTargetClustersResponse);
+    ESPmethod [requiredaccess("INMETHOD"), min_ver(1.25)] TpMachineInfo(TpMachineInfoRequest, TpMachineInfoResponse);
+
+    ESPmethod [requiredaccess("INMETHOD")] SystemLog(SystemLogRequest, SystemLogResponse);
+
+    //ESPmethod [requiredaccess("ClusterTopologyAccess:READ"), resp_xsl_default("/esp/xslt/services.xslt")] TpServiceQuery(TpServiceQueryRequest, TpServiceQueryResponse);
+    //ESPmethod [requiredaccess("ClusterTopologyAccess:WRITE")] TpSetMachineStatus(TpSetMachineStatusRequest, TpSetMachineStatusResponse);
+    //ESPmethod [requiredaccess("ClusterTopologyAccess:FULL")] TpSwapNode(TpSwapNodeRequest, TpSwapNodeResponse);
+    //ESPmethod [requiredaccess("ClusterTopologyAccess:READ")] TpXMLFile(TpXMLFileRequest, TpXMLFileResponse);
+    //ESPmethod [requiredaccess("ClusterTopologyAccess:READ"), resp_xsl_default("/esp/xslt/tplog.xslt")] TpLogFile(TpLogFileRequest, TpLogFileResponse);
+    //ESPmethod [requiredaccess("ClusterTopologyAccess:READ"), resp_xsl_default("/esp/xslt/tplogdisplay.xslt")] TpLogFileDisplay(TpLogFileRequest, TpLogFileResponse);
+    //ESPmethod [requiredaccess("ClusterTopologyAccess:FULL")] TpGetComponentFile(TpGetComponentFileRequest, TpGetComponentFileResponse);
+    //ESPmethod [requiredaccess("ClusterTopologyAccess:READ")] TpGetServicePlugins(TpGetServicePluginsRequest, TpGetServicePluginsResponse);
+    //ESPmethod [requiredaccess("ClusterTopologyAccess:READ")] TpListTargetClusters(TpListTargetClustersRequest, TpListTargetClustersResponse);
+    //ESPmethod [requiredaccess("ClusterTopologyAccess:READ"), min_ver(1.25)] TpMachineInfo(TpMachineInfoRequest, TpMachineInfoResponse);
+
+    //ESPmethod [requiredaccess("ClusterTopologyAccess:READ")] SystemLog(SystemLogRequest, SystemLogResponse);
 };
 
 SCMexportdef(WSWU);
 
 SCMapi(WSWU) IClientWsTopology *createWsTopologyClient();
-

+ 4 - 6
esp/scm/ws_workunits.ecm

@@ -1768,6 +1768,7 @@ ESPresponse [exceptions_inline, nil_remove] WUGetArchiveFileResponse
 };
 
 ESPservice [
+    requiredaccess("INMETHOD"), //This declares that the method logic handles feature level authorization
     version("1.60"), default_client_version("1.60"),
     noforms,exceptions_inline("./smc_xslt/exceptions.xslt"),use_method_name] WsWorkunits
 {
@@ -1778,7 +1779,7 @@ ESPservice [
     ESPmethod [resp_xsl_default("/esp/xslt/wuid.xslt")]     WUGraphTiming(WUGraphTimingRequest, WUGraphTimingResponse);
     ESPmethod [resp_xsl_default("/esp/xslt/graph.xslt")]         WUGraphInfo(WUGraphInfoRequest, WUGraphInfoResponse);
     ESPmethod [resp_xsl_default("/esp/xslt/graph_gvc.xslt")]     WUGVCGraphInfo(WUGVCGraphInfoRequest, WUGVCGraphInfoResponse);
-    ESPmethod[description("Stub for Ajax GVC Graph."), help(""), resp_xsl_default("/esp/xslt/GvcGraph.xslt")] GVCAjaxGraph(GVCAjaxGraphRequest, GVCAjaxGraphResponse);
+    ESPmethod [description("Stub for Ajax GVC Graph."), help(""), resp_xsl_default("/esp/xslt/GvcGraph.xslt")] GVCAjaxGraph(GVCAjaxGraphRequest, GVCAjaxGraphResponse);
     ESPmethod [resp_xsl_default("/esp/xslt/result.xslt")]        WUResult(WUResultRequest, WUResultResponse);
     ESPmethod WUResultView(WUResultViewRequest, WUResultViewResponse);
     ESPmethod [resp_xsl_default("/esp/xslt/wuid_jobs.xslt")]     WUJobList(WUJobListRequest, WUJobListResponse);
@@ -1793,8 +1794,8 @@ ESPservice [
     ESPmethod WUClusterJobXLS(WUClusterJobXLSRequest, WUClusterJobXLSResponse);
     ESPmethod WUClusterJobSummaryXLS(WUClusterJobSummaryXLSRequest, WUClusterJobSummaryXLSResponse);
 
-    ESPmethod WUCreate(WUCreateRequest, WUCreateResponse);
-    ESPmethod WUCreateAndUpdate(WUUpdateRequest, WUUpdateResponse);
+    ESPmethod [requiredaccess("OwnWorkunitsAccess:WRITE")] WUCreate(WUCreateRequest, WUCreateResponse);
+    ESPmethod [requiredaccess("OwnWorkunitsAccess:WRITE")] WUCreateAndUpdate(WUUpdateRequest, WUUpdateResponse);
     ESPmethod WUUpdate(WUUpdateRequest, WUUpdateResponse);
     ESPmethod WUDelete(WUDeleteRequest, WUDeleteResponse);
     ESPmethod WUSubmit(WUSubmitRequest, WUSubmitResponse);
@@ -1808,10 +1809,8 @@ ESPservice [
     ESPmethod WURun(WURunRequest, WURunResponse);
 
     ESPmethod WUExport(WUExportRequest, WUExportResponse);
-
     ESPmethod WUWaitCompiled(WUWaitRequest, WUWaitResponse);
     ESPmethod WUWaitComplete(WUWaitRequest, WUWaitResponse);
-    
     ESPmethod WUSyntaxCheckECL(WUSyntaxCheckRequest, WUSyntaxCheckResponse);
     ESPmethod WUCompileECL(WUCompileECLRequest, WUCompileECLResponse);
     
@@ -1825,7 +1824,6 @@ ESPservice [
 
     ESPmethod WUListLocalFileRequired(WUListLocalFileRequiredRequest, WUListLocalFileRequiredResponse);
     ESPmethod WUAddLocalFileToWorkunit(WUAddLocalFileToWorkunitRequest, WUAddLocalFileToWorkunitResponse);
-
     ESPmethod WUCDebug(WUDebugRequest, WUDebugResponse);
     
     ESPmethod [resp_xsl_default("/esp/xslt/WUPublishWorkunit.xslt")] WUPublishWorkunit(WUPublishWorkunitRequest, WUPublishWorkunitResponse);

+ 4 - 4
esp/services/ws_workunits/ws_workunitsService.cpp

@@ -418,8 +418,8 @@ bool CWsWorkunitsEx::onWUCreate(IEspContext &context, IEspWUCreateRequest &req,
 {
     try
     {
-        if (!context.validateFeatureAccess(OWN_WU_ACCESS, SecAccess_Write, false))
-            throw MakeStringException(ECLWATCH_ECL_WU_ACCESS_DENIED, "Failed to create workunit. Permission denied.");
+        //if (!context.validateFeatureAccess(OWN_WU_ACCESS, SecAccess_Write, false))
+        //    throw MakeStringException(ECLWATCH_ECL_WU_ACCESS_DENIED, "Failed to create workunit. Permission denied.");
 
         NewWsWorkunit wu(context);
         resp.updateWorkunit().setWuid(wu->queryWuid());
@@ -599,8 +599,8 @@ bool CWsWorkunitsEx::onWUCreateAndUpdate(IEspContext &context, IEspWUUpdateReque
 {
     try
     {
-        if (!context.validateFeatureAccess(OWN_WU_ACCESS, SecAccess_Write, false))
-            throw MakeStringException(ECLWATCH_ECL_WU_ACCESS_DENIED, "Failed to create workunit. Permission denied.");
+         //if (!context.validateFeatureAccess(OWN_WU_ACCESS, SecAccess_Write, false))
+         //           throw MakeStringException(ECLWATCH_ECL_WU_ACCESS_DENIED, "Failed to create workunit. Permission denied.");
 
         const char* wuid = req.getWuid();
         if (!wuid || !*wuid)

+ 0 - 1
tools/esdlcomp/esdlcomp.h

@@ -1071,7 +1071,6 @@ public:
         return ::getMetaStringValue(tags, val, tag);
     }
 
-
     int getMetaInt(const char *tag, int def_val=0)
     {
         return ::getMetaInt(tags, tag, def_val);

+ 1 - 1
tools/hidl/CMakeLists.txt

@@ -44,7 +44,7 @@ set (    SRCS
 
 include_directories ( 
          ${CMAKE_CURRENT_BINARY_DIR}   # for generated .h file
-         ${HPCC_SOURCE_DIR}/system/include 
+         ${HPCC_SOURCE_DIR}/system/include
          ${CMAKE_CURRENT_SOURCE_DIR}
     )
 

+ 175 - 29
tools/hidl/hidlcomp.cpp

@@ -21,6 +21,7 @@
 
 #include "hidl_utils.hpp"
 #include "hidlcomp.h"
+
 //#undef new
 #include <map>
 #include <set>
@@ -5373,57 +5374,166 @@ void EspServInfo::write_factory_impl()
     outf(" IClient%s * create%sClient() {  return new CClient%s(); }\n", name_, name_, name_);
 }
 
+const char * translateAuthLevel(const char * level)
+{
+    /*
+     *  This method might belong in seclib where the enumeration is defined (selib.h)
+     *  enum SecAccessFlags
+     *  {
+     *     SecAccess_Unknown = -255,
+     *     SecAccess_None = 0,
+     *     SecAccess_Access = 1,
+     *     SecAccess_Read = 3,
+     *     SecAccess_Write = 7,
+     *     SecAccess_Full = 255
+     *   };
+    */
+
+    if (!level || !*level)
+    {
+        outs(2, "\n//FEATURE LEVEL NOT SET, DEFAULTING TO 'READ'\n");
+        return "SecAccess_Read";
+    }
+
+    if (strieq(level, "NONE"))
+    {
+        outs(2, "\n//WARNING: FEATURE LEVEL AUTHORIZATION HAS BEEN TURNED OFF!!\n");
+        return "SecAccess_None";
+    }
+
+    if (strieq(level, "INMETHOD"))
+    {
+        outs(2, "\n//WARNING: FEATURE LEVEL AUTHORIZATION HAS BEEN DEFERED TO INMETHOD!!\n");
+        return "SecAccess_None";
+    }
+
+    if (strieq(level, "FULL"))
+        return "SecAccess_Full";
+    else if (strieq(level, "WRITE"))
+        return "SecAccess_Write";
+    else if (strieq(level, "READ"))
+        return "SecAccess_Read";
+    else if (strieq(level, "ACCESS"))
+        return "SecAccess_Access";
+
+    //we might need to throw here...
+    outs(2, "\n//FEATURE LEVEL VALUE INVALID: DEFAULTING REQUIRED LEVEL to 'READ'!\n//Valid values are NONE INMETHOD, ACCESS, READ, WRITE, FULL\n");
+    return "SecAccess_Read";
+}
+
+void writeAccessMap(const char * rawServiceAccessList, const char * methodname, int tabs)
+{
+    StrBuffer indent;
+    for (int tabindex = 0; tabindex < tabs; tabindex++)
+        indent.append('\t');
+
+    if (rawServiceAccessList && *rawServiceAccessList)
+    {
+        int listlen = strlen(rawServiceAccessList);
+        StrBuffer currAccessName;
+        StrBuffer currAccessLevel;
+        bool nameComplete = false;
+
+        for (int i = 0; i <= listlen; i++ )
+        {
+            if (i == listlen || rawServiceAccessList[i] == ',')
+            {
+                if (nameComplete == false)
+                {
+                    if (strieq(currAccessName, "NONE") || strieq(currAccessName, "INMETHOD"))
+                    {
+                        //outf("\n%sm_accessmap.setValue(\"%sAccess\", %s);\n", indent.str(), methodname, translateAuthLevel("NONE"));
+                        //outf("\n%sm_accessmap.kill();\n", indent.str());
+                        continue;
+                    }
+                    else
+                        outf("\nError: Access level must be declared in service definition: ESPservice [%s(\"myAccessFeature:FULL\"]\n", FEATEACCESSATTRIBUTE);
+                }
+
+                outf("\n%sm_accessmap.setValue(\"%s\", %s);\n", indent.str(), currAccessName.str(), translateAuthLevel(currAccessLevel.str()));
+                currAccessName.clear();
+                currAccessLevel.clear();
+                nameComplete = false;
+                continue;
+            }
+            else if (rawServiceAccessList[i] == ':')
+            {
+                if (currAccessName.length()==0)
+                {
+                    currAccessName.setf("%sAccess", methodname);
+                    outf("\n//processaccesslist: defaulted current name to : %s\n", currAccessName.str());
+                }
+
+                nameComplete = true;
+                continue;
+            }
+            else if (rawServiceAccessList[i] == '"')
+                continue;
+
+            if (!nameComplete)
+                currAccessName.append(rawServiceAccessList[i]);
+            else
+                currAccessLevel.append(rawServiceAccessList[i]);
+        }
+    }
+    else
+    {
+        outf("\n%sm_accessmap.setValue(\"%sAccess\", %s);\n", indent.str(), methodname, "SecAccess_Read"); //This seems to be the default per seclib
+    }
+}
+
 void EspServInfo::write_esp_binding_ipp()
 {
     EspMethodInfo *mthi=NULL;
     int useMethodName = getMetaInt("use_method_name", 0);
-    
+
     outf("\n\nclass C%sSoapBinding : public CHttpSoapBinding\n", name_);
     outs("{\npublic:\n");
+
     //dom
     outf("\tC%sSoapBinding(http_soap_log_level level=hsl_none);\n", name_);
     outf("\tC%sSoapBinding(IPropertyTree* cfg, const char *bindname=NULL, const char *procname=NULL, http_soap_log_level level=hsl_none);\n", name_);
-    
+
     outs("\tvirtual void init_strings();\n");
-    
+
     //method ==> processRequest
     outs("\tvirtual int processRequest(IRpcMessage* rpc_call, IRpcMessage* rpc_response);\n");
-    
+
     //method ==> getXsdDefinition
     outs("\tint getXsdDefinition(IEspContext &context, CHttpRequest* request, StringBuffer &content, const char *service, const char *method, bool mda);\n");
-    
+
     //method ==> getMethodHtmlForm
     outs("\tvirtual int getMethodHtmlForm(IEspContext &context, CHttpRequest* request, const char *serv, const char *method, StringBuffer &page, bool bIncludeFormTag);\n");
-    
+
     //method ==> getQualifiedNames
     outs("\tint getQualifiedNames(IEspContext& ctx, MethodInfoArray & methods);\n");
-    
+
     //method ==> getServiceName
     outs("\tStringBuffer & getServiceName(StringBuffer &resp);\n");
-    
+
     //method ==> isValidServiceName
     outs("\tbool isValidServiceName(IEspContext &context, const char *name);\n");
-    
+
     //method ==> qualifyMethodName
     outs("\tbool qualifyMethodName(IEspContext &context, const char *methname, StringBuffer *methQName);\n");
-    
+
     //method ==> qualifyServiceName
     outs("\tbool qualifyServiceName(IEspContext &context, const char *servname, const char *methname, StringBuffer &servQName, StringBuffer *methQName);\n");
-    
+
     //method ==> onGetFile
     outs("\tvirtual int onGetFile(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *pathex);\n");
-    
+
     //Method ==> onGetForm
     outs("\tvirtual int onGetForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method);\n");
-    
+
     //Method ==> onGetXForm
     //if (getMetaInt("use_new_form",0))
     outs("\tvirtual int onGetXForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method);\n");
-    
+
     //Method ==> supportGeneratedForms
     if (getMetaInt("noforms", 0))
         outs("\tvirtual bool supportGeneratedForms(){return false;}\n");
-    
+
     if (getMetaInt("no_ws_index", 0))
     {
         //Method ==> onGetIndex
@@ -5432,7 +5542,7 @@ void EspServInfo::write_esp_binding_ipp()
         outs("\t\treturn onGetNotFound(context, request, response, service);\n");
         outs("\t}\n");
     }
-    
+
     //Method ==> onGetService
     outs("\tvirtual int onGetService(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method, const char *pathex);\n");
 
@@ -5441,12 +5551,13 @@ void EspServInfo::write_esp_binding_ipp()
 
     //Method ==> onGetInstantQuery
     outs("\tvirtual int onGetInstantQuery(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method);\n");
-    
+
     //Method ==> xslTransform
     if (needsXslt)
     {
         outs("\tvoid setXslProcessor(IInterface *xslp_){xslp.set(dynamic_cast<IXslProcessor *>(xslp_));}\n");
         outs("private:\n");
+
         outs("\tOwned<IXslProcessor> xslp;\n");
         outs("\tvoid xslTransform(const char* xml, const char* xslFile, StringBuffer& output, IProperties *params)\n"
             "\t{\n"
@@ -5466,7 +5577,10 @@ void EspServInfo::write_esp_binding_ipp()
     }
     else
         outs("\tvoid setXslProcessor(IInterface *xslp){}\n");
-    
+
+    outs("private:\n");
+    outs("\tMapStringTo<SecAccessFlags> m_accessmap;\n");
+
     outs("};\n\n");
 }
 
@@ -5485,9 +5599,19 @@ void EspServInfo::write_esp_binding()
     outs("\n//=======================================================");
     outs("\n");
 
-    outf("\nC%sSoapBinding::C%sSoapBinding(http_soap_log_level level):CHttpSoapBinding(NULL, NULL, NULL, level)\n{\n\tinit_strings();\n\tsetWsdlVersion(%s);\n}\n", name_, name_, wsdlVer.str());
-    outf("\nC%sSoapBinding::C%sSoapBinding(IPropertyTree* cfg, const char *bindname, const char *procname, http_soap_log_level level):CHttpSoapBinding(cfg, bindname, procname, level)\n{\n\tinit_strings(); \n\tsetWsdlVersion(%s);\n}\n", name_, name_, wsdlVer.str());
-    
+    StrBuffer servicefeatureurl;
+    getMetaStringValue(servicefeatureurl,FEATEACCESSATTRIBUTE);
+    if (servicefeatureurl.length() == 0)
+        outf("ESDL Error: %s service definition must declare default feature access. Example 'ESPservice [%s(\"MyServiceAccess:FULL\")]'", name_, FEATEACCESSATTRIBUTE);
+
+    outf("\nC%sSoapBinding::C%sSoapBinding(http_soap_log_level level):CHttpSoapBinding(NULL, NULL, NULL, level)\n{\n\tinit_strings();\n\tsetWsdlVersion(%s);", name_, name_, wsdlVer.str());
+    writeAccessMap(servicefeatureurl.str(),name_, 1);
+    outf("\n}\n");
+
+    outf("\nC%sSoapBinding::C%sSoapBinding(IPropertyTree* cfg, const char *bindname, const char *procname, http_soap_log_level level):CHttpSoapBinding(cfg, bindname, procname, level)\n{\n\tinit_strings(); \n\tsetWsdlVersion(%s);\n", name_, name_, wsdlVer.str());
+    writeAccessMap(servicefeatureurl.str(),name_, 1);
+    outf("\n}\n");
+
     outf("\nvoid C%sSoapBinding::init_strings()\n", name_);
     outs("{\n");
     
@@ -5550,7 +5674,8 @@ void EspServInfo::write_esp_binding()
         bool bHandleExceptions = 0 != mthi->getMetaInt("exceptions_inline", 0);
         if (!bHandleExceptions)
             bHandleExceptions = 0 != getMetaInt("exceptions_inline", 0);
-        
+
+        const char * methodAccess = mthi->getMetaString(FEATEACCESSATTRIBUTE, NULL);
         //begin try block
         if (bHandleExceptions)
         {
@@ -5566,7 +5691,14 @@ void EspServInfo::write_esp_binding()
                 outs("\t\t\t\tthrow MakeStringException(-1, \"Client version is too old, please update your client application.\");");
             }
             outs("\t\t\tresponse->set_status(SOAP_OK);\n");
+
+            if (methodAccess && *methodAccess)
+                writeAccessMap(methodAccess, name_, 3);
+
+            outf("\t\t\tif( m_accessmap.ordinality() > 0 )\n\t\t\t\tonFeaturesAuthorize(context, m_accessmap, \"%s\", \"%s\");\n", name_, mthi->getName());
+
             outf("\t\t\tiserv->on%s(context, *esp_request, *esp_response);\n", mthi->getName());
+
             outs("\t\t}\n");
             
             write_catch_blocks(mthi, ct_soapresp, 2);
@@ -5580,6 +5712,10 @@ void EspServInfo::write_esp_binding()
             }
             if (mthi->getMetaInt("do_not_log",0))
                 outs("\t\tcontext.queryRequestParameters()->setProp(\"do_not_log\",1);\n");
+
+            if (methodAccess && *methodAccess)
+                writeAccessMap(methodAccess, name_, 3);
+            outf("\t\tif(m_accessmap.ordinality()>0)\n\t\t\tonFeaturesAuthorize(context, m_accessmap, \"%s\", \"%s\");\n", name_, mthi->getName());
             outf("\t\tiserv->on%s(*rpc_call->queryContext(), *esp_request, *esp_response);\n", mthi->getName());
             outs("\t\tresponse->set_status(SOAP_OK);\n");
         }
@@ -5966,7 +6102,6 @@ void EspServInfo::write_esp_binding()
         if (!bHandleExceptions)
             bHandleExceptions = 0 != getMetaInt("exceptions_inline", 0) || getMetaInt("http_exceptions_inline", 0);
 
-        
         if (respXsl==NULL)
         {
             outf("\t\tif(!stricmp(method, \"%s\")||!stricmp(method, \"%s\"))\n", mthi->getName(), mthi->getReq());
@@ -5977,6 +6112,8 @@ void EspServInfo::write_esp_binding()
             outf("\t\t\tC%s* resp = new C%s(\"%s\");\n", mthi->getResp(), mthi->getResp(), name_);
             outf("\t\t\tesp_response.setown(resp);\n");
             
+            const char * methodAccess = mthi->getMetaString(FEATEACCESSATTRIBUTE, NULL);
+
             if (bHandleExceptions)
             {
                 outf("\t\t\tsource.setf(\"%s::%%s()\", method);\n", name_);
@@ -5985,6 +6122,12 @@ void EspServInfo::write_esp_binding()
                 //begin try block
                 outs("\t\t\ttry\n");
                 outs("\t\t\t{\n");
+
+                if (methodAccess && *methodAccess)
+                    writeAccessMap(methodAccess, name_, 4);
+
+                outf("\t\t\t\tif(m_accessmap.ordinality()>0)\n\t\t\t\t\tonFeaturesAuthorize(context, m_accessmap, \"%s\", \"%s\");\n", name_, mthi->getName());
+
                 if (mthi->getMetaInt("do_not_log",0))
                     outf("\t\t\t\tcontext.queryRequestParameters()->setProp(\"do_not_log\",1);\n");
                 outf("\t\t\t\tiserv->on%s(context, *esp_request.get(), *resp);\n", mthi->getName());
@@ -5993,13 +6136,17 @@ void EspServInfo::write_esp_binding()
                 write_catch_blocks(mthi, ct_httpresp, 3);
             }
             else
+            {
+                if (methodAccess && *methodAccess)
+                    writeAccessMap(methodAccess, name_, 3);
+                outf("\t\t\tif(m_accessmap.ordinality()>0)\n\t\t\t\tonFeaturesAuthorize(context, m_accessmap, \"%s\", \"%s\");\n", name_, mthi->getName());
                 outf("\t\t\tiserv->on%s(*request->queryContext(), *esp_request.get(), *resp);\n", mthi->getName());
-            
+            }
+
             outs("\t\t}\n");
         }
         else
         {
-            
             outf("\t\tif(!stricmp(method, \"%s\")||!stricmp(method, \"%s\"))\n", mthi->getName(), mthi->getReq());
             outs("\t\t{\n");
             outf("\t\t\tOwned<C%s> esp_request = new C%s(&context, \"%s\", request->queryParameters(), request->queryAttachments());\n", mthi->getReq(), mthi->getReq(), name_);
@@ -6024,8 +6171,7 @@ void EspServInfo::write_esp_binding()
             {
                 outf("\t\t\t\tiserv->on%s(*request->queryContext(), *esp_request.get(), *esp_response.get());\n", mthi->getName());
             }
-            
-            
+
             outs("\t\t\tif (canRedirect(*request) && esp_response->getRedirectUrl() && *esp_response->getRedirectUrl())\n");
             outs("\t\t\t{\n");
             outs("\t\t\t\tresponse->redirect(*request, esp_response->getRedirectUrl());\n");
@@ -6056,7 +6202,6 @@ void EspServInfo::write_esp_binding()
             outs("\t\t\t\t\tesp_response->serializeStruct(&context, xml, NULL);\n\n");
             if (bClientXslt)
             {
-                
                 outs("\t\t\t\t\tif (request->supportClientXslt()){\n");
                 outs("\t\t\t\t\t\txml.swapWith(sResponse);\n");
                 outs("\t\t\t\t\t\tresponse->setContentType(\"text/xml\");\n");
@@ -6077,7 +6222,6 @@ void EspServInfo::write_esp_binding()
             if (bClientXslt)
                 outs("\t\t\t\t\t}\n");
 
-                
             outs("\t\t\t\t\tresponse->setContent(sResponse.str());\n");
             outs("\t\t\t\t}\n");
             
@@ -6224,6 +6368,8 @@ void EspServInfo::write_esp_client_ipp()
     outs("\tStringBuffer m_realm;\n");
     outs("\tStringBuffer m_action;\n");
     outs("\tlong m_reqId;\n");
+    outs("\tMapStringTo<SecAccessFlags> m_accessmap;\n");
+
     outs("\npublic:\n");
     outs("\tIMPLEMENT_IINTERFACE;\n\n");
 

+ 1 - 0
tools/hidl/hidlcomp.h

@@ -28,6 +28,7 @@
 #define HIDLVER "1.3"
 
 #define RETURNNAME "_return"
+#define FEATEACCESSATTRIBUTE "requiredaccess"
 
 #ifndef _WIN32
 #define stricmp strcasecmp