PageRenderTime 566ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/core/infinit.e.api.server/WEB-INF/src/com/ikanow/infinit/e/api/social/community/CommunityHandler.java

https://github.com/IKANOW/Infinit.e
Java | 1988 lines | 1426 code | 183 blank | 379 comment | 245 complexity | 838b344c1817509c644b8cc745689b9c MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*******************************************************************************
  2. * Copyright 2012, The Infinit.e Open Source Project.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. ******************************************************************************/
  16. package com.ikanow.infinit.e.api.social.community;
  17. import java.util.ArrayList;
  18. import java.util.Arrays;
  19. import java.util.Date;
  20. import java.util.HashMap;
  21. import java.util.HashSet;
  22. import java.util.Iterator;
  23. import java.util.Map;
  24. import java.util.Set;
  25. import java.util.List;
  26. import org.apache.log4j.Logger;
  27. import org.bson.types.ObjectId;
  28. import com.ikanow.infinit.e.api.config.source.SourceHandler;
  29. import com.ikanow.infinit.e.api.custom.mapreduce.CustomHandler;
  30. import com.ikanow.infinit.e.api.utils.SocialUtils;
  31. import com.ikanow.infinit.e.api.utils.PropertiesManager;
  32. import com.ikanow.infinit.e.api.utils.RESTTools;
  33. import com.ikanow.infinit.e.api.utils.SendMail;
  34. import com.ikanow.infinit.e.data_model.api.ApiManager;
  35. import com.ikanow.infinit.e.data_model.api.ResponsePojo;
  36. import com.ikanow.infinit.e.data_model.api.ResponsePojo.ResponseObject;
  37. import com.ikanow.infinit.e.data_model.api.social.community.CommunityApprovalPojo;
  38. import com.ikanow.infinit.e.data_model.api.social.community.CommunityPojoApiMap;
  39. import com.ikanow.infinit.e.data_model.store.DbManager;
  40. import com.ikanow.infinit.e.data_model.store.MongoDbManager;
  41. import com.ikanow.infinit.e.data_model.store.config.source.SourcePojo;
  42. import com.ikanow.infinit.e.data_model.store.custom.mapreduce.CustomMapReduceJobPojo;
  43. import com.ikanow.infinit.e.data_model.store.document.DocCountPojo;
  44. import com.ikanow.infinit.e.data_model.store.social.community.CommunityApprovePojo;
  45. import com.ikanow.infinit.e.data_model.store.social.community.CommunityAttributePojo;
  46. import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberContactPojo;
  47. import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberLinkPojo;
  48. import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberPojo;
  49. import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberUserAttributePojo;
  50. import com.ikanow.infinit.e.data_model.store.social.community.CommunityPojo;
  51. import com.ikanow.infinit.e.data_model.store.social.community.CommunityUserAttributePojo;
  52. import com.ikanow.infinit.e.data_model.store.social.person.PersonCommunityPojo;
  53. import com.ikanow.infinit.e.data_model.store.social.person.PersonContactPojo;
  54. import com.ikanow.infinit.e.data_model.store.social.person.PersonLinkPojo;
  55. import com.ikanow.infinit.e.data_model.store.social.person.PersonPojo;
  56. import com.ikanow.infinit.e.data_model.store.social.sharing.SharePojo;
  57. import com.ikanow.infinit.e.data_model.store.social.sharing.SharePojo.ShareCommunityPojo;
  58. import com.ikanow.infinit.e.data_model.store.social.sharing.SharePojo.ShareOwnerPojo;
  59. import com.ikanow.infinit.e.processing.generic.GenericProcessingController;
  60. import com.mongodb.BasicDBObject;
  61. import com.mongodb.DBCursor;
  62. import com.mongodb.DBObject;
  63. /**
  64. * This class is for all operations related to the retrieval, addition
  65. * or update of communities within the system
  66. */
  67. public class CommunityHandler
  68. {
  69. private static final Logger logger = Logger.getLogger(CommunityHandler.class);
  70. private SourceHandler sourceHandler = new SourceHandler();
  71. //////////////////////////////////////////////////////////////////////////
  72. //////////////////////// REST handlers ////////////////////////////////
  73. //////////////////////////////////////////////////////////////////////////
  74. /**
  75. * getCommunities (REST)
  76. * Returns information for all communities
  77. * @return
  78. */
  79. public ResponsePojo getCommunities(String userIdStr)
  80. {
  81. ResponsePojo rp = new ResponsePojo();
  82. /////////////////////////////////////////////////////////////////////////////////////////////////
  83. // Note: Only Sys Admins see all communities
  84. boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
  85. try
  86. {
  87. if (isSysAdmin)
  88. {
  89. DBCursor dbc = DbManager.getSocial().getCommunity().find();
  90. if ( dbc.count() > 0 )
  91. {
  92. List<CommunityPojo> communities = CommunityPojo.listFromDb(dbc, CommunityPojo.listType());
  93. filterCommunityMembers(communities, isSysAdmin, userIdStr);
  94. rp.setData(communities, new CommunityPojoApiMap());
  95. rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));
  96. }
  97. else
  98. {
  99. rp.setResponse(new ResponseObject("Community Info", true, "No communities returned"));
  100. }
  101. }
  102. else // Get all public communities and all private communities to which the user belongs
  103. {
  104. // Set up the query
  105. BasicDBObject queryTerm1 = new BasicDBObject("communityAttributes.isPublic.value", "true");
  106. BasicDBObject queryTerm2 = new BasicDBObject("members._id", new ObjectId(userIdStr));
  107. BasicDBObject queryTerm3 = new BasicDBObject("ownerId", new ObjectId(userIdStr));
  108. BasicDBObject query = new BasicDBObject(MongoDbManager.or_, Arrays.asList(queryTerm1, queryTerm2, queryTerm3));
  109. DBCursor dbc = DbManager.getSocial().getCommunity().find(query);
  110. if ( dbc.count() > 0 )
  111. {
  112. List<CommunityPojo> communities = CommunityPojo.listFromDb(dbc, CommunityPojo.listType());
  113. filterCommunityMembers(communities, isSysAdmin, userIdStr);
  114. //add personal community
  115. DBObject dbo = DbManager.getSocial().getCommunity().findOne(new BasicDBObject("_id",new ObjectId(userIdStr)));
  116. if ( dbo != null )
  117. {
  118. communities.add(CommunityPojo.fromDb(dbo, CommunityPojo.class));
  119. }
  120. rp.setData(communities, new CommunityPojoApiMap());
  121. rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));
  122. }
  123. else
  124. {
  125. rp.setResponse(new ResponseObject("Community Info", true, "No communities returned"));
  126. }
  127. }
  128. }
  129. catch (Exception e)
  130. {
  131. logger.error("Exception Message: " + e.getMessage(), e);
  132. rp.setResponse(new ResponseObject("Community Info", false, "error returning community info"));
  133. }
  134. return rp;
  135. }
  136. /**
  137. * getCommunities (REST)
  138. * Returns information for communities where isPublic = true/false
  139. * @param isPublic
  140. * @return
  141. */
  142. public ResponsePojo getCommunities(String userIdStr, Boolean isPublic)
  143. {
  144. ResponsePojo rp = new ResponsePojo();
  145. /////////////////////////////////////////////////////////////////////////////////////////////////
  146. // Note: Only Sys Admins see private communities
  147. boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
  148. try
  149. {
  150. // Set up the query
  151. BasicDBObject query = new BasicDBObject();
  152. query.put("communityAttributes.isPublic.value", isPublic.toString());
  153. if (!isPublic && !isSysAdmin)
  154. {
  155. //Add user ID to query so only get (private) communities of which I'm a member
  156. query.put("members._id", new ObjectId(userIdStr));
  157. }
  158. query.put("communityStatus", new BasicDBObject("$ne", "disabled"));
  159. DBCursor dbc = DbManager.getSocial().getCommunity().find(query);
  160. if ( dbc.count() > 0 )
  161. {
  162. List<CommunityPojo> communities = CommunityPojo.listFromDb(dbc, CommunityPojo.listType());
  163. filterCommunityMembers(communities, isSysAdmin, userIdStr);
  164. rp.setData(communities, new CommunityPojoApiMap());
  165. rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));
  166. }
  167. else
  168. {
  169. rp.setResponse(new ResponseObject("Community Info", true, "No communities returned"));
  170. }
  171. }
  172. catch (Exception e)
  173. {
  174. logger.error("Exception Message: " + e.getMessage(), e);
  175. rp.setResponse(new ResponseObject("Community Info", false, "error returning community info"));
  176. }
  177. return rp;
  178. }
  179. /**
  180. * getCommunity (REST)
  181. * Returns information for a single community
  182. * @param communityIdStr
  183. * @return
  184. */
  185. public ResponsePojo getCommunity(String userIdStr, String communityIdStr, boolean showDocInfo)
  186. {
  187. ResponsePojo rp = new ResponsePojo();
  188. try
  189. {
  190. // Set up the query
  191. BasicDBObject query = new BasicDBObject();
  192. if (communityIdStr != null)
  193. {
  194. communityIdStr = allowCommunityRegex(userIdStr, communityIdStr);
  195. query.put("_id", new ObjectId(communityIdStr));
  196. }
  197. else
  198. {
  199. query.put("_id", new ObjectId("4c927585d591d31d7b37097a")); // (hardwired sys community)
  200. }
  201. // Get GsonBuilder object with MongoDb de/serializers registered
  202. BasicDBObject dbo = (BasicDBObject)DbManager.getSocial().getCommunity().findOne(query);
  203. if (dbo != null)
  204. {
  205. CommunityPojo community = CommunityPojo.fromDb(dbo, CommunityPojo.class);
  206. if (showDocInfo) {
  207. DocCountPojo dc = (DocCountPojo) DbManager.getDocument().getCounts().findOne(query);
  208. if (null != dc) {
  209. dc.set_id(null);
  210. community.setDocumentInfo(dc);
  211. }
  212. }
  213. community = filterCommunityMembers(community, RESTTools.adminLookup(userIdStr), userIdStr);
  214. rp.setData(community, new CommunityPojoApiMap());
  215. rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));
  216. }
  217. else
  218. {
  219. rp.setResponse(new ResponseObject("Community Info", false, "Unable to return information for the community specified."));
  220. }
  221. }
  222. catch (Exception e)
  223. {
  224. //logger.error("Exception Message: " + e.getMessage(), e);
  225. rp.setResponse(new ResponseObject("Community Info", false, "Error returning community info: " + e.getMessage()));
  226. }
  227. return rp;
  228. }
  229. /**
  230. * getSystemCommunity (REST)
  231. * @return ResponsePojo
  232. */
  233. public ResponsePojo getSystemCommunity()
  234. {
  235. return getCommunity(null, null, false);
  236. }
  237. /**
  238. * addCommunity (REST)
  239. * Creates a new community
  240. * @param userIdStr
  241. * @param name
  242. * @param description
  243. * @param parentIdStr
  244. * @param parentName
  245. * @param tags
  246. * @param ownerId
  247. * @param ownerDisplayName
  248. * @return ResponsePojo
  249. */
  250. public ResponsePojo addCommunity(String userIdStr, String name, String description, String parentIdStr, String tags)
  251. {
  252. String userName = null;
  253. String userEmail = null;
  254. String parentName = null;
  255. try
  256. {
  257. DBObject dboperson = DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(userIdStr)));
  258. if ( dboperson != null )
  259. {
  260. PersonPojo person = PersonPojo.fromDb(dboperson, PersonPojo.class);
  261. userName = person.getDisplayName();
  262. userEmail = person.getEmail();
  263. // Parent Community is Optional
  264. if (parentIdStr != null)
  265. {
  266. try {
  267. DBObject dboparent = DbManager.getSocial().getCommunity().findOne(new BasicDBObject("_id", new ObjectId(parentIdStr)));
  268. if ( dboparent != null )
  269. {
  270. CommunityPojo cp = CommunityPojo.fromDb(dboparent, CommunityPojo.class);
  271. parentName = cp.getName();
  272. if (cp.getIsPersonalCommunity()) {
  273. return new ResponsePojo(new ResponseObject("Add Community", false, "Can't create sub-community of personal community"));
  274. }//TESTED
  275. if ((null == cp.getCommunityStatus()) || !cp.getCommunityStatus().equalsIgnoreCase("active")) {
  276. return new ResponsePojo(new ResponseObject("Add Community", false, "Can't create sub-community of inactive community"));
  277. }//TESTED
  278. // Check attributes
  279. if (null != cp.getCommunityAttributes()) {
  280. CommunityAttributePojo attr = cp .getCommunityAttributes().get("usersCanCreateSubCommunities");
  281. if ((null == attr) || (null== attr.getValue()) || (attr.getValue().equals("false"))) {
  282. if (!cp.isOwner(person.get_id()) && !SocialUtils.isModerator(userIdStr, cp) && !RESTTools.adminLookup(userIdStr)) {
  283. return new ResponsePojo(new ResponseObject("Add Community", false, "Can't create sub-community when not permitted by parent"));
  284. }//TESTED (owner+admin+mod)
  285. }
  286. }
  287. }//TESTED - different restrictions as above
  288. else
  289. {
  290. return new ResponsePojo(new ResponseObject("Add Community", false, "Parent community does not exist"));
  291. }//TESTED
  292. }
  293. catch (Exception e) {
  294. return new ResponsePojo(new ResponseObject("Add Community", false, "Invalid parent community id"));
  295. }//TESTED
  296. }
  297. }
  298. else
  299. {
  300. return new ResponsePojo(new ResponseObject("Add Community", false, "Error: Unable to get person record"));
  301. }
  302. }
  303. catch (Exception ex)
  304. {
  305. return new ResponsePojo(new ResponseObject("Add Community", false, "General Error: " + ex.getMessage()));
  306. }
  307. return addCommunity(userIdStr, name, description, parentIdStr, parentName, tags, userIdStr, userName, userEmail);
  308. }
  309. /**
  310. * addCommunity (REST)
  311. * Creates a new community by id (alternate)
  312. */
  313. private ResponsePojo addCommunity(String userIdStr, String name, String description,
  314. String parentIdStr, String parentName, String tags, String ownerIdStr,
  315. String ownerDisplayName, String ownerEmail)
  316. {
  317. return addCommunity(userIdStr, null, name, description, parentIdStr, parentName, tags,
  318. ownerIdStr, ownerDisplayName, ownerEmail);
  319. }
  320. public ResponsePojo addCommunity(String userId, String idStr, String name, String description,
  321. String parentIdStr, String parentName, String tags, String ownerIdStr,
  322. String ownerDisplayName, String ownerEmail)
  323. {
  324. ResponsePojo rp = new ResponsePojo();
  325. try
  326. {
  327. // Check to see if a community exists already with the supplied name or ID
  328. // do not create new one if true -
  329. // TODO (INF-1214): Think about need for unique names - proposed:
  330. // Community names unique per parent community
  331. BasicDBObject query = new BasicDBObject();
  332. if (idStr == null)
  333. {
  334. query.put("name", name);
  335. }
  336. else
  337. {
  338. query.put("_id", new ObjectId(idStr));
  339. }
  340. DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
  341. if (dbo == null)
  342. {
  343. ObjectId oId = null;
  344. if (idStr == null)
  345. {
  346. oId = new ObjectId();
  347. }
  348. else
  349. {
  350. oId = new ObjectId(idStr);
  351. }
  352. CommunityPojo c = new CommunityPojo();
  353. c.setId(oId);
  354. c.setCreated(new Date());
  355. c.setModified(new Date());
  356. c.setName(name);
  357. c.setDescription(description);
  358. if (parentIdStr != null && parentName != null)
  359. {
  360. c.setParentId(new ObjectId(parentIdStr));
  361. c.setParentName(parentName);
  362. c = SocialUtils.createParentTreeRecursion(c, false);
  363. }
  364. c.setIsPersonalCommunity(false);
  365. c.setTags(getTagsFromString(tags));
  366. c.setOwnerId(new ObjectId(ownerIdStr));
  367. c.setOwnerDisplayName(ownerDisplayName);
  368. c.setNumberOfMembers(0);
  369. c.setCommunityAttributes(getDefaultCommunityAttributes());
  370. c.setCommunityUserAttribute(getDefaultCommunityUserAttributes());
  371. // Insert new community document in the community collection
  372. DBObject commObj = c.toDb();
  373. // Create the index form of the community:
  374. try {
  375. GenericProcessingController.createCommunityDocIndex(c.getId().toString(), c.getParentId(), c.getIsPersonalCommunity(), c.getIsSystemCommunity(), false);
  376. }
  377. catch (Exception e) { // Can't create community
  378. rp.setResponse(new ResponseObject("Add Community", false, "Error adding new community because of index failure: " + e.getMessage()));
  379. return rp;
  380. }
  381. //TESTED
  382. DbManager.getSocial().getCommunity().save(commObj);
  383. // If a child, update the parent:
  384. if (null != c.getParentId()) {
  385. BasicDBObject updateQuery = new BasicDBObject("_id", c.getParentId());
  386. BasicDBObject updateUpdate = new BasicDBObject(DbManager.addToSet_, new BasicDBObject("children", c.getId()));
  387. DbManager.getSocial().getCommunity().update(updateQuery, updateUpdate, false, true);
  388. }
  389. //TESTED
  390. // Update the new community record to add the owner to the list of members
  391. rp = addCommunityMember(userId, oId.toStringMongod(), name, ownerIdStr, ownerEmail, ownerDisplayName, "owner", "active");
  392. rp.setResponse(new ResponseObject("Add Community", true, "The " + name + " community has " +
  393. "been added."));
  394. }
  395. else
  396. {
  397. rp.setResponse(new ResponseObject("Add Community", false,
  398. "Error adding new community. A community with the name " + name + " " +
  399. "already exists."));
  400. }
  401. }
  402. catch (Exception e)
  403. {
  404. // If an exception occurs log the error
  405. logger.error("Exception Message: " + e.getMessage(), e);
  406. rp.setResponse(new ResponseObject("Add Community", false,
  407. "Error adding new community " + e.getMessage()));
  408. }
  409. return rp;
  410. }
  411. /**
  412. * removeCommunity (REST)
  413. * Remove communityid only if the personid is the owner
  414. * TODO (INF-1214): Remove users from the groups in both personpojo and communitypojo
  415. *
  416. * @param personIdStr
  417. * @param communityIdStr
  418. * @return
  419. */
  420. public ResponsePojo removeCommunity(String personIdStr, String communityIdStr)
  421. {
  422. boolean isSysAdmin = RESTTools.adminLookup(personIdStr);
  423. ResponsePojo rp = new ResponsePojo();
  424. try
  425. {
  426. ObjectId communityId = new ObjectId(communityIdStr);
  427. //get the communitypojo
  428. communityIdStr = allowCommunityRegex(personIdStr, communityIdStr);
  429. DBObject communitydbo = DbManager.getSocial().getCommunity().findOne(new BasicDBObject("_id",communityId));
  430. if ( communitydbo != null )
  431. {
  432. CommunityPojo cp = CommunityPojo.fromDb(communitydbo, CommunityPojo.class);
  433. //get the personpojo
  434. DBObject persondbo = DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id",new ObjectId(personIdStr)));
  435. if ( persondbo != null )
  436. {
  437. //PersonPojo pp = gson.fromJson(persondbo.toString(),PersonPojo.class);
  438. if ( !cp.getIsPersonalCommunity() )
  439. {
  440. if ( cp.isOwner(new ObjectId(personIdStr)) || isSysAdmin )
  441. {
  442. if (cp.getCommunityStatus().equals("disabled")) { // Delete for good, this is going to be ugly...
  443. if ((null != cp.getChildren()) && !cp.getChildren().isEmpty()) {
  444. rp.setResponse(new ResponseObject("Delete community", false, "Undeleted sub-communities exist, please delete them first"));
  445. return rp;
  446. }
  447. //TESTED
  448. // 1] Remove from all shares (delete shares if that leaves them orphaned)
  449. BasicDBObject deleteQuery1 = new BasicDBObject(ShareCommunityPojo.shareQuery_id_, communityId);
  450. BasicDBObject deleteFields1 = new BasicDBObject(SharePojo.communities_, 1);
  451. List<SharePojo> shares = SharePojo.listFromDb(DbManager.getSocial().getShare().find(deleteQuery1, deleteFields1), SharePojo.listType());
  452. for (SharePojo share: shares) {
  453. if (1 == share.getCommunities().size()) { // delete this share
  454. DbManager.getSocial().getShare().remove(new BasicDBObject(SharePojo._id_, share.get_id()));
  455. }
  456. }
  457. BasicDBObject update1 = new BasicDBObject(DbManager.pull_, new BasicDBObject(SharePojo.communities_,
  458. new BasicDBObject(ShareOwnerPojo._id_, communityId)));
  459. DbManager.getSocial().getShare().update(deleteQuery1, update1, false, true);
  460. //TESTED (both types)
  461. // 2] Remove from all sources (also delete the documents)
  462. // (In most cases this will leave the source orphaned, so delete it)
  463. BasicDBObject deleteQuery2 = new BasicDBObject(SourcePojo.communityIds_, communityId);
  464. BasicDBObject deleteFields2 = new BasicDBObject(SourcePojo.communityIds_, 1);
  465. List<SourcePojo> sources = SourcePojo.listFromDb(DbManager.getIngest().getSource().find(deleteQuery2, deleteFields2), SourcePojo.listType());
  466. List<SourcePojo> failedSources = new ArrayList<SourcePojo>();
  467. for (SourcePojo source: sources)
  468. {
  469. ResponsePojo rp1 = null;
  470. SourceHandler tmpHandler = new SourceHandler();
  471. if (1 == source.getCommunityIds().size()) { // delete this source
  472. rp1 = tmpHandler.deleteSource(source.getId().toString(), communityIdStr, personIdStr, false);
  473. // (deletes all docs and removes from the share)
  474. }
  475. else { // Still need to delete docs from this share from this community
  476. rp1 = tmpHandler.deleteSource(source.getId().toString(), communityIdStr, personIdStr, true);
  477. }
  478. if ( rp1 != null && !rp1.getResponse().isSuccess() )
  479. {
  480. failedSources.add(source);
  481. }
  482. }
  483. //if we have more than 1 failed source, bail out w/ error
  484. if (failedSources.size() > 0 )
  485. {
  486. StringBuilder sb = new StringBuilder();
  487. for ( SourcePojo source : failedSources )
  488. sb.append(source.getId().toString() + " ");
  489. rp.setResponse(new ResponseObject("Delete community", false, "Could not stop sources (they might be currently running): " + sb.toString()));
  490. return rp;
  491. }
  492. BasicDBObject update2 = new BasicDBObject(DbManager.pull_, new BasicDBObject(SourcePojo.communityIds_, communityId));
  493. DbManager.getSocial().getShare().update(deleteQuery2, update2, false, true);
  494. //TESTED (both types, check docs deleted)
  495. // 3] Remove from all map reduce jobs (delete any that it is only comm left on)
  496. String customJobsMessage = removeCommunityFromJobs(personIdStr, communityId);
  497. if ( customJobsMessage.length() > 0)
  498. {
  499. rp.setResponse(new ResponseObject("Delete community", false, "Could not stop all map reduce jobs (they might be currently running): " + customJobsMessage));
  500. return rp;
  501. }
  502. // 4] Finally delete the object itself
  503. DbManager.getSocial().getCommunity().remove(new BasicDBObject("_id", communityId));
  504. // Remove from index:
  505. GenericProcessingController.deleteCommunityDocIndex(communityId.toString(), cp.getParentId(), false);
  506. //TESTED
  507. // 5] Finally finally remove from parent communities
  508. if (null != cp.getParentId()) {
  509. BasicDBObject updateQuery = new BasicDBObject("_id", cp.getParentId());
  510. BasicDBObject updateUpdate = new BasicDBObject(DbManager.pull_, new BasicDBObject("children", cp.getId()));
  511. DbManager.getSocial().getCommunity().update(updateQuery, updateUpdate, false, true);
  512. }
  513. //TESTED
  514. rp.setResponse(new ResponseObject("Delete community", true, "Community deleted forever. " + customJobsMessage));
  515. }
  516. else { // First time, just remove all users and disable
  517. //at this point, we have verified, community/user exist, not a personal group, user is member and owner
  518. //set community as inactive (for some reason we don't delete it)
  519. DbManager.getSocial().getCommunity().update(new BasicDBObject("_id", communityId),
  520. new BasicDBObject(DbManager.set_, new BasicDBObject("communityStatus","disabled")));
  521. //remove all members
  522. for ( CommunityMemberPojo cmp : cp.getMembers())
  523. removeCommunityMember(personIdStr, communityIdStr, cmp.get_id().toString());
  524. rp.setResponse(new ResponseObject("Delete community", true, "Community disabled successfully - call delete again to remove for good, including all sources, shares, and documents"));
  525. }
  526. }
  527. else
  528. {
  529. rp.setResponse(new ResponseObject("Delete community", false, "You are not the owner of this community"));
  530. }
  531. }
  532. else
  533. {
  534. rp.setResponse(new ResponseObject("Delete community", false, "Cannot delete personal community."));
  535. }
  536. }
  537. else
  538. {
  539. rp.setResponse(new ResponseObject("Delete community", false, "Person ID was incorrect, no matching person found"));
  540. }
  541. }
  542. else
  543. {
  544. rp.setResponse(new ResponseObject("Delete community", false, "Community ID was incorrect, no matching commmunity found"));
  545. }
  546. }
  547. catch (Exception ex)
  548. {
  549. rp.setResponse(new ResponseObject("Delete community", false, "Error returning community info: " + ex.getMessage()));
  550. }
  551. return rp;
  552. }
  553. /**
  554. * Removes this community from any map reduce jobs, then deletes any jobs where it was the only community
  555. *
  556. * @param communityId
  557. * @return
  558. */
  559. private String removeCommunityFromJobs(String personIdStr, ObjectId communityId)
  560. {
  561. StringBuilder sb = new StringBuilder();
  562. List<CustomMapReduceJobPojo> failedToRemove = CustomHandler.removeCommunityJobs(communityId);
  563. //return a list of job ids
  564. for ( CustomMapReduceJobPojo cmr : failedToRemove )
  565. {
  566. sb.append(cmr.jobtitle + " ");
  567. }
  568. if ( sb.length() > 0 )
  569. {
  570. sb.insert(0, "These map reduce jobs could not be removed: " );
  571. }
  572. return sb.toString();
  573. }
  574. // (Note supports personId as either Id or username (email) both are unique indexes)
  575. /**
  576. * updateMemberStatus (REST)
  577. */
  578. public ResponsePojo updateMemberStatus(String callerIdStr, String personIdStr, String communityIdStr, String userStatus)
  579. {
  580. boolean isSysAdmin = RESTTools.adminLookup(callerIdStr);
  581. ResponsePojo rp = new ResponsePojo();
  582. try
  583. {
  584. communityIdStr = allowCommunityRegex(callerIdStr, communityIdStr);
  585. //verify user is in this community, then update status
  586. BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
  587. DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
  588. if ( dbo != null )
  589. {
  590. // PersonId can be _id or username/email
  591. BasicDBObject dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("email", personIdStr));
  592. if (null == dboPerson) { // (ie personId isn't an email address... convert to ObjectId and try again)
  593. dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(personIdStr)));
  594. }
  595. else {
  596. personIdStr = dboPerson.getString("_id");
  597. }
  598. // OK from here on, personId is the object Id...
  599. boolean bAuthorized = isSysAdmin || SocialUtils.isOwnerOrModerator(communityIdStr, callerIdStr);
  600. if (bAuthorized) {
  601. CommunityPojo cp = CommunityPojo.fromDb(dbo,CommunityPojo.class);
  602. ObjectId personId = new ObjectId(personIdStr);
  603. if ( cp.isOwner(personId) && !userStatus.equalsIgnoreCase("active")) {
  604. rp.setResponse(new ResponseObject("Update member status",false,"Can't change owner status, remove their ownership first"));
  605. return rp;
  606. }//TESTED (tried as owner+admin (failed both times), tested owner works fine if setting/keeping active)
  607. else if ( cp.isMember(personId) )
  608. {
  609. // Remove user:
  610. if (userStatus.equalsIgnoreCase("remove"))
  611. {
  612. //removeCommunityMember(callerIdStr, communityIdStr, personIdStr);
  613. rp = removeCommunityMember(callerIdStr, communityIdStr, personIdStr); //.setResponse(new ResponseObject("Update member status",true,"Member removed from community."));
  614. }
  615. else
  616. {
  617. //verified user, update status
  618. if ( cp.updateMemberStatus(personIdStr, userStatus) )
  619. {
  620. /////////////////////////////////////////////////////////////////////////////////////////////////
  621. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  622. // Caleb: this means change update to $set
  623. /////////////////////////////////////////////////////////////////////////////////////////////////
  624. DbManager.getSocial().getCommunity().update(query, cp.toDb());
  625. rp.setResponse(new ResponseObject("Update member status",true,"Updated member status successfully"));
  626. }
  627. else
  628. {
  629. rp.setResponse(new ResponseObject("Update member status",false,"Failed to update status"));
  630. }
  631. }
  632. }
  633. else
  634. {
  635. rp.setResponse(new ResponseObject("Update member status",false,"User was not a member of the community"));
  636. }
  637. }
  638. else
  639. {
  640. rp.setResponse(new ResponseObject("Update member status",false,"Caller must be admin, or a community owner or moderator"));
  641. }//TESTED - tried to update my status as member (failed), as admin (succeeded), as moderator (succeeded), as owner (succeeded)
  642. }
  643. else
  644. {
  645. rp.setResponse(new ResponseObject("Update member status",false,"Community does not exist"));
  646. }
  647. }
  648. catch(Exception ex)
  649. {
  650. rp.setResponse(new ResponseObject("Update member status",false,"General Error, bad params maybe? " + ex.getMessage()));
  651. }
  652. return rp;
  653. }//TESTED
  654. // (Note supports personId as either Id or username (email) both are unique indexes)
  655. /**
  656. * updateMemberType (REST)
  657. */
  658. public ResponsePojo updateMemberType(String callerIdStr, String personIdStr, String communityIdStr, String userType)
  659. {
  660. boolean isSysAdmin = RESTTools.adminLookup(callerIdStr);
  661. ResponsePojo rp = new ResponsePojo();
  662. try
  663. {
  664. if (!userType.equalsIgnoreCase("owner") && !userType.equalsIgnoreCase("moderator") && !userType.equalsIgnoreCase("member") && !userType.equalsIgnoreCase("content_publisher"))
  665. {
  666. rp.setResponse(new ResponseObject("Update member type",false,"Invalid user type: " + userType));
  667. return rp;
  668. }//TESTED - tested all the types work, hacked members.jsp to insert invalid type
  669. //verify user is in this community, then update status
  670. communityIdStr = allowCommunityRegex(callerIdStr, communityIdStr);
  671. BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
  672. DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
  673. if ( dbo != null )
  674. {
  675. // PersonId can be _id or username/email
  676. BasicDBObject dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("email", personIdStr));
  677. if (null == dboPerson) { // (ie personId isn't an email address... convert to ObjectId and try again)
  678. dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(personIdStr)));
  679. }
  680. else {
  681. personIdStr = dboPerson.getString("_id");
  682. }
  683. // OK from here on, personId is the object Id...
  684. CommunityPojo cp = CommunityPojo.fromDb(dbo,CommunityPojo.class);
  685. boolean bOwnershipChangeRequested = userType.equalsIgnoreCase("owner");
  686. boolean bAuthorized = isSysAdmin;
  687. if (!bAuthorized) {
  688. if (bOwnershipChangeRequested) { // must be owner or admin
  689. bAuthorized = cp.isOwner(new ObjectId(callerIdStr));
  690. }//TESTED - tried to update myself as moderator to owner (failed), gave up my community (succeeded), changed ownership as admin (FAILED)
  691. else { // Can also be moderator
  692. bAuthorized = SocialUtils.isOwnerOrModerator(communityIdStr, callerIdStr);
  693. }//TESTED - tried to update my role as member (failed), as admin->moderator (succeeded), as moderator (succeeded)
  694. }
  695. if (bAuthorized) // (see above)
  696. {
  697. if ( cp.isMember(new ObjectId(personIdStr)))
  698. {
  699. boolean bChangedMembership = false;
  700. boolean bChangedOwnership = !bOwnershipChangeRequested;
  701. ObjectId personId = new ObjectId(personIdStr);
  702. // Check that not trying to downgrade owner...
  703. if (cp.isOwner(personId) && !bOwnershipChangeRequested) {
  704. rp.setResponse(new ResponseObject("Update member type",false,"To change ownership, set new owner, will automatically downgrade existing owner to moderator"));
  705. return rp;
  706. }//TESTED
  707. String personDisplayName = null;
  708. //verified user, update status
  709. for ( CommunityMemberPojo cmp : cp.getMembers())
  710. {
  711. if ( cmp.get_id().equals(personId) )
  712. {
  713. cmp.setUserType(userType);
  714. personDisplayName = cmp.getDisplayName();
  715. bChangedMembership = true;
  716. if (bChangedOwnership) { // (includes case where didn't need to)
  717. break;
  718. }
  719. }//TESTED
  720. if (bOwnershipChangeRequested && cmp.get_id().equals(cp.getOwnerId())) {
  721. cmp.setUserType("moderator");
  722. bChangedOwnership = true;
  723. if (bChangedMembership) {
  724. break;
  725. }
  726. }//TESTED
  727. }
  728. if (bChangedMembership) {
  729. if (bOwnershipChangeRequested) {
  730. cp.setOwnerId(personId);
  731. cp.setOwnerDisplayName(personDisplayName);
  732. }//TESTED
  733. /////////////////////////////////////////////////////////////////////////////////////////////////
  734. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  735. // Caleb: this means change update to $set
  736. /////////////////////////////////////////////////////////////////////////////////////////////////
  737. DbManager.getSocial().getCommunity().update(query, cp.toDb());
  738. rp.setResponse(new ResponseObject("Update member type",true,"Updated member type successfully"));
  739. }//TESTED
  740. }
  741. else
  742. {
  743. rp.setResponse(new ResponseObject("Update member type",false,"User was not a member of the community"));
  744. }
  745. }
  746. else
  747. {
  748. rp.setResponse(new ResponseObject("Update member type",false,"Caller must be admin/owner/moderator (unless changing ownership)"));
  749. }
  750. }
  751. else
  752. {
  753. rp.setResponse(new ResponseObject("Update member type",false,"Community does not exist"));
  754. }
  755. }
  756. catch(Exception ex)
  757. {
  758. rp.setResponse(new ResponseObject("Update member type",false,"General Error, bad params maybe? " + ex.getMessage()));
  759. }
  760. return rp;
  761. }//TESTED (see sub-clauses for details)
  762. /**
  763. * joinCommunity (REST)
  764. */
  765. public ResponsePojo joinCommunity(String personIdStr, String communityIdStr)
  766. {
  767. boolean isSysAdmin = RESTTools.adminLookup(personIdStr);
  768. return joinCommunity(personIdStr, communityIdStr, isSysAdmin);
  769. }
  770. public ResponsePojo joinCommunity(String personIdStr, String communityIdStr, boolean isSysAdmin)
  771. {
  772. ResponsePojo rp = new ResponsePojo();
  773. try
  774. {
  775. communityIdStr = allowCommunityRegex(personIdStr, communityIdStr);
  776. BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
  777. DBObject dboComm = DbManager.getSocial().getCommunity().findOne(query);
  778. if ( dboComm != null )
  779. {
  780. CommunityPojo cp = CommunityPojo.fromDb(dboComm, CommunityPojo.class);
  781. if ( !cp.getIsPersonalCommunity() )
  782. {
  783. BasicDBObject queryPerson = new BasicDBObject("_id",new ObjectId(personIdStr));
  784. DBObject dboPerson = DbManager.getSocial().getPerson().findOne(queryPerson);
  785. PersonPojo pp = PersonPojo.fromDb(dboPerson,PersonPojo.class);
  786. boolean isPending = isMemberPending(cp, pp);
  787. if ( !cp.isMember(new ObjectId(personIdStr)) || isPending )
  788. {
  789. Map<String,CommunityAttributePojo> commatt = cp.getCommunityAttributes();
  790. if ( isSysAdmin || (commatt.containsKey("usersCanSelfRegister") && commatt.get("usersCanSelfRegister").getValue().equals("true") ))
  791. {
  792. boolean requiresApproval = false;
  793. if ( !isSysAdmin && commatt.containsKey("registrationRequiresApproval") )
  794. requiresApproval = commatt.get("registrationRequiresApproval").getValue().equals("true");
  795. //if approval is required, add user to comm, wait for owner to approve
  796. //otherwise go ahead and add as a member
  797. if ( requiresApproval )
  798. {
  799. cp.addMember(pp,true);
  800. //write both objects back to db now
  801. /////////////////////////////////////////////////////////////////////////////////////////////////
  802. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  803. // Caleb: this means change update to $set
  804. /////////////////////////////////////////////////////////////////////////////////////////////////
  805. DbManager.getSocial().getCommunity().update(query, cp.toDb());
  806. //send email out to owner for approval
  807. CommunityApprovePojo cap = cp.createCommunityApprove(personIdStr,communityIdStr,"join",personIdStr);
  808. DbManager.getSocial().getCommunityApprove().insert(cap.toDb());
  809. // Get to addresses for Owner and Moderators
  810. String toAddresses = getToAddressesFromCommunity(cp);
  811. PropertiesManager propManager = new PropertiesManager();
  812. String rootUrl = propManager.getUrlRoot();
  813. String subject = pp.getDisplayName() + " is trying to join infinit.e community: " + cp.getName();
  814. String body = pp.getDisplayName() + " is trying to join infinit.e community: " + cp.getName() + "<br/>Do you want to accept this request?" +
  815. "<br/><a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/true\">Accept</a> " +
  816. "<a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/false\">Deny</a>";
  817. SendMail mail = new SendMail(new PropertiesManager().getAdminEmailAddress(), toAddresses, subject, body);
  818. if (mail.send("text/html"))
  819. {
  820. rp.setResponse(new ResponseObject("Join Community",true,"Joined community successfully, awaiting owner approval"));
  821. rp.setData(new CommunityApprovalPojo(false));
  822. }
  823. else
  824. {
  825. rp.setResponse(new ResponseObject("Join Community",false,"The system was uable to send an email to the owner"));
  826. }
  827. }
  828. else
  829. {
  830. cp.addMember(pp);
  831. pp.addCommunity(cp);
  832. //write both objects back to db now
  833. /////////////////////////////////////////////////////////////////////////////////////////////////
  834. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  835. // Caleb: this means change update to $set
  836. /////////////////////////////////////////////////////////////////////////////////////////////////
  837. DbManager.getSocial().getCommunity().update(query, cp.toDb());
  838. DbManager.getSocial().getPerson().update(queryPerson, pp.toDb());
  839. rp.setResponse(new ResponseObject("Join Community",true,"Joined community successfully"));
  840. rp.setData(new CommunityApprovalPojo(true));
  841. }
  842. }
  843. else
  844. {
  845. rp.setResponse(new ResponseObject("Join Community",false,"You must be invited to this community"));
  846. }
  847. }
  848. else
  849. {
  850. rp.setResponse(new ResponseObject("Join Community",false,"You are already a member of this community"));
  851. }
  852. }
  853. else
  854. {
  855. rp.setResponse(new ResponseObject("Join Community",false,"Cannot add members to personal community"));
  856. }
  857. }
  858. else
  859. {
  860. rp.setResponse(new ResponseObject("Join Community",false,"Community does not exist"));
  861. }
  862. }
  863. catch(Exception ex)
  864. {
  865. rp.setResponse(new ResponseObject("Join Community",false,"General Error, bad params maybe? " + ex.getMessage()));
  866. }
  867. return rp;
  868. }
  869. /**
  870. * leaveCommunity (REST)
  871. */
  872. public ResponsePojo leaveCommunity(String personIdStr, String communityIdStr)
  873. {
  874. ResponsePojo rp = new ResponsePojo();
  875. try
  876. {
  877. communityIdStr = allowCommunityRegex(personIdStr, communityIdStr);
  878. BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
  879. DBObject dboComm = DbManager.getSocial().getCommunity().findOne(query);
  880. if ( dboComm != null )
  881. {
  882. CommunityPojo cp = CommunityPojo.fromDb(dboComm, CommunityPojo.class);
  883. if ( !cp.getIsPersonalCommunity())
  884. {
  885. BasicDBObject queryPerson = new BasicDBObject("_id",new ObjectId(personIdStr));
  886. DBObject dboPerson = DbManager.getSocial().getPerson().findOne(queryPerson);
  887. PersonPojo pp = PersonPojo.fromDb(dboPerson,PersonPojo.class);
  888. cp.removeMember(new ObjectId(personIdStr));
  889. pp.removeCommunity(cp);
  890. //write both objects back to db now
  891. /////////////////////////////////////////////////////////////////////////////////////////////////
  892. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  893. // Caleb: this means change update to $set
  894. /////////////////////////////////////////////////////////////////////////////////////////////////
  895. DbManager.getSocial().getCommunity().update(query, cp.toDb());
  896. DbManager.getSocial().getPerson().update(queryPerson, pp.toDb());
  897. rp.setResponse(new ResponseObject("Leave Community",true,"Left community successfully"));
  898. }
  899. else
  900. {
  901. rp.setResponse(new ResponseObject("Leave Community",false,"Cannot leave personal community"));
  902. }
  903. }
  904. else
  905. {
  906. rp.setResponse(new ResponseObject("Leave Community",false,"Community does not exist"));
  907. }
  908. }
  909. catch(Exception ex)
  910. {
  911. rp.setResponse(new ResponseObject("Leave Community",false,"General Error, bad params maybe? " + ex.getMessage()));
  912. }
  913. return rp;
  914. }
  915. /**
  916. * inviteCommunity (REST)
  917. * Invite a user to a community, only add them as pending to community
  918. * and do not add community into the person object yet
  919. * Need to send email out
  920. // (Note supports personId as either Id or username (email) both are unique indexes)
  921. * @param personIdStr
  922. * @param userIdStr
  923. * @param communityIdStr
  924. * @return
  925. */
  926. public ResponsePojo inviteCommunity(String userIdStr, String personIdStr, String communityIdStr, String skipInvitation)
  927. {
  928. ResponsePojo rp = new ResponsePojo();
  929. try {
  930. communityIdStr = allowCommunityRegex(userIdStr, communityIdStr);
  931. }
  932. catch (Exception e) {
  933. rp.setResponse(new ResponseObject("Invite Community", false, "Error returning community info: " + e.getMessage()));
  934. return rp;
  935. }
  936. boolean skipInvite = ((null != skipInvitation) && (skipInvitation.equalsIgnoreCase("true"))) ? true : false;
  937. /////////////////////////////////////////////////////////////////////////////////////////////////
  938. // Note: Only Sys Admins, Community Owner, and Community Moderators can invite users to
  939. // private communities however any member can be able to invite someone to a public community
  940. boolean isOwnerOrModerator = SocialUtils.isOwnerOrModerator(communityIdStr, userIdStr);
  941. boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
  942. boolean canInvite = (isOwnerOrModerator || isSysAdmin) ? true : false;
  943. try
  944. {
  945. BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
  946. DBObject dboComm = DbManager.getSocial().getCommunity().findOne(query);
  947. if ( dboComm != null )
  948. {
  949. CommunityPojo cp = CommunityPojo.fromDb(dboComm, CommunityPojo.class);
  950. // Make sure this isn't a personal community
  951. if ( !cp.getIsPersonalCommunity() )
  952. {
  953. // Check to see if the user has permissions to invite or selfregister
  954. boolean selfRegister = canSelfRegister(cp);
  955. if ( canInvite || cp.getOwnerId().toString().equalsIgnoreCase(userIdStr) || selfRegister )
  956. {
  957. BasicDBObject dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("email", personIdStr));
  958. if (null == dboPerson) { // (ie personId isn't an email address... convert to ObjectId and try again)
  959. dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(personIdStr)));
  960. }
  961. else {
  962. personIdStr = dboPerson.getString("_id");
  963. }
  964. // OK from here on, personId is the object Id...
  965. if ( dboPerson != null )
  966. {
  967. PersonPojo pp = PersonPojo.fromDb(dboPerson,PersonPojo.class);
  968. //need to check for if a person is pending, and skipInvite and isSysAdmin, otherwise
  969. //they would just get sent an email again, so leave it be
  970. boolean isPending = false;
  971. if ( isSysAdmin && skipInvite )
  972. {
  973. isPending = isMemberPending(cp, pp);
  974. }
  975. if ( selfRegister )
  976. {
  977. //If the comm allows for self registering, just call join community
  978. //instead of invite, it will handle registration
  979. return this.joinCommunity(pp.get_id().toString(), communityIdStr, isSysAdmin);
  980. }
  981. else if ( !cp.isMember(pp.get_id()) || isPending )
  982. {
  983. if (isSysAdmin && skipInvite) // Can only skip invite if user is Admin
  984. {
  985. // Update community with new member
  986. cp.addMember(pp, false); // Member status set to Active
  987. cp.setNumberOfMembers(cp.getNumberOfMembers() + 1); // Increment number of members
  988. /////////////////////////////////////////////////////////////////////////////////////////////////
  989. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  990. // Caleb: this means change update to $set
  991. /////////////////////////////////////////////////////////////////////////////////////////////////
  992. DbManager.getSocial().getCommunity().update(query, cp.toDb());
  993. // Add community to persons object and save to db
  994. pp.addCommunity(cp);
  995. /////////////////////////////////////////////////////////////////////////////////////////////////
  996. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  997. // Caleb: this means change update to $set
  998. /////////////////////////////////////////////////////////////////////////////////////////////////
  999. DbManager.getSocial().getPerson().update(new BasicDBObject("_id", pp.get_id()), pp.toDb());
  1000. rp.setResponse(new ResponseObject("Invite Community",true,"User added to community successfully."));
  1001. }
  1002. else
  1003. {
  1004. cp.addMember(pp, true); // Member status set to Pending
  1005. /////////////////////////////////////////////////////////////////////////////////////////////////
  1006. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  1007. // Caleb: this means change update to $set
  1008. /////////////////////////////////////////////////////////////////////////////////////////////////
  1009. DbManager.getSocial().getCommunity().update(query, cp.toDb());
  1010. //send email out inviting user
  1011. CommunityApprovePojo cap = cp.createCommunityApprove(personIdStr,communityIdStr,"invite",userIdStr);
  1012. DbManager.getSocial().getCommunityApprove().insert(cap.toDb());
  1013. PropertiesManager propManager = new PropertiesManager();
  1014. String rootUrl = propManager.getUrlRoot();
  1015. if (null == rootUrl) {
  1016. rp.setResponse(new ResponseObject("Invite Community",false,"The system was unable to email the invite because an invite was required and root.url is not set up."));
  1017. return rp;
  1018. }
  1019. String subject = "Invite to join infinit.e community: " + cp.getName();
  1020. String body = "You have been invited to join the community " + cp.getName() +
  1021. "<br/><a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/true\">Accept</a> " +
  1022. "<a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/false\">Deny</a>";
  1023. SendMail mail = new SendMail(new PropertiesManager().getAdminEmailAddress(), pp.getEmail(), subject, body);
  1024. if (mail.send("text/html"))
  1025. {
  1026. if (isSysAdmin) {
  1027. rp.setResponse(new ResponseObject("Invite Community",true,"Invited user to community successfully: " + cap.get_id().toString()));
  1028. }
  1029. else {
  1030. rp.setResponse(new ResponseObject("Invite Community",true,"Invited user to community successfully"));
  1031. }
  1032. }
  1033. else
  1034. {
  1035. rp.setResponse(new ResponseObject("Invite Community",false,"The system was unable to email the invite for an unknown reason (eg an invite was required and the mail server is not setup)."));
  1036. }
  1037. }
  1038. }
  1039. else
  1040. {
  1041. //otherwise just return we failed
  1042. rp.setResponse(new ResponseObject("Invite Community",false,"The user is already a member of this community."));
  1043. }
  1044. }
  1045. else
  1046. {
  1047. rp.setResponse(new ResponseObject("Invite Community",false,"Person does not exist"));
  1048. }
  1049. }
  1050. else
  1051. {
  1052. rp.setResponse(new ResponseObject("Invite Community",false,"You must be owner to invite other members, if you received an invite, you must accept it through that"));
  1053. }
  1054. }
  1055. else
  1056. {
  1057. rp.setResponse(new ResponseObject("Invite Community",false,"Cannot invite members to personal community"));
  1058. }
  1059. }
  1060. else
  1061. {
  1062. rp.setResponse(new ResponseObject("Invite Community",false,"Community does not exist"));
  1063. }
  1064. }
  1065. catch(Exception ex)
  1066. {
  1067. rp.setResponse(new ResponseObject("Invite Community",false,"General Error, bad params maybe? " + ex.getMessage()));
  1068. }
  1069. return rp;
  1070. }
  1071. /**
  1072. * Returns true if users can self register to this community
  1073. *
  1074. * @param cp
  1075. * @return
  1076. */
  1077. private boolean canSelfRegister(CommunityPojo cp)
  1078. {
  1079. if ( cp != null )
  1080. {
  1081. if ( cp.getCommunityAttributes().containsKey("usersCanSelfRegister") &&
  1082. cp.getCommunityAttributes().get("usersCanSelfRegister").getValue().equals("true"))
  1083. {
  1084. return true;
  1085. }
  1086. }
  1087. return false;
  1088. }
  1089. /**
  1090. * Returns true if the given member is pending in the given community
  1091. *
  1092. * @return
  1093. */
  1094. private boolean isMemberPending( CommunityPojo cp, PersonPojo pp)
  1095. {
  1096. for ( CommunityMemberPojo cmp : cp.getMembers() )
  1097. {
  1098. if ( cmp.get_id().equals(pp.get_id()) )
  1099. {
  1100. if ( cmp.getUserStatus().equals("pending") )
  1101. {
  1102. //found the user, and his status is pending
  1103. return true;
  1104. }
  1105. return false;
  1106. }
  1107. }
  1108. return false;
  1109. //TESTED only finds members that are pending while sysadmin
  1110. }
  1111. /**
  1112. * requestResponse (REST)
  1113. * @param requestIdStr
  1114. * @param resp
  1115. * @return
  1116. */
  1117. public ResponsePojo requestResponse(String requestIdStr, String resp)
  1118. {
  1119. ResponsePojo rp = new ResponsePojo();
  1120. try
  1121. {
  1122. // Check for valid text response value
  1123. if ( resp.equals("true") || resp.equals("false") )
  1124. {
  1125. // Attempt to retrieve the invite from the social.communityapprove collection
  1126. DBObject dbo = DbManager.getSocial().getCommunityApprove().findOne(new BasicDBObject("_id", new ObjectId(requestIdStr)));
  1127. if (dbo != null )
  1128. {
  1129. CommunityApprovePojo cap = CommunityApprovePojo.fromDb(dbo, CommunityApprovePojo.class);
  1130. if ( cap.getType().equals("source"))
  1131. {
  1132. //approving a source
  1133. if ( resp.equals("true"))
  1134. {
  1135. rp = sourceHandler.approveSource(cap.getSourceId(), cap.getCommunityId(), cap.getRequesterId());
  1136. }
  1137. else
  1138. {
  1139. rp = sourceHandler.denySource(cap.getSourceId(), cap.getCommunityId(), cap.getRequesterId());
  1140. }
  1141. if ( rp.getResponse().isSuccess() )
  1142. {
  1143. //remove request object now
  1144. DbManager.getSocial().getCommunityApprove().remove(new BasicDBObject("_id",new ObjectId(requestIdStr)));
  1145. }
  1146. }
  1147. else
  1148. {
  1149. //approving a user joining a community
  1150. BasicDBObject query = new BasicDBObject("_id",new ObjectId(cap.getCommunityId()));
  1151. DBObject dboComm = DbManager.getSocial().getCommunity().findOne(query);
  1152. //get user
  1153. BasicDBObject queryPerson = new BasicDBObject("_id",new ObjectId(cap.getPersonId()));
  1154. DBObject dboperson = DbManager.getSocial().getPerson().findOne(queryPerson);
  1155. PersonPojo pp = PersonPojo.fromDb(dboperson, PersonPojo.class);
  1156. if ( dboComm != null )
  1157. {
  1158. CommunityPojo cp = CommunityPojo.fromDb(dboComm, CommunityPojo.class);
  1159. boolean isStillPending = isMemberPending(cp, pp);
  1160. //make sure the user is still waiting to join the community, otherwise remove this request and return
  1161. if ( isStillPending )
  1162. {
  1163. if ( resp.equals("false"))
  1164. {
  1165. //if response is false (deny), always just remove user from community
  1166. cp.removeMember(new ObjectId(cap.getPersonId()));
  1167. /////////////////////////////////////////////////////////////////////////////////////////////////
  1168. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  1169. // Caleb: this means change update to $set
  1170. /////////////////////////////////////////////////////////////////////////////////////////////////
  1171. DbManager.getSocial().getCommunity().update(query, cp.toDb());
  1172. }
  1173. else
  1174. {
  1175. //if response is true (allow), always just add community info to user, and change status to active
  1176. if ( dboperson != null)
  1177. {
  1178. cp.updateMemberStatus(cap.getPersonId(), "active");
  1179. cp.setNumberOfMembers(cp.getNumberOfMembers()+1);
  1180. /////////////////////////////////////////////////////////////////////////////////////////////////
  1181. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  1182. // Caleb: this means change update to $set
  1183. /////////////////////////////////////////////////////////////////////////////////////////////////
  1184. DbManager.getSocial().getCommunity().update(query, cp.toDb());
  1185. pp.addCommunity(cp);
  1186. /////////////////////////////////////////////////////////////////////////////////////////////////
  1187. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  1188. // Caleb: this means change update to $set
  1189. /////////////////////////////////////////////////////////////////////////////////////////////////
  1190. DbManager.getSocial().getPerson().update(queryPerson, pp.toDb());
  1191. }
  1192. else
  1193. {
  1194. rp.setResponse(new ResponseObject("Request Response",false,"The person does not exist."));
  1195. }
  1196. }
  1197. //return successfully
  1198. rp.setResponse(new ResponseObject("Request Response",true,"Request answered successfully!"));
  1199. }
  1200. else
  1201. {
  1202. //return fail
  1203. rp.setResponse(new ResponseObject("Request Response",false,"Request has already been answered!"));
  1204. }
  1205. //remove request object now
  1206. DbManager.getSocial().getCommunityApprove().remove(new BasicDBObject("_id",new ObjectId(requestIdStr)));
  1207. }
  1208. else
  1209. {
  1210. rp.setResponse(new ResponseObject("Request Response",false,"The community does not exist."));
  1211. }
  1212. }
  1213. }
  1214. else
  1215. {
  1216. rp.setResponse(new ResponseObject("Request Response",false,"This request does not exist, possibly answered already?"));
  1217. }
  1218. }
  1219. else
  1220. {
  1221. rp.setResponse(new ResponseObject("Request Response",false,"Reponse must be true or false"));
  1222. }
  1223. }
  1224. catch(Exception ex)
  1225. {
  1226. rp.setResponse(new ResponseObject("Request Response",false,"General Error, bad params maybe?" + ex.getMessage()));
  1227. }
  1228. return rp;
  1229. }
  1230. /**
  1231. * updateCommunity (REST)
  1232. * Updates a community found with communityId with fields from updateItem (communitypojo in json form)
  1233. * Must be owner of communityId to update
  1234. * @param userIdStr
  1235. * @param communityIdStr
  1236. * @param json
  1237. * @return
  1238. */
  1239. public ResponsePojo updateCommunity(String userIdStr, String communityIdStr, String json)
  1240. {
  1241. ResponsePojo rp = new ResponsePojo();
  1242. try {
  1243. communityIdStr = allowCommunityRegex(userIdStr, communityIdStr);
  1244. }
  1245. catch (Exception e) {
  1246. rp.setResponse(new ResponseObject("Update Community", false, "Error returning community info: " + e.getMessage()));
  1247. return rp;
  1248. }
  1249. /////////////////////////////////////////////////////////////////////////////////////////////////
  1250. // Note: Only Sys Admins, Community Owner, and Community Moderators can add update communities
  1251. boolean isOwnerOrModerator = SocialUtils.isOwnerOrModerator(communityIdStr, userIdStr);
  1252. boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
  1253. boolean canUpdate = (isOwnerOrModerator || isSysAdmin) ? true : false;
  1254. if (!canUpdate)
  1255. {
  1256. rp.setResponse(new ResponseObject("Update Community",false,"User does not have permission to update the community."));
  1257. return rp;
  1258. }
  1259. /////////////////////////////////////////////////////////////////////////////////////////////////
  1260. // Attempt to parse the JSON passed in to a CommunityPojo
  1261. CommunityPojo updateCommunity = null;
  1262. try
  1263. {
  1264. updateCommunity = ApiManager.mapFromApi(json, CommunityPojo.class, new CommunityPojoApiMap());
  1265. }
  1266. catch (Exception ex)
  1267. {
  1268. rp.setResponse(new ResponseObject("Update Community",false,"Update json is badly formatted, could not deserialize."));
  1269. return rp;
  1270. }
  1271. try
  1272. {
  1273. // Retrieve community we are trying to update from the database
  1274. BasicDBObject query = new BasicDBObject("_id", new ObjectId(communityIdStr));
  1275. DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
  1276. String originalName = null;
  1277. if ( dbo != null )
  1278. {
  1279. CommunityPojo cp = CommunityPojo.fromDb(dbo, CommunityPojo.class);
  1280. if (null == cp) {
  1281. rp.setResponse(new ResponseObject("Update Community",false,"Community to update does not exist"));
  1282. return rp;
  1283. }
  1284. // Here are the fields you are allowed to change:
  1285. // name:
  1286. if (null != updateCommunity.getName())
  1287. {
  1288. // If you're changing name then ensure it's unique for consistency
  1289. //TODO (INF-1214): see addCommunity, this is currently something of a security hole
  1290. BasicDBObject nameCheck = new BasicDBObject("name", updateCommunity.getName());
  1291. nameCheck.put("_id", new BasicDBObject(MongoDbManager.ne_, cp.getId()));
  1292. if (null != MongoDbManager.getSocial().getCommunity().findOne(nameCheck)) {
  1293. rp.setResponse(new ResponseObject("Update Community",false,"Can't change name to an existing community"));
  1294. return rp;
  1295. }//TESTED (tested changing names of existing community works...)
  1296. originalName = cp.getName();
  1297. cp.setName(updateCommunity.getName());
  1298. }
  1299. if (null != updateCommunity.getDescription()) {
  1300. cp.setDescription(updateCommunity.getDescription());
  1301. }
  1302. if (null != updateCommunity.getTags()) {
  1303. cp.setTags(updateCommunity.getTags());
  1304. }
  1305. if ((null != updateCommunity.getCommunityAttributes() && !updateCommunity.getCommunityAttributes().isEmpty()))
  1306. {
  1307. cp.setCommunityAttributes(updateCommunity.getCommunityAttributes());
  1308. }
  1309. if ((null != updateCommunity.getCommunityUserAttribute() && !updateCommunity.getCommunityUserAttribute().isEmpty()))
  1310. {
  1311. cp.setCommunityUserAttribute(updateCommunity.getCommunityUserAttribute());
  1312. }
  1313. // Change owner: not allowed here, use community/update/status
  1314. if ((null != updateCommunity.getOwnerId()) && !updateCommunity.getOwnerId().equals(cp.getOwnerId()))
  1315. {
  1316. rp.setResponse(new ResponseObject("Update Community",false,"Use community/update/status to change ownership"));
  1317. return rp;
  1318. }//TESTED
  1319. DbManager.getSocial().getCommunity().update(query, cp.toDb());
  1320. // Community name has changed, member records need to be updated to reflect the name change
  1321. if (originalName != null)
  1322. {
  1323. DBObject query_person = new BasicDBObject("communities.name", originalName);
  1324. DBObject update_person = new BasicDBObject("$set",new BasicDBObject("communities.$.name", updateCommunity.getName()));
  1325. DbManager.getSocial().getPerson().update(query_person, update_person, false, true);
  1326. //Also need to update share community names to reflect the name change
  1327. DBObject query_share = new BasicDBObject("communities.name", originalName);
  1328. DBObject update_share = new BasicDBObject("$set",new BasicDBObject("communities.$.name", updateCommunity.getName()));
  1329. DbManager.getSocial().getShare().update(query_share, update_share, false, true);
  1330. }
  1331. /////////////////////////////////////////////////////////////////////////////////////////////////
  1332. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  1333. // propagate out to other records like Person
  1334. // caleb note: 1/7 (change this to use $set is what this means,
  1335. // including above DbManager.getSocial().getCommunity().update(query, cp.toDb()); )
  1336. // and the below unwritten communityuserattri
  1337. /////////////////////////////////////////////////////////////////////////////////////////////////
  1338. /////////////////////////////////////////////////////////////////////////////////////////////////
  1339. // Community.communityUserAttribute
  1340. // If user attributes have changed we might need to update member records...
  1341. rp.setResponse(new ResponseObject("Update Community", true, "Community updated successfully."));
  1342. }
  1343. else
  1344. {
  1345. rp.setResponse(new ResponseObject("Update Community",false,"Community does not exist"));
  1346. }
  1347. }
  1348. catch (Exception ex)
  1349. {
  1350. rp.setResponse(new ResponseObject("Update Community",false,"Unable to update community. Error:" + ex.getMessage()));
  1351. }
  1352. return rp;
  1353. }
  1354. //////////////////////////////////////////////////////////////////////////
  1355. //////////////////////// Helper Functions ////////////////////////////////
  1356. //////////////////////////////////////////////////////////////////////////
  1357. /**
  1358. * addCommunityMember (only called internally and by PersonHandler)
  1359. * @param communityIdStr
  1360. * @param personIdStr
  1361. * @param email
  1362. * @param displayName
  1363. * @param userType
  1364. * @param userStatus
  1365. * @return
  1366. */
  1367. private ResponsePojo addCommunityMember(String userIdStr, String communityIdStr, String communityName,
  1368. String personIdStr, String email, String displayName, String userType, String userStatus)
  1369. {
  1370. return addCommunityMember(userIdStr,communityIdStr,communityName,personIdStr,email,displayName,userType,userStatus,false);
  1371. }
  1372. public ResponsePojo addCommunityMember(String userIdStr, String communityIdStr, String communityName,
  1373. String personIdStr, String email, String displayName, String userType, String userStatus, boolean override)
  1374. {
  1375. /////////////////////////////////////////////////////////////////////////////////////////////////
  1376. // Note: Only Sys Admins, Community Owner, and Community Moderators can add users to communities
  1377. boolean isOwnerOrModerator = SocialUtils.isOwnerOrModerator(communityIdStr, userIdStr);
  1378. boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
  1379. boolean canAdd = (isOwnerOrModerator || isSysAdmin || override) ? true : false;
  1380. ResponsePojo rp = new ResponsePojo();
  1381. if (canAdd)
  1382. {
  1383. try
  1384. {
  1385. // Find person record to update
  1386. BasicDBObject query = new BasicDBObject();
  1387. query.put("_id", new ObjectId(communityIdStr));
  1388. DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
  1389. if (dbo != null)
  1390. {
  1391. // Get GsonBuilder object with MongoDb de/serializers registered
  1392. CommunityPojo community = CommunityPojo.fromDb(dbo, CommunityPojo.class);
  1393. // Get the list of existing members, check to see if user is already
  1394. // a member of the community, make sure CommunityMember obj isn't null/empty
  1395. Boolean alreadyMember = false;
  1396. Set<CommunityMemberPojo> cmps = null;
  1397. if (community.getMembers() != null)
  1398. {
  1399. cmps = community.getMembers();
  1400. for (CommunityMemberPojo c : cmps)
  1401. {
  1402. if (c.get_id().toStringMongod().equals(personIdStr)) alreadyMember = true;
  1403. }
  1404. }
  1405. else
  1406. {
  1407. cmps = new HashSet<CommunityMemberPojo>();
  1408. community.setMembers(cmps);
  1409. }
  1410. if (!alreadyMember)
  1411. {
  1412. // Note: This changes community owner
  1413. if (userType.equals("owner"))
  1414. {
  1415. community.setOwnerId(new ObjectId(personIdStr));
  1416. community.setOwnerDisplayName(displayName);
  1417. }
  1418. // Create the new member object
  1419. CommunityMemberPojo cmp = new CommunityMemberPojo();
  1420. cmp.set_id(new ObjectId(personIdStr));
  1421. cmp.setEmail(email);
  1422. cmp.setDisplayName(displayName);
  1423. cmp.setUserStatus(userStatus);
  1424. cmp.setUserType(userType);
  1425. // Set the userAttributes based on default
  1426. Set<CommunityMemberUserAttributePojo> cmua = new HashSet<CommunityMemberUserAttributePojo>();
  1427. Map<String,CommunityUserAttributePojo> cua = community.getCommunityUserAttribute();
  1428. Iterator<Map.Entry<String,CommunityUserAttributePojo>> it = cua.entrySet().iterator();
  1429. while (it.hasNext())
  1430. {
  1431. CommunityMemberUserAttributePojo c = new CommunityMemberUserAttributePojo();
  1432. Map.Entry<String,CommunityUserAttributePojo> pair = it.next();
  1433. c.setType(pair.getKey().toString());
  1434. CommunityUserAttributePojo v = (CommunityUserAttributePojo)pair.getValue();
  1435. c.setValue(v.getDefaultValue());
  1436. cmua.add(c);
  1437. }
  1438. cmp.setUserAttributes(cmua);
  1439. // Get Person data to added to member record
  1440. BasicDBObject query2 = new BasicDBObject();
  1441. query2.put("_id", new ObjectId(personIdStr));
  1442. DBObject dbo2 = DbManager.getSocial().getPerson().findOne(query2);
  1443. PersonPojo p = PersonPojo.fromDb(dbo2, PersonPojo.class);
  1444. if (p.getContacts() != null)
  1445. {
  1446. // Set contacts from person record
  1447. Set<CommunityMemberContactPojo> contacts = new HashSet<CommunityMemberContactPojo>();
  1448. Map<String, PersonContactPojo> pcp = p.getContacts();
  1449. Iterator<Map.Entry<String, PersonContactPojo>> it2 = pcp.entrySet().iterator();
  1450. while (it2.hasNext())
  1451. {
  1452. CommunityMemberContactPojo c = new CommunityMemberContactPojo();
  1453. Map.Entry<String, PersonContactPojo> pair = it2.next();
  1454. c.setType(pair.getKey().toString());
  1455. PersonContactPojo v = (PersonContactPojo)pair.getValue();
  1456. c.setValue(v.getValue());
  1457. contacts.add(c);
  1458. }
  1459. cmp.setContacts(contacts);
  1460. }
  1461. // Set links from person record
  1462. if (p.getLinks() != null)
  1463. {
  1464. // Set contacts from person record
  1465. Set<CommunityMemberLinkPojo> links = new HashSet<CommunityMemberLinkPojo>();
  1466. Map<String, PersonLinkPojo> plp = p.getLinks();
  1467. Iterator<Map.Entry<String, PersonLinkPojo>> it3 = plp.entrySet().iterator();
  1468. while (it.hasNext())
  1469. {
  1470. CommunityMemberLinkPojo c = new CommunityMemberLinkPojo();
  1471. Map.Entry<String, PersonLinkPojo> pair = it3.next();
  1472. c.setTitle(pair.getKey().toString());
  1473. PersonLinkPojo v = (PersonLinkPojo)pair.getValue();
  1474. c.setUrl(v.getUrl());
  1475. links.add(c);
  1476. }
  1477. cmp.setLinks(links);
  1478. }
  1479. // Add new member object to the set
  1480. cmps.add(cmp);
  1481. // Increment number of members by 1
  1482. community.setNumberOfMembers(community.getNumberOfMembers() + 1);
  1483. /////////////////////////////////////////////////////////////////////////////////////////////////
  1484. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  1485. // Caleb: this means change update to $set
  1486. /////////////////////////////////////////////////////////////////////////////////////////////////
  1487. DbManager.getSocial().getCommunity().update(query, community.toDb());
  1488. PersonHandler person = new PersonHandler();
  1489. person.addCommunity(personIdStr, communityIdStr, communityName);
  1490. rp.setData(community, new CommunityPojoApiMap());
  1491. rp.setResponse(new ResponseObject("Add member to community", true, "Person has been added as member of community"));
  1492. }
  1493. else
  1494. {
  1495. rp.setResponse(new ResponseObject("Add member to community",true,"Person is already a member of the community."));
  1496. }
  1497. }
  1498. else
  1499. {
  1500. rp.setResponse(new ResponseObject("Add member to community", false, "Community not found."));
  1501. }
  1502. }
  1503. catch (Exception e)
  1504. {
  1505. // If an exception occurs log the error
  1506. logger.error("Exception Message: " + e.getMessage(), e);
  1507. rp.setResponse(new ResponseObject("Add member to community", false,
  1508. "Error adding member to community " + e.getMessage()));
  1509. }
  1510. }
  1511. else
  1512. {
  1513. rp.setResponse(new ResponseObject("Add member to community", false,
  1514. "The user does not have permissions to add a user to the community."));
  1515. }
  1516. return rp;
  1517. }
  1518. /**
  1519. * removeCommunityMember (only called internally and from PersonHandler)
  1520. * @param userIdStr
  1521. * @param communityIdStr
  1522. * @param personIdStr
  1523. * @return ResponsePojo
  1524. */
  1525. public ResponsePojo removeCommunityMember(String userIdStr, String communityIdStr, String personIdStr)
  1526. {
  1527. /////////////////////////////////////////////////////////////////////////////////////////////////
  1528. // Note: Only Sys Admins, Community Owner, and Community Moderators can remove users
  1529. boolean isOwnerOrModerator = SocialUtils.isOwnerOrModerator(communityIdStr, userIdStr);
  1530. boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
  1531. boolean canRemove = (isOwnerOrModerator || isSysAdmin) ? true : false;
  1532. ResponsePojo rp = new ResponsePojo();
  1533. if (canRemove)
  1534. {
  1535. try
  1536. {
  1537. // Find person record to update
  1538. BasicDBObject query = new BasicDBObject();
  1539. query.put("_id", new ObjectId(communityIdStr));
  1540. DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
  1541. if (dbo != null)
  1542. {
  1543. // Get GsonBuilder object with MongoDb de/serializers registered
  1544. CommunityPojo community = CommunityPojo.fromDb(dbo, CommunityPojo.class);
  1545. Boolean isMember = false;
  1546. Set<CommunityMemberPojo> cmps = null;
  1547. CommunityMemberPojo cmp = null;
  1548. if (community.getMembers() != null)
  1549. {
  1550. cmps = community.getMembers();
  1551. for (CommunityMemberPojo c : cmps)
  1552. {
  1553. if (c.get_id().toStringMongod().equals(personIdStr))
  1554. {
  1555. cmp = c;
  1556. isMember = true;
  1557. }
  1558. }
  1559. }
  1560. if (isMember)
  1561. {
  1562. cmps.remove(cmp);
  1563. community.setNumberOfMembers(community.getNumberOfMembers() - 1);
  1564. /////////////////////////////////////////////////////////////////////////////////////////////////
  1565. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  1566. // Caleb: this means change update to $set
  1567. /////////////////////////////////////////////////////////////////////////////////////////////////
  1568. DbManager.getSocial().getCommunity().update(query, community.toDb());
  1569. PersonHandler person = new PersonHandler();
  1570. person.removeCommunity(personIdStr, communityIdStr);
  1571. rp.setData(community, new CommunityPojoApiMap());
  1572. rp.setResponse(new ResponseObject("Remove member from community", true, "Member has been removed from community"));
  1573. }
  1574. else
  1575. {
  1576. rp.setResponse(new ResponseObject("Remove member from community",true,"Person is not a member of this community."));
  1577. }
  1578. }
  1579. else
  1580. {
  1581. rp.setResponse(new ResponseObject("Remove member from community", false, "Community not found."));
  1582. }
  1583. }
  1584. catch (Exception e)
  1585. {
  1586. // If an exception occurs log the error
  1587. logger.error("Exception Message: " + e.getMessage(), e);
  1588. rp.setResponse(new ResponseObject("Remove member from community", false,
  1589. "Error removing member from community " + e.getMessage()));
  1590. }
  1591. }
  1592. else
  1593. {
  1594. rp.setResponse(new ResponseObject("Remove member from community", false,
  1595. "The user does not have permissions to remove a user from the community."));
  1596. }
  1597. return rp;
  1598. }
  1599. /**
  1600. * createSelfCommunity
  1601. * Creates a personal group for the given user and adds them to it.
  1602. * @param person
  1603. */
  1604. public void createSelfCommunity(PersonPojo person)
  1605. {
  1606. try
  1607. {
  1608. //create community
  1609. CommunityPojo selfCommunity = new CommunityPojo();
  1610. selfCommunity.setId(person.get_id()); //set to same as users
  1611. selfCommunity.setName(person.getDisplayName() + "'s Personal Community");
  1612. selfCommunity.setDescription(person.getDisplayName() + "'s Personal Community");
  1613. selfCommunity.setCreated(new Date());
  1614. selfCommunity.setModified(new Date());
  1615. selfCommunity.setIsPersonalCommunity(true);
  1616. Map<String,CommunityAttributePojo> commAttributes = new HashMap<String,CommunityAttributePojo>();
  1617. commAttributes.put("isPublic", new CommunityAttributePojo("boolean","false") );
  1618. commAttributes.put("usersCanSelfRegister", new CommunityAttributePojo("boolean","false") );
  1619. commAttributes.put("registrationRequiresApproval", new CommunityAttributePojo("boolean","false") );
  1620. commAttributes.put("usersCanCreateSubCommunities", new CommunityAttributePojo("boolean","false") );
  1621. selfCommunity.setCommunityAttributes(commAttributes);
  1622. Map<String,CommunityUserAttributePojo> commUserAttributes = new HashMap<String,CommunityUserAttributePojo>();
  1623. commUserAttributes.put("publishLoginToActivityFeed", new CommunityUserAttributePojo("boolean","true",true));
  1624. commUserAttributes.put("publishCommentsToActivityFeed", new CommunityUserAttributePojo("boolean","true",true));
  1625. commUserAttributes.put("publishSharingToActivityFeed", new CommunityUserAttributePojo("boolean","true",true));
  1626. commUserAttributes.put("publishQueriesToActivityFeed", new CommunityUserAttributePojo("boolean","true",true));
  1627. commUserAttributes.put("publishCommentsPublicly", new CommunityUserAttributePojo("boolean","false",true));
  1628. selfCommunity.setCommunityUserAttribute(commUserAttributes);
  1629. selfCommunity.setNumberOfMembers(0);
  1630. // Create the index form of the community:
  1631. try {
  1632. GenericProcessingController.createCommunityDocIndex(selfCommunity.getId().toString(), null, true, false, false);
  1633. //TESTED
  1634. }
  1635. catch (Exception e) {} // Do nothing, will have to update the user to stop bad things from happening on query though
  1636. //write community to db
  1637. DbManager.getSocial().getCommunity().insert(selfCommunity.toDb());
  1638. //update user to be in this community
  1639. PersonCommunityPojo pcpSelf = new PersonCommunityPojo(person.get_id(), selfCommunity.getName());
  1640. person.getCommunities().add(pcpSelf);
  1641. /////////////////////////////////////////////////////////////////////////////////////////////////
  1642. // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
  1643. // Caleb: this means change update to $set
  1644. /////////////////////////////////////////////////////////////////////////////////////////////////
  1645. DbManager.getSocial().getPerson().update(new BasicDBObject("_id",person.get_id()), person.toDb());
  1646. }
  1647. catch (Exception ex)
  1648. {
  1649. }
  1650. }
  1651. //////////////////////////////////////////////////////////////////////////
  1652. //////////////////////// Helper Functions ////////////////////////////////
  1653. ///////// These functions do not get called from the public API //////////
  1654. //////////////////////////////////////////////////////////////////////////
  1655. /**
  1656. * getToAddressesFromCommunity (Internal)
  1657. * @param cp
  1658. * @return
  1659. */
  1660. private static String getToAddressesFromCommunity(CommunityPojo cp)
  1661. {
  1662. StringBuffer emailAddresses = new StringBuffer();
  1663. emailAddresses.append(cp.getOwner().getEmail());
  1664. for (CommunityMemberPojo cm : cp.getMembers())
  1665. {
  1666. if (cm.getUserType().equalsIgnoreCase("moderator"))
  1667. {
  1668. emailAddresses.append(";" + cm.getEmail());
  1669. }
  1670. }
  1671. return emailAddresses.toString();
  1672. }
  1673. /**
  1674. * getTagsFromString
  1675. * @param t
  1676. * @return List<String>
  1677. */
  1678. private List<String> getTagsFromString(String t)
  1679. {
  1680. List<String> tags = new ArrayList<String>();
  1681. if (t != null)
  1682. {
  1683. try
  1684. {
  1685. String[] a = t.split(",");
  1686. for (String v : a)
  1687. {
  1688. tags.add(v);
  1689. }
  1690. }
  1691. catch (Exception e)
  1692. {
  1693. }
  1694. }
  1695. return tags;
  1696. }
  1697. /**
  1698. * getDefaultCommunityAttributes
  1699. * @return Map<String, CommunityAttributePojo
  1700. */
  1701. private Map<String, CommunityAttributePojo> getDefaultCommunityAttributes()
  1702. {
  1703. Map<String, CommunityAttributePojo> c = new HashMap<String, CommunityAttributePojo>();
  1704. CommunityAttributePojo v = new CommunityAttributePojo();
  1705. v.setType("Boolean");
  1706. v.setValue("false");
  1707. c.put("isPublic", v);
  1708. v = new CommunityAttributePojo();
  1709. v.setType("Boolean");
  1710. v.setValue("true");
  1711. c.put("usersCanSelfRegister", v);
  1712. v = new CommunityAttributePojo();
  1713. v.setType("Boolean");
  1714. v.setValue("true");
  1715. c.put("registrationRequiresApproval", v);
  1716. v = new CommunityAttributePojo();
  1717. v.setType("Boolean");
  1718. v.setValue("false");
  1719. c.put("usersCanCreateSubCommunities", v);
  1720. return c;
  1721. }
  1722. /**
  1723. * getDefaultCommunityUserAttributes
  1724. * @return Map<String, CommunityUserAttributePojo>
  1725. */
  1726. private Map<String, CommunityUserAttributePojo> getDefaultCommunityUserAttributes()
  1727. {
  1728. Map<String, CommunityUserAttributePojo> c = new HashMap<String, CommunityUserAttributePojo>();
  1729. CommunityUserAttributePojo v = new CommunityUserAttributePojo();
  1730. v.setType("Boolean");
  1731. v.setDefaultValue("true");
  1732. v.setAllowOverride(false);
  1733. c.put("publishLoginToActivityFeed", v);
  1734. v = new CommunityUserAttributePojo();
  1735. v.setType("Boolean");
  1736. v.setDefaultValue("true");
  1737. v.setAllowOverride(false);
  1738. c.put("publishCommentsToActivityFeed", v);
  1739. v = new CommunityUserAttributePojo();
  1740. v.setType("Boolean");
  1741. v.setDefaultValue("true");
  1742. v.setAllowOverride(false);
  1743. c.put("publishSharingToActivityFeed", v);
  1744. v = new CommunityUserAttributePojo();
  1745. v.setType("Boolean");
  1746. v.setDefaultValue("true");
  1747. v.setAllowOverride(false);
  1748. c.put("publishQueriesToActivityFeed", v);
  1749. v = new CommunityUserAttributePojo();
  1750. v.setType("Boolean");
  1751. v.setDefaultValue("false");
  1752. v.setAllowOverride(false);
  1753. c.put("publishCommentsPublicly", v);
  1754. return c;
  1755. }
  1756. /**
  1757. * Utility function to remove members if users are not suppose to see them
  1758. *
  1759. * @param inputCommunities
  1760. * @param isAdminModerator
  1761. * @return
  1762. */
  1763. private CommunityPojo filterCommunityMembers(CommunityPojo community, boolean isAdmin, String userId)
  1764. {
  1765. //an admin can see everything
  1766. if ( !(isAdmin || SocialUtils.isOwnerOrModerator(community.getId().toString(), userId) ) )
  1767. {
  1768. //if community has publish members turned off, remove the members
  1769. if ( community.getCommunityAttributes().containsKey("publishMemberOverride") &&
  1770. community.getCommunityAttributes().get("publishMemberOverride").getValue().equals("false") )
  1771. {
  1772. community.setMembers(null);
  1773. }
  1774. }
  1775. return community;
  1776. }
  1777. private List<CommunityPojo> filterCommunityMembers(List<CommunityPojo> inputCommunities, boolean isAdmin, String userId)
  1778. {
  1779. //an admin can see everything
  1780. if ( !isAdmin )
  1781. {
  1782. for ( CommunityPojo community : inputCommunities )
  1783. {
  1784. filterCommunityMembers(community, isAdmin, userId);
  1785. }
  1786. }
  1787. return inputCommunities;
  1788. }
  1789. // Utility: make life easier in terms of adding/update/inviting/leaving from the command line
  1790. private static String allowCommunityRegex(String userIdStr, String communityIdStr) {
  1791. if (communityIdStr.startsWith("*")) {
  1792. String[] communityIdStrs = SocialUtils.getCommunityIds(userIdStr, communityIdStr);
  1793. if (1 == communityIdStrs.length) {
  1794. communityIdStr = communityIdStrs[0];
  1795. }
  1796. else if (communityIdStrs.length > 0) {
  1797. throw new RuntimeException("Invalid community pattern (many): " + Arrays.toString(communityIdStrs));
  1798. }
  1799. else {
  1800. throw new RuntimeException("Invalid community pattern (none)");
  1801. }
  1802. }
  1803. return communityIdStr;
  1804. }
  1805. }