sechandler.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. // SecHandler.cpp: implementation of the CSecHandler class.
  14. //
  15. //////////////////////////////////////////////////////////////////////
  16. #include "sechandler.hpp"
  17. #include "bindutil.hpp"
  18. #include <map>
  19. #include <string>
  20. #include "espcontext.hpp"
  21. //////////////////////////////////////////////////////////////////////
  22. // Construction/Destruction
  23. //////////////////////////////////////////////////////////////////////
  24. SecHandler::SecHandler()
  25. {
  26. }
  27. SecHandler::~SecHandler()
  28. {
  29. }
  30. void SecHandler::setSecManger(ISecManager* mgr)
  31. {
  32. m_secmgr.set(mgr);
  33. }
  34. void SecHandler::setResources(ISecResourceList* rlist)
  35. {
  36. m_resources.set(rlist);
  37. }
  38. void SecHandler::setUser(ISecUser* user)
  39. {
  40. m_user.set(user);
  41. }
  42. void SecHandler::setFeatureAuthMap(IAuthMap * map)
  43. {
  44. if(map != NULL)
  45. m_feature_authmap.set(map);
  46. }
  47. bool SecHandler::authorizeSecFeature(const char * pszFeatureUrl, const char* UserID, const char* CompanyID, SecAccessFlags & required_access,bool bCheckTrial,int DebitUnits, SecUserStatus & user_status)
  48. {
  49. if(m_user.get()==0)
  50. throw MakeStringException(500,"No user defined in SecHandler::authorizeSecFeature");
  51. user_status = SecUserStatus_Unknown;
  52. //lets see is our primary user allowed to access the resource.
  53. bool bPrimaryAccessAllowed = authorizeSecFeature(pszFeatureUrl,required_access);
  54. if(bPrimaryAccessAllowed==false)
  55. return false;
  56. //by now the prime ISecUser will have been fully initialized. We should be able
  57. //..to tell its status.
  58. if(m_user->getStatus() == SecUserStatus_FreeTrial || m_user->getStatus() == SecUserStatus_Rollover)
  59. {
  60. bool bReturn = true;
  61. if(bCheckTrial==true)
  62. bReturn = authorizeTrial(*m_user.get(),pszFeatureUrl,required_access);
  63. user_status = m_user->getStatus();
  64. return bReturn;
  65. }
  66. //m_user should be the user who logs in. This may not be the user whose resource we are looking for.
  67. //if userid and companyid are blank then we must be authenticating a normal user.. so continue on..
  68. if(UserID==0 || *UserID=='\0' || CompanyID==0 || *CompanyID=='\0')
  69. return bPrimaryAccessAllowed;
  70. //see do we have a cached version of our secondary user.....
  71. //.. if we do then check it...
  72. Owned<ISecUser> pSecondaryUser;
  73. pSecondaryUser.set(m_secmgr->findUser(UserID));
  74. if(pSecondaryUser.get()== NULL)
  75. {
  76. pSecondaryUser.setown(m_secmgr->createUser(UserID));
  77. if (!pSecondaryUser)
  78. return false;
  79. pSecondaryUser->setRealm(CompanyID);
  80. bool bSecondaryAccessAllowed = m_secmgr->initUser(*pSecondaryUser.get());
  81. if(bSecondaryAccessAllowed==false)
  82. return false;
  83. m_secmgr->addUser(*pSecondaryUser.get());
  84. }
  85. // currently not the responsibility of this service to authenticate the secondary user.
  86. //we just need to chech and see if on a free trial whether they should be allowed continue
  87. if(pSecondaryUser->getStatus() == SecUserStatus_FreeTrial || pSecondaryUser->getStatus() == SecUserStatus_Rollover)
  88. {
  89. //if the primary user is inhouse then we only want to check for a free trial
  90. // if a debit units value has been passed in.
  91. if(m_user->getStatus() == SecUserStatus_Inhouse && DebitUnits == 0)
  92. {
  93. if (getEspLogLevel() >= LogNormal)
  94. DBGLOG("Inhouse primary user and DebitUtits are 0 so not decrementing free trial");
  95. return true;
  96. }
  97. if (DebitUnits > 0)
  98. pSecondaryUser->setPropertyInt("debitunits",DebitUnits);
  99. bool bReturn = true;
  100. if(bCheckTrial==true)
  101. bReturn = authorizeTrial(*pSecondaryUser,pszFeatureUrl,required_access);
  102. user_status = pSecondaryUser->getStatus();
  103. return bReturn;
  104. }
  105. return true;
  106. }
  107. bool SecHandler::authorizeTrial(ISecUser& user,const char* pszFeatureUrl, SecAccessFlags & required_access)
  108. {
  109. int trial_access = m_secmgr->authorizeEx(RT_TRIAL,user,pszFeatureUrl);
  110. if(trial_access < required_access)
  111. throw MakeStringException(201,"Your company has used up all of their free transaction credits");
  112. return true;
  113. }
  114. bool SecHandler::authorizeSecFeature(const char* pszFeatureUrl, SecAccessFlags& access)
  115. {
  116. StringArray features;
  117. features.append(pszFeatureUrl);
  118. Owned<IEspStringIntMap> pmap=createStringIntMap();
  119. bool rc = authorizeSecFeatures(features, *pmap);
  120. if (rc)
  121. {
  122. int accessAllowed = pmap->queryValue(pszFeatureUrl);
  123. if (accessAllowed == -1)
  124. rc = false;
  125. else
  126. access = (SecAccessFlags) accessAllowed;
  127. }
  128. return rc;
  129. }
  130. bool SecHandler::authorizeSecFeatures(StringArray & features, IEspStringIntMap & pmap)
  131. {
  132. return authorizeSecReqFeatures(features, pmap, NULL);
  133. }
  134. bool SecHandler::authorizeSecReqFeatures(StringArray & features, IEspStringIntMap & pmap, unsigned *required)
  135. {
  136. if(features.length() == 0)
  137. return false;
  138. if(m_secmgr.get() == NULL)
  139. {
  140. for(unsigned i = 0; i < features.length(); i++)
  141. {
  142. const char* feature = features.item(i);
  143. if(feature != NULL && feature[0] != 0)
  144. pmap.setValue(feature, SecAccess_Full);
  145. }
  146. return true;
  147. }
  148. if(m_user.get() == NULL)
  149. {
  150. AuditMessage(AUDIT_TYPE_ACCESS_FAILURE, "Authorization", "Access Denied: No username provided");
  151. return false;
  152. }
  153. Owned<ISecResourceList> plist = m_secmgr->createResourceList("FeatureMap");
  154. std::map<std::string, std::string> namemap;
  155. unsigned i;
  156. for(i = 0; i < features.length(); i++)
  157. {
  158. const char* feature = features.item(i);
  159. if(feature == NULL || feature[0] == 0)
  160. continue;
  161. if(m_feature_authmap.get() == NULL)
  162. {
  163. plist->addResource(feature);
  164. namemap[feature] = feature;
  165. }
  166. else
  167. {
  168. ISecResourceList* rlist = m_feature_authmap->queryResourceList(feature);
  169. ISecResource* resource = NULL;
  170. if(rlist != NULL && (resource = rlist->queryResource((unsigned)0)) != NULL)
  171. {
  172. plist->addResource(resource->clone());
  173. namemap[resource->getName()] = feature;
  174. }
  175. else
  176. {
  177. // Use the feature name as the resource name if no authmap was found
  178. ISecResource* res = plist->addResource(feature);
  179. res->setRequiredAccessFlags(SecAccess_Unknown);
  180. namemap[feature] = feature;
  181. }
  182. }
  183. }
  184. bool auth_ok = false;
  185. try
  186. {
  187. auth_ok = m_secmgr->authorize(*m_user.get(), plist);
  188. }
  189. catch(IException* e)
  190. {
  191. StringBuffer errmsg;
  192. e->errorMessage(errmsg);
  193. ERRLOG("Exception authorizing, error=%s\n", errmsg.str());
  194. return false;
  195. }
  196. catch(...)
  197. {
  198. ERRLOG("Unknown exception authorizing\n");
  199. return false;
  200. }
  201. if(auth_ok)
  202. {
  203. for(i = 0; i < plist->count(); i++)
  204. {
  205. ISecResource* resource = plist->queryResource(i);
  206. if(resource != NULL)
  207. {
  208. std::string feature = namemap[resource->getName()];
  209. if(feature.size() == 0)
  210. continue;
  211. pmap.setValue(feature.c_str(), resource->getAccessFlags());
  212. if (required && required[i]>0 && resource->getAccessFlags()<required[i])
  213. {
  214. AuditMessage(AUDIT_TYPE_ACCESS_FAILURE, "Authorization", "Access Denied: Not enough access rights for resource", "Resource: %s [%s]", resource->getName(), resource->getDescription());
  215. }
  216. }
  217. }
  218. }
  219. return auth_ok;
  220. }
  221. bool SecHandler::validateSecFeatureAccess(const char* pszFeatureUrl, unsigned required, bool throwExcpt)
  222. {
  223. StringArray features;
  224. features.append(pszFeatureUrl);
  225. unsigned reqarray[1];
  226. reqarray[0] = required;
  227. Owned<IEspStringIntMap> pmap=createStringIntMap();
  228. if (authorizeSecReqFeatures(features, *pmap, reqarray))
  229. {
  230. int accessAllowed = pmap->queryValue(pszFeatureUrl);
  231. if ((accessAllowed == -1) || (required && (accessAllowed < required)))
  232. {
  233. if (throwExcpt)
  234. throw MakeStringException(-1, "Access Denied!");
  235. return false;
  236. }
  237. else
  238. return true;
  239. }
  240. if (throwExcpt)
  241. throw MakeStringException(-1, "Access Denied!");
  242. return false;
  243. }
  244. void SecHandler::AuditMessage(AuditType type, const char *filterType, const char *title, const char *parms, ...)
  245. {
  246. va_list args;
  247. va_start(args, parms);
  248. StringBuffer msg;
  249. StringBuffer format(title);
  250. format.appendf("\n\tProcess: esp\n\tUser: %s", m_user->getName());
  251. if (parms)
  252. format.append("\n\t").append(parms);
  253. msg.valist_appendf(format.str(), args);
  254. va_end(args);
  255. AUDIT(type, msg.str());
  256. }
  257. void SecHandler::AuditMessage(AuditType type, const char *filterType, const char *title)
  258. {
  259. VStringBuffer msg("%s\n\tProcess: esp\n\tUser: %s", title, m_user->getName());
  260. AUDIT(type, msg.str());
  261. }