private async Task UnReact(ActivityObject reaction, ActivityDeliveryContext ctx) { foreach (var target in (reaction ?? throw new ArgumentNullException(nameof(reaction))).target.items) { await _redis.Decrement <ReactionsSummaryModel>($"{reaction.type}Count", target.id, null); } }
public async Task <BaseObject> Delete(ActivityDeliveryContext ctx, Delete delete) { // var now = DateTime.UtcNow; // shop.WhenDeleted = now; // shop.LastUpdated = now; // await _dbContext.SaveChangesAsync(); return(null); }
public async Task <BaseObject> Follow(ActivityDeliveryContext ctx, Delete delete) { // todo: A blog can only follow 5,000 other blogs at a time. // var now = DateTime.UtcNow; // shop.WhenDeleted = now; // shop.LastUpdated = now; // await _dbContext.SaveChangesAsync(); return(null); }
public async Task <CollectionObject> Get(ActivityStreamFilter filter) { var ret = new List <BaseObject>(); var pipe = this.ctx.GetPipe(); var ctx = new ActivityDeliveryContext { IsReading = true, context = this.ctx, box = this, Filter = filter }; var tryCount = 0; using (var reader = await OpenReader(filter)) { while (true) { var item = await reader.Read(); if (item == null) { if (tryCount == 0) { return(null); } break; } else if (item is Error err) { ret.Add(item); } else if (item is ActivityObject activity) { if (filter.IsMatch(activity)) { ctx.item = activity; var res = await pipe.Pipe(ctx) ?? ctx.item; if (res != null) { ret.Add(res); } } } else { throw new Exception($"Invalid type {item.type}"); } tryCount++; } } if (ctx.Undos.Count > 0) { ret = ret.Where(r => !ctx.Undos.Contains(r.id)).ToList(); } return(ret.ToCollection()); }
public override Task <BaseObject> Pipe(ActivityDeliveryContext ctx) { if (ctx.IsWriting && ctx.box.filter.index == "outbox") { return(base.Pipe(ctx)); } else { return(Task.FromResult <BaseObject>(null)); } }
private async Task <BaseObject> ReactAndGetSummary(ActivityDeliveryContext ctx, ActivityObject reaction, ReactionType reactionType) { if (ctx.HasWritten) { foreach (var target in ctx.item.target.items) { await _redis.Increment <ReactionsSummaryModel>($"{reactionType}Count", target.id, null); } } return(null); }
public Task <BaseObject> BlockPerson(ActivityDeliveryContext ctx, Block block, Person person) { BaseObject ret = null; if (block.GetPublisher().PublicId == person.PublicId) { ret = new Error { statusCode = 403, errorCode = 403, summary = "Cannot block yourself" }; } return(Task.FromResult(ret)); }
public async Task <BaseObject> CreateNote(ActivityDeliveryContext ctx, Create create, Note note) { // // if (ctx.box.name != "sharedOutbox" && ctx.box.name != "sharedOutbox" && // // (ctx.item.visibility ?? Visibility.VISIBLE_TO_WORLD) == Visibility.VISIBLE_TO_WORLD) // // { // // ctx.Forward(ctx.item, new Tides.Models.ActivityStreamFilter // // { // // index = "sharedOutbox", // // }); // // } return(null); }
public async Task <BaseObject> Pipe(ActivityDeliveryContext ctx) { if (ctx.IsReading) { // var mentions = await _dbContext.Mentions.Where(m => m.PostId == p.Id).ToListAsync(); // foreach (var m in mentions) // { // m.MentionedPublicUser = await _users.GetUser(new PublicId(m.MentionedUserId, m.MentionedUserPeerId), value.ViewerId); // } // value.Mentions = mentions.Where(m => m.MentionedPublicUser != null).ToList(); } return(null); }
public Task <BaseObject> Pipe(ActivityDeliveryContext ctx) { if (ctx.IsReading && ctx.item.obj != null && ctx.Filter != null && ctx.Filter.objectTypes != null && ctx.Filter.objectTypes.Length > 0) { if (Array.IndexOf(ctx.Filter.objectTypes, ctx.item.obj.type) < 0 && Array.IndexOf(ctx.Filter.objectTypes, ctx.item.obj.BaseType) < 0) { ctx.item = null; } } return(Task.FromResult <BaseObject>(null)); }
public async Task <BaseObject> Pipe(ActivityDeliveryContext ctx) { if (ctx.item.obj is Document media) { // if (media.RelatedPost == null && media.RelatedPostId.HasValue) // { // // TODO: give media peer ids // media.RelatedPost = await _posts.GetPost(new PublicId(media.RelatedPostId.Value, 0), viewerId); // } } await Task.Delay(1); return(ctx.item.obj); }
protected async Task <BaseObject> HandleRequest(ActivityDeliveryContext ctx, string handlerName, Func <ActivityDeliveryContext, object[]> getArguments) { var handler = this.GetType().GetMember(handlerName, BindingFlags.Instance | BindingFlags.Public); if (handler != null && handler.Length == 1) { var res = this.GetType().InvokeMember(handlerName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, null, this, getArguments != null ? getArguments.Invoke(ctx) : new object[] { ctx }); return(await HandleResult(res)); } else { return(null); //throw new Exception($"Cannot handle {activityAction}"); } }
public override async Task <BaseObject> Pipe(ActivityDeliveryContext ctx) { if (ctx.item.from == null || ctx.item.from.items.Count == 0) { return(new Error { errorCode = 403, statusCode = 403, summary = "Missing from in item" }); } else if (ctx.item is ActivityObject activity && activity.obj != null && (activity.obj.from == null || activity.obj.from.items.Count == 0)) { return(new Error { errorCode = 403, statusCode = 403, summary = "Missing from in item.obj" }); } return(null); }
private async Task BindSqlActorCollection(CollectionObject collection, ActivityDeliveryContext ctx) { if (collection?.items != null) { var nonActors = collection.items.Except(collection.items.OfType <ActorObject>()).ToList(); foreach (var actor in nonActors) { var actor2 = await _contentRepository.Get(actor.PublicId, new PublicId(ctx.Filter.viewerId, 0)); collection.items[collection.items.IndexOf(actor)] = actor2; } foreach (var actor in collection.items.Where(a => a != null).OfType <ActorObject>()) { await BindSqlActor(ctx, actor); } } }
private async Task BindSqlExtra(ActivityDeliveryContext ctx, BaseObject bindTo) { if (bindTo.ViewerId.HasValue) { var viewerId = new PublicId(bindTo?.ViewerId.Value, 0); viewerId.Type = "Person"; var reactionsFilter = new ActivityStreamFilter("outbox") { id = viewerId, viewerId = bindTo?.ViewerId.Value, targetId = bindTo.PublicId, includeReplies = false, }.ReactionsOnly(); var reactionsBox = ctx.context.GetBox(reactionsFilter); bindTo.Reactions = await reactionsBox.Get(reactionsFilter); if (bindTo.Reactions.items.Count > 0) { var reactionTypes = bindTo.Reactions.items.Select(r => r.type).ToHashSet(); if (reactionTypes.Count > 0) { bindTo.HasLiked = reactionTypes.Contains(nameof(ReactionType.Like)); bindTo.HasDisliked = reactionTypes.Contains(nameof(ReactionType.Dislike)); bindTo.HasUpvoted = reactionTypes.Contains(nameof(ReactionType.Upvote)); bindTo.HasDownvoted = reactionTypes.Contains(nameof(ReactionType.Downvote)); bindTo.HasFollowed = reactionTypes.Contains(nameof(ReactionType.Follow)); bindTo.HasIgnored = reactionTypes.Contains(nameof(ReactionType.Ignore)); bindTo.HasBlocked = reactionTypes.Contains(nameof(ReactionType.Block)); bindTo.HasReported = reactionTypes.Contains(nameof(ReactionType.Report)); bindTo.HasBeenBlockedOrReportedByViewer = bindTo.HasReported || bindTo.HasBlocked; } } } var reactionsSummary = await _redis.Get <ReactionsSummaryModel>(bindTo.id); if (reactionsSummary != null) { bindTo.LikeCount = reactionsSummary.LikeCount; bindTo.DislikeCount = reactionsSummary.DislikeCount; bindTo.UpvoteCount = reactionsSummary.UpvoteCount; bindTo.DownvoteCount = reactionsSummary.DownvoteCount; bindTo.FollowCount = reactionsSummary.FollowCount; bindTo.IgnoreCount = reactionsSummary.IgnoreCount; bindTo.BlockCount = reactionsSummary.BlockCount; bindTo.ReportCount = reactionsSummary.ReportCount; } }
public async Task <BaseObject> Create(ActivityDeliveryContext ctx, Create create) { if (ctx.HasWritten) { var publisher = create.GetPublisher(); if (publisher != null && publisher.PublicId.IsLocal && ctx.item.obj != null && ctx.item.obj.PublicId.IsLocal && ctx.item.obj.tag != null && ctx.item.obj.tag.items.Any()) { var tags = ctx.item.obj.tag.items.Select(t => new TagModel { Tag = t.content }).ToList(); await _tags.Save(tags, publisher.UserId.Value, ctx.item.obj.PublicId); } } else { var publisherId = create.GetPublisher()?.PublicId; if (publisherId != null) { if (create.obj.objectId == null && (create.obj.PeerId == null || create.obj.PeerId == 0)) { create.published = DateTime.UtcNow; await _ids.UploadObject(publisherId, create.obj); } } else { throw new ArgumentNullException(nameof(publisherId)); } if (create.obj != null && create.obj is ActorObject actor && !string.IsNullOrWhiteSpace(actor.preferredUsername)) { if (await _handles.HandleExists(actor.preferredUsername, actor.type)) { throw new ArgumentException($"{actor.type} preferredUsername taken", nameof(actor.preferredUsername)); } } } return(null); }
public async Task <BaseObject> Create(ActivityDeliveryContext ctx, Create create) { if (ctx.HasWritten) { // deliver to other inboxes // var followers = await _users.GetFollowers(new PublicId(post.UserId, post.PeerId), post.UserId); // if (followers.Length > 0) // { // await _notifications.Publish(new Models.AhPushIt.Notification() { // FromUserId = post.UserId, // SubjectId = post.Id, // Priority = NotificationPriority.Normal, // Subject = ReactionSubject.Post, // Type = NotificationType.TEXT_POST_FOLLOWED_USER, // }, followers.Select(u => u.PublicId).ToArray()); // } } else { } return(null); }
private async Task BindSqlActor(ActivityDeliveryContext ctx, ActorObject bindTo) { if (bindTo.PublicId != null && bindTo.PublicId.IsLocal && bindTo.PublicId.Id.HasValue) { var profile = await _db.Users.FindAsync(bindTo.PublicId.Id.Value); if (profile != null) { bindTo.name = profile.DisplayName; bindTo.Handle = profile.Handle; bindTo.BanExpires = profile.BanExpires; bindTo.BanReason = profile.BanReason; bindTo.summary = profile.Bio; //bindTo.content = content.Content; //bindTo.mediaType = content.MediaType; //bindTo.vis = content.Visibility; bindTo.published = profile.WhenCreated; bindTo.updated = profile.WhenLastUpdated; bindTo.deleted = profile.WhenDeleted; //bindTo.IsMature = profile.IsMature; } } }
public async Task <BaseObject> CreateNote(ActivityDeliveryContext ctx, Create create, Note note) { if (ctx.HasWritten) { if (create.to?.items != null && create.to.items.Any()) { // _dbContext.Mentions.AddRange(create.to); // new MentionModel() // { // WhenMentioned = DateTime.UtcNow, // PostId = p.Id, // PostPeerId = p.PeerId, // Post = p, // MentionedUserId = user.UserId, // MentionedUserPeerId = user.PeerId, // MentionedPublicUser = user // }; } // // if (ctx.box.name != "sharedOutbox" && ctx.box.name != "sharedOutbox" && // // (ctx.item.visibility ?? Visibility.VISIBLE_TO_WORLD) == Visibility.VISIBLE_TO_WORLD) // // { // // ctx.Forward(ctx.item, new Tides.Models.ActivityStreamFilter // // { // // index = "sharedOutbox", // // }); // // } } else { if (!string.IsNullOrWhiteSpace(note.content)) { await ExtractMentions(note); await ExtractTags(create, note); } } return(null); }
private async Task BindReactions(ActivityDeliveryContext ctx) { await BindSqlActorCollection(ctx.item.actor, ctx); if (ctx.item.obj != null) { await BindSqlActorCollection(ctx.item.obj.from, ctx); if (ctx.item.type != "Undo") { await BindSqlExtra(ctx, ctx.item.obj); } } if (ctx.item.target?.items != null) { foreach (var target in ctx.item.target.items) { await BindSqlActorCollection(target.from, ctx); await _contentRepository.BindSqlContent(target); await BindSqlExtra(ctx, target); } } }
public async Task <BaseObject> Pipe(ActivityDeliveryContext ctx) { ctx.item.ViewerId = ctx.Filter.viewerId; if (ctx.item.obj != null) { ctx.item.obj.ViewerId = ctx.Filter.viewerId; } if (ctx.item.PeerId == 0) { // if (shop.OwnerUser == null) // { // shop.OwnerUser = await _users.GetUser(new PublicId(shop.UserId, shop.PeerId), viewerId); // } // if (value.User == null) // { // value.User = await _users.GetUser(value.UserId, value.ViewerId); // } } if (ctx.item.ViewerId.HasValue && ctx.IsReading) { await BindReactions(ctx); if (ctx.item.obj != null && ctx.item.obj.ViewerIsPublisher) { } else { //var blockOrReport = await _reactions.HasBlockedViewer(ReactionSubject.Profile, id, viewerId); //user.HasBeenBlockedOrReportedByPublisher = blockOrReport; //media.ViewerIsFollowing = true; } } return(null); }
public async Task <BaseObject> Follow(ActivityDeliveryContext ctx, Follow follow) => await ReactAndGetSummary(ctx, follow, ReactionType.Follow);
public async Task <BaseObject> Upvote(ActivityDeliveryContext ctx, Upvote upvote) => await ReactAndGetSummary(ctx, upvote, ReactionType.Upvote);
public async Task <BaseObject> CreateOrganization(ActivityDeliveryContext ctx, Create create, Organization org) { return(null); }
public async Task <BaseObject> Downvote(ActivityDeliveryContext ctx, Downvote downvote) => await ReactAndGetSummary(ctx, downvote, ReactionType.Downvote);
public override async Task <BaseObject> Pipe(ActivityDeliveryContext ctx) { if (ctx.IsWriting && ctx.box.filter.index == "outbox") { if (ctx.HasWritten) { if (ctx.item.to != null && ctx.item.to.items.Count > 0) { var vis = ctx.item.to.items.Concat(ctx.item.obj.audience.items). OfType <ActorObject>().Where(a => a.BaseType == "Actor" && a.type == "Group"). Select(a => a.Handle).ToArray(); // deliver to other outboxes if (vis.Contains("followers")) { var publisher = ctx.item.GetPublisher(); var followers = await ctx.context.GetAll(new ActivityStreamFilter("followers") { id = publisher.PublicId }); if (followers != null && followers.items.Count > 0) { // Send to followers foreach (var follower in followers.items.OfType <ActorObject>()) { await ctx.context.Set(ctx.item, new ActivityStreamFilter("inbox") { id = publisher.PublicId }); } } } if (vis.Contains("registered")) { await ctx.context.Set(ctx.item, new ActivityStreamFilter("sharedOutbox") { id = ctx.Filter.id }); } // await ctx.context.Post("sharedOutbox", ctx.item); } else { await ctx.context.Set(ctx.item, new ActivityStreamFilter("sharedOutbox") { id = ctx.Filter.id }); } // if (!string.IsNullOrWhiteSpace(ctx.item.obj?.id)) // { // await ctx.context.Set(ctx.item, new ActivityStreamFilter(ctx.item.obj.id)); // } // if (ctx.Filter.index == "sharedOutbox") // { // if (vis == null) // { // await ctx.context.Set(ctx.item, new ActivityStreamFilter("globalOutbox")); // } // } } else { if (!await _rateLimitService.TryActorAction(ctx.item.GetPublisher().PublicId, ctx.item.type)) { return(new Error { errorCode = 429, statusCode = 429, summary = "Too many requests for this action" }); } if (string.IsNullOrWhiteSpace(ctx.item.id)) { ctx.item.id = Guid.NewGuid().ToString(); ctx.item.published = DateTime.UtcNow; } } return(await base.Pipe(ctx)); } else { return(null); } }
public async Task <BaseObject> Ignore(ActivityDeliveryContext ctx, Ignore ignore) => await ReactAndGetSummary(ctx, ignore, ReactionType.Ignore);
public async Task <BaseObject> Undo(ActivityDeliveryContext ctx, Undo undo) { if (ctx.HasWritten) { switch (undo.obj.type) { case nameof(Like): await UnReact(undo.obj as Like, ctx); break; case nameof(Dislike): await UnReact(undo.obj as Dislike, ctx); break; case nameof(Upvote): await UnReact(undo.obj as Upvote, ctx); break; case nameof(Downvote): await UnReact(undo.obj as Downvote, ctx); break; case nameof(Ignore): await UnReact(undo.obj as Ignore, ctx); // todo: remove from ignore list break; case nameof(Report): await UnReact(undo.obj as Report, ctx); // todo: remove from report list break; case nameof(Flag): await UnReact(undo.obj as Flag, ctx); // todo: remove from flag list break; case nameof(Block): await UnReact(undo.obj as Block, ctx); // todo: remove from block list break; case nameof(Follow): await UnReact(undo.obj as Follow, ctx); // todo: send unfollow break; default: return(new Error { statusCode = 403, errorCode = 403, summary = $"Cannot undo {undo.obj.type}" }); } } return(null); }
public async Task <BaseObject> Report(ActivityDeliveryContext ctx, Report report) => await ReactAndGetSummary(ctx, report, ReactionType.Report);
public async Task <BaseObject> Block(ActivityDeliveryContext ctx, Block block) => await ReactAndGetSummary(ctx, block, ReactionType.Block);