/// <summary> /// Deletes all the contents of the community, including its sub communities/folders and contents recursively. /// </summary> /// <param name="community">Community whose contents to be deleted</param> /// <param name="profileId">User Identity</param> private void DeleteCommunityContents(Community community, long profileId, bool isOffensive, OffensiveEntry offensiveDetails) { if (community != null) { community.DeletedDatetime = DateTime.UtcNow; community.IsDeleted = true; if (offensiveDetails.EntityID == community.CommunityID) { community.IsOffensive = isOffensive; } // Update all the offensive entity entries if the community is being deleted. UpdateAllOffensiveCommunityEntry(community.CommunityID, offensiveDetails); // Mark all the contents of the community as deleted and also delete the relation entry from CommunityContents table. for (var i = community.CommunityContents.Count - 1; i >= 0; i--) { var communityContent = Enumerable.ElementAt(community.CommunityContents, i); if (communityContent.Content.IsDeleted == false) { if (offensiveDetails.EntityID == community.CommunityID) { communityContent.Content.IsOffensive = isOffensive; } communityContent.Content.IsDeleted = true; communityContent.Content.DeletedDatetime = DateTime.UtcNow; // Update all the offensive entity entries if the community is being deleted. UpdateAllOffensiveContentEntry(communityContent.Content.ContentID, offensiveDetails); } } // Mark all the child communities and folders as deleted. Note that current community is parent and // all its relations with children will be there in CommunityRelation. Also deleting the relation entry from CommunityRelation table. for (var i = community.CommunityRelation.Count - 1; i >= 0; i--) { var communityRelation = Enumerable.ElementAt(community.CommunityRelation, i); // Incase if the same community is marked as its parent/child in DB directly, without this check delete call will go indefinitely. if (communityRelation.Community1.IsDeleted == false && communityRelation.Community1.CommunityID != community.CommunityID) { DeleteCommunityContents(communityRelation.Community1, profileId, isOffensive, offensiveDetails); } } } }
/// <summary> /// Sets the Community-Tags relations for given Tags. If the tags are not there in the DB, they will be added. /// </summary> /// <param name="tagsString">Comma separated tags string</param> /// <param name="community">Community to which tags to be related</param> internal void SetCommunityTags(string tagsString, Community community) { // Delete all existing tags which are not part of the new tags list. community.RemoveTags(tagsString); // Create Tags and relationships. if (!string.IsNullOrWhiteSpace(tagsString)) { var tagsArray = tagsString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()); if (tagsArray != null && tagsArray.Count() > 0) { var notExistingTags = from tag in tagsArray where Enumerable.FirstOrDefault(community.CommunityTags, t => t.Tag.Name == tag) == null select tag; foreach (var tag in notExistingTags) { var objTag = _tagRepository.GetItem((Tag t) => t.Name == tag); if (objTag == null) { objTag = new Tag(); objTag.Name = tag; } var communityTag = new CommunityTags(); communityTag.Community = community; communityTag.Tag = objTag; community.CommunityTags.Add(communityTag); } } } }
/// <summary> /// Marks all the sub-communities/folder and contents of the community as un-deleted, only if they are not offensive. /// </summary> /// <param name="community">Community whose content and sub-communities/folder to be marked as un-deleted</param> /// <param name="updatePermissions">Update permissions for the community? Only for root community which is getting undeleted to be /// updated for permissions</param> private void UnDeleteCommunityContents(Community community, bool updatePermissions) { if (community != null) { // NOTE: We Should NOT undelete the Community/Content if it is explicitly deleted by the user. // 1. Mark the community as not deleted. community.IsDeleted = false; // We need to mark the community as not offensive as the Admin is marking the community as undeleted. community.IsOffensive = false; // We need to mark the DeletedBy as null as we are Undoing the delete operation. // Also DeleteBy filed will be used to check if the user has explicitly deleted the Community. community.User2 = null; // 2. Check if parent community exists. If it exists and not deleted, continue to next step. If parent community // exist and deleted, delete the parent relationship. if (community.CommunityRelation1.Count > 0) { var parentCommunityId = Enumerable.ElementAt(community.CommunityRelation1, 0).Community.CommunityID; if (Enumerable.ElementAt(community.CommunityRelation1, 0).Community.IsDeleted == true) { parentCommunityId = 0; community.CommunityRelation1.Remove(Enumerable.ElementAt(community.CommunityRelation1, 0)); } if (updatePermissions) { // 3. Update the permissions. // 3.1 If there is not parent community is there or if parent community is deleted, mark all the // permissions as direct, not inherited. // 3.2 If the parent community is available, then check for the roles which are inherited from parent. _userCommunitiesRepository.InheritParentRoles(community, parentCommunityId); } } // 4. Mark all the contents of the community as undeleted, only if they are not offensive. // Also make sure we don't undelete contents which are explicitly deleted by the User. (DeletedBYID will be set explicitly if the content is deleted by user) for (var i = community.CommunityContents.Count - 1; i >= 0; i--) { var communityContent = Enumerable.ElementAt(community.CommunityContents, i); // DeletedBy filed will be used to check if the user has explicitly deleted the Community. if (communityContent.Content.IsDeleted == true && communityContent.Content.DeletedByID == null && (!communityContent.Content.IsOffensive.HasValue || !(bool)communityContent.Content.IsOffensive)) { communityContent.Content.IsDeleted = false; // We need to mark the DeletedBy as null as we are Undoing the delete operation. // Also DeleteBy filed will be used to check if the user has explicitly deleted the Community. communityContent.Content.User2 = null; } } // 5. Mark all the child communities and folders as undeleted. Note that current community is parent and // all its relations with children will be there in CommunityRelation. for (var i = community.CommunityRelation.Count - 1; i >= 0; i--) { var communityRelation = Enumerable.ElementAt(community.CommunityRelation, i); // Incase if the same community is marked as its parent/child in DB directly, without this check delete call will go indefinitely. if (communityRelation.Community1.IsDeleted == true && communityRelation.Community1.CommunityID != community.CommunityID && communityRelation.Community1.DeletedByID == null && (!communityRelation.Community1.IsOffensive.HasValue || !(bool)communityRelation.Community1.IsOffensive)) { UnDeleteCommunityContents(communityRelation.Community1, false); } } } }
public long CreateCommunity(CommunityDetails communityDetail) { // Make sure communityDetails is not null this.CheckNotNull(() => new { communityDetails = communityDetail }); var userRole = GetCommunityUserRole(communityDetail.ParentID, communityDetail.CreatedByID); if (!CanCreateCommunity(communityDetail.ParentID, userRole)) { throw new HttpException(401, Resources.NoPermissionCreateCommunityMessage); } // In case if the community getting created is "User" type, check that the same user already has a "User" community associated with him. // There should be only one "User" community to be created per user. if (communityDetail.CommunityType == CommunityTypes.User) { var existingUserCommunity = _communityRepository.GetItem( c => c.CommunityTypeID == (int) CommunityTypes.User && c.CreatedByID == communityDetail.CreatedByID); if (existingUserCommunity != null) { return existingUserCommunity.CommunityID; } } // 1. Add Community details to the community object. var community = new Community(); Mapper.Map(communityDetail, community); // While creating the community, IsDeleted to be false always. community.IsDeleted = false; community.CreatedDatetime = community.ModifiedDatetime = DateTime.UtcNow; // 2. Add Thumbnail to blob if (communityDetail.Thumbnail != null && communityDetail.Thumbnail.AzureID != Guid.Empty) { if (MoveThumbnail(communityDetail.Thumbnail)) { community.ThumbnailID = communityDetail.Thumbnail.AzureID; } } // 3. Add Tag details. This will also take care of creating tags if they are not there in the Layerscape database. SetCommunityTags(communityDetail.Tags, community); var parentAddedToUserRole = false; if (communityDetail.ParentID > 0) { // 4. Add Parent Community details var communityRelation = new CommunityRelation { ParentCommunityID = communityDetail.ParentID, ChildCommunityID = communityDetail.ID }; // TODO: Need to rename the Data Model property CommunityRelation1 with a more meaningful name. // Note that the relation to be added is to CommunityRelation1 since the current Community is Child. // When the current community is parent, it's relation to be added in CommunityRelation. community.CommunityRelation1.Add(communityRelation); var parentCommunity = _communityRepository.GetItem(c => c.CommunityID == communityDetail.ParentID); if (parentCommunity != null && parentCommunity.UserCommunities.Count > 0) { parentCommunity.ModifiedByID = communityDetail.CreatedByID; parentCommunity.ModifiedDatetime = DateTime.UtcNow; // 5. Inherit Parent Permission Details foreach (var communityUserRole in parentCommunity.UserCommunities) { var userCommunityRole = new UserCommunities { CommunityId = communityDetail.ID, UserID = communityUserRole.UserID, RoleID = communityUserRole.RoleID, IsInherited = true, CreatedDatetime = DateTime.UtcNow }; // Add the current community to the use role // Add the existing users along with their roles community.UserCommunities.Add(userCommunityRole); if (communityUserRole.UserID == communityDetail.CreatedByID) { parentAddedToUserRole = true; } } } } if (!parentAddedToUserRole) { // 6. Add Owner Permission Details only if its not already inherited. var userCommunity = new UserCommunities { CommunityId = communityDetail.ID, UserID = communityDetail.CreatedByID, CreatedDatetime = DateTime.UtcNow, RoleID = (int) UserRole.Owner, IsInherited = false }; // User who is creating the community is the owner. community.UserCommunities.Add(userCommunity); } // Add the community to the repository _communityRepository.Add(community); // Save all the changes made. _communityRepository.SaveChanges(); return community.CommunityID; }
/// <summary> /// Increments the view count of the community identified by the Condition. /// </summary> /// <param name="community">Community for which view count has to be incremented</param> private void IncrementViewCount(Community community) { if (community != null) { // Increment view Count. community.ViewCount = community.ViewCount.HasValue ? community.ViewCount.Value + 1 : 1; _communityRepository.Update(community); // Save changes to the database _communityRepository.SaveChanges(); } }
/// <summary> /// Creates the private community details for the given community. User id is used to check if the user is having any /// pending requests on the private community. /// </summary> /// <param name="community">Community for which private community details has to be created</param> /// <param name="userId">Current user id</param> /// <returns>Community details instance</returns> private CommunityDetails CreatePrivateCommunityDetails(Community community, long? userId) { CommunityDetails communityDetails = null; var permission = Permission.Visitor; // Check if already any pending approvals are there. if (userId.HasValue && _userRepository.PendingPermissionRequests(userId.Value, community.CommunityID)) { permission = Permission.PendingApproval; } communityDetails = new CommunityDetails(permission); communityDetails.ID = community.CommunityID; communityDetails.Name = community.Name; communityDetails.Description = community.Description; communityDetails.AccessTypeID = (int)AccessType.Private; communityDetails.CommunityType = (CommunityTypes)community.CommunityTypeID; // Set Thumbnail properties. var thumbnailDetail = new FileDetail(); thumbnailDetail.AzureID = community.ThumbnailID.HasValue ? community.ThumbnailID.Value : Guid.Empty; communityDetails.Thumbnail = thumbnailDetail; return communityDetails; }
/// <summary> /// Creates the community details for the given community. User id is used to check the user role /// on the community,based on that, CommunityDetails might be null in case is user is not having permission. /// </summary> /// <param name="community">Community for which community details has to be created</param> /// <param name="userId">Current user id</param> /// <param name="checkPendingRequest">Check for pending requests of the user</param> /// <returns>Community details instance</returns> private CommunityDetails CreateCommunityDetails(Community community, long? userId, bool checkPendingRequest) { CommunityDetails communityDetails = null; if (community != null) { Permission permission; var userRole = GetCommunityUserRole(community.CommunityID, userId); if (!CanReadCommunity(userRole)) { throw new HttpException(401, Resources.NoPermissionReadCommunityMessage); } permission = userRole.GetPermission(); // 1. For visitors (not assigned any roles for the community) who are logged in, need to find if any role request is pending approval. // 2. Pending approval is needed only for community details, not to be added in other places. if (checkPendingRequest && userRole == UserRole.Visitor && userId.HasValue && _userRepository.PendingPermissionRequests(userId.Value, community.CommunityID)) { permission = Permission.PendingApproval; } communityDetails = new CommunityDetails(permission); // Some of the values which comes from complex objects need to be set through this method. communityDetails.SetValuesFrom(community); communityDetails.ViewCount = community.ViewCount.HasValue ? community.ViewCount.Value : 0; // Update parent details based on the permission. var parent = Enumerable.FirstOrDefault(community.CommunityRelation1); if (parent != null && parent.Community != null) { var parentUserRole = GetCommunityUserRole(parent.Community.CommunityID, userId); if (!CanReadCommunity(parentUserRole)) { communityDetails.ParentName = string.Empty; communityDetails.ParentID = -1; communityDetails.ParentType = CommunityTypes.None; } } } return communityDetails; }
/// <summary> /// Check whether the user can edit/delete the community. /// </summary> /// <param name="community">Community instance</param> /// <param name="userId">User Identification</param> /// <param name="userRole">Role of the User.</param> /// <returns>True if the user has permission to edit/delete the community; Otherwise False.</returns> protected bool CanEditDeleteCommunity(Community community, long userId, UserRole userRole) { var canEditDelete = false; if (community != null) { if (community.CommunityRelation1.Count == 0) { // a. At the root level only an owner or Site Administrator can modify the community canEditDelete = userRole >= UserRole.Owner; } else { var parentCommunityId = Enumerable.ElementAt(community.CommunityRelation1, 0).ParentCommunityID; if (userRole >= UserRole.ModeratorInheritted) { // Inherited Moderator can edit/delete the current community. canEditDelete = true; } else if (userRole == UserRole.Contributor && community.CreatedByID == userId) { // Contributors can edit/delete only community that they have added, they cannot modify/delete community added by others canEditDelete = true; } else if (GetCommunityUserRole(parentCommunityId, userId) >= UserRole.Moderator) { // b. A moderator can edit/delete any communities/content including those created by others (even the owner) // as long as he is the moderator of the parent of the community/content canEditDelete = true; } } } return canEditDelete; }