/core/infinit.e.api.server/WEB-INF/src/com/ikanow/infinit/e/api/social/community/CommunityHandler.java
Java | 1988 lines | 1426 code | 183 blank | 379 comment | 245 complexity | 838b344c1817509c644b8cc745689b9c MD5 | raw file
Possible License(s): BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- /*******************************************************************************
- * Copyright 2012, The Infinit.e Open Source Project.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- ******************************************************************************/
- package com.ikanow.infinit.e.api.social.community;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.Set;
- import java.util.List;
- import org.apache.log4j.Logger;
- import org.bson.types.ObjectId;
- import com.ikanow.infinit.e.api.config.source.SourceHandler;
- import com.ikanow.infinit.e.api.custom.mapreduce.CustomHandler;
- import com.ikanow.infinit.e.api.utils.SocialUtils;
- import com.ikanow.infinit.e.api.utils.PropertiesManager;
- import com.ikanow.infinit.e.api.utils.RESTTools;
- import com.ikanow.infinit.e.api.utils.SendMail;
- import com.ikanow.infinit.e.data_model.api.ApiManager;
- import com.ikanow.infinit.e.data_model.api.ResponsePojo;
- import com.ikanow.infinit.e.data_model.api.ResponsePojo.ResponseObject;
- import com.ikanow.infinit.e.data_model.api.social.community.CommunityApprovalPojo;
- import com.ikanow.infinit.e.data_model.api.social.community.CommunityPojoApiMap;
- import com.ikanow.infinit.e.data_model.store.DbManager;
- import com.ikanow.infinit.e.data_model.store.MongoDbManager;
- import com.ikanow.infinit.e.data_model.store.config.source.SourcePojo;
- import com.ikanow.infinit.e.data_model.store.custom.mapreduce.CustomMapReduceJobPojo;
- import com.ikanow.infinit.e.data_model.store.document.DocCountPojo;
- import com.ikanow.infinit.e.data_model.store.social.community.CommunityApprovePojo;
- import com.ikanow.infinit.e.data_model.store.social.community.CommunityAttributePojo;
- import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberContactPojo;
- import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberLinkPojo;
- import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberPojo;
- import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberUserAttributePojo;
- import com.ikanow.infinit.e.data_model.store.social.community.CommunityPojo;
- import com.ikanow.infinit.e.data_model.store.social.community.CommunityUserAttributePojo;
- import com.ikanow.infinit.e.data_model.store.social.person.PersonCommunityPojo;
- import com.ikanow.infinit.e.data_model.store.social.person.PersonContactPojo;
- import com.ikanow.infinit.e.data_model.store.social.person.PersonLinkPojo;
- import com.ikanow.infinit.e.data_model.store.social.person.PersonPojo;
- import com.ikanow.infinit.e.data_model.store.social.sharing.SharePojo;
- import com.ikanow.infinit.e.data_model.store.social.sharing.SharePojo.ShareCommunityPojo;
- import com.ikanow.infinit.e.data_model.store.social.sharing.SharePojo.ShareOwnerPojo;
- import com.ikanow.infinit.e.processing.generic.GenericProcessingController;
- import com.mongodb.BasicDBObject;
- import com.mongodb.DBCursor;
- import com.mongodb.DBObject;
- /**
- * This class is for all operations related to the retrieval, addition
- * or update of communities within the system
- */
- public class CommunityHandler
- {
- private static final Logger logger = Logger.getLogger(CommunityHandler.class);
- private SourceHandler sourceHandler = new SourceHandler();
-
- //////////////////////////////////////////////////////////////////////////
- //////////////////////// REST handlers ////////////////////////////////
- //////////////////////////////////////////////////////////////////////////
-
- /**
- * getCommunities (REST)
- * Returns information for all communities
- * @return
- */
- public ResponsePojo getCommunities(String userIdStr)
- {
- ResponsePojo rp = new ResponsePojo();
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Note: Only Sys Admins see all communities
- boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
- try
- {
- if (isSysAdmin)
- {
- DBCursor dbc = DbManager.getSocial().getCommunity().find();
-
- if ( dbc.count() > 0 )
- {
- List<CommunityPojo> communities = CommunityPojo.listFromDb(dbc, CommunityPojo.listType());
- filterCommunityMembers(communities, isSysAdmin, userIdStr);
- rp.setData(communities, new CommunityPojoApiMap());
- rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));
- }
- else
- {
- rp.setResponse(new ResponseObject("Community Info", true, "No communities returned"));
- }
- }
- else // Get all public communities and all private communities to which the user belongs
- {
- // Set up the query
- BasicDBObject queryTerm1 = new BasicDBObject("communityAttributes.isPublic.value", "true");
- BasicDBObject queryTerm2 = new BasicDBObject("members._id", new ObjectId(userIdStr));
- BasicDBObject queryTerm3 = new BasicDBObject("ownerId", new ObjectId(userIdStr));
- BasicDBObject query = new BasicDBObject(MongoDbManager.or_, Arrays.asList(queryTerm1, queryTerm2, queryTerm3));
- DBCursor dbc = DbManager.getSocial().getCommunity().find(query);
- if ( dbc.count() > 0 )
- {
- List<CommunityPojo> communities = CommunityPojo.listFromDb(dbc, CommunityPojo.listType());
- filterCommunityMembers(communities, isSysAdmin, userIdStr);
- //add personal community
- DBObject dbo = DbManager.getSocial().getCommunity().findOne(new BasicDBObject("_id",new ObjectId(userIdStr)));
- if ( dbo != null )
- {
- communities.add(CommunityPojo.fromDb(dbo, CommunityPojo.class));
- }
- rp.setData(communities, new CommunityPojoApiMap());
- rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));
- }
- else
- {
- rp.setResponse(new ResponseObject("Community Info", true, "No communities returned"));
- }
- }
- }
- catch (Exception e)
- {
- logger.error("Exception Message: " + e.getMessage(), e);
- rp.setResponse(new ResponseObject("Community Info", false, "error returning community info"));
- }
- return rp;
- }
-
- /**
- * getCommunities (REST)
- * Returns information for communities where isPublic = true/false
- * @param isPublic
- * @return
- */
- public ResponsePojo getCommunities(String userIdStr, Boolean isPublic)
- {
- ResponsePojo rp = new ResponsePojo();
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Note: Only Sys Admins see private communities
- boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
-
- try
- {
- // Set up the query
- BasicDBObject query = new BasicDBObject();
- query.put("communityAttributes.isPublic.value", isPublic.toString());
- if (!isPublic && !isSysAdmin)
- {
- //Add user ID to query so only get (private) communities of which I'm a member
- query.put("members._id", new ObjectId(userIdStr));
- }
- query.put("communityStatus", new BasicDBObject("$ne", "disabled"));
-
- DBCursor dbc = DbManager.getSocial().getCommunity().find(query);
- if ( dbc.count() > 0 )
- {
- List<CommunityPojo> communities = CommunityPojo.listFromDb(dbc, CommunityPojo.listType());
- filterCommunityMembers(communities, isSysAdmin, userIdStr);
- rp.setData(communities, new CommunityPojoApiMap());
- rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));
- }
- else
- {
- rp.setResponse(new ResponseObject("Community Info", true, "No communities returned"));
- }
- }
- catch (Exception e)
- {
- logger.error("Exception Message: " + e.getMessage(), e);
- rp.setResponse(new ResponseObject("Community Info", false, "error returning community info"));
- }
- return rp;
- }
-
-
- /**
- * getCommunity (REST)
- * Returns information for a single community
- * @param communityIdStr
- * @return
- */
- public ResponsePojo getCommunity(String userIdStr, String communityIdStr, boolean showDocInfo)
- {
- ResponsePojo rp = new ResponsePojo();
-
- try
- {
-
- // Set up the query
- BasicDBObject query = new BasicDBObject();
- if (communityIdStr != null)
- {
- communityIdStr = allowCommunityRegex(userIdStr, communityIdStr);
- query.put("_id", new ObjectId(communityIdStr));
- }
- else
- {
- query.put("_id", new ObjectId("4c927585d591d31d7b37097a")); // (hardwired sys community)
- }
-
- // Get GsonBuilder object with MongoDb de/serializers registered
- BasicDBObject dbo = (BasicDBObject)DbManager.getSocial().getCommunity().findOne(query);
-
- if (dbo != null)
- {
- CommunityPojo community = CommunityPojo.fromDb(dbo, CommunityPojo.class);
- if (showDocInfo) {
- DocCountPojo dc = (DocCountPojo) DbManager.getDocument().getCounts().findOne(query);
- if (null != dc) {
- dc.set_id(null);
- community.setDocumentInfo(dc);
- }
- }
- community = filterCommunityMembers(community, RESTTools.adminLookup(userIdStr), userIdStr);
- rp.setData(community, new CommunityPojoApiMap());
- rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));
- }
- else
- {
- rp.setResponse(new ResponseObject("Community Info", false, "Unable to return information for the community specified."));
- }
- }
- catch (Exception e)
- {
- //logger.error("Exception Message: " + e.getMessage(), e);
- rp.setResponse(new ResponseObject("Community Info", false, "Error returning community info: " + e.getMessage()));
- }
- return rp;
- }
- /**
- * getSystemCommunity (REST)
- * @return ResponsePojo
- */
- public ResponsePojo getSystemCommunity()
- {
- return getCommunity(null, null, false);
- }
-
- /**
- * addCommunity (REST)
- * Creates a new community
- * @param userIdStr
- * @param name
- * @param description
- * @param parentIdStr
- * @param parentName
- * @param tags
- * @param ownerId
- * @param ownerDisplayName
- * @return ResponsePojo
- */
- public ResponsePojo addCommunity(String userIdStr, String name, String description, String parentIdStr, String tags)
- {
- String userName = null;
- String userEmail = null;
- String parentName = null;
-
- try
- {
- DBObject dboperson = DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(userIdStr)));
-
- if ( dboperson != null )
- {
- PersonPojo person = PersonPojo.fromDb(dboperson, PersonPojo.class);
- userName = person.getDisplayName();
- userEmail = person.getEmail();
-
- // Parent Community is Optional
- if (parentIdStr != null)
- {
- try {
- DBObject dboparent = DbManager.getSocial().getCommunity().findOne(new BasicDBObject("_id", new ObjectId(parentIdStr)));
- if ( dboparent != null )
- {
- CommunityPojo cp = CommunityPojo.fromDb(dboparent, CommunityPojo.class);
- parentName = cp.getName();
-
- if (cp.getIsPersonalCommunity()) {
- return new ResponsePojo(new ResponseObject("Add Community", false, "Can't create sub-community of personal community"));
- }//TESTED
- if ((null == cp.getCommunityStatus()) || !cp.getCommunityStatus().equalsIgnoreCase("active")) {
- return new ResponsePojo(new ResponseObject("Add Community", false, "Can't create sub-community of inactive community"));
- }//TESTED
- // Check attributes
- if (null != cp.getCommunityAttributes()) {
- CommunityAttributePojo attr = cp .getCommunityAttributes().get("usersCanCreateSubCommunities");
- if ((null == attr) || (null== attr.getValue()) || (attr.getValue().equals("false"))) {
- if (!cp.isOwner(person.get_id()) && !SocialUtils.isModerator(userIdStr, cp) && !RESTTools.adminLookup(userIdStr)) {
- return new ResponsePojo(new ResponseObject("Add Community", false, "Can't create sub-community when not permitted by parent"));
- }//TESTED (owner+admin+mod)
- }
- }
- }//TESTED - different restrictions as above
- else
- {
- return new ResponsePojo(new ResponseObject("Add Community", false, "Parent community does not exist"));
- }//TESTED
- }
- catch (Exception e) {
- return new ResponsePojo(new ResponseObject("Add Community", false, "Invalid parent community id"));
- }//TESTED
- }
- }
- else
- {
- return new ResponsePojo(new ResponseObject("Add Community", false, "Error: Unable to get person record"));
- }
- }
- catch (Exception ex)
- {
- return new ResponsePojo(new ResponseObject("Add Community", false, "General Error: " + ex.getMessage()));
- }
- return addCommunity(userIdStr, name, description, parentIdStr, parentName, tags, userIdStr, userName, userEmail);
- }
-
- /**
- * addCommunity (REST)
- * Creates a new community by id (alternate)
- */
- private ResponsePojo addCommunity(String userIdStr, String name, String description,
- String parentIdStr, String parentName, String tags, String ownerIdStr,
- String ownerDisplayName, String ownerEmail)
- {
- return addCommunity(userIdStr, null, name, description, parentIdStr, parentName, tags,
- ownerIdStr, ownerDisplayName, ownerEmail);
- }
- public ResponsePojo addCommunity(String userId, String idStr, String name, String description,
- String parentIdStr, String parentName, String tags, String ownerIdStr,
- String ownerDisplayName, String ownerEmail)
- {
- ResponsePojo rp = new ResponsePojo();
-
- try
- {
- // Check to see if a community exists already with the supplied name or ID
- // do not create new one if true -
- // TODO (INF-1214): Think about need for unique names - proposed:
- // Community names unique per parent community
- BasicDBObject query = new BasicDBObject();
- if (idStr == null)
- {
- query.put("name", name);
- }
- else
- {
- query.put("_id", new ObjectId(idStr));
- }
- DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
-
- if (dbo == null)
- {
- ObjectId oId = null;
- if (idStr == null)
- {
- oId = new ObjectId();
- }
- else
- {
- oId = new ObjectId(idStr);
- }
- CommunityPojo c = new CommunityPojo();
- c.setId(oId);
- c.setCreated(new Date());
- c.setModified(new Date());
- c.setName(name);
- c.setDescription(description);
- if (parentIdStr != null && parentName != null)
- {
- c.setParentId(new ObjectId(parentIdStr));
- c.setParentName(parentName);
- c = SocialUtils.createParentTreeRecursion(c, false);
- }
- c.setIsPersonalCommunity(false);
- c.setTags(getTagsFromString(tags));
- c.setOwnerId(new ObjectId(ownerIdStr));
- c.setOwnerDisplayName(ownerDisplayName);
- c.setNumberOfMembers(0);
- c.setCommunityAttributes(getDefaultCommunityAttributes());
- c.setCommunityUserAttribute(getDefaultCommunityUserAttributes());
-
- // Insert new community document in the community collection
- DBObject commObj = c.toDb();
- // Create the index form of the community:
- try {
- GenericProcessingController.createCommunityDocIndex(c.getId().toString(), c.getParentId(), c.getIsPersonalCommunity(), c.getIsSystemCommunity(), false);
- }
- catch (Exception e) { // Can't create community
- rp.setResponse(new ResponseObject("Add Community", false, "Error adding new community because of index failure: " + e.getMessage()));
- return rp;
- }
- //TESTED
-
- DbManager.getSocial().getCommunity().save(commObj);
-
- // If a child, update the parent:
- if (null != c.getParentId()) {
- BasicDBObject updateQuery = new BasicDBObject("_id", c.getParentId());
- BasicDBObject updateUpdate = new BasicDBObject(DbManager.addToSet_, new BasicDBObject("children", c.getId()));
- DbManager.getSocial().getCommunity().update(updateQuery, updateUpdate, false, true);
- }
- //TESTED
-
- // Update the new community record to add the owner to the list of members
- rp = addCommunityMember(userId, oId.toStringMongod(), name, ownerIdStr, ownerEmail, ownerDisplayName, "owner", "active");
- rp.setResponse(new ResponseObject("Add Community", true, "The " + name + " community has " +
- "been added."));
- }
- else
- {
- rp.setResponse(new ResponseObject("Add Community", false,
- "Error adding new community. A community with the name " + name + " " +
- "already exists."));
- }
-
- }
- catch (Exception e)
- {
- // If an exception occurs log the error
- logger.error("Exception Message: " + e.getMessage(), e);
- rp.setResponse(new ResponseObject("Add Community", false,
- "Error adding new community " + e.getMessage()));
- }
- return rp;
- }
- /**
- * removeCommunity (REST)
- * Remove communityid only if the personid is the owner
- * TODO (INF-1214): Remove users from the groups in both personpojo and communitypojo
- *
- * @param personIdStr
- * @param communityIdStr
- * @return
- */
- public ResponsePojo removeCommunity(String personIdStr, String communityIdStr)
- {
- boolean isSysAdmin = RESTTools.adminLookup(personIdStr);
- ResponsePojo rp = new ResponsePojo();
- try
- {
- ObjectId communityId = new ObjectId(communityIdStr);
- //get the communitypojo
- communityIdStr = allowCommunityRegex(personIdStr, communityIdStr);
- DBObject communitydbo = DbManager.getSocial().getCommunity().findOne(new BasicDBObject("_id",communityId));
- if ( communitydbo != null )
- {
- CommunityPojo cp = CommunityPojo.fromDb(communitydbo, CommunityPojo.class);
- //get the personpojo
- DBObject persondbo = DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id",new ObjectId(personIdStr)));
- if ( persondbo != null )
- {
- //PersonPojo pp = gson.fromJson(persondbo.toString(),PersonPojo.class);
- if ( !cp.getIsPersonalCommunity() )
- {
- if ( cp.isOwner(new ObjectId(personIdStr)) || isSysAdmin )
- {
- if (cp.getCommunityStatus().equals("disabled")) { // Delete for good, this is going to be ugly...
-
- if ((null != cp.getChildren()) && !cp.getChildren().isEmpty()) {
- rp.setResponse(new ResponseObject("Delete community", false, "Undeleted sub-communities exist, please delete them first"));
- return rp;
- }
- //TESTED
-
- // 1] Remove from all shares (delete shares if that leaves them orphaned)
-
- BasicDBObject deleteQuery1 = new BasicDBObject(ShareCommunityPojo.shareQuery_id_, communityId);
- BasicDBObject deleteFields1 = new BasicDBObject(SharePojo.communities_, 1);
- List<SharePojo> shares = SharePojo.listFromDb(DbManager.getSocial().getShare().find(deleteQuery1, deleteFields1), SharePojo.listType());
- for (SharePojo share: shares) {
- if (1 == share.getCommunities().size()) { // delete this share
- DbManager.getSocial().getShare().remove(new BasicDBObject(SharePojo._id_, share.get_id()));
- }
- }
- BasicDBObject update1 = new BasicDBObject(DbManager.pull_, new BasicDBObject(SharePojo.communities_,
- new BasicDBObject(ShareOwnerPojo._id_, communityId)));
- DbManager.getSocial().getShare().update(deleteQuery1, update1, false, true);
-
- //TESTED (both types)
-
- // 2] Remove from all sources (also delete the documents)
- // (In most cases this will leave the source orphaned, so delete it)
-
- BasicDBObject deleteQuery2 = new BasicDBObject(SourcePojo.communityIds_, communityId);
- BasicDBObject deleteFields2 = new BasicDBObject(SourcePojo.communityIds_, 1);
- List<SourcePojo> sources = SourcePojo.listFromDb(DbManager.getIngest().getSource().find(deleteQuery2, deleteFields2), SourcePojo.listType());
- List<SourcePojo> failedSources = new ArrayList<SourcePojo>();
- for (SourcePojo source: sources)
- {
- ResponsePojo rp1 = null;
- SourceHandler tmpHandler = new SourceHandler();
- if (1 == source.getCommunityIds().size()) { // delete this source
- rp1 = tmpHandler.deleteSource(source.getId().toString(), communityIdStr, personIdStr, false);
- // (deletes all docs and removes from the share)
- }
- else { // Still need to delete docs from this share from this community
- rp1 = tmpHandler.deleteSource(source.getId().toString(), communityIdStr, personIdStr, true);
- }
- if ( rp1 != null && !rp1.getResponse().isSuccess() )
- {
- failedSources.add(source);
- }
- }
-
- //if we have more than 1 failed source, bail out w/ error
- if (failedSources.size() > 0 )
- {
- StringBuilder sb = new StringBuilder();
- for ( SourcePojo source : failedSources )
- sb.append(source.getId().toString() + " ");
- rp.setResponse(new ResponseObject("Delete community", false, "Could not stop sources (they might be currently running): " + sb.toString()));
- return rp;
- }
-
- BasicDBObject update2 = new BasicDBObject(DbManager.pull_, new BasicDBObject(SourcePojo.communityIds_, communityId));
- DbManager.getSocial().getShare().update(deleteQuery2, update2, false, true);
- //TESTED (both types, check docs deleted)
-
- // 3] Remove from all map reduce jobs (delete any that it is only comm left on)
- String customJobsMessage = removeCommunityFromJobs(personIdStr, communityId);
- if ( customJobsMessage.length() > 0)
- {
- rp.setResponse(new ResponseObject("Delete community", false, "Could not stop all map reduce jobs (they might be currently running): " + customJobsMessage));
- return rp;
- }
-
- // 4] Finally delete the object itself
-
- DbManager.getSocial().getCommunity().remove(new BasicDBObject("_id", communityId));
-
- // Remove from index:
- GenericProcessingController.deleteCommunityDocIndex(communityId.toString(), cp.getParentId(), false);
- //TESTED
-
- // 5] Finally finally remove from parent communities
- if (null != cp.getParentId()) {
- BasicDBObject updateQuery = new BasicDBObject("_id", cp.getParentId());
- BasicDBObject updateUpdate = new BasicDBObject(DbManager.pull_, new BasicDBObject("children", cp.getId()));
- DbManager.getSocial().getCommunity().update(updateQuery, updateUpdate, false, true);
- }
- //TESTED
-
- rp.setResponse(new ResponseObject("Delete community", true, "Community deleted forever. " + customJobsMessage));
- }
- else { // First time, just remove all users and disable
- //at this point, we have verified, community/user exist, not a personal group, user is member and owner
- //set community as inactive (for some reason we don't delete it)
- DbManager.getSocial().getCommunity().update(new BasicDBObject("_id", communityId),
- new BasicDBObject(DbManager.set_, new BasicDBObject("communityStatus","disabled")));
-
- //remove all members
- for ( CommunityMemberPojo cmp : cp.getMembers())
- removeCommunityMember(personIdStr, communityIdStr, cmp.get_id().toString());
- rp.setResponse(new ResponseObject("Delete community", true, "Community disabled successfully - call delete again to remove for good, including all sources, shares, and documents"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Delete community", false, "You are not the owner of this community"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Delete community", false, "Cannot delete personal community."));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Delete community", false, "Person ID was incorrect, no matching person found"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Delete community", false, "Community ID was incorrect, no matching commmunity found"));
- }
- }
- catch (Exception ex)
- {
- rp.setResponse(new ResponseObject("Delete community", false, "Error returning community info: " + ex.getMessage()));
- }
-
- return rp;
- }
-
- /**
- * Removes this community from any map reduce jobs, then deletes any jobs where it was the only community
- *
- * @param communityId
- * @return
- */
- private String removeCommunityFromJobs(String personIdStr, ObjectId communityId)
- {
- StringBuilder sb = new StringBuilder();
- List<CustomMapReduceJobPojo> failedToRemove = CustomHandler.removeCommunityJobs(communityId);
- //return a list of job ids
- for ( CustomMapReduceJobPojo cmr : failedToRemove )
- {
- sb.append(cmr.jobtitle + " ");
- }
- if ( sb.length() > 0 )
- {
- sb.insert(0, "These map reduce jobs could not be removed: " );
- }
- return sb.toString();
- }
- // (Note supports personId as either Id or username (email) both are unique indexes)
- /**
- * updateMemberStatus (REST)
- */
-
- public ResponsePojo updateMemberStatus(String callerIdStr, String personIdStr, String communityIdStr, String userStatus)
- {
- boolean isSysAdmin = RESTTools.adminLookup(callerIdStr);
- ResponsePojo rp = new ResponsePojo();
- try
- {
- communityIdStr = allowCommunityRegex(callerIdStr, communityIdStr);
-
- //verify user is in this community, then update status
- BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
- DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
- if ( dbo != null )
- {
- // PersonId can be _id or username/email
- BasicDBObject dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("email", personIdStr));
- if (null == dboPerson) { // (ie personId isn't an email address... convert to ObjectId and try again)
- dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(personIdStr)));
- }
- else {
- personIdStr = dboPerson.getString("_id");
- }
- // OK from here on, personId is the object Id...
-
- boolean bAuthorized = isSysAdmin || SocialUtils.isOwnerOrModerator(communityIdStr, callerIdStr);
- if (bAuthorized) {
-
- CommunityPojo cp = CommunityPojo.fromDb(dbo,CommunityPojo.class);
- ObjectId personId = new ObjectId(personIdStr);
-
- if ( cp.isOwner(personId) && !userStatus.equalsIgnoreCase("active")) {
- rp.setResponse(new ResponseObject("Update member status",false,"Can't change owner status, remove their ownership first"));
- return rp;
- }//TESTED (tried as owner+admin (failed both times), tested owner works fine if setting/keeping active)
- else if ( cp.isMember(personId) )
- {
- // Remove user:
- if (userStatus.equalsIgnoreCase("remove"))
- {
- //removeCommunityMember(callerIdStr, communityIdStr, personIdStr);
- rp = removeCommunityMember(callerIdStr, communityIdStr, personIdStr); //.setResponse(new ResponseObject("Update member status",true,"Member removed from community."));
- }
- else
- {
- //verified user, update status
- if ( cp.updateMemberStatus(personIdStr, userStatus) )
- {
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
- // Caleb: this means change update to $set
- /////////////////////////////////////////////////////////////////////////////////////////////////
- DbManager.getSocial().getCommunity().update(query, cp.toDb());
- rp.setResponse(new ResponseObject("Update member status",true,"Updated member status successfully"));
- }
- else
- {
- rp.setResponse(new ResponseObject("Update member status",false,"Failed to update status"));
- }
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Update member status",false,"User was not a member of the community"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Update member status",false,"Caller must be admin, or a community owner or moderator"));
- }//TESTED - tried to update my status as member (failed), as admin (succeeded), as moderator (succeeded), as owner (succeeded)
- }
- else
- {
- rp.setResponse(new ResponseObject("Update member status",false,"Community does not exist"));
- }
- }
- catch(Exception ex)
- {
- rp.setResponse(new ResponseObject("Update member status",false,"General Error, bad params maybe? " + ex.getMessage()));
- }
- return rp;
- }//TESTED
- // (Note supports personId as either Id or username (email) both are unique indexes)
- /**
- * updateMemberType (REST)
- */
- public ResponsePojo updateMemberType(String callerIdStr, String personIdStr, String communityIdStr, String userType)
- {
- boolean isSysAdmin = RESTTools.adminLookup(callerIdStr);
- ResponsePojo rp = new ResponsePojo();
- try
- {
- if (!userType.equalsIgnoreCase("owner") && !userType.equalsIgnoreCase("moderator") && !userType.equalsIgnoreCase("member") && !userType.equalsIgnoreCase("content_publisher"))
- {
- rp.setResponse(new ResponseObject("Update member type",false,"Invalid user type: " + userType));
- return rp;
- }//TESTED - tested all the types work, hacked members.jsp to insert invalid type
-
- //verify user is in this community, then update status
- communityIdStr = allowCommunityRegex(callerIdStr, communityIdStr);
- BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
- DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
- if ( dbo != null )
- {
- // PersonId can be _id or username/email
- BasicDBObject dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("email", personIdStr));
- if (null == dboPerson) { // (ie personId isn't an email address... convert to ObjectId and try again)
- dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(personIdStr)));
- }
- else {
- personIdStr = dboPerson.getString("_id");
- }
- // OK from here on, personId is the object Id...
- CommunityPojo cp = CommunityPojo.fromDb(dbo,CommunityPojo.class);
-
- boolean bOwnershipChangeRequested = userType.equalsIgnoreCase("owner");
- boolean bAuthorized = isSysAdmin;
- if (!bAuthorized) {
- if (bOwnershipChangeRequested) { // must be owner or admin
- bAuthorized = cp.isOwner(new ObjectId(callerIdStr));
- }//TESTED - tried to update myself as moderator to owner (failed), gave up my community (succeeded), changed ownership as admin (FAILED)
- else { // Can also be moderator
- bAuthorized = SocialUtils.isOwnerOrModerator(communityIdStr, callerIdStr);
- }//TESTED - tried to update my role as member (failed), as admin->moderator (succeeded), as moderator (succeeded)
- }
-
- if (bAuthorized) // (see above)
- {
- if ( cp.isMember(new ObjectId(personIdStr)))
- {
- boolean bChangedMembership = false;
- boolean bChangedOwnership = !bOwnershipChangeRequested;
-
- ObjectId personId = new ObjectId(personIdStr);
-
- // Check that not trying to downgrade owner...
- if (cp.isOwner(personId) && !bOwnershipChangeRequested) {
- rp.setResponse(new ResponseObject("Update member type",false,"To change ownership, set new owner, will automatically downgrade existing owner to moderator"));
- return rp;
- }//TESTED
-
- String personDisplayName = null;
- //verified user, update status
- for ( CommunityMemberPojo cmp : cp.getMembers())
- {
- if ( cmp.get_id().equals(personId) )
- {
- cmp.setUserType(userType);
- personDisplayName = cmp.getDisplayName();
- bChangedMembership = true;
-
- if (bChangedOwnership) { // (includes case where didn't need to)
- break;
- }
-
- }//TESTED
- if (bOwnershipChangeRequested && cmp.get_id().equals(cp.getOwnerId())) {
- cmp.setUserType("moderator");
- bChangedOwnership = true;
-
- if (bChangedMembership) {
- break;
- }
-
- }//TESTED
- }
- if (bChangedMembership) {
- if (bOwnershipChangeRequested) {
- cp.setOwnerId(personId);
- cp.setOwnerDisplayName(personDisplayName);
- }//TESTED
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
- // Caleb: this means change update to $set
- /////////////////////////////////////////////////////////////////////////////////////////////////
- DbManager.getSocial().getCommunity().update(query, cp.toDb());
- rp.setResponse(new ResponseObject("Update member type",true,"Updated member type successfully"));
- }//TESTED
- }
- else
- {
- rp.setResponse(new ResponseObject("Update member type",false,"User was not a member of the community"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Update member type",false,"Caller must be admin/owner/moderator (unless changing ownership)"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Update member type",false,"Community does not exist"));
- }
- }
- catch(Exception ex)
- {
- rp.setResponse(new ResponseObject("Update member type",false,"General Error, bad params maybe? " + ex.getMessage()));
- }
- return rp;
- }//TESTED (see sub-clauses for details)
- /**
- * joinCommunity (REST)
- */
- public ResponsePojo joinCommunity(String personIdStr, String communityIdStr)
- {
- boolean isSysAdmin = RESTTools.adminLookup(personIdStr);
- return joinCommunity(personIdStr, communityIdStr, isSysAdmin);
- }
-
- public ResponsePojo joinCommunity(String personIdStr, String communityIdStr, boolean isSysAdmin)
- {
- ResponsePojo rp = new ResponsePojo();
- try
- {
- communityIdStr = allowCommunityRegex(personIdStr, communityIdStr);
- BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
- DBObject dboComm = DbManager.getSocial().getCommunity().findOne(query);
- if ( dboComm != null )
- {
- CommunityPojo cp = CommunityPojo.fromDb(dboComm, CommunityPojo.class);
- if ( !cp.getIsPersonalCommunity() )
- {
- BasicDBObject queryPerson = new BasicDBObject("_id",new ObjectId(personIdStr));
- DBObject dboPerson = DbManager.getSocial().getPerson().findOne(queryPerson);
- PersonPojo pp = PersonPojo.fromDb(dboPerson,PersonPojo.class);
- boolean isPending = isMemberPending(cp, pp);
-
- if ( !cp.isMember(new ObjectId(personIdStr)) || isPending )
- {
- Map<String,CommunityAttributePojo> commatt = cp.getCommunityAttributes();
- if ( isSysAdmin || (commatt.containsKey("usersCanSelfRegister") && commatt.get("usersCanSelfRegister").getValue().equals("true") ))
- {
- boolean requiresApproval = false;
- if ( !isSysAdmin && commatt.containsKey("registrationRequiresApproval") )
- requiresApproval = commatt.get("registrationRequiresApproval").getValue().equals("true");
- //if approval is required, add user to comm, wait for owner to approve
- //otherwise go ahead and add as a member
- if ( requiresApproval )
- {
- cp.addMember(pp,true);
- //write both objects back to db now
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
- // Caleb: this means change update to $set
- /////////////////////////////////////////////////////////////////////////////////////////////////
- DbManager.getSocial().getCommunity().update(query, cp.toDb());
-
- //send email out to owner for approval
- CommunityApprovePojo cap = cp.createCommunityApprove(personIdStr,communityIdStr,"join",personIdStr);
- DbManager.getSocial().getCommunityApprove().insert(cap.toDb());
-
- // Get to addresses for Owner and Moderators
- String toAddresses = getToAddressesFromCommunity(cp);
-
- PropertiesManager propManager = new PropertiesManager();
- String rootUrl = propManager.getUrlRoot();
-
- String subject = pp.getDisplayName() + " is trying to join infinit.e community: " + cp.getName();
- String body = pp.getDisplayName() + " is trying to join infinit.e community: " + cp.getName() + "<br/>Do you want to accept this request?" +
- "<br/><a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/true\">Accept</a> " +
- "<a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/false\">Deny</a>";
-
- SendMail mail = new SendMail(new PropertiesManager().getAdminEmailAddress(), toAddresses, subject, body);
-
- if (mail.send("text/html"))
- {
- rp.setResponse(new ResponseObject("Join Community",true,"Joined community successfully, awaiting owner approval"));
- rp.setData(new CommunityApprovalPojo(false));
- }
- else
- {
- rp.setResponse(new ResponseObject("Join Community",false,"The system was uable to send an email to the owner"));
- }
- }
- else
- {
- cp.addMember(pp);
- pp.addCommunity(cp);
- //write both objects back to db now
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
- // Caleb: this means change update to $set
- /////////////////////////////////////////////////////////////////////////////////////////////////
- DbManager.getSocial().getCommunity().update(query, cp.toDb());
- DbManager.getSocial().getPerson().update(queryPerson, pp.toDb());
- rp.setResponse(new ResponseObject("Join Community",true,"Joined community successfully"));
- rp.setData(new CommunityApprovalPojo(true));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Join Community",false,"You must be invited to this community"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Join Community",false,"You are already a member of this community"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Join Community",false,"Cannot add members to personal community"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Join Community",false,"Community does not exist"));
- }
- }
- catch(Exception ex)
- {
- rp.setResponse(new ResponseObject("Join Community",false,"General Error, bad params maybe? " + ex.getMessage()));
- }
- return rp;
- }
-
- /**
- * leaveCommunity (REST)
- */
-
- public ResponsePojo leaveCommunity(String personIdStr, String communityIdStr)
- {
- ResponsePojo rp = new ResponsePojo();
- try
- {
- communityIdStr = allowCommunityRegex(personIdStr, communityIdStr);
- BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
- DBObject dboComm = DbManager.getSocial().getCommunity().findOne(query);
- if ( dboComm != null )
- {
- CommunityPojo cp = CommunityPojo.fromDb(dboComm, CommunityPojo.class);
- if ( !cp.getIsPersonalCommunity())
- {
- BasicDBObject queryPerson = new BasicDBObject("_id",new ObjectId(personIdStr));
- DBObject dboPerson = DbManager.getSocial().getPerson().findOne(queryPerson);
- PersonPojo pp = PersonPojo.fromDb(dboPerson,PersonPojo.class);
- cp.removeMember(new ObjectId(personIdStr));
- pp.removeCommunity(cp);
- //write both objects back to db now
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
- // Caleb: this means change update to $set
- /////////////////////////////////////////////////////////////////////////////////////////////////
- DbManager.getSocial().getCommunity().update(query, cp.toDb());
- DbManager.getSocial().getPerson().update(queryPerson, pp.toDb());
- rp.setResponse(new ResponseObject("Leave Community",true,"Left community successfully"));
- }
- else
- {
- rp.setResponse(new ResponseObject("Leave Community",false,"Cannot leave personal community"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Leave Community",false,"Community does not exist"));
- }
- }
- catch(Exception ex)
- {
- rp.setResponse(new ResponseObject("Leave Community",false,"General Error, bad params maybe? " + ex.getMessage()));
- }
- return rp;
- }
- /**
- * inviteCommunity (REST)
- * Invite a user to a community, only add them as pending to community
- * and do not add community into the person object yet
- * Need to send email out
- // (Note supports personId as either Id or username (email) both are unique indexes)
- * @param personIdStr
- * @param userIdStr
- * @param communityIdStr
- * @return
- */
- public ResponsePojo inviteCommunity(String userIdStr, String personIdStr, String communityIdStr, String skipInvitation)
- {
- ResponsePojo rp = new ResponsePojo();
- try {
- communityIdStr = allowCommunityRegex(userIdStr, communityIdStr);
- }
- catch (Exception e) {
- rp.setResponse(new ResponseObject("Invite Community", false, "Error returning community info: " + e.getMessage()));
- return rp;
- }
-
- boolean skipInvite = ((null != skipInvitation) && (skipInvitation.equalsIgnoreCase("true"))) ? true : false;
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Note: Only Sys Admins, Community Owner, and Community Moderators can invite users to
- // private communities however any member can be able to invite someone to a public community
- boolean isOwnerOrModerator = SocialUtils.isOwnerOrModerator(communityIdStr, userIdStr);
- boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
- boolean canInvite = (isOwnerOrModerator || isSysAdmin) ? true : false;
- try
- {
- BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
- DBObject dboComm = DbManager.getSocial().getCommunity().findOne(query);
-
- if ( dboComm != null )
- {
- CommunityPojo cp = CommunityPojo.fromDb(dboComm, CommunityPojo.class);
-
- // Make sure this isn't a personal community
- if ( !cp.getIsPersonalCommunity() )
- {
- // Check to see if the user has permissions to invite or selfregister
- boolean selfRegister = canSelfRegister(cp);
- if ( canInvite || cp.getOwnerId().toString().equalsIgnoreCase(userIdStr) || selfRegister )
- {
- BasicDBObject dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("email", personIdStr));
- if (null == dboPerson) { // (ie personId isn't an email address... convert to ObjectId and try again)
- dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(personIdStr)));
- }
- else {
- personIdStr = dboPerson.getString("_id");
- }
- // OK from here on, personId is the object Id...
-
- if ( dboPerson != null )
- {
- PersonPojo pp = PersonPojo.fromDb(dboPerson,PersonPojo.class);
- //need to check for if a person is pending, and skipInvite and isSysAdmin, otherwise
- //they would just get sent an email again, so leave it be
- boolean isPending = false;
- if ( isSysAdmin && skipInvite )
- {
- isPending = isMemberPending(cp, pp);
- }
-
- if ( selfRegister )
- {
- //If the comm allows for self registering, just call join community
- //instead of invite, it will handle registration
- return this.joinCommunity(pp.get_id().toString(), communityIdStr, isSysAdmin);
- }
- else if ( !cp.isMember(pp.get_id()) || isPending )
- {
- if (isSysAdmin && skipInvite) // Can only skip invite if user is Admin
- {
- // Update community with new member
- cp.addMember(pp, false); // Member status set to Active
- cp.setNumberOfMembers(cp.getNumberOfMembers() + 1); // Increment number of members
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
- // Caleb: this means change update to $set
- /////////////////////////////////////////////////////////////////////////////////////////////////
- DbManager.getSocial().getCommunity().update(query, cp.toDb());
-
- // Add community to persons object and save to db
- pp.addCommunity(cp);
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
- // Caleb: this means change update to $set
- /////////////////////////////////////////////////////////////////////////////////////////////////
- DbManager.getSocial().getPerson().update(new BasicDBObject("_id", pp.get_id()), pp.toDb());
-
- rp.setResponse(new ResponseObject("Invite Community",true,"User added to community successfully."));
- }
- else
- {
- cp.addMember(pp, true); // Member status set to Pending
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
- // Caleb: this means change update to $set
- /////////////////////////////////////////////////////////////////////////////////////////////////
- DbManager.getSocial().getCommunity().update(query, cp.toDb());
-
- //send email out inviting user
- CommunityApprovePojo cap = cp.createCommunityApprove(personIdStr,communityIdStr,"invite",userIdStr);
- DbManager.getSocial().getCommunityApprove().insert(cap.toDb());
-
- PropertiesManager propManager = new PropertiesManager();
- String rootUrl = propManager.getUrlRoot();
-
- if (null == rootUrl) {
- 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."));
- return rp;
- }
-
- String subject = "Invite to join infinit.e community: " + cp.getName();
- String body = "You have been invited to join the community " + cp.getName() +
- "<br/><a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/true\">Accept</a> " +
- "<a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/false\">Deny</a>";
-
- SendMail mail = new SendMail(new PropertiesManager().getAdminEmailAddress(), pp.getEmail(), subject, body);
-
- if (mail.send("text/html"))
- {
- if (isSysAdmin) {
- rp.setResponse(new ResponseObject("Invite Community",true,"Invited user to community successfully: " + cap.get_id().toString()));
- }
- else {
- rp.setResponse(new ResponseObject("Invite Community",true,"Invited user to community successfully"));
- }
- }
- else
- {
- 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)."));
- }
- }
- }
- else
- {
- //otherwise just return we failed
- rp.setResponse(new ResponseObject("Invite Community",false,"The user is already a member of this community."));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Invite Community",false,"Person does not exist"));
- }
- }
- else
- {
- 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"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Invite Community",false,"Cannot invite members to personal community"));
- }
- }
- else
- {
- rp.setResponse(new ResponseObject("Invite Community",false,"Community does not exist"));
- }
- }
- catch(Exception ex)
- {
- rp.setResponse(new ResponseObject("Invite Community",false,"General Error, bad params maybe? " + ex.getMessage()));
- }
- return rp;
- }
-
- /**
- * Returns true if users can self register to this community
- *
- * @param cp
- * @return
- */
- private boolean canSelfRegister(CommunityPojo cp)
- {
- if ( cp != null )
- {
- if ( cp.getCommunityAttributes().containsKey("usersCanSelfRegister") &&
- cp.getCommunityAttributes().get("usersCanSelfRegister").getValue().equals("true"))
- {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns true if the given member is pending in the given community
- *
- * @return
- */
- private boolean isMemberPending( CommunityPojo cp, PersonPojo pp)
- {
- for ( CommunityMemberPojo cmp : cp.getMembers() )
- {
- if ( cmp.get_id().equals(pp.get_id()) )
- {
- if ( cmp.getUserStatus().equals("pending") )
- {
- //found the user, and his status is pending
- return true;
- }
- return false;
- }
- }
- return false;
- //TESTED only finds members that are pending while sysadmin
- }
- /**
- * requ…
Large files files are truncated, but you can click here to view the full file