public async Task Test_05_AccessControl_GetBlogsAsync() { using (KoalaBlogDbContext dbContext = new KoalaBlogDbContext()) { BlogHandler blogHandler = new BlogHandler(dbContext); GroupHandler groupHandler = new GroupHandler(dbContext); GroupMemberHandler gmHandler = new GroupMemberHandler(dbContext); PersonHandler perHandler = new PersonHandler(dbContext); PersonXPersonHandler pxpHandler = new PersonXPersonHandler(dbContext); Person faker = CreatePerson("TestFaker", "TestFaker"); Person marin = CreatePerson("TestMarin", "TestMarin"); Person deft = CreatePerson("TestDeft", "TestDeft"); Follow(faker.ID, marin.ID, deft.ID); //1. test access info MySelfOnly. await blogHandler.CreateBlogAsync(faker.ID, "TestContentByFakerOne", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(marin.ID, "TestContentByMarinOne", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(marin.ID, "TestContentByMarinTwo", BlogInfoAccessInfo.MyselfOnly); await blogHandler.CreateBlogAsync(deft.ID, "TestContentByDeftOne", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(deft.ID, "TestContentByDeftTwo", BlogInfoAccessInfo.MyselfOnly); List<Blog> blogs = await blogHandler.GetBlogsAsync(faker.ID); Assert.AreEqual(blogs.Count, 3); foreach (var blog in blogs) { Assert.AreNotEqual(blog.Content, "TestContentByMarinTwo"); Assert.AreNotEqual(blog.Content, "TestContentByDeftTwo"); } //2. test access info GroupOnly. Person paul = CreatePerson("TestPaul", "TestPaul"); Person judy = CreatePerson("TestJudy", "TestJudy"); Person anne = CreatePerson("TestAnne", "TestAnne"); Person alisa = CreatePerson("TestAlisa", "TestAlisa"); Follow(paul.ID, judy.ID, anne.ID, alisa.ID); //judy group not include paul. Group judyGroup = await groupHandler.CreateGroupAsync(judy.ID, "TestJudyGroup", GroupType.GroupList); //anne group include paul. Group anneGroup = await groupHandler.CreateGroupAsync(anne.ID, "TestAnneGroup", GroupType.GroupList); GroupMember groupMemberByAnne = new GroupMember() { GroupID = anneGroup.ID, PersonID = paul.ID }; gmHandler.Add(groupMemberByAnne); gmHandler.SaveChanges(); //alisa group include judy, anne but not paul. Group alisaGroup = await groupHandler.CreateGroupAsync(alisa.ID, "TestAlisaGroup", GroupType.GroupList); GroupMember groupMemberByAlisaOne = new GroupMember() { GroupID = alisaGroup.ID, PersonID = judy.ID }; GroupMember groupMemberByAlisaTwo = new GroupMember() { GroupID = alisaGroup.ID, PersonID = anne.ID }; gmHandler.Add(groupMemberByAlisaOne); gmHandler.Add(groupMemberByAlisaTwo); gmHandler.SaveChanges(); await blogHandler.CreateBlogAsync(paul.ID, "TestContentByPaul", BlogInfoAccessInfo.MyselfOnly); await blogHandler.CreateBlogAsync(judy.ID, "TestContentByJudyOne", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(judy.ID, "TestContentByJudyTwo", BlogInfoAccessInfo.GroupOnly, judyGroup.ID); await blogHandler.CreateBlogAsync(anne.ID, "TestContentByAnne", BlogInfoAccessInfo.GroupOnly, anneGroup.ID); await blogHandler.CreateBlogAsync(alisa.ID, "TestContentByAlisa", BlogInfoAccessInfo.GroupOnly, alisaGroup.ID); blogs = await blogHandler.GetBlogsAsync(paul.ID); Assert.AreEqual(blogs.Count, 3); foreach (var blog in blogs) { Assert.AreNotEqual(blog.Content, "TestContentByJudyTwo"); Assert.AreNotEqual(blog.Content, "TestContentByAlisa"); } //3. test access info FriendOnly. Person sam = CreatePerson("TestSam", "TestSam"); Person joan = CreatePerson("TestJoan", "TestJoan"); Person lily = CreatePerson("TestLily", "TestLily"); Follow(sam.ID, joan.ID, lily.ID); //3.1 test joan and sam is friend but not lily. Follow(joan.ID, sam.ID); await blogHandler.CreateBlogAsync(joan.ID, "TestContentByJoanOne", BlogInfoAccessInfo.FriendOnly); await blogHandler.CreateBlogAsync(joan.ID, "TestContentByJoanTwo", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(lily.ID, "TestContentByLilyOne", BlogInfoAccessInfo.FriendOnly); await blogHandler.CreateBlogAsync(lily.ID, "TestContentByLilyTwo", BlogInfoAccessInfo.FriendOnly); blogs = await blogHandler.GetBlogsAsync(sam.ID); Assert.AreEqual(blogs.Count, 2); foreach (var blog in blogs) { Assert.AreNotEqual(blog.Content, "TestContentByLilyOne"); Assert.AreNotEqual(blog.Content, "TestContentByLilyTwo"); } //3.2 now lily follow sam too. Follow(lily.ID, sam.ID); blogs = await blogHandler.GetBlogsAsync(sam.ID); Assert.AreEqual(blogs.Count, 4); } }
private void Follow(long selfPerId, params long[] followingIds) { using(KoalaBlogDbContext dbContext = new KoalaBlogDbContext()) { PersonXPersonHandler pxpHandler = new PersonXPersonHandler(dbContext); foreach (var followingId in followingIds) { PersonXPerson pxp = new PersonXPerson() { FollowerID = selfPerId, FollowingID = followingId }; pxpHandler.Add(pxp); } pxpHandler.SaveChanges(); } }
public async Task Test_04_Normal_GetBlogsAsync() { using(KoalaBlogDbContext dbContext = new KoalaBlogDbContext()) { BlogHandler blogHandler = new BlogHandler(dbContext); GroupHandler groupHandler = new GroupHandler(dbContext); GroupMemberHandler gmHandler = new GroupMemberHandler(dbContext); PersonHandler perHandler = new PersonHandler(dbContext); PersonXPersonHandler pxpHandler = new PersonXPersonHandler(dbContext); //1. test normal. bool isChecked = false; try { List<Blog> invalidPersonIdBlogs = await blogHandler.GetBlogsAsync(999999999); } catch (Exception ex) { isChecked = true; Assert.AreEqual(ex.Message, "该用户不存在"); } Assert.IsTrue(isChecked); Person master = CreatePerson("TestMasterPer", "TestMasterMind"); Person mary = CreatePerson("TestMary", "TestMary"); Person nick = CreatePerson("TestNick", "TestNick"); Person tony = CreatePerson("TestTony", "TestTony"); //1. create some blog and test it. await blogHandler.CreateBlogAsync(master.ID, "TestContentByMaster", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(mary.ID, "TestContentByMaryOne", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(mary.ID, "TestContentByMaryTwo", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(nick.ID, "TestContentByNickOne", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(tony.ID, "TestContentByTonyOne", BlogInfoAccessInfo.All); Follow(master.ID, mary.ID, nick.ID, tony.ID); List<Blog> blogs = await blogHandler.GetBlogsAsync(master.ID); Assert.AreEqual(blogs.Count, 5); Assert.AreEqual(blogs.Count(x => x.PersonID == mary.ID), 2); Assert.AreEqual(blogs.Count(x => x.PersonID == nick.ID), 1); Assert.AreEqual(blogs.Count(x => x.PersonID == tony.ID), 1); Assert.AreEqual(blogs.Count(x => x.PersonID == master.ID), 1); //2. add a group and add some group member test it. Group masterGroup = new Group() { PersonID = master.ID, Name = "TestMasterGroup", Type = GroupType.GroupList }; groupHandler.Add(masterGroup); groupHandler.SaveChanges(); GroupMember GroupMemberByMary = new GroupMember() { GroupID = masterGroup.ID, PersonID = mary.ID }; GroupMember GroupMemberByNick = new GroupMember() { GroupID = masterGroup.ID, PersonID = nick.ID }; gmHandler.Add(GroupMemberByMary); gmHandler.Add(GroupMemberByNick); gmHandler.SaveChanges(); //3. test get blog by group. blogs = await blogHandler.GetBlogsAsync(master.ID, masterGroup.ID); Assert.AreEqual(blogs.Count, 4); Assert.AreEqual(blogs.Count(x => x.PersonID == mary.ID), 2); Assert.AreEqual(blogs.Count(x => x.PersonID == nick.ID), 1); Assert.AreEqual(blogs.Count(x => x.PersonID == master.ID), 1); //4. add shield group and test it. Person mike = CreatePerson("TestMike", "TestMike"); Person yoyo = CreatePerson("TestYOYO", "TestYOYO"); Person pipi = CreatePerson("TestPIPI", "TestPIPI"); Person poko = CreatePerson("TestPoko", "TestPoko"); Follow(master.ID, mike.ID, yoyo.ID, pipi.ID, poko.ID); await blogHandler.CreateBlogAsync(mike.ID, "TestContentByMikeOne", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(mike.ID, "TestContentByMikeTwo", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(yoyo.ID, "TestContentByYoyoOne", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(yoyo.ID, "TestContentByYoyoTwo", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(pipi.ID, "TestContentByPipiOne", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(poko.ID, "TestContentByPokoOne", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(poko.ID, "TestContentByPokoTwo", BlogInfoAccessInfo.All); await blogHandler.CreateBlogAsync(poko.ID, "TestContentByPokoThree", BlogInfoAccessInfo.All); Group masterShieldGroup = new Group() { PersonID = master.ID, Name = "TestMasterShield", Type = GroupType.ShieldList }; groupHandler.Add(masterShieldGroup); groupHandler.SaveChanges(); GroupMember GroupMemberByPoko = new GroupMember() { GroupID = masterShieldGroup.ID, PersonID = poko.ID }; gmHandler.Add(GroupMemberByPoko); gmHandler.SaveChanges(); blogs = await blogHandler.GetBlogsAsync(master.ID); Assert.AreEqual(blogs.Count, 10); foreach (var blog in blogs) { Assert.AreNotEqual(blog.PersonID, poko.ID); Assert.AreNotEqual(blog.Content, "TestContentByPokoOne"); Assert.AreNotEqual(blog.Content, "TestContentByPokoTwo"); Assert.AreNotEqual(blog.Content, "TestContentByPokoThree"); } //5. add group member to normal group and test it. GroupMember GroupMemberByPoko_Normal = new GroupMember() { GroupID = masterGroup.ID, PersonID = poko.ID }; gmHandler.Add(GroupMemberByMary); blogs = await blogHandler.GetBlogsAsync(master.ID, masterGroup.ID); Assert.AreEqual(blogs.Count, 4); Assert.AreEqual(blogs.Count(x => x.PersonID == mary.ID), 2); Assert.AreEqual(blogs.Count(x => x.PersonID == nick.ID), 1); Assert.AreEqual(blogs.Count(x => x.PersonID == master.ID), 1); } }
/// <summary> /// 取消关注 /// </summary> /// <param name="followerId">关注者ID</param> /// <param name="unFollowPerId">取消关注者ID</param> /// <returns></returns> public async Task<bool> UnFollowAsync(long followerId, long unFollowPerId) { PersonXPersonHandler pxpHandler = new PersonXPersonHandler(_dbContext); //1. 检查关注人的关注名单是否已经关注了。 PersonXPerson pxp = await pxpHandler.Fetch(x => x.FollowerID == followerId && x.FollowingID == unFollowPerId).SingleOrDefaultAsync(); //2. 如果存在记录,则删除记录,取消关注。 if(pxp != null) { pxpHandler.MarkAsDeleted(pxp); return await pxpHandler.SaveChangesAsync() > 0; } return true; }
/// <summary> /// 关注 /// </summary> /// <param name="followerId">关注者ID</param> /// <param name="followingId">被关注者ID</param> /// <returns></returns> public async Task<bool> FollowAsync(long followerId, long followingId) { GroupHandler groupHandler = new GroupHandler(_dbContext); PersonXPersonHandler pxpHandler = new PersonXPersonHandler(_dbContext); //1. 检查被关注人黑名单是否存在关注人,若已拉黑,则无法关注。 Group blackGroup = await groupHandler.Include(x => x.GroupMembers).SingleOrDefaultAsync(x => x.PersonID == followingId && x.Type == GroupType.BlackList); if(blackGroup != null && blackGroup.GroupMembers.Count > 0) { bool isInGroupMember = blackGroup.GroupMembers.Select(x => x.PersonID).Contains(followerId); if(isInGroupMember) { throw new DisplayableException("由于用户设置,你无法关注。"); } } //2. 检查关注人的关注名单是否已经关注了。 bool isFollow = await pxpHandler.Fetch(x => x.FollowerID == followerId && x.FollowingID == followingId).SingleOrDefaultAsync() != null; //3. 如果未关注则添加纪录。 if(!isFollow) { PersonXPerson pxp = new PersonXPerson() { FollowerID = followerId, FollowingID = followingId }; pxpHandler.Add(pxp); return await SaveChangesAsync() > 0; } return true; }
/// <summary> /// 获取正在关注数量 /// </summary> /// <param name="personId">PersonID</param> /// <returns></returns> public async Task<int> GetFollowingCountAsync(long personId) { using (KoalaBlogDbContext dbContext = new KoalaBlogDbContext()) { PersonXPersonHandler pxpHandler = new PersonXPersonHandler(dbContext); return await pxpHandler.GetFollowingCountAsync(personId); } }
/// <summary> /// 获取当前用户关注的人Blog /// </summary> /// <param name="personId">用户ID</param> /// <param name="groupId">组ID</param> /// <returns></returns> public async Task<List<Blog>> GetBlogsAsync(long personId, long? groupId = null, int pageIndex = 1, int pageSize = int.MaxValue) { PersonHandler perHandler = new PersonHandler(_dbContext); GroupHandler groupHandler = new GroupHandler(_dbContext); BlogAccessControlHandler acHandler = new BlogAccessControlHandler(_dbContext); //1. 获取当前用户Person实体,并加载正在关注列表。 Person per = await perHandler.Include(x => x.MyFollowingPersons).SingleOrDefaultAsync(x => x.ID == personId); if(per == null) { throw new DisplayableException("该用户不存在"); } //2. 获取组成员或者已关注的用户ID集合,若指定了GroupID,则获取组里成员ID集合,反则获取已关注的人ID集合。 List<long> perIds = new List<long>(); if(groupId.HasValue) { Group normalGroup = await groupHandler.Include(x => x.GroupMembers).SingleOrDefaultAsync(x => x.ID == groupId); if(normalGroup != null) { if(normalGroup.PersonID != personId) { throw new DisplayableException("该组不属于此用户"); } //2.1 获取指定Group的用户ID集合。 if(normalGroup.GroupMembers.Count > 0) { perIds = normalGroup.GroupMembers.Select(x => x.PersonID).ToList(); } } } else { //2.2 获取当前用户已关注的用户ID集合。 perIds = per.MyFollowingPersons.Select(x => x.FollowingID).ToList(); } //2.3 加上当前用户的ID,提供查询当前用户的Blog。 perIds.Add(personId); //3. 获取当前用户屏蔽名单Group。 Group shieldGroup = await groupHandler.Include(x => x.GroupMembers).SingleOrDefaultAsync(x => x.PersonID == personId && x.Type == GroupType.ShieldList); if (shieldGroup != null && shieldGroup.GroupMembers.Count > 0) { List<long> shieldListIds = shieldGroup.GroupMembers.Select(x => x.PersonID).ToList(); //3.1 过滤屏蔽名单上的用户,不加载屏蔽名单上用户的Blog。 perIds = perIds.Except(shieldListIds).ToList(); } //4. 获取过滤后的用户ID集合的Blog列表,以创建时间降序排序。 List<Blog> blogs = await Fetch(x => perIds.Contains(x.PersonID) && !x.IsDeleted).OrderByDescending(x => x.CreatedDate).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(); if(blogs.Count > 0) { //5.1 获取排除当前用户ID的BlogIDs集合。 List<long> blogListIds = blogs.Where(x => x.PersonID != personId).Select(x => x.ID).ToList(); //5.2 获取Blog列表的AccessControl(权限控制)列表,排除公开的权限控制。 List<BlogAccessControl> blogAccessControls = await acHandler.Fetch(x => blogListIds.Contains(x.BlogID) && x.AccessLevel != BlogInfoAccessInfo.All).ToListAsync(); foreach (var blogAccessControl in blogAccessControls) { Blog acBlog = blogs.Single(x => x.ID == blogAccessControl.BlogID); //5.3 如果权限控制为仅自己可见,且发表Blog的用户ID不等于当前用户ID,则过滤掉此Blog。 if (blogAccessControl.AccessLevel == BlogInfoAccessInfo.MyselfOnly) { blogs.Remove(acBlog); } //5.4 如果权限控制为群可见,判断此群的人员名单是否包含当前用户,没有则过滤此Blog。 else if (blogAccessControl.AccessLevel == BlogInfoAccessInfo.GroupOnly) { BlogAccessControlXGroupHandler acxgHandler = new BlogAccessControlXGroupHandler(_dbContext); BlogAccessControlXGroup acxGroup = await acxgHandler.Include(x => x.Group, x => x.Group.GroupMembers).SingleOrDefaultAsync(x => x.BlogAccessControlID == blogAccessControl.ID); if (acxGroup != null) { bool isInGroupMember = false; if (acxGroup.Group != null && acxGroup.Group.GroupMembers.Count > 0) { isInGroupMember = acxGroup.Group.GroupMembers.Select(x => x.PersonID).Any(x => x == personId); } if (!isInGroupMember) { blogs.Remove(acBlog); } } } //5.5 如果权限控制为朋友圈可见,判断当前用户是否与互相关注(Friends),如果不是则过滤此Blog。 else if (blogAccessControl.AccessLevel == BlogInfoAccessInfo.FriendOnly) { PersonXPersonHandler pxpHandler = new PersonXPersonHandler(_dbContext); bool isFriend = await pxpHandler.IsFriendAsync(personId, acBlog.PersonID); if (!isFriend) { blogs.Remove(acBlog); } } } } return blogs; }