public async Task <ASObject> BuildFakeObject(APEntity entity, string fragment) { if (!_configuration.IsActor(entity.Data)) { return(null); } if (fragment == "key") { var key = await _context.GetKey(entity.Id); var salm = new MagicKey(key.PrivateKey); var pemData = salm.AsPEM; var keyObj = new ASObject(); keyObj.Replace("owner", new ASTerm(entity.Id)); keyObj.Replace("publicKeyPem", new ASTerm(pemData)); keyObj.Replace("id", new ASTerm($"{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", 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(entity.Id + "#endpoints")); return(endpoints); } return(null); }
public async Task <IActionResult> GetKey(string id) { var user = await _entityStore.GetEntity(id, false); if (user == null || !user.IsOwner) { return(NotFound()); } var key = await _context.GetKey(user.Id); var salm = new MagicKey(key.PrivateKey); var data = salm.AsPEM; var keyObj = new ASObject(); keyObj.Replace("owner", new ASTerm(user.Id)); keyObj.Replace("publicKeyPem", new ASTerm(data)); keyObj.Replace("id", new ASTerm($"{Request.Scheme}://{Request.Host}{Request.Path}{Request.QueryString}")); return(Content(keyObj.Serialize().ToString(), "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")); }
public MagicKey GetMagicKey() { //Cached key if (_magicKey != null) { return(_magicKey); } //Generate key if needed if (!File.Exists(Path)) { var key = MagicKey.Generate(); File.WriteAllText(Path, key.PrivateKey); } //Load and return key var serializedKey = File.ReadAllText(Path); _magicKey = new MagicKey(serializedKey); return(_magicKey); }
private async Task <string> _buildSignature(string ownerId, HttpRequestMessage message) { string[] headers = new string[] { "(request-target)", "date", "authorization", "content-type" }; var toSign = new StringBuilder(); foreach (var header in headers) { if (header == "(request-target)") { toSign.Append($"{header}: {message.Method.Method.ToLower()} {message.RequestUri.PathAndQuery}\n"); } else { if (message.Headers.TryGetValues(header, out var vals)) { toSign.Append($"{header}: {string.Join(", ", vals)}\n"); } else if (message.Content.Headers.TryGetValues(header, out var cvals)) { toSign.Append($"{header}: {string.Join(", ", cvals)}\n"); } else { toSign.Append($"{header}: \n"); } } } toSign.Remove(toSign.Length - 1, 1); var key = await _context.GetKey(ownerId); var magic = new MagicKey(key.PrivateKey); var signed = Convert.ToBase64String(magic.Sign(Encoding.UTF8.GetBytes(toSign.ToString()))); var ownerOrigin = new Uri(ownerId); var keyId = ownerId + "#key"; return($"keyId=\"{keyId}\",algorithm=\"rsa-sha256\",headers=\"{string.Join(" ", headers)}\",signature=\"{signed}\""); }
public async Task Test() { var g = MagicKey.Generate(); var magicKey = new MagicKey(g.PrivateKey); }
public override async Task <bool> Handle() { if (MainObject.Type != "Create") { return(true); } var activityData = MainObject.Data; var objectEntity = await EntityStore.GetEntity((string)activityData["object"].First().Primitive, 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, "likes", 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(new ASTerm(blocked.Id)); blocks.Data = blocksData; objectEntity.Data = objectData; await EntityStore.StoreEntity(blocked); await EntityStore.StoreEntity(blocks); await EntityStore.StoreEntity(objectEntity); var userId = User.FindFirst(ClaimTypes.NameIdentifier).Value; _context.UserActorPermissions.Add(new UserActorPermission { UserId = userId, ActorId = objectEntity.Id, IsAdmin = true }); var key = new SalmonKey(); var salmon = MagicKey.Generate(); key.EntityId = objectEntity.Id; key.PrivateKey = salmon.PrivateKey; _context.SalmonKeys.Add(key); if (!activityData["locked"].Any() && !activityData["_:locked"].Any()) { activityData.Replace("_:locked", new ASTerm(false)); } if (!activityData["actor"].Any()) { activityData["actor"].Add(new ASTerm(objectEntity.Id)); } MainObject.Data = activityData; await EntityStore.StoreEntity(MainObject); await EntityStore.CommitChanges(); await _context.SaveChangesAsync(); return(true); }
public async Task <IActionResult> WebFinger(string resource) { if (!resource.StartsWith("acct:")) { return(Unauthorized()); } var username = resource.Split(':')[1].Split('@'); var items = await _relevantEntities.FindEntitiesWithPreferredUsername(username[0]); if (items.Count == 0) { return(NotFound()); } var item = items.First(); var result = new WebfingerResult() { subject = resource, aliases = new List <string>() { item.Id }, links = new List <WebfingerLink> { new WebfingerLink { rel = "http://webfinger.net/rel/profile-page", type = "text/html", href = item.Id }, new WebfingerLink { rel = "self", type = "application/activity+json", href = item.Id }, new WebfingerLink { rel = "self", type = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"", href = item.Id }, new WebfingerLink { rel = "http://ostatus.org/schema/1.0/subscribe", template = item.Id + "#id=%40{uri}" } } }; var salmon = await _keyService.GetKey(item.Id); var magicKey = new MagicKey(salmon.PrivateKey); result.links.Add(new WebfingerLink { rel = "magic-public-key", href = "data:application/magic-public-key," + magicKey.PublicKey }); return(Json(result)); }