예제 #1
0
 protected BaseHandler(IEntityStore entityStore, APEntity mainObject, APEntity actor, APEntity targetBox, ClaimsPrincipal user)
 {
     EntityStore = entityStore;
     MainObject  = mainObject;
     Actor       = actor;
     TargetBox   = targetBox;
     User        = user;
 }
예제 #2
0
        private async Task <Account> _processAccount(APEntity entity)
        {
            var result = new Account
            {
                id           = Uri.EscapeDataString(entity.Id),
                username     = (string)entity.Data["preferredUsername"].FirstOrDefault()?.Primitive ?? entity.Id,
                display_name = (string)entity.Data["name"].FirstOrDefault()?.Primitive ?? entity.Id,
                locked       = entity.Data["manuallyApprovesFollowers"].Any(a => (bool)a.Primitive),
                created_at   = DateTime.Now,
                note         = (string)entity.Data["summary"].FirstOrDefault()?.Primitive ?? "",
                url          = (string)entity.Data["url"].FirstOrDefault()?.Primitive ?? entity.Id,
                moved        = null,

                followers_count = -1,
                following_count = -1,
                statuses_count  = -1,

                avatar        = "",
                avatar_static = ""
            };

            if (entity.IsOwner)
            {
                result.acct = result.username;
            }
            else
            {
                result.acct = result.username + "@" + (new Uri(entity.Id)).Host;
            }

            if (entity.Data["icon"].Any())
            {
                result.avatar = result.avatar_static = entity.Data["icon"].First().Id ?? entity.Data["icon"].First().SubObject["url"].First().Id;
            }

            var followers = await _entityStore.GetEntity(entity.Data["followers"].First().Id, false);

            if (followers != null && followers.Data["totalItems"].Any())
            {
                result.followers_count = (int)followers.Data["totalItems"].First().Primitive;
            }

            var following = await _entityStore.GetEntity(entity.Data["following"].First().Id, false);

            if (following != null && following.Data["totalItems"].Any())
            {
                result.following_count = (int)following.Data["totalItems"].First().Primitive;
            }

            var outbox = await _entityStore.GetEntity(entity.Data["outbox"].First().Id, false);

            if (outbox != null && outbox.Data["totalItems"].Any())
            {
                result.statuses_count = (int)outbox.Data["totalItems"].First().Primitive;
            }

            return(result);
        }
예제 #3
0
        public async Task RemoveFromCollection(APEntity collection, string id)
        {
            var item = await _context.CollectionItems.FirstOrDefaultAsync(a => a.CollectionId == collection.Id && a.ElementId == id);

            if (item != null)
            {
                _context.CollectionItems.Remove(item);
            }
        }
예제 #4
0
 private void _queueInboxDelivery(string targetUrl, APEntity entity)
 {
     _context.EventQueue.Add(
         DeliverToActivityPubTask.Make(new DeliverToActivityPubData
     {
         ObjectId    = entity.Id,
         TargetInbox = targetUrl
     }));
 }
예제 #5
0
 private void _queueSalmonDelivery(string targetUrl, APEntity entity)
 {
     _context.EventQueue.Add(
         DeliverToSalmonTask.Make(new DeliverToSalmonData
     {
         EntityId  = entity.Id,
         SalmonUrl = targetUrl
     }));
 }
예제 #6
0
        public async Task QueueDeliveryForEntity(APEntity entity, int collectionId, string ownedBy = null)
        {
            var audienceInbox = await _buildAudienceInbox(entity.Data, forward : ownedBy, actor : true);

            foreach (var target in audienceInbox.Item1)
            {
                await _queueInboxDelivery(target, entity);
            }
        }
예제 #7
0
        private ASObject _getEndpoints(APEntity entity)
        {
            var data = entity.Data;

            data.Replace("endpoints", new ASTerm(entity.Id + "#endpoints"));
            data.Replace("publicKey", new ASTerm(entity.Id + "#key"));
            data.Replace("sharedInbox", new ASTerm(_configuration.BaseUri + "/auth/sharedInbox"));
            return(data);
        }
예제 #8
0
        private async Task <APEntity> _flatten(IEntityStore store, ASObject @object, bool generateId, IDictionary <string, APEntity> entities, string parentId = null)
        {
            var entity = new APEntity();

            if (@object["href"].Any()) // Link
            {
                return(null);
            }

            if (@object.Id == null)
            {
                if (!generateId)
                {
                    return(null);
                }
                @object.Id = await _configuration.FindUnusedID(store, @object, null, parentId);

                entity.IsOwner = true;
            }

            entity.Id = @object.Id;
            var t = @object.Type.FirstOrDefault();

            if (t?.StartsWith("_") != false && t?.StartsWith("_:") != true)
            {
                t = "Unknown";
            }
            entity.Type = t;

            foreach (var kv in @object)
            {
                foreach (var value in kv.Value)
                {
                    if (value.SubObject == null)
                    {
                        continue;
                    }

                    var subObject = await _flatten(store, value.SubObject, generateId, entities, entity.Id);

                    if (subObject == null)
                    {
                        continue;
                    }

                    value.Id        = subObject.Id;
                    value.Primitive = null;
                    value.SubObject = null;
                }
            }

            entity.Data         = @object;
            entities[entity.Id] = entity;

            return(entity);
        }
예제 #9
0
        private async Task <APEntity> _flatten(IEntityStore store, ASObject @object, bool generateId, IDictionary <string, APEntity> entities, string parentId = null)
        {
            var entity = new APEntity();

            if (@object["id"].Count == 0)
            {
                if (!generateId)
                {
                    return(null);
                }
                @object["id"].Add(new ASTerm(await _configuration.FindUnusedID(store, @object, null, parentId)));
                entity.IsOwner = true;
            }

            entity.Id = (string)@object["id"].First().Primitive;
            var t = (string)@object["type"].FirstOrDefault()?.Primitive;

            if (t?.StartsWith("_") != false && t?.StartsWith("_:") != true)
            {
                t = "Unknown";
            }
            entity.Type = t;

            foreach (var kv in @object)
            {
                if (!IdHolding.Contains(kv.Key))
                {
                    continue;
                }
                foreach (var value in kv.Value)
                {
                    if (value.SubObject == null)
                    {
                        continue;
                    }
                    if (value.SubObject["id"].Any(a => a.Primitive == null))
                    {
                        continue;                                                      // transient object
                    }
                    var subObject = await _flatten(store, value.SubObject, generateId, entities, entity.Id);

                    if (subObject == null)
                    {
                        continue;
                    }

                    value.Primitive = subObject.Id;
                    value.SubObject = null;
                }
            }

            entity.Data         = @object;
            entities[entity.Id] = entity;

            return(entity);
        }
예제 #10
0
            private async Task <ASObject> _getCollection(APEntity entity, IQueryCollection arguments)
            {
                var  from_id    = arguments["from_id"].FirstOrDefault();
                var  collection = entity.Data;
                bool seePrivate = collection["attributedTo"].Any() && _user.FindFirstValue(JwtTokenSettings.ActorClaim) == (string)collection["attributedTo"].First().Primitive;

                collection["current"].Add(new ASTerm(entity.Id));
                collection["totalItems"].Add(new ASTerm(await _collectionTools.Count(entity.Id)));

                if (from_id != null)
                {
                    var fromId = int.Parse(from_id);
                    var items  = await _collectionTools.GetItems(entity.Id, fromId, 11);

                    var hasItems = items.Any();
                    var page     = new ASObject();
                    page["type"].Add(new ASTerm("OrderedCollectionPage"));
                    page["summary"].Add(new ASTerm("A collection"));
                    page["id"].Add(new ASTerm(entity.Id + "?from_id=" + (hasItems ? fromId : 0)));
                    page["partOf"].Add(new ASTerm(entity.Id));
                    if (collection["attributedTo"].Any())
                    {
                        page["attributedTo"].Add(collection["attributedTo"].First());
                    }
                    if (items.Count > 10)
                    {
                        page["next"].Add(new ASTerm(entity.Id + "?from_id=" + (items.Last().CollectionItemId - 1).ToString()));
                    }
                    page["orderedItems"].AddRange(items.Take(10).Select(a => new ASTerm(a.ElementId)));

                    return(page);
                }
                else
                {
                    var items = await _collectionTools.GetItems(entity.Id, count : 10);

                    var hasItems = items.Any();
                    var page     = new ASObject();
                    page["type"].Add(new ASTerm("OrderedCollectionPage"));
                    page["id"].Add(new ASTerm(entity.Id + "?from_id=" + (hasItems ? items.First().CollectionItemId + 1 : 0)));
                    page["partOf"].Add(new ASTerm(entity.Id));
                    if (collection["attributedTo"].Any())
                    {
                        page["attributedTo"].Add(collection["attributedTo"].First());
                    }
                    if (items.Count > 0)
                    {
                        page["next"].Add(new ASTerm(entity.Id + "?from_id=" + (items.Last().CollectionItemId - 1)));
                    }
                    page["orderedItems"].AddRange(items.Select(a => new ASTerm(a.ElementId)));

                    collection["first"].Add(new ASTerm(page));
                }

                return(collection);
            }
예제 #11
0
        public async Task <bool> Contains(APEntity collection, string otherId)
        {
            var otherEntity = await _getId(otherId);

            if (otherEntity == null)
            {
                return(false);
            }

            return(await _connection.ExecuteScalarAsync <bool>("select exists(select 1 from \"CollectionItems\" where \"CollectionId\" = @CollectionId and \"ElementId\" = @ElementId)", new { CollectionId = collection.DbId, ElementId = otherEntity.Value }));
        }
예제 #12
0
        public async Task RemoveFromCollection(APEntity collection, string id)
        {
            var otherEntity = await _getId(id);

            if (otherEntity == null)
            {
                return;
            }

            await _connection.ExecuteAsync("delete from \"CollectionItems\" where \"CollectionId\" = @CollectionId and \"ElementId\" = @ElementId", new { CollectionId = collection.DbId, ElementId = otherEntity.Value });
        }
예제 #13
0
        public async Task <IActionResult> Proxy(string id)
        {
            if (User.FindFirstValue(JwtTokenSettings.ActorClaim) == null)
            {
                return(Unauthorized());
            }

            APEntity entity = null;

            if (id.StartsWith('@'))
            {
                id = id.Substring(1);
                var spl  = id.Split(new char[] { '@' }, 2);
                var host = spl.Length > 1 ? spl[1] : Request.Host.ToString();
                var ent  = await _relevantEntities.FindEntitiesWithPreferredUsername(spl[0]);

                var withHost = ent.FirstOrDefault(a => new Uri(a.Id).Host == host);
                if (withHost == null && spl.Length == 1)
                {
                    return(NotFound());
                }

                entity = withHost;

                if (entity == null && spl.Length > 1)
                {
                    var hc              = new HttpClient();
                    var webfinger       = JsonConvert.DeserializeObject <WellKnownController.WebfingerResult>(await hc.GetStringAsync($"https://{host}/.well-known/webfinger?resource=acct:{id}"));
                    var activityStreams = webfinger.links.FirstOrDefault(a => a.rel == "self" && (a.type == "application/activity+json" || a.type == "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""));
                    if (activityStreams == null)
                    {
                        return(NotFound());
                    }

                    id = activityStreams.href;
                }
            }

            if (entity == null)
            {
                entity = await _entityStore.GetEntity(id, true);
            }

            if (entity == null)
            {
                return(NotFound());
            }

            var unflattened = await _entityFlattener.Unflatten(_entityStore, entity);

            return(Content(unflattened.Serialize(true).ToString(), "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""));
        }
예제 #14
0
        public async Task <APEntity> GetEntity(string id, bool doRemote)
        {
            string query    = null;
            string parsedId = null;

            if (id.Contains("?"))
            {
                var split = id.Split(new char[] { '?' }, 2);
                query    = split[1];
                parsedId = split[0];
            }

            APEntity original;
            var      entity = original = await Bypass.GetEntity(id, false);

            if (entity == null && parsedId != null)
            {
                entity = await Bypass.GetEntity(parsedId, false);
            }
            if (entity == null || !entity.IsOwner)
            {
                return(doRemote ? await Bypass.GetEntity(id, true) : original);
            }
            if (!entity.Type.StartsWith("_") && entity.Type != "OrderedCollection")
            {
                return(doRemote ? await Bypass.GetEntity(id, true) : original);
            }

            if (query == null)
            {
                return(APEntity.From(await _buildCollection(entity), true));
            }
            else
            {
                int from_id = int.MaxValue;
                int to_id   = int.MinValue;
                foreach (var item in query.Split('&'))
                {
                    var kv = item.Split('=');
                    if (kv[0] == "from_id" && kv.Length > 1)
                    {
                        from_id = int.Parse(kv[1]);
                    }
                    if (kv[0] == "to_id" && kv.Length > 1)
                    {
                        to_id = int.Parse(kv[1]);
                    }
                }

                return(APEntity.From(await _buildPage(entity, from_id, to_id)));
            }
        }
예제 #15
0
        public async Task <CollectionItem> AddToCollection(APEntity collection, APEntity entity)
        {
            var ci = new CollectionItem
            {
                Collection = collection,
                Element    = entity,
                IsPublic   = DeliveryService.IsPublic(entity.Data)
            };

            await _context.CollectionItems.AddAsync(ci);

            return(ci);
        }
예제 #16
0
        private async Task <ASObject> _getCollection(APEntity entity, IQueryCollection arguments)
        {
            var  from_id    = arguments["from_id"].FirstOrDefault();
            var  to_id      = arguments["to_id"].FirstOrDefault();
            var  collection = entity.Data;
            bool seePrivate = collection["attributedTo"].Any() && _user.FindFirstValue("actor") == collection["attributedTo"].First().Id;

            if (from_id != null || to_id != null)
            {
                var fromId = from_id != null?int.Parse(from_id) : int.MaxValue;

                var toId = to_id != null?int.Parse(to_id) : int.MinValue;

                var maxitem = (await _collectionTools.GetItems(entity.Id, count: 1)).FirstOrDefault()?.CollectionItemId;
                var items   = await _collectionTools.GetItems(entity.Id, fromId, toId, count : 11);

                var hasItems = items.Any();
                var page     = new ASObject();
                page.Type.Add("https://www.w3.org/ns/activitystreams#OrderedCollectionPage");
                page["summary"].Add(ASTerm.MakePrimitive("A collection"));
                page.Id = entity.Id + "?from_id=" + (hasItems ? fromId : 0);
                page["partOf"].Add(ASTerm.MakeId(entity.Id));
                if (collection["attributedTo"].Any())
                {
                    page["attributedTo"].Add(collection["attributedTo"].First());
                }
                if (items.Count > 0 && items[0].CollectionItemId != maxitem)
                {
                    page["prev"].Add(ASTerm.MakeId(entity.Id + "?to_id=" + items[0].CollectionItemId.ToString()));
                }
                if (items.Count > 10)
                {
                    page["next"].Add(ASTerm.MakeId(entity.Id + "?from_id=" + (items[9].CollectionItemId - 1).ToString()));
                }
                page["orderedItems"].AddRange(items.Take(10).Select(a => ASTerm.MakeId(a.Entity.Id)));

                return(page);
            }
            else
            {
                var items = await _collectionTools.GetItems(entity.Id, count : 1);

                var hasItems = items.Any();
                var page     = entity.Id + "?from_id=" + (hasItems ? items.First().CollectionItemId + 1 : 0);
                collection["current"].Add(ASTerm.MakeId(entity.Id));
                collection["totalItems"].Add(ASTerm.MakePrimitive(await _collectionTools.Count(entity.Id), ASTerm.NON_NEGATIVE_INTEGER));
                collection["first"].Add(ASTerm.MakeId(page));
                return(collection);
            }
        }
예제 #17
0
            public async Task Render(HttpRequest request, HttpResponse response, APEntity toRender)
            {
                response.ContentType = "application/atom+xml";

                var user = await _entityStore.GetEntity(toRender.Data["actor"].Single().Id, false);

                var key = await _keyService.GetKey(user.Id);

                var magicKey = key != null ? new MagicKey(key.PrivateKey) : MagicKey.Generate();

                var doc = await _entryGenerator.Build(toRender.Data);

                var enveloped = new MagicEnvelope(doc.ToString(), "application/atom+xml", magicKey);
                await response.WriteAsync(enveloped.Build().ToString());
            }
예제 #18
0
        private async Task <APEntity> _newCollection(string type, string attributedTo)
        {
            var obj = new ASObject();

            obj["type"].Add(new ASTerm("OrderedCollection"));
            obj["attributedTo"].Add(new ASTerm(attributedTo));
            obj.Replace("id", new ASTerm(await _entityData.FindUnusedID(_entityStore, obj, type, attributedTo)));
            var entity = APEntity.From(obj, true);

            entity.Type = "_" + type;
            entity      = await _entityStore.StoreEntity(entity);

            await _entityStore.CommitChanges();

            return(entity);
        }
예제 #19
0
            public async Task Render(HttpRequest request, HttpResponse response, ASObject toRender)
            {
                response.ContentType = ConverterHelpers.GetBestMatch(_factory.MimeTypes, request.Headers["Accept"]);
                if (toRender["type"].Any(a => (string)a.Primitive == "Tombstone"))
                {
                    response.StatusCode = 410;
                }

                response.Headers.Add("Access-Control-Allow-Origin", "*");

                var depth = Math.Min(int.Parse(request.Query["depth"].FirstOrDefault() ?? "3"), 5);

                var unflattened = await _flattener.Unflatten(_entityStore, APEntity.From(toRender), depth);

                await response.WriteAsync(unflattened.Serialize(true).ToString());
            }
예제 #20
0
        public async Task <CollectionItem> AddToCollection(APEntity collection, APEntity entity)
        {
            var ci = new CollectionItem
            {
                CollectionId = collection.DbId,
                ElementId    = entity.DbId,
                IsPublic     = _isPublic(entity.Data) || EntityData.IsActor(entity.Data)
            };


            await _connection.ExecuteAsync("insert into \"CollectionItems\" (\"CollectionId\", \"ElementId\", \"IsPublic\") values (@CollectionId, @ElementId, @IsPublic)", ci);

            await _notifier.Notify($"collection/{collection.Id}", entity.Id);

            return(ci);
        }
예제 #21
0
        public async Task <APEntity> GetEntity(string id, bool doRemote)
        {
            string fragment = null;
            string parsedId = null;

            // no fragment, so who cares
            if (!id.Contains("#"))
            {
                return(await Bypass.GetEntity(id, doRemote));
            }

            var split = id.Split(new char[] { '#' }, 2);

            fragment = split[1];
            parsedId = split[0];

            // try local get
            var entity = await Bypass.GetEntity(id, false);

            if (entity != null)
            {
                return(entity);
            }

            // doesn't exist, so try non-fragment
            entity = await Bypass.GetEntity(parsedId, false);

            if (entity != null && entity.IsOwner)
            {
                // exists, and I own it!
                var result = await _fakeEntityService.BuildFakeObject(entity, fragment);

                if (result == null)
                {
                    return(null);
                }
                return(APEntity.From(result, true));
            }

            if (!doRemote)
            {
                return(null);
            }

            return(await Bypass.GetEntity(id, true));
        }
예제 #22
0
        private async Task <ASObject> _buildCollection(APEntity entity)
        {
            var collection = entity.Data;

            collection["current"].Add(ASTerm.MakeId(entity.Id));
            collection["totalItems"].Add(ASTerm.MakePrimitive(await _collectionTools.Count(entity.Id), ASTerm.NON_NEGATIVE_INTEGER));
            var item = await _collectionTools.GetItems(entity.Id, count : 1);

            if (item.Any())
            {
                collection["first"].Add(ASTerm.MakeId(entity.Id + $"?from_id={item.First().CollectionItemId + 1}"));
            }
            else
            {
                collection["first"].Add(ASTerm.MakeId(entity.Id + $"?from_id=0"));
            }
            return(collection);
        }
예제 #23
0
        public async Task <ASObject> BuildFakeObject(APEntity entity, string fragment)
        {
            if (!EntityData.IsActor(entity.Data))
            {
                return(null);
            }

            if (fragment == "key")
            {
                var key = await _keyService.GetKey(entity.Id);

                var salm    = new MagicKey(key.PrivateKey);
                var pemData = salm.AsPEM;

                var keyObj = new ASObject();
                keyObj.Replace("owner", ASTerm.MakeId(entity.Id));
                keyObj.Replace("publicKeyPem", ASTerm.MakePrimitive(pemData));
                keyObj.Id = $"{entity.Id}#key";
                return(keyObj);
            }
            else if (fragment == "endpoints")
            {
                var data = entity.Data;
                var idu  = new Uri(entity.Id);

                var basePath = $"{idu.Scheme}://{idu.Host}{(idu.IsDefaultPort?"":$":{idu.Port}")}{_configuration.BasePath}";

                var endpoints = new ASObject();
                endpoints.Replace("oauthAuthorizationEndpoint", ASTerm.MakeId(basePath + "oauth/authorize?id=" + Uri.EscapeDataString(entity.Id)));
                endpoints.Replace("oauthTokenEndpoint", ASTerm.MakeId(basePath + "oauth/token?"));
                endpoints.Replace("settingsEndpoint", ASTerm.MakeId(basePath + "settings/auth"));
                endpoints.Replace("uploadMedia", data["outbox"].Single());
                endpoints.Replace("relevantObjects", ASTerm.MakeId(basePath + "settings/relevant"));
                endpoints.Replace("proxyUrl", ASTerm.MakeId(basePath + "auth/proxy"));
                endpoints.Replace("jwks", ASTerm.MakeId(basePath + "auth/jwks?id=" + Uri.EscapeDataString(entity.Id)));
                endpoints.Replace("sharedInbox", ASTerm.MakeId(basePath + "auth/sharedInbox"));
                endpoints.Replace("search", ASTerm.MakeId(basePath + "auth/search"));
                endpoints.Id = entity.Id + "#endpoints";
                return(endpoints);
            }

            return(null);
        }
예제 #24
0
        public async Task <APEntity> StoreEntity(APEntity entity)
        {
            var exists = await _context.Entities.FirstOrDefaultAsync(a => a.Id == entity.Id);

            if (exists == null)
            {
                entity.Updated = DateTime.Now;
                await _context.Entities.AddAsync(entity);
            }
            else
            {
                exists.SerializedData = entity.SerializedData;
                exists.Updated        = DateTime.Now;
                exists.Type           = entity.Type;
                entity = exists;
            }

            return(entity);
        }
예제 #25
0
            public async Task Render(HttpRequest request, HttpResponse response, APEntity toRender)
            {
                response.ContentType = ConverterHelpers.GetBestMatch(_factory.MimeTypes, request.Headers["Accept"]);
                if (toRender.Type.Contains("Tombstone"))
                {
                    response.StatusCode = 410;
                }

                if (request.Method == "POST")
                {
                    response.StatusCode = 201;
                    response.Headers.Add("Location", toRender.Id);
                }

                var depth       = Math.Min(int.Parse(request.Query["depth"].FirstOrDefault() ?? "3"), 5);
                var unflattened = await _flattener.Unflatten(_entityStore, toRender, depth, isOwner : toRender.IsOwner);

                await response.WriteAsync(unflattened.Serialize(true).ToString());
            }
예제 #26
0
        public async Task QueueDeliveryForEntity(APEntity entity, int collectionId, string ownedBy = null)
        {
            var audienceInbox = await _buildAudienceInbox(entity.Data, forward : ownedBy, actor : true);

            // Is public post?
            if (audienceInbox.Item2 && ownedBy == null)
            {
                await _queueWebsubDelivery(entity.Data["actor"].First().Id, collectionId, entity.Id);
            }

            foreach (var target in audienceInbox.Item1)
            {
                await _queueInboxDelivery(target, entity);
            }

            foreach (var salmon in audienceInbox.Item3)
            {
                await _queueSalmonDelivery(salmon, entity);
            }
        }
예제 #27
0
        public async Task <IActionResult> RelevantEntities(RelevantObjectsModel model)
        {
            var user = User.FindFirstValue(JwtTokenSettings.ActorClaim);

            if (user == null)
            {
                return(Json(new List <ASObject>()));
            }

            var relevant = await _relevantEntities.FindRelevantObject(user, null, model.id);

            ASObject relevantObject = new ASObject();

            foreach (var item in relevant)
            {
                relevantObject["relevant"].Add(ASTerm.MakeSubObject(item.Data));
            }

            return(Content((await _flattener.Unflatten(_entityStore, APEntity.From(relevantObject), 5)).Serialize().ToString(), "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""));
        }
예제 #28
0
        public async Task <APEntity> Get(string url, IQueryCollection arguments, HttpContext context, APEntity existing)
        {
            var userId = _user.FindFirstValue("actor");
            var entity = existing ?? await _mainStore.GetEntity(url, false);

            if (entity == null)
            {
                return(null);
            }
            if (userId == null)
            {
                userId = await _verifier.Verify(url, context);
            }
            if (!await _authorizer.VerifyAccess(entity, userId))
            {
                var unauth = new ASObject();
                unauth.Id = "kroeg:unauthorized";
                unauth.Type.Add("kroeg:Unauthorized");

                return(APEntity.From(unauth));
            }
            if (entity.Type == "https://www.w3.org/ns/activitystreams#OrderedCollection" ||
                entity.Type == "https://www.w3.org/ns/activitystreams#Collection" ||
                entity.Type.StartsWith("_"))
            {
                if (entity.IsOwner && !entity.Data["totalItems"].Any())
                {
                    try {
                        return(APEntity.From(await _getCollection(entity, arguments), true));
                    } catch (FormatException) {
                        throw new InvalidOperationException("Invalid parameters!");
                    }
                }
                else
                {
                    return((await _mainStore.GetEntity(url + context.Request.QueryString.Value, true)) ?? entity);
                }
            }

            return(entity);
        }
예제 #29
0
        public async Task <ASObject> Unflatten(IEntityStore store, APEntity entity, int depth = 3, Dictionary <string, APEntity> mapped = null)
        {
            if (mapped == null)
            {
                mapped = new Dictionary <string, APEntity>();
            }

            if (entity.Id != null)
            {
                var e = await store.GetEntity(entity.Id, false);

                if (e?.IsOwner == true)
                {
                    entity.IsOwner = true;
                }
            }

            var unflattened = await _unflatten(store, entity, depth, mapped, _configuration.UnflattenRemotely);

            return(unflattened);
        }
예제 #30
0
        private ASObject _getEndpoints(APEntity entity)
        {
            var data = entity.Data;
            var idu  = new Uri(entity.Id);

            var basePath = $"{idu.Scheme}://{idu.Host}{_configuration.BasePath}";

            var endpoints = new ASObject();

            endpoints.Replace("oauthAuthorizationEndpoint", new ASTerm(basePath + "auth/oauth?id=" + Uri.EscapeDataString(entity.Id)));
            endpoints.Replace("oauthTokenEndpoint", new ASTerm(basePath + "auth/token?"));
            endpoints.Replace("settingsEndpoint", new ASTerm(basePath + "settings/auth"));
            endpoints.Replace("uploadMedia", new ASTerm((string)data["outbox"].Single().Primitive));
            endpoints.Replace("relevantObjects", new ASTerm(basePath + "settings/relevant"));
            endpoints.Replace("proxyUrl", new ASTerm(basePath + "auth/proxy"));
            endpoints.Replace("jwks", new ASTerm(basePath + "auth/jwks?id=" + Uri.EscapeDataString(entity.Id)));
            endpoints.Replace("id", new ASTerm((string)null));

            data.Replace("endpoints", new ASTerm(endpoints));
            data.Replace("publicKey", new ASTerm(basePath + "auth/key?id=" + Uri.EscapeDataString(entity.Id)));
            return(data);
        }