public override async Task <bool> Handle() { if (MainObject.Type != "https://www.w3.org/ns/activitystreams#Delete") { return(true); } var oldObject = await EntityStore.GetEntity(MainObject.Data["object"].Single().Id, true); var newData = oldObject.Data; foreach (var kv in newData) { if (!DeleteWhitelist.Contains(kv.Key)) { kv.Value.Clear(); } } newData.Type.Clear(); newData.Type.Add("https://www.w3.org/ns/activitystreams#Tombstone"); newData.Replace("deleted", ASTerm.MakePrimitive(DateTime.Now.ToString("o"))); var newObject = APEntity.From(newData); await EntityStore.StoreEntity(newObject); return(true); }
private async Task <ASObject> _buildPage(APEntity entity, int from_id, int to_id) { var collection = entity.Data; var maxitem = (await _collectionTools.GetItems(entity.Id, count: 1)).FirstOrDefault()?.CollectionItemId; var items = await _collectionTools.GetItems(entity.Id, from_id, to_id, 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 ? from_id : 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); }
public override async Task <bool> Handle() { if (MainObject.Type != "https://www.w3.org/ns/activitystreams#Create") { return(true); } var activityData = MainObject.Data; var objectEntity = await EntityStore.GetEntity(activityData["object"].First().Id, false); if (!_entityData.IsActor(objectEntity.Data)) { return(true); } var objectData = objectEntity.Data; var id = objectEntity.Id; await AddCollection(objectData, "inbox", id); await AddCollection(objectData, "outbox", id); await AddCollection(objectData, "following", id); await AddCollection(objectData, "followers", id); await AddCollection(objectData, "liked", id); var blocks = await AddCollection(objectData, "blocks", id); var blocked = await _collection.NewCollection(EntityStore, null, "blocked", blocks.Id); var blocksData = blocks.Data; blocksData["blocked"].Add(ASTerm.MakeId(blocked.Id)); blocks.Data = blocksData; if (!objectData["manuallyApprovesFollowers"].Any()) { objectData.Replace("manuallyApprovesFollowers", ASTerm.MakePrimitive(false)); } objectEntity.Data = objectData; await EntityStore.StoreEntity(blocked); await EntityStore.StoreEntity(blocks); await EntityStore.StoreEntity(objectEntity); var userId = UserOverride ?? User.FindFirst(ClaimTypes.NameIdentifier).Value; if (!activityData["actor"].Any()) { activityData["actor"].Add(ASTerm.MakeId(objectEntity.Id)); } MainObject.Data = activityData; await EntityStore.StoreEntity(MainObject); await _connection.ExecuteAsync("insert into \"UserActorPermissions\" (\"UserId\", \"ActorId\", \"IsAdmin\") values (@UserId, @ActorId, TRUE)", new { UserId = userId, ActorId = objectEntity.DbId }); return(true); }
public async Task <IActionResult> UploadMedia() { var @object = Request.Form["object"]; var file = Request.Form.Files["file"]; var handler = ActivatorUtilities.CreateInstance <GetEntityMiddleware.GetEntityHandler>(_provider, User); var obj = ASObject.Parse(@object); var mainObj = obj; if (obj["object"].Any()) { mainObj = obj["object"].Single().SubObject; } var uploadPath = _configuration.GetSection("Kroeg")["FileUploadPath"]; var uploadUri = _configuration.GetSection("Kroeg")["FileUploadUrl"]; var extension = file.FileName.Split('.').Last().Replace('/', '_'); var fileName = Guid.NewGuid().ToString() + "." + extension; var str = System.IO.File.OpenWrite(uploadPath + fileName); await file.CopyToAsync(str); str.Dispose(); mainObj.Replace("url", ASTerm.MakePrimitive(uploadUri + fileName)); var entity = await _entityStore.GetEntity((string)HttpContext.Items["fullPath"], false); try { using (var transaction = _connection.BeginTransaction()) { var entOut = await handler.Post(HttpContext, (string)HttpContext.Items["fullPath"], entity, obj); if (entOut == null) { return(NotFound()); } obj = await _flattener.Unflatten(_entityStore, entOut); transaction.Commit(); return(Content(obj.Serialize().ToString(), "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")); } } catch (UnauthorizedAccessException e) { Console.WriteLine(e); return(StatusCode(403, e)); } catch (InvalidOperationException e) { Console.WriteLine(e); return(StatusCode(401, e)); } }
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); } }
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); }
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); }
public async Task <IActionResult> MakeNewActor(NewActorModel model) { var data = await _getUserInfo(); if (string.IsNullOrWhiteSpace(model.Username)) { return(View("NewActor", model)); } var user = model.Username; var obj = new ASObject(); obj.Type.Add("https://www.w3.org/ns/activitystreams#Person"); obj["preferredUsername"].Add(ASTerm.MakePrimitive(user)); obj["name"].Add(ASTerm.MakePrimitive(string.IsNullOrWhiteSpace(model.Name) ? "Unnamed" : model.Name)); if (!string.IsNullOrWhiteSpace(model.Summary)) { obj["summary"].Add(ASTerm.MakePrimitive(model.Summary)); } var create = new ASObject(); create.Type.Add("https://www.w3.org/ns/activitystreams#Create"); create["object"].Add(ASTerm.MakeSubObject(obj)); create["to"].Add(ASTerm.MakeId("https://www.w3.org/ns/activitystreams#Public")); var stagingStore = new StagingEntityStore(_entityStore); var apo = await _flattener.FlattenAndStore(stagingStore, create); var handler = new CreateActorHandler(stagingStore, apo, null, null, User, _collectionTools, _entityData, _connection); await handler.Handle(); var resultUser = await _entityStore.GetEntity(handler.MainObject.Data["object"].First().Id, false); var outbox = await _entityStore.GetEntity(resultUser.Data["outbox"].First().Id, false); var delivery = new DeliveryHandler(stagingStore, handler.MainObject, resultUser, outbox, User, _collectionTools, _provider.GetRequiredService <DeliveryService>()); await delivery.Handle(); return(RedirectToAction("Edit", new { id = resultUser.Id })); }
public override async Task <bool> Handle() { if (MainObject.Type != "https://www.w3.org/ns/activitystreams#Update" && MainObject.Type != "https://www.w3.org/ns/activitystreams#Delete") { return(true); } var activityData = MainObject.Data; var oldObject = await EntityStore.Bypass.GetEntity(activityData["object"].Single().Id, false); if (oldObject == null) { throw new InvalidOperationException("Cannot remove or update a non-existant object!"); } if (!oldObject.IsOwner) { throw new InvalidOperationException("Cannot remove or update an object not on this server!"); } var originatingCreate = (await _relevantEntities.FindRelevantObject("https://www.w3.org/ns/activitystreams#Create", oldObject.Id)).FirstOrDefault(); if (originatingCreate.Data["actor"].Single().Id != Actor.Id) { throw new InvalidOperationException("Cannot remove or update objects that weren't made by you!"); } if (MainObject.Type == "https://www.w3.org/ns/activitystreams#Update") { var newObject = await EntityStore.GetEntity(activityData["object"].Single().Id, false); if (newObject == oldObject) { throw new InvalidOperationException("No new object passed!"); } var data = oldObject.Data; foreach (var item in newObject.Data) { // SequenceEqual ensures that clients doing full-object updates won't cause this exception on e.g. type, attributedTo, etc if (UpdateBlacklist.Contains(item.Key) && (data[item.Key].Count != item.Value.Count || data[item.Key].Zip(item.Value, _isEqual).Any(a => !a))) { throw new InvalidOperationException($"Cannot update key {item.Key} as it's on the blacklist!"); } data[item.Key].Clear(); data[item.Key].AddRange(item.Value); } data.Replace("updated", ASTerm.MakePrimitive(DateTime.Now.ToString("o"))); newObject.Data = data; newObject.Type = oldObject.Type; await EntityStore.StoreEntity(newObject); } else { var newData = oldObject.Data; foreach (var kv in newData) { if (!DeleteWhitelist.Contains(kv.Key)) { kv.Value.Clear(); } } newData.Type.Clear(); newData.Type.Add("https://www.w3.org/ns/activitystreams#Tombstone"); newData.Replace("deleted", ASTerm.MakePrimitive(DateTime.Now.ToString("o"))); var newObject = APEntity.From(newData, true); await EntityStore.StoreEntity(newObject); } return(true); }
private ASObject _parseAuthor(XElement element) { var ao = new ASObject(); ao.Type.Add("https://www.w3.org/ns/activitystreams#Person"); // set preferredUsername and name { var atomName = element.Element(Atom + "name")?.Value; var pocoDisplayName = element.Element(PortableContacts + "displayName")?.Value; var pocoPreferredUsername = element.Element(PortableContacts + "preferredUsername")?.Value; ao.Replace("preferredUsername", ASTerm.MakePrimitive(pocoPreferredUsername ?? atomName)); ao.Replace("name", ASTerm.MakePrimitive(pocoDisplayName ?? pocoPreferredUsername ?? atomName)); } // set summary { var atomSummary = element.Element(Atom + "summary")?.Value; var pocoNote = element.Element(PortableContacts + "note")?.Value; ao.Replace("summary", ASTerm.MakePrimitive(pocoNote ?? atomSummary)); } string retrievalUrl = null; { foreach (var link in element.Elements(Atom + "link")) { var rel = link.Attribute(NoNamespace + "rel")?.Value; var type = link.Attribute(NoNamespace + "type")?.Value; var href = link.Attribute(NoNamespace + "href")?.Value; switch (rel) { case "avatar": var avatarObject = new ASObject(); avatarObject.Type.Add("https://www.w3.org/ns/activitystreams#Image"); avatarObject.Replace("mediaType", ASTerm.MakePrimitive(type)); var width = link.Attribute(AtomMedia + "width")?.Value; var height = link.Attribute(AtomMedia + "height")?.Value; if (width != null && height != null) { avatarObject.Replace("width", ASTerm.MakePrimitive(int.Parse(width))); avatarObject.Replace("height", ASTerm.MakePrimitive(int.Parse(height))); } avatarObject.Replace("url", ASTerm.MakePrimitive(href)); ao["icon"].Add(ASTerm.MakeSubObject(avatarObject)); break; case "alternate": if (type == "text/html") { if (retrievalUrl == null) { retrievalUrl = href; } ao["atomUri"].Add(ASTerm.MakePrimitive(href)); } break; case "self": if (type == "application/atom+xml") { retrievalUrl = href; } break; } } } // should be Mastodon *and* GNU social compatible: Mastodon uses uri as id if (element.Element(Atom + "id") != null) { ao.Id = element.Element(Atom + "id")?.Value; } else { ao.Id = element.Element(Atom + "uri")?.Value; } if (element.Element(Atom + "uri") != null) { ao["url"].Add(ASTerm.MakePrimitive(element.Element(Atom + "uri")?.Value)); } if (element.Element(Atom + "email") != null) { ao["email"].Add(ASTerm.MakePrimitive(element.Element(Atom + "email")?.Value)); } foreach (var url in element.Elements(PortableContacts + "urls")) { ao["url"].Add(ASTerm.MakePrimitive(url.Element(PortableContacts + "value")?.Value)); } if (retrievalUrl != null) { ao.Replace("atomUri", ASTerm.MakePrimitive(retrievalUrl)); } return(ao); }
private async Task <ASObject> _parseFeed(XElement element, string targetUser) { var ao = new ASObject(); ao.Type.Add("https://www.w3.org/ns/activitystreams#OrderedCollectionPage"); ao.Replace("_:origin", ASTerm.MakePrimitive("atom")); ao.Id = element.Element(Atom + "id").Value; if (element.Element(Atom + "title") != null) { ao.Replace("summary", ASTerm.MakePrimitive(element.Element(Atom + "title").Value)); } if (element.Element(Atom + "updated") != null) { ao.Replace("updated", ASTerm.MakePrimitive(element.Element(Atom + "updated").Value)); } var author = _parseAuthor(element.Element(Atom + "author")); ao.Replace("attributedTo", ASTerm.MakeSubObject(author)); var authorId = author.Id; foreach (var entry in element.Elements(Atom + "entry")) { ao["orderedItems"].Add(await _parseActivity(entry, authorId, targetUser)); } foreach (var link in element.Elements(Atom + "link")) { var rel = link.Attribute(NoNamespace + "rel").Value; var type = link.Attribute(NoNamespace + "type")?.Value; var href = link.Attribute(NoNamespace + "href").Value; if (rel == "alternate" && type == "text/html") { ao["url"].Add(ASTerm.MakePrimitive(href)); } else if (rel == "self" && type == "application/atom+xml") { author.Replace("atomUri", ASTerm.MakePrimitive(href)); } else { switch (rel) { case "salmon": ao["_:salmonUrl"].Add(ASTerm.MakePrimitive(href)); break; case "hub": ao["_:hubUrl"].Add(ASTerm.MakePrimitive(href)); break; case "prev": ao["prev"].Add(ASTerm.MakeId(href)); break; case "next": ao["next"].Add(ASTerm.MakeId(href)); break; } } } author["_:salmonUrl"].AddRange(ao["_:salmonUrl"]); author["_:hubUrl"].AddRange(ao["_:hubUrl"]); return(ao); }
private async Task <ASTerm> _parseActivity(XElement element, string authorId, string targetUser) { if (await _isSelf(element.Element(Atom + "id").Value)) { return(ASTerm.MakeId(await _fixActivityToObjectId(element.Element(Atom + "id").Value))); } var ao = new ASObject(); ao.Id = element.Element(Atom + "id").Value; ao.Replace("_:origin", ASTerm.MakePrimitive("atom")); var verb = _objectTypeToType(element.Element(ActivityStreams + "verb")?.Value) ?? "Post"; var originalVerb = verb; if (verb == "Unfollow" && (await _entityStore.GetEntity(element.Element(Atom + "id").Value, false))?.Type == "Follow") // egh egh egh, why, mastodon { ao.Id += "#unfollow"; } if (verb == "Unfavorite") { verb = "Undo"; } if (verb == "Unfollow") { verb = "Undo"; } if (verb == "Request-friend") { return(null); } if (verb == "Post") { verb = "Create"; } else if (verb == "Share") { verb = "Announce"; } else if (verb == "Favorite") { verb = "Like"; } #pragma warning disable 618 if (!_entityConfiguration.IsActivity(verb)) { return(null); } #pragma warning restore 618 ao.Type.Add("https://www.w3.org/ns/activitystreams#" + verb); if (element.Element(Atom + "title") != null) { ao.Replace("summary", ASTerm.MakePrimitive(element.Element(Atom + "title").Value)); } if (element.Element(Atom + "published") != null) { ao.Replace("published", ASTerm.MakePrimitive(element.Element(Atom + "published").Value)); } if (element.Element(Atom + "updated") != null) { ao.Replace("updated", ASTerm.MakePrimitive(element.Element(Atom + "updated").Value)); } if (element.Element(Atom + "author") != null) { var newAuthor = _parseAuthor(element.Element(Atom + "author")); authorId = newAuthor.Id; } if (authorId != null) { ao.Replace("actor", ASTerm.MakeId(authorId)); } string retrievalUrl = null; foreach (var link in element.Elements(Atom + "link")) { var rel = link.Attribute(NoNamespace + "rel").Value; var type = link.Attribute(NoNamespace + "type")?.Value; var href = link.Attribute(NoNamespace + "href").Value; if (rel == "self" && type == "application/atom+xml") { retrievalUrl = href; } else if (rel == "alternate" && type == "text/html") { ao["url"].Add(ASTerm.MakePrimitive(href)); if (retrievalUrl == null) { retrievalUrl = href; } } else if (rel == "mentioned") { if (href == "http://activityschema.org/collection/public") { href = "https://www.w3.org/ns/activitystreams#Public"; } ao["to"].Add(ASTerm.MakeId(href)); } } if (targetUser != null) { ao["cc"].Add(ASTerm.MakeId(targetUser)); } if (retrievalUrl != null) { ao.Replace("atomUri", ASTerm.MakePrimitive(retrievalUrl)); } if (element.Element(ActivityStreams + "object") != null) { var parsedActivityObject = await _parseActivityObject(element.Element(ActivityStreams + "object"), authorId, targetUser); if (verb == "Undo" && originalVerb == "Unfavorite") { parsedActivityObject = ASTerm.MakeId((await _relevantEntities.FindRelevantObject(authorId, "https://www.w3.org/ns/activitystreams#Like", _getId(parsedActivityObject))).FirstOrDefault()?.Id); } else if (verb == "Undo" && originalVerb == "Unfollow") { parsedActivityObject = ASTerm.MakeId((await _relevantEntities.FindRelevantObject(authorId, "https://www.w3.org/ns/activitystreams#Follow", _getId(parsedActivityObject))).FirstOrDefault()?.Id); } ao.Replace("object", parsedActivityObject); } else if (element.Element(ActivityStreams + "object-type") == null && originalVerb == "Unfollow") { // you thought Mastodon was bad? // GNU Social doesn't send an object in an unfollow. // .. what ao.Replace("object", ASTerm.MakeId((await _relevantEntities.FindRelevantObject(authorId, "https://www.w3.org/ns/activitystreams#Follow", targetUser)).FirstOrDefault()?.Id)); } else { ao.Replace("object", await _parseActivityObject(element, authorId, targetUser, true)); } return(ASTerm.MakeSubObject(ao)); }
private async Task <ASTerm> _parseActivityObject(XElement element, string authorId, string targetUser, bool isActivity = false) { if (!isActivity && element.Element(ActivityStreams + "verb") != null) { return(await _parseActivity(element, authorId, targetUser)); } var entity = await _entityStore.GetEntity(element.Element(Atom + "id")?.Value, true); if (entity != null) { if (entity.Type.Contains("https://www.w3.org/ns/activitystreams#Create")) { return(ASTerm.MakeId(entity.Data["object"].First().Id)); } return(ASTerm.MakeId(element.Element(Atom + "id")?.Value)); } var ao = new ASObject(); ao.Id = element.Element(Atom + "id")?.Value + (isActivity ? "#object" : ""); ao.Replace("kroeg:origin", ASTerm.MakePrimitive("atom")); var objectType = _objectTypeToType(element.Element(ActivityStreams + "object-type")?.Value); if (objectType == "https://www.w3.org/ns/activitystreams#Person") { return(ASTerm.MakeSubObject(_parseAuthor(element))); } ao.Type.Add(objectType); ao.Replace("attributedTo", ASTerm.MakeId(authorId)); if (element.Element(Atom + "summary") != null) { ao.Replace("summary", ASTerm.MakePrimitive(element.Element(Atom + "summary")?.Value)); } if (element.Element(Atom + "published") != null) { ao.Replace("published", ASTerm.MakePrimitive(element.Element(Atom + "published")?.Value)); } if (element.Element(Atom + "updated") != null) { ao.Replace("updated", ASTerm.MakePrimitive(element.Element(Atom + "updated")?.Value)); } ao.Replace("content", ASTerm.MakePrimitive(element.Element(Atom + "content")?.Value)); var mediaType = element.Element(Atom + "content")?.Attribute(NoNamespace + "type")?.Value; if (mediaType != null) { if (mediaType == "text") { mediaType = "text/plain"; } if (mediaType.Contains("/")) { ao.Replace("mediaType", ASTerm.MakePrimitive(mediaType)); } } if (element.Element(OStatus + "conversation") != null) { ao.Replace("conversation", ASTerm.MakePrimitive(element.Element(OStatus + "conversation").Attribute(NoNamespace + "ref")?.Value ?? element.Element(OStatus + "conversation").Value)); } if (element.Element(AtomThreading + "in-reply-to") != null) { var elm = element.Element(AtomThreading + "in-reply-to"); var @ref = await _findInReplyTo(elm.Attribute(NoNamespace + "ref").Value); var hrel = elm.Attribute(NoNamespace + "href")?.Value; if (hrel == null) { ao.Replace("inReplyTo", ASTerm.MakeId(@ref)); } else if (await _entityStore.GetEntity(@ref, false) != null) { ao.Replace("inReplyTo", ASTerm.MakeId(@ref)); } else { var lazyLoad = new ASObject(); lazyLoad.Id = @ref; lazyLoad.Type.Add("_:LazyLoad"); lazyLoad.Replace("href", ASTerm.MakePrimitive(hrel)); ao.Replace("inReplyTo", ASTerm.MakeSubObject(lazyLoad)); } } foreach (var tag in element.Elements(Atom + "category")) { var val = tag.Attribute(NoNamespace + "term").Value; var tagao = new ASObject(); tagao.Id = $"{_entityConfiguration.BaseUri}/tag/{val}"; tagao["name"].Add(ASTerm.MakePrimitive("#" + val)); tagao.Type.Add("Hashtag"); ao["tag"].Add(ASTerm.MakeSubObject(tagao)); } string retrievalUrl = null; foreach (var link in element.Elements(Atom + "link")) { var rel = link.Attribute(NoNamespace + "rel").Value; var type = link.Attribute(NoNamespace + "type")?.Value; var href = link.Attribute(NoNamespace + "href").Value; if (rel == "self" && type == "application/atom+xml") { retrievalUrl = href; } else if (rel == "alternate" && type == "text/html") { ao["url"].Add(ASTerm.MakePrimitive(href)); if (retrievalUrl == null) { retrievalUrl = href; } } else if (rel == "mentioned") { if (href == "http://activityschema.org/collection/public") { href = "https://www.w3.org/ns/activitystreams#Public"; } ao["to"].Add(ASTerm.MakeId(href)); } else if (rel == "enclosure") { // image var subAo = new ASObject(); subAo["url"].Add(ASTerm.MakePrimitive(href)); subAo["mediaType"].Add(ASTerm.MakePrimitive(type)); switch (type.Split('/')[0]) { case "image": subAo.Type.Add("https://www.w3.org/ns/activitystreams#Image"); break; case "video": subAo.Type.Add("https://www.w3.org/ns/activitystreams#Video"); break; default: continue; } if (link.Attribute(NoNamespace + "length") != null) { subAo["fileSize"].Add(ASTerm.MakePrimitive(int.Parse(link.Attribute(NoNamespace + "length").Value))); } ao["attachment"].Add(ASTerm.MakeSubObject(subAo)); } } return(ASTerm.MakeSubObject(ao)); }
public async Task <IActionResult> DoRegister(RegisterViewModel model) { if (!_configuration.GetSection("Kroeg").GetValue <bool>("CanRegister")) { return(NotFound()); } var apuser = new APUser { Username = model.Username, Email = model.Email }; if ((await _relevantEntities.FindEntitiesWithPreferredUsername(model.Username)).Count > 0) { ModelState.AddModelError("", "Username is already in use!"); } if (model.Password != model.VerifyPassword) { ModelState.AddModelError("", "Passwords don't match!"); } if (!ModelState.IsValid) { return(View("Register", model)); } await _connection.OpenAsync(); using (var trans = _connection.BeginTransaction()) { var result = await _userManager.CreateAsync(apuser, model.Password); if (!result.Succeeded) { ModelState.AddModelError("", result.Errors.First().Description); } if (!ModelState.IsValid) { return(View("Register", model)); } if (await _connection.ExecuteAsync("select count(*) from \"Users\"") == 1) { // await _userManager.AddClaimAsync(apuser, new Claim("admin", "true")); } await _signInManager.SignInAsync(apuser, false); var user = model.Username; var obj = new ASObject(); obj.Type.Add("https://www.w3.org/ns/activitystreams#Person"); obj["preferredUsername"].Add(ASTerm.MakePrimitive(user)); obj["name"].Add(ASTerm.MakePrimitive(user)); var create = new ASObject(); create.Type.Add("https://www.w3.org/ns/activitystreams#Create"); create["object"].Add(ASTerm.MakeSubObject(obj)); create["to"].Add(ASTerm.MakeId("https://www.w3.org/ns/activitystreams#Public")); Console.WriteLine($"--- creating actor. Unflattened:\n{create.Serialize().ToString(Formatting.Indented)}"); var apo = await _entityFlattener.FlattenAndStore(_entityStore, create); Console.WriteLine($"Flat: {apo.Data.Serialize().ToString(Formatting.Indented)}\n----"); var handler = new CreateActorHandler(_entityStore, apo, null, null, User, _collectionTools, _entityConfiguration, _connection); handler.UserOverride = apuser.Id; await handler.Handle(); var resultUser = await _entityStore.GetEntity(handler.MainObject.Data["object"].First().Id, false); var outbox = await _entityStore.GetEntity(resultUser.Data["outbox"].First().Id, false); var delivery = new DeliveryHandler(_entityStore, handler.MainObject, resultUser, outbox, User, _collectionTools, _provider.GetRequiredService <DeliveryService>()); await delivery.Handle(); trans.Commit(); return(RedirectToActionPermanent("Index", "Settings")); } }