PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/repository/src/org/pentaho/platform/security/userroledao/jackrabbit/AbstractJcrBackedUserRoleDao.java

https://github.com/dbogdanovich/pentaho-platform
Java | 800 lines | 669 code | 103 blank | 28 comment | 191 complexity | c10e03c4420c0afd4a84de8972f4dbcd MD5 | raw file
  1. package org.pentaho.platform.security.userroledao.jackrabbit;
  2. import java.io.Serializable;
  3. import java.util.ArrayList;
  4. import java.util.Arrays;
  5. import java.util.EnumSet;
  6. import java.util.HashMap;
  7. import java.util.HashSet;
  8. import java.util.Iterator;
  9. import java.util.List;
  10. import java.util.Properties;
  11. import java.util.Set;
  12. import javax.jcr.Credentials;
  13. import javax.jcr.NamespaceException;
  14. import javax.jcr.Node;
  15. import javax.jcr.RepositoryException;
  16. import javax.jcr.Session;
  17. import javax.jcr.Value;
  18. import org.apache.commons.collections.map.LRUMap;
  19. import org.apache.jackrabbit.api.security.user.Authorizable;
  20. import org.apache.jackrabbit.api.security.user.AuthorizableExistsException;
  21. import org.apache.jackrabbit.api.security.user.Group;
  22. import org.apache.jackrabbit.api.security.user.User;
  23. import org.apache.jackrabbit.api.security.user.UserManager;
  24. import org.apache.jackrabbit.core.SessionImpl;
  25. import org.apache.jackrabbit.core.security.authentication.CryptedSimpleCredentials;
  26. import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
  27. import org.apache.jackrabbit.core.security.user.UserManagerImpl;
  28. import org.apache.jackrabbit.spi.Name;
  29. import org.apache.jackrabbit.spi.NameFactory;
  30. import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
  31. import org.pentaho.platform.api.engine.security.userroledao.IPentahoRole;
  32. import org.pentaho.platform.api.engine.security.userroledao.IPentahoUser;
  33. import org.pentaho.platform.api.engine.security.userroledao.IUserRoleDao;
  34. import org.pentaho.platform.api.engine.security.userroledao.NotFoundException;
  35. import org.pentaho.platform.api.mt.ITenant;
  36. import org.pentaho.platform.api.mt.ITenantedPrincipleNameResolver;
  37. import org.pentaho.platform.api.repository2.unified.IRepositoryDefaultAclHandler;
  38. import org.pentaho.platform.api.repository2.unified.RepositoryFile;
  39. import org.pentaho.platform.api.repository2.unified.RepositoryFileAcl;
  40. import org.pentaho.platform.api.repository2.unified.RepositoryFileAcl.Builder;
  41. import org.pentaho.platform.api.repository2.unified.RepositoryFilePermission;
  42. import org.pentaho.platform.api.repository2.unified.RepositoryFileSid;
  43. import org.pentaho.platform.api.repository2.unified.RepositoryFileSid.Type;
  44. import org.pentaho.platform.engine.core.system.TenantUtils;
  45. import org.pentaho.platform.security.userroledao.messages.Messages;
  46. import org.pentaho.platform.repository2.unified.IRepositoryFileAclDao;
  47. import org.pentaho.platform.repository2.unified.IRepositoryFileDao;
  48. import org.pentaho.platform.repository2.unified.ServerRepositoryPaths;
  49. import org.pentaho.platform.repository2.unified.jcr.ILockHelper;
  50. import org.pentaho.platform.repository2.unified.jcr.IPathConversionHelper;
  51. import org.pentaho.platform.repository2.unified.jcr.JcrRepositoryFileAclUtils;
  52. import org.pentaho.platform.repository2.unified.jcr.JcrRepositoryFileUtils;
  53. import org.pentaho.platform.repository2.unified.jcr.JcrTenantUtils;
  54. import org.pentaho.platform.repository2.unified.jcr.PentahoJcrConstants;
  55. import org.pentaho.platform.security.userroledao.PentahoRole;
  56. import org.pentaho.platform.security.userroledao.PentahoUser;
  57. import org.springframework.security.providers.dao.UserCache;
  58. import org.springframework.security.providers.dao.cache.NullUserCache;
  59. public abstract class AbstractJcrBackedUserRoleDao implements IUserRoleDao {
  60. NameFactory NF = NameFactoryImpl.getInstance();
  61. Name P_PRINCIPAL_NAME = NF.create(Name.NS_REP_URI, "principalName"); //$NON-NLS-1$
  62. protected ITenantedPrincipleNameResolver tenantedUserNameUtils;
  63. protected ITenantedPrincipleNameResolver tenantedRoleNameUtils;
  64. String pPrincipalName = "rep:principalName"; //$NON-NLS-1$
  65. IRepositoryFileAclDao repositoryFileAclDao;
  66. IRepositoryFileDao repositoryFileDao;
  67. String defaultTenant;
  68. String authenticatedRoleName;
  69. String tenantAdminRoleName;
  70. String repositoryAdminUsername;
  71. IPathConversionHelper pathConversionHelper;
  72. IRepositoryDefaultAclHandler defaultAclHandler;
  73. ILockHelper lockHelper;
  74. List<String> systemRoles;
  75. List<String> extraRoles;
  76. HashMap<String, UserManagerImpl> userMgrMap = new HashMap<String, UserManagerImpl>();
  77. private LRUMap userCache = new LRUMap(4096);
  78. private UserCache userDetailsCache = new NullUserCache();
  79. public AbstractJcrBackedUserRoleDao(ITenantedPrincipleNameResolver userNameUtils,
  80. ITenantedPrincipleNameResolver roleNameUtils, String authenticatedRoleName, String tenantAdminRoleName,
  81. String repositoryAdminUsername, IRepositoryFileAclDao repositoryFileAclDao, IRepositoryFileDao repositoryFileDao,
  82. final IPathConversionHelper pathConversionHelper, final ILockHelper lockHelper,
  83. final IRepositoryDefaultAclHandler defaultAclHandler, final List<String> systemRoles, final List<String> extraRoles, UserCache userDetailsCache) throws NamespaceException {
  84. this.tenantedUserNameUtils = userNameUtils;
  85. this.tenantedRoleNameUtils = roleNameUtils;
  86. this.authenticatedRoleName = authenticatedRoleName;
  87. this.tenantAdminRoleName = tenantAdminRoleName;
  88. this.repositoryAdminUsername = repositoryAdminUsername;
  89. this.repositoryFileAclDao = repositoryFileAclDao;
  90. this.repositoryFileDao = repositoryFileDao;
  91. this.pathConversionHelper = pathConversionHelper;
  92. this.lockHelper = lockHelper;
  93. this.defaultAclHandler = defaultAclHandler;
  94. this.systemRoles = systemRoles;
  95. this.extraRoles = extraRoles;
  96. this.userDetailsCache = userDetailsCache;
  97. }
  98. public void setRoleMembers(Session session, final ITenant theTenant, final String roleName,
  99. final String[] memberUserNames) throws RepositoryException, NotFoundException {
  100. List<IPentahoUser> currentRoleMembers = getRoleMembers(session, theTenant, roleName);
  101. if(tenantAdminRoleName.equals(roleName) && (currentRoleMembers != null && currentRoleMembers.size() > 0) && memberUserNames.length == 0) {
  102. throw new RepositoryException(Messages.getInstance().getString(
  103. "AbstractJcrBackedUserRoleDao.ERROR_0001_LAST_ADMIN_ROLE", tenantAdminRoleName));
  104. }
  105. Group jackrabbitGroup = getJackrabbitGroup(theTenant, roleName, session);
  106. if ((jackrabbitGroup == null)
  107. || !TenantUtils.isAccessibleTenant(theTenant == null ? tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID())
  108. : theTenant)) {
  109. throw new NotFoundException(Messages.getInstance().getString(
  110. "AbstractJcrBackedUserRoleDao.ERROR_0002_ROLE_NOT_FOUND"));
  111. }
  112. HashMap<String, User> currentlyAssignedUsers = new HashMap<String, User>();
  113. Iterator<Authorizable> currentMembers = jackrabbitGroup.getMembers();
  114. while (currentMembers.hasNext()) {
  115. Authorizable member = currentMembers.next();
  116. if (member instanceof User) {
  117. currentlyAssignedUsers.put(member.getID(), (User) member);
  118. }
  119. }
  120. HashMap<String, User> finalCollectionOfAssignedUsers = new HashMap<String, User>();
  121. if (memberUserNames != null) {
  122. ITenant tenant = theTenant == null ? JcrTenantUtils.getTenant(roleName, false) : theTenant;
  123. for (String user : memberUserNames) {
  124. User jackrabbitUser = getJackrabbitUser(tenant, user, session);
  125. if (jackrabbitUser != null) {
  126. finalCollectionOfAssignedUsers.put(tenantedRoleNameUtils.getPrincipleId(tenant, user), jackrabbitUser);
  127. }
  128. }
  129. }
  130. ArrayList<String> usersToRemove = new ArrayList<String>(currentlyAssignedUsers.keySet());
  131. usersToRemove.removeAll(finalCollectionOfAssignedUsers.keySet());
  132. ArrayList<String> usersToAdd = new ArrayList<String>(finalCollectionOfAssignedUsers.keySet());
  133. usersToAdd.removeAll(currentlyAssignedUsers.keySet());
  134. for (String userId : usersToRemove) {
  135. jackrabbitGroup.removeMember(currentlyAssignedUsers.get(userId));
  136. }
  137. for (String userId : usersToAdd) {
  138. jackrabbitGroup.addMember(finalCollectionOfAssignedUsers.get(userId));
  139. // Purge the UserDetails cache
  140. purgeUserFromCache(userId);
  141. }
  142. }
  143. private void setUserRolesForNewUser(Session session, final ITenant theTenant, final String userName,
  144. final String[] roles) throws RepositoryException, NotFoundException {
  145. Set<String> roleSet = new HashSet<String>();
  146. if (roles != null) {
  147. roleSet.addAll(Arrays.asList(roles));
  148. }
  149. roleSet.add(authenticatedRoleName);
  150. User jackrabbitUser = getJackrabbitUser(theTenant, userName, session);
  151. if ((jackrabbitUser == null)
  152. || !TenantUtils.isAccessibleTenant(theTenant == null ? tenantedUserNameUtils.getTenant(jackrabbitUser.getID())
  153. : theTenant)) {
  154. throw new NotFoundException(Messages.getInstance().getString(
  155. "AbstractJcrBackedUserRoleDao.ERROR_0003_USER_NOT_FOUND"));
  156. }
  157. HashMap<String, Group> finalCollectionOfAssignedGroups = new HashMap<String, Group>();
  158. ITenant tenant = theTenant == null ? JcrTenantUtils.getTenant(userName, true) : theTenant;
  159. for (String role : roleSet) {
  160. Group jackrabbitGroup = getJackrabbitGroup(tenant, role, session);
  161. if (jackrabbitGroup != null) {
  162. finalCollectionOfAssignedGroups.put(tenantedRoleNameUtils.getPrincipleId(tenant, role), jackrabbitGroup);
  163. }
  164. }
  165. ArrayList<String> groupsToAdd = new ArrayList<String>(finalCollectionOfAssignedGroups.keySet());
  166. for (String groupId : groupsToAdd) {
  167. finalCollectionOfAssignedGroups.get(groupId).addMember(jackrabbitUser);
  168. // Purge the UserDetails cache
  169. purgeUserFromCache(userName);
  170. }
  171. }
  172. private void purgeUserFromCache(String userName) {
  173. userDetailsCache.removeUserFromCache(getTenantedUserNameUtils().getPrincipleName(userName));
  174. }
  175. public void setUserRoles(Session session, final ITenant theTenant, final String userName, final String[] roles)
  176. throws RepositoryException, NotFoundException {
  177. if(hasAdminRole(getUserRoles(theTenant, userName)) && (roles.length == 0)) {
  178. throw new RepositoryException(Messages.getInstance().getString(
  179. "AbstractJcrBackedUserRoleDao.ERROR_0005_LAST_ADMIN_USER", userName));
  180. }
  181. Set<String> roleSet = new HashSet<String>();
  182. if (roles != null) {
  183. roleSet.addAll(Arrays.asList(roles));
  184. }
  185. roleSet.add(authenticatedRoleName);
  186. User jackrabbitUser = getJackrabbitUser(theTenant, userName, session);
  187. if ((jackrabbitUser == null)
  188. || !TenantUtils.isAccessibleTenant(theTenant == null ? tenantedUserNameUtils.getTenant(jackrabbitUser.getID())
  189. : theTenant)) {
  190. throw new NotFoundException(Messages.getInstance().getString(
  191. "AbstractJcrBackedUserRoleDao.ERROR_0003_USER_NOT_FOUND"));
  192. }
  193. HashMap<String, Group> currentlyAssignedGroups = new HashMap<String, Group>();
  194. Iterator<Group> currentGroups = jackrabbitUser.memberOf();
  195. while (currentGroups.hasNext()) {
  196. Group currentGroup = currentGroups.next();
  197. currentlyAssignedGroups.put(currentGroup.getID(), currentGroup);
  198. }
  199. HashMap<String, Group> finalCollectionOfAssignedGroups = new HashMap<String, Group>();
  200. ITenant tenant = theTenant == null ? JcrTenantUtils.getTenant(userName, true) : theTenant;
  201. for (String role : roleSet) {
  202. Group jackrabbitGroup = getJackrabbitGroup(tenant, role, session);
  203. if (jackrabbitGroup != null) {
  204. finalCollectionOfAssignedGroups.put(tenantedRoleNameUtils.getPrincipleId(tenant, role), jackrabbitGroup);
  205. }
  206. }
  207. ArrayList<String> groupsToRemove = new ArrayList<String>(currentlyAssignedGroups.keySet());
  208. groupsToRemove.removeAll(finalCollectionOfAssignedGroups.keySet());
  209. ArrayList<String> groupsToAdd = new ArrayList<String>(finalCollectionOfAssignedGroups.keySet());
  210. groupsToAdd.removeAll(currentlyAssignedGroups.keySet());
  211. for (String groupId : groupsToRemove) {
  212. currentlyAssignedGroups.get(groupId).removeMember(jackrabbitUser);
  213. }
  214. for (String groupId : groupsToAdd) {
  215. finalCollectionOfAssignedGroups.get(groupId).addMember(jackrabbitUser);
  216. }
  217. // Purge the UserDetails cache
  218. purgeUserFromCache(userName);
  219. }
  220. public IPentahoRole createRole(Session session, final ITenant theTenant, final String roleName,
  221. final String description, final String[] memberUserNames) throws AuthorizableExistsException, RepositoryException {
  222. ITenant tenant = theTenant;
  223. String role = roleName;
  224. if (tenant == null) {
  225. tenant = JcrTenantUtils.getTenant(roleName, false);
  226. role = JcrTenantUtils.getPrincipalName(roleName, false);
  227. }
  228. if (tenant == null || tenant.getId() == null) {
  229. tenant = JcrTenantUtils.getCurrentTenant();
  230. }
  231. if (!TenantUtils.isAccessibleTenant(tenant)) {
  232. throw new NotFoundException(Messages.getInstance().getString(
  233. "AbstractJcrBackedUserRoleDao.ERROR_0006_TENANT_NOT_FOUND", theTenant.getId()));
  234. }
  235. String roleId = tenantedRoleNameUtils.getPrincipleId(tenant, role);
  236. UserManager tenantUserMgr = getUserManager(tenant, session);
  237. // Intermediate path will always be an empty string. The path is already provided while creating a user manager
  238. tenantUserMgr.createGroup(new PrincipalImpl(roleId), ""); //$NON-NLS-1$
  239. setRoleMembers(session, tenant, role, memberUserNames);
  240. setRoleDescription(session, tenant, role, description);
  241. return getRole(session, theTenant, roleName);
  242. }
  243. public IPentahoUser createUser(Session session, final ITenant theTenant, final String userName,
  244. final String password, final String description, final String[] roles) throws AuthorizableExistsException,
  245. RepositoryException {
  246. ITenant tenant = theTenant;
  247. String user = userName;
  248. if (tenant == null) {
  249. tenant = JcrTenantUtils.getTenant(userName, true);
  250. user = JcrTenantUtils.getPrincipalName(userName, true);
  251. }
  252. if (tenant == null || tenant.getId() == null) {
  253. tenant = JcrTenantUtils.getCurrentTenant();
  254. }
  255. if (!TenantUtils.isAccessibleTenant(tenant)) {
  256. throw new NotFoundException(Messages.getInstance().getString(
  257. "AbstractJcrBackedUserRoleDao.ERROR_0006_TENANT_NOT_FOUND", theTenant.getId()));
  258. }
  259. String userId = tenantedUserNameUtils.getPrincipleId(tenant, user);
  260. UserManager tenantUserMgr = getUserManager(tenant, session);
  261. tenantUserMgr.createUser(userId, password, new PrincipalImpl(userId), ""); //$NON-NLS-1$
  262. session.save();
  263. /** This call is absolutely necessary. setUserRolesForNewUser will never
  264. ** inspect what roles this user is a part of. Since this is a new user
  265. ** it will not be a part of new roles
  266. **/
  267. setUserRolesForNewUser(session, tenant, user, roles);
  268. setUserDescription(session, tenant, user, description);
  269. session.save();
  270. createUserHomeFolder(tenant, user, session);
  271. session.save();
  272. this.userDetailsCache.removeUserFromCache(userName);
  273. return getUser(session, tenant, userName);
  274. }
  275. public void deleteRole(Session session, final IPentahoRole role) throws NotFoundException, RepositoryException {
  276. if(canDeleteRole(session, role)) {
  277. Group jackrabbitGroup = getJackrabbitGroup(role.getTenant(), role.getName(), session);
  278. if (jackrabbitGroup != null
  279. && TenantUtils.isAccessibleTenant(tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID()))) {
  280. jackrabbitGroup.remove();
  281. } else {
  282. throw new NotFoundException(""); //$NON-NLS-1$
  283. }
  284. } else {
  285. throw new RepositoryException(Messages.getInstance().getString(
  286. "AbstractJcrBackedUserRoleDao.ERROR_0007_ATTEMPTED_SYSTEM_ROLE_DELETE"));
  287. }
  288. }
  289. public void deleteUser(Session session, final IPentahoUser user) throws NotFoundException, RepositoryException {
  290. if(canDeleteUser(session, user)) {
  291. User jackrabbitUser = getJackrabbitUser(user.getTenant(), user.getUsername(), session);
  292. if (jackrabbitUser != null
  293. && TenantUtils.isAccessibleTenant(tenantedUserNameUtils.getTenant(jackrabbitUser.getID()))) {
  294. // [BISERVER-9215] Adding new user with same user name as a previously deleted user, defaults to all previous roles
  295. Iterator<Group> currentGroups = jackrabbitUser.memberOf();
  296. while (currentGroups.hasNext()) {
  297. currentGroups.next().removeMember(jackrabbitUser);
  298. }
  299. // [BISERVER-9215]
  300. jackrabbitUser.remove();
  301. } else {
  302. throw new NotFoundException(""); //$NON-NLS-1$
  303. }
  304. } else {
  305. throw new RepositoryException(Messages.getInstance().getString(
  306. "AbstractJcrBackedUserRoleDao.ERROR_0004_LAST_USER_NEEDED_IN_ROLE", tenantAdminRoleName));
  307. }
  308. }
  309. public List<IPentahoRole> getRoles(Session session) throws RepositoryException {
  310. return getRoles(session, JcrTenantUtils.getCurrentTenant());
  311. }
  312. private IPentahoUser convertToPentahoUser(User jackrabbitUser) throws RepositoryException {
  313. if(userCache.containsKey(jackrabbitUser.getID())){
  314. return (IPentahoUser) userCache.get(jackrabbitUser.getID());
  315. }
  316. IPentahoUser pentahoUser = null;
  317. Value[] propertyValues = null;
  318. String description = null;
  319. try {
  320. propertyValues = jackrabbitUser.getProperty("description"); //$NON-NLS-1$
  321. description = propertyValues.length > 0 ? propertyValues[0].getString() : null;
  322. } catch (Exception ex) {
  323. }
  324. Credentials credentials = jackrabbitUser.getCredentials();
  325. String password = null;
  326. if (credentials instanceof CryptedSimpleCredentials) {
  327. password = new String(((CryptedSimpleCredentials) credentials).getPassword());
  328. }
  329. pentahoUser = new PentahoUser(tenantedUserNameUtils.getTenant(jackrabbitUser.getID()),
  330. tenantedUserNameUtils.getPrincipleName(jackrabbitUser.getID()), password, description,
  331. !jackrabbitUser.isDisabled());
  332. userCache.put(jackrabbitUser.getID(), pentahoUser);
  333. return pentahoUser;
  334. }
  335. private IPentahoRole convertToPentahoRole(Group jackrabbitGroup) throws RepositoryException {
  336. IPentahoRole role = null;
  337. Value[] propertyValues = null;
  338. String description = null;
  339. try {
  340. propertyValues = jackrabbitGroup.getProperty("description"); //$NON-NLS-1$
  341. description = propertyValues.length > 0 ? propertyValues[0].getString() : null;
  342. } catch (Exception ex) {
  343. }
  344. role = new PentahoRole(tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID()),
  345. tenantedRoleNameUtils.getPrincipleName(jackrabbitGroup.getID()), description);
  346. return role;
  347. }
  348. public List<IPentahoUser> getUsers(Session session) throws RepositoryException {
  349. return getUsers(session, JcrTenantUtils.getCurrentTenant());
  350. }
  351. public void setRoleDescription(Session session, final ITenant theTenant, final String roleName,
  352. final String description) throws NotFoundException, RepositoryException {
  353. Group jackrabbitGroup = getJackrabbitGroup(theTenant, roleName, session);
  354. if (jackrabbitGroup != null
  355. && TenantUtils.isAccessibleTenant(theTenant == null ? tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID())
  356. : theTenant)) {
  357. if (description == null) {
  358. jackrabbitGroup.removeProperty("description"); //$NON-NLS-1$
  359. } else {
  360. jackrabbitGroup.setProperty("description", session.getValueFactory().createValue(description)); //$NON-NLS-1$
  361. }
  362. } else {
  363. throw new NotFoundException(Messages.getInstance().getString(
  364. "AbstractJcrBackedUserRoleDao.ERROR_0002_ROLE_NOT_FOUND"));
  365. }
  366. }
  367. public void setUserDescription(Session session, final ITenant theTenant, final String userName,
  368. final String description) throws NotFoundException, RepositoryException {
  369. User jackrabbitUser = getJackrabbitUser(theTenant, userName, session);
  370. if ((jackrabbitUser == null)
  371. || !TenantUtils.isAccessibleTenant(theTenant == null ? tenantedUserNameUtils.getTenant(jackrabbitUser.getID())
  372. : theTenant)) {
  373. throw new NotFoundException(Messages.getInstance().getString(
  374. "AbstractJcrBackedUserRoleDao.ERROR_0003_USER_NOT_FOUND"));
  375. }
  376. if (description == null) {
  377. jackrabbitUser.removeProperty("description"); //$NON-NLS-1$
  378. } else {
  379. jackrabbitUser.setProperty("description", session.getValueFactory().createValue(description)); //$NON-NLS-1$
  380. }
  381. }
  382. public void setPassword(Session session, final ITenant theTenant, final String userName, final String password)
  383. throws NotFoundException, RepositoryException {
  384. User jackrabbitUser = getJackrabbitUser(theTenant, userName, session);
  385. if ((jackrabbitUser == null)
  386. || !TenantUtils.isAccessibleTenant(theTenant == null ? tenantedUserNameUtils.getTenant(jackrabbitUser.getID())
  387. : theTenant)) {
  388. throw new NotFoundException(Messages.getInstance().getString(
  389. "AbstractJcrBackedUserRoleDao.ERROR_0003_USER_NOT_FOUND"));
  390. }
  391. jackrabbitUser.changePassword(password);
  392. /**
  393. * BISERVER-9906 Clear cache after changing password
  394. */
  395. purgeUserFromCache(userName);
  396. userCache.remove(jackrabbitUser.getID());
  397. }
  398. public ITenantedPrincipleNameResolver getTenantedUserNameUtils() {
  399. return tenantedUserNameUtils;
  400. }
  401. public ITenantedPrincipleNameResolver getTenantedRoleNameUtils() {
  402. return tenantedRoleNameUtils;
  403. }
  404. public List<IPentahoRole> getRoles(Session session, ITenant tenant) throws RepositoryException, NamespaceException {
  405. return getRoles(session, tenant, false);
  406. }
  407. public List<IPentahoRole> getRoles(Session session, final ITenant theTenant, boolean includeSubtenants)
  408. throws RepositoryException {
  409. ArrayList<IPentahoRole> roles = new ArrayList<IPentahoRole>();
  410. if (TenantUtils.isAccessibleTenant(theTenant)) {
  411. UserManager userMgr = getUserManager(theTenant, session);
  412. pPrincipalName = ((SessionImpl) session).getJCRName(P_PRINCIPAL_NAME);
  413. Iterator<Authorizable> it = userMgr.findAuthorizables(pPrincipalName, null, UserManager.SEARCH_TYPE_GROUP);
  414. while (it.hasNext()) {
  415. Group group = (Group) it.next();
  416. IPentahoRole pentahoRole = convertToPentahoRole(group);
  417. // Exclude the system role from the list of roles to be returned back
  418. if(!extraRoles.contains(pentahoRole.getName())) {
  419. if (includeSubtenants) {
  420. roles.add(pentahoRole);
  421. } else {
  422. if (pentahoRole.getTenant() != null && pentahoRole.getTenant().equals(theTenant)) {
  423. roles.add(pentahoRole);
  424. }
  425. }
  426. }
  427. }
  428. }
  429. return roles;
  430. }
  431. public List<IPentahoUser> getUsers(Session session, ITenant tenant) throws RepositoryException {
  432. return getUsers(session, tenant, false);
  433. }
  434. public List<IPentahoUser> getUsers(Session session, final ITenant theTenant, boolean includeSubtenants)
  435. throws RepositoryException {
  436. ArrayList<IPentahoUser> users = new ArrayList<IPentahoUser>();
  437. if (TenantUtils.isAccessibleTenant(theTenant)) {
  438. UserManager userMgr = getUserManager(theTenant, session);
  439. pPrincipalName = ((SessionImpl) session).getJCRName(P_PRINCIPAL_NAME);
  440. Iterator<Authorizable> it = userMgr.findAuthorizables(pPrincipalName, null, UserManager.SEARCH_TYPE_USER);
  441. while (it.hasNext()) {
  442. User user = (User) it.next();
  443. IPentahoUser pentahoUser = convertToPentahoUser(user);
  444. if (includeSubtenants) {
  445. users.add(pentahoUser);
  446. } else {
  447. if (pentahoUser.getTenant() != null && pentahoUser.getTenant().equals(theTenant)) {
  448. users.add(pentahoUser);
  449. }
  450. }
  451. }
  452. }
  453. return users;
  454. }
  455. public IPentahoRole getRole(Session session, final ITenant tenant, final String name) throws RepositoryException {
  456. Group jackrabbitGroup = getJackrabbitGroup(tenant, name, session);
  457. return jackrabbitGroup != null
  458. && TenantUtils.isAccessibleTenant(tenant == null ? tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID())
  459. : tenant) ? convertToPentahoRole(jackrabbitGroup) : null;
  460. }
  461. private UserManagerImpl getUserManager(ITenant theTenant, Session session) throws RepositoryException {
  462. Properties tenantProperties = new Properties();
  463. tenantProperties.put(UserManagerImpl.PARAM_USERS_PATH,
  464. UserManagerImpl.USERS_PATH + theTenant.getRootFolderAbsolutePath());
  465. tenantProperties.put(UserManagerImpl.PARAM_GROUPS_PATH,
  466. UserManagerImpl.GROUPS_PATH + theTenant.getRootFolderAbsolutePath());
  467. return new UserManagerImpl((SessionImpl) session, session.getUserID(), tenantProperties);
  468. }
  469. public IPentahoUser getUser(Session session, final ITenant tenant, final String name) throws RepositoryException {
  470. User jackrabbitUser = getJackrabbitUser(tenant, name, session);
  471. return jackrabbitUser != null
  472. && TenantUtils.isAccessibleTenant(tenant == null ? tenantedUserNameUtils.getTenant(jackrabbitUser.getID())
  473. : tenant) ? convertToPentahoUser(jackrabbitUser) : null;
  474. }
  475. private Group getJackrabbitGroup(ITenant theTenant, String name, Session session) throws RepositoryException {
  476. Group jackrabbitGroup = null;
  477. String roleId = name;
  478. String roleName = name;
  479. ITenant tenant = theTenant;
  480. if (tenant == null) {
  481. tenant = JcrTenantUtils.getTenant(roleName, false);
  482. roleName = JcrTenantUtils.getPrincipalName(roleName, false);
  483. }
  484. if (tenant == null || tenant.getId() == null) {
  485. tenant = JcrTenantUtils.getCurrentTenant();
  486. }
  487. if (tenant == null || tenant.getId() == null) {
  488. tenant = JcrTenantUtils.getDefaultTenant();
  489. }
  490. roleId = tenantedRoleNameUtils.getPrincipleId(tenant, roleName);
  491. UserManager userMgr = getUserManager(tenant, session);
  492. Authorizable authorizable = userMgr.getAuthorizable(roleId);
  493. if (authorizable instanceof Group) {
  494. jackrabbitGroup = (Group) authorizable;
  495. }
  496. return jackrabbitGroup;
  497. }
  498. private User getJackrabbitUser(ITenant theTenant, String name, Session session) throws RepositoryException {
  499. User jackrabbitUser = null;
  500. String userId = name;
  501. String userName = name;
  502. ITenant tenant = theTenant;
  503. if (tenant == null) {
  504. tenant = JcrTenantUtils.getTenant(userName, true);
  505. userName = JcrTenantUtils.getPrincipalName(userName, true);
  506. }
  507. if (tenant == null || tenant.getId() == null) {
  508. tenant = JcrTenantUtils.getCurrentTenant();
  509. }
  510. if (tenant == null || tenant.getId() == null) {
  511. tenant = JcrTenantUtils.getDefaultTenant();
  512. }
  513. if (tenant != null) {
  514. userId = tenantedUserNameUtils.getPrincipleId(tenant, userName);
  515. UserManager userMgr = getUserManager(tenant, session);
  516. Authorizable authorizable = userMgr.getAuthorizable(userId);
  517. if (authorizable instanceof User) {
  518. jackrabbitUser = (User) authorizable;
  519. }
  520. }
  521. return jackrabbitUser;
  522. }
  523. protected boolean tenantExists(String tenantName) {
  524. return tenantName != null && tenantName.trim().length() > 0;
  525. }
  526. public List<IPentahoUser> getRoleMembers(Session session, final ITenant theTenant, final String roleName)
  527. throws RepositoryException {
  528. List<IPentahoUser> users = new ArrayList<IPentahoUser>();
  529. Group jackrabbitGroup = getJackrabbitGroup(theTenant, roleName, session);
  530. if ((jackrabbitGroup != null)
  531. && TenantUtils.isAccessibleTenant(theTenant == null ? tenantedRoleNameUtils.getTenant(jackrabbitGroup.getID())
  532. : theTenant)) {
  533. Iterator<Authorizable> authorizables = jackrabbitGroup.getMembers();
  534. while (authorizables.hasNext()) {
  535. Authorizable authorizable = authorizables.next();
  536. if (authorizable instanceof User) {
  537. users.add(convertToPentahoUser((User) authorizable));
  538. }
  539. }
  540. }
  541. return users;
  542. }
  543. public List<IPentahoRole> getUserRoles(Session session, final ITenant theTenant, final String userName)
  544. throws RepositoryException {
  545. ArrayList<IPentahoRole> roles = new ArrayList<IPentahoRole>();
  546. User jackrabbitUser = getJackrabbitUser(theTenant, userName, session);
  547. if ((jackrabbitUser != null)
  548. && TenantUtils.isAccessibleTenant(theTenant == null ? tenantedUserNameUtils.getTenant(jackrabbitUser.getID())
  549. : theTenant)) {
  550. Iterator<Group> groups = jackrabbitUser.memberOf();
  551. while (groups.hasNext()) {
  552. IPentahoRole role = convertToPentahoRole(groups.next());
  553. // Exclude the extra role from the list of roles to be returned back
  554. if(!extraRoles.contains(role.getName())) {
  555. roles.add(role);
  556. }
  557. }
  558. }
  559. return roles;
  560. }
  561. private RepositoryFile createUserHomeFolder(ITenant theTenant, String username, Session session)
  562. throws RepositoryException {
  563. Builder aclsForUserHomeFolder = null;
  564. Builder aclsForTenantHomeFolder = null;
  565. if (theTenant == null) {
  566. theTenant = JcrTenantUtils.getTenant(username, true);
  567. username = JcrTenantUtils.getPrincipalName(username, true);
  568. }
  569. if (theTenant == null || theTenant.getId() == null) {
  570. theTenant = JcrTenantUtils.getCurrentTenant();
  571. }
  572. if (theTenant == null || theTenant.getId() == null) {
  573. theTenant = JcrTenantUtils.getDefaultTenant();
  574. }
  575. RepositoryFile userHomeFolder = null;
  576. String userId = tenantedUserNameUtils.getPrincipleId(theTenant, username);
  577. final RepositoryFileSid userSid = new RepositoryFileSid(userId);
  578. RepositoryFile tenantHomeFolder = null;
  579. RepositoryFile tenantRootFolder = null;
  580. RepositoryFileSid ownerSid = null;
  581. // Get the Tenant Root folder. If the Tenant Root folder does not exist then exit.
  582. tenantRootFolder = JcrRepositoryFileUtils.getFileByAbsolutePath(session,
  583. ServerRepositoryPaths.getTenantRootFolderPath(theTenant), pathConversionHelper, lockHelper, false, null);
  584. if (tenantRootFolder != null) {
  585. // Try to see if Tenant Home folder exist
  586. tenantHomeFolder = JcrRepositoryFileUtils.getFileByAbsolutePath(session,
  587. ServerRepositoryPaths.getTenantHomeFolderPath(theTenant), pathConversionHelper, lockHelper, false, null);
  588. if (tenantHomeFolder == null) {
  589. String ownerId = tenantedUserNameUtils.getPrincipleId(theTenant, username);
  590. ownerSid = new RepositoryFileSid(ownerId, Type.USER);
  591. String tenantAuthenticatedRoleId = tenantedRoleNameUtils.getPrincipleId(theTenant, authenticatedRoleName);
  592. RepositoryFileSid tenantAuthenticatedRoleSid = new RepositoryFileSid(tenantAuthenticatedRoleId, Type.ROLE);
  593. aclsForTenantHomeFolder = new RepositoryFileAcl.Builder(userSid).ace(tenantAuthenticatedRoleSid,
  594. EnumSet.of(RepositoryFilePermission.READ));
  595. aclsForUserHomeFolder = new RepositoryFileAcl.Builder(userSid).ace(ownerSid,
  596. EnumSet.of(RepositoryFilePermission.ALL));
  597. tenantHomeFolder = internalCreateFolder(session, tenantRootFolder.getId(), new RepositoryFile.Builder(
  598. ServerRepositoryPaths.getTenantHomeFolderName()).folder(true).title(Messages.getInstance().getString("AbstractJcrBackedUserRoleDao.usersFolderDisplayName")).build(), aclsForTenantHomeFolder.build(),
  599. "tenant home folder"); //$NON-NLS-1$
  600. } else {
  601. String ownerId = tenantedUserNameUtils.getPrincipleId(theTenant, username);
  602. ownerSid = new RepositoryFileSid(ownerId, Type.USER);
  603. aclsForUserHomeFolder = new RepositoryFileAcl.Builder(userSid).ace(ownerSid,
  604. EnumSet.of(RepositoryFilePermission.ALL));
  605. }
  606. // now check if user's home folder exist
  607. userHomeFolder = JcrRepositoryFileUtils.getFileByAbsolutePath(session,
  608. ServerRepositoryPaths.getUserHomeFolderPath(theTenant, username), pathConversionHelper, lockHelper, false,
  609. null);
  610. if (userHomeFolder == null) {
  611. userHomeFolder = internalCreateFolder(session, tenantHomeFolder.getId(), new RepositoryFile.Builder(username)
  612. .folder(true).build(), aclsForUserHomeFolder.build(), "user home folder"); //$NON-NLS-1$
  613. }
  614. }
  615. return userHomeFolder;
  616. }
  617. private RepositoryFile internalCreateFolder(final Session session, final Serializable parentFolderId,
  618. final RepositoryFile folder, final RepositoryFileAcl acl, final String versionMessage) throws RepositoryException {
  619. PentahoJcrConstants pentahoJcrConstants = new PentahoJcrConstants(session);
  620. JcrRepositoryFileUtils.checkoutNearestVersionableFileIfNecessary(session, pentahoJcrConstants, parentFolderId);
  621. Node folderNode = JcrRepositoryFileUtils.createFolderNode(session, pentahoJcrConstants, parentFolderId, folder);
  622. // we must create the acl during checkout
  623. JcrRepositoryFileAclUtils.createAcl(session, pentahoJcrConstants, folderNode.getIdentifier(),
  624. acl == null ? defaultAclHandler.createDefaultAcl(folder) : acl);
  625. session.save();
  626. if (folder.isVersioned()) {
  627. JcrRepositoryFileUtils.checkinNearestVersionableNodeIfNecessary(session, pentahoJcrConstants, folderNode,
  628. versionMessage);
  629. }
  630. JcrRepositoryFileUtils
  631. .checkinNearestVersionableFileIfNecessary(
  632. session,
  633. pentahoJcrConstants,
  634. parentFolderId,
  635. Messages
  636. .getInstance()
  637. .getString(
  638. "JcrRepositoryFileDao.USER_0001_VER_COMMENT_ADD_FOLDER", folder.getName(), (parentFolderId == null ? "root" : parentFolderId.toString()))); //$NON-NLS-1$ //$NON-NLS-2$
  639. return JcrRepositoryFileUtils
  640. .nodeToFile(session, pentahoJcrConstants, pathConversionHelper, lockHelper, folderNode);
  641. }
  642. /**
  643. * Checks to see if the removal of the received roles and users would
  644. * cause the system to have no login associated with the Admin role.
  645. * This check is to be made before any changes take place
  646. * @param deleteRoles Roles to be deleted separated with | char
  647. * @param deleteUsers Users to be deleted separated with | char
  648. * @return Error message if invalid or null if ok
  649. * @throws RepositoryException
  650. */
  651. private boolean canDeleteUser(Session session, final IPentahoUser user) throws RepositoryException {
  652. boolean userHasAdminRole = false;
  653. List<IPentahoRole> roles = getUserRoles(null, user.getUsername());
  654. for(IPentahoRole role:roles) {
  655. if(tenantAdminRoleName.equals(role.getName())) {
  656. userHasAdminRole = true;
  657. break;
  658. }
  659. }
  660. if(userHasAdminRole) {
  661. List<IPentahoUser> usersWithAdminRole = getRoleMembers(session, null, tenantAdminRoleName);
  662. if(usersWithAdminRole != null) {
  663. } else {
  664. throw new RepositoryException(Messages.getInstance().getString(
  665. "AbstractJcrBackedUserRoleDao.ERROR_0004_LAST_USER_NEEDED_IN_ROLE", tenantAdminRoleName));
  666. }
  667. if(usersWithAdminRole.size() > 1) {
  668. return true;
  669. } else if(usersWithAdminRole.size() == 1) {
  670. return false;
  671. } else {
  672. throw new RepositoryException(Messages.getInstance().getString(
  673. "AbstractJcrBackedUserRoleDao.ERROR_0004_LAST_USER_NEEDED_IN_ROLE", tenantAdminRoleName));
  674. }
  675. }
  676. return true;
  677. }
  678. private boolean canDeleteRole(Session session, final IPentahoRole role) {
  679. return !(role != null && systemRoles.contains(role.getName()));
  680. }
  681. private boolean hasAdminRole(List<IPentahoRole> roles) {
  682. for(IPentahoRole role:roles) {
  683. if(tenantAdminRoleName.equals(role.getName())) {
  684. return true;
  685. }
  686. }
  687. return false;
  688. }
  689. private boolean hasAdminRole(String[] roles) {
  690. for(int i=0;i<roles.length;i++) {
  691. if(tenantAdminRoleName.equals(roles[i])) {
  692. return true;
  693. }
  694. }
  695. return false;
  696. }
  697. }