Example #1
0
        public async Task <IActionResult> SharedInbox()
        {
            var userId = await _verifier.Verify(Request.Scheme + "://" + Request.Host.ToUriComponent() + Request.Path, HttpContext);

            if (userId == null)
            {
                return(Unauthorized());
            }
            var reader = new StreamReader(Request.Body);
            var data   = ASObject.Parse(await reader.ReadToEndAsync());

            if (!EntityData.IsActivity(data))
            {
                return(StatusCode(403, "Not an activity?"));
            }

            await _connection.OpenAsync();

            using (var transaction = _connection.BeginTransaction())
            {
                APEntity resultEntity;
                if (data["actor"].Any((a) => a.Id == userId))
                {
                    var temporaryStore = new StagingEntityStore(_entityStore);
                    resultEntity = await _entityFlattener.FlattenAndStore(temporaryStore, data, false);

                    await temporaryStore.TrimDown((new Uri(new Uri(userId), "/")).ToString());

                    await temporaryStore.CommitChanges();
                }
                else
                {
                    resultEntity = await _entityStore.GetEntity(data.Id, true);

                    if (resultEntity == null)
                    {
                        return(StatusCode(202));
                    }
                    data = resultEntity.Data;
                }

                var users = await _deliveryService.GetUsersForSharedInbox(data);

                foreach (var user in users)
                {
                    await DeliverToActivityPubTask.Make(new DeliverToActivityPubData { ObjectId = resultEntity.Id, TargetInbox = user.Data["inbox"].First().Id }, _connection);
                }

                transaction.Commit();
                return(StatusCode(202));
            }
        }
Example #2
0
        public async Task <IActionResult> SharedInbox()
        {
            var userId = await _verifier.Verify(Request.Scheme + "://" + Request.Host.ToUriComponent() + Request.Path, HttpContext);

            if (userId == null)
            {
                return(Unauthorized());
            }
            var reader = new StreamReader(Request.Body);
            var data   = ASObject.Parse(await reader.ReadToEndAsync());

            if (!_entityConfiguration.IsActivity(data))
            {
                return(StatusCode(403, "Not an activity?"));
            }
            if (!data["actor"].Any((a) => (string)a.Primitive == userId))
            {
                return(StatusCode(403, "Invalid signature!"));
            }

            var temporaryStore = new StagingEntityStore(_entityStore);
            var resultEntity   = await _entityFlattener.FlattenAndStore(temporaryStore, data, false);

            temporaryStore.TrimDown((new Uri(new Uri(userId), "/")).ToString());
            await temporaryStore.CommitChanges(); // shouuuuld be safe

            var users = await _deliveryService.GetUsersForSharedInbox(data);

            foreach (var user in users)
            {
                if (user.IsOwner)
                {
                    _context.EventQueue.Add(DeliverToActivityPubTask.Make(new DeliverToActivityPubData {
                        ObjectId = resultEntity.Id, TargetInbox = (string)user.Data["inbox"].First().Primitive
                    }));
                }
            }

            await _context.SaveChangesAsync();

            return(StatusCode(202));
        }
Example #3
0
        public async Task <APEntity> ServerToServer(APEntity inbox, ASObject activity, string subject = null)
        {
            var stagingStore = new StagingEntityStore(_mainStore);
            var userId       = inbox.Data["attributedTo"].Single().Id;
            var user         = await _mainStore.GetEntity(userId, false);

            APEntity flattened;

            string prefix = "";

            if (subject != null)
            {
                var subjectUri = new Uri(subject);
                prefix = $"{subjectUri.Scheme}://{subjectUri.Host}";
                if (!subjectUri.IsDefaultPort)
                {
                    prefix += $":{subjectUri.Port}";
                }
                prefix += "/";
            }

            var id = activity.Id;

            flattened = await _mainStore.GetEntity(id, false);

            if (flattened == null)
            {
                flattened = await _flattener.FlattenAndStore(stagingStore, activity, false);
            }

            await stagingStore.TrimDown(prefix);     // remove all staging entities that may be faked

            var sentBy = activity["actor"].First().Id;

            if (subject != null && sentBy != subject)
            {
                throw new UnauthorizedAccessException("Invalid authorization header for this subject!");
            }

            if (user.Data["blocks"].Any())
            {
                var blocks = await _mainStore.GetEntity(user.Data["blocks"].First().Id, false);

                var blocked = await _mainStore.GetEntity(blocks.Data["blocked"].First().Id, false);

                if (await _collectionTools.Contains(blocked, sentBy))
                {
                    throw new UnauthorizedAccessException("You are blocked.");
                }
            }

            if (await _collectionTools.Contains(inbox, id))
            {
                return(flattened);
            }

            await stagingStore.CommitChanges();

            foreach (var type in ServerConfig.ServerToServerHandlers)
            {
                var handler = (BaseHandler)ActivatorUtilities.CreateInstance(_serviceProvider, type,
                                                                             _mainStore, flattened, user, inbox, _user);
                var handled = await handler.Handle();

                flattened = handler.MainObject;
                if (!handled)
                {
                    break;
                }
            }

            return(flattened);
        }