Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #4
0
        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}\"");
        }
Пример #5
0
        public async Task Test()
        {
            var g = MagicKey.Generate();

            var magicKey = new MagicKey(g.PrivateKey);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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));
        }