예제 #1
0
        private static async Task GenerateQRCodeAsync(LinkBundle linkDocument, HttpRequest req, Binder binder)
        {
            req.Headers.TryGetValue("Origin", out StringValues origin);
            Url    generator = new Url($"{origin.ToString()}/{linkDocument.VanityUrl}");
            string payload   = generator.ToString();

            QRCodeGenerator qrGenerator = new QRCodeGenerator();
            QRCodeData      qrCodeData  = qrGenerator.CreateQrCode(payload, QRCodeGenerator.ECCLevel.Q);

            PngByteQRCode qrCode = new PngByteQRCode(qrCodeData);

            byte[] qrCodeAsPngByteArr = qrCode.GetGraphic(20);

            var attributes = new Attribute[]
            {
                new BlobAttribute(blobPath: $"{QRCODECONTAINER}/{linkDocument.VanityUrl}.png", FileAccess.Write),
                new StorageAccountAttribute("AzureWebJobsStorage")
            };

            using (var writer = await binder.BindAsync <CloudBlobStream>(attributes).ConfigureAwait(false))

            {
                writer.Write(qrCodeAsPngByteArr);
            }
        }
예제 #2
0
        private static void EnsureVanityUrl(LinkBundle linkDocument)
        {
            if (string.IsNullOrWhiteSpace(linkDocument.VanityUrl))
            {
                var code = new char[7];
                var rng  = new RNGCryptoServiceProvider();

                var bytes = new byte[sizeof(uint)];
                for (int i = 0; i < code.Length; i++)
                {
                    rng.GetBytes(bytes);
                    uint num = BitConverter.ToUInt32(bytes, 0) % (uint)CHARACTERS.Length;
                    code[i] = CHARACTERS[(int)num];
                }

                linkDocument.VanityUrl = new String(code);

                telemetryClient.TrackEvent(new EventTelemetry {
                    Name = "Custom Vanity Generated"
                });
            }

            // force lowercase
            linkDocument.VanityUrl = linkDocument.VanityUrl.ToLower();
        }
예제 #3
0
        private static bool ValidatePayLoad(LinkBundle linkDocument, HttpRequest req, out ProblemDetails problems)
        {
            bool isValid = (linkDocument != null) && linkDocument.Links.Count() > 0;

            problems = null;

            if (!isValid)
            {
                problems = new ProblemDetails()
                {
                    Title    = "Payload is invalid",
                    Detail   = "No links provided",
                    Status   = StatusCodes.Status400BadRequest,
                    Type     = "/linkylink/clientissue",
                    Instance = req.Path
                };
            }
            return(isValid);
        }
예제 #4
0
        public IActionResult GetLinks(
            [HttpTrigger(AuthorizationLevel.Function, "GET", Route = "links/{vanityUrl}")] HttpRequest req,
            [CosmosDB(
                 databaseName: "linkylinkdb",
                 collectionName: "linkbundles",
                 ConnectionStringSetting = "LinkLinkConnection",
                 SqlQuery = "SELECT * FROM linkbundles lb WHERE LOWER(lb.vanityUrl) = LOWER({vanityUrl})"
                 )] IEnumerable <LinkBundle> documents,
            string vanityUrl,
            ILogger log)
        {
            if (!documents.Any())
            {
                log.LogInformation($"Bundle for {vanityUrl} not found.");
                return(new NotFoundResult());
            }

            LinkBundle doc = documents.Single();

            return(new OkObjectResult(doc));
        }
예제 #5
0
        public async Task <IActionResult> UpdateList(
            [HttpTrigger(AuthorizationLevel.Function, "PATCH", Route = "links/{vanityUrl}")] HttpRequest req,
            [CosmosDB(
                 databaseName: "linkylinkdb",
                 collectionName: "linkbundles",
                 ConnectionStringSetting = "LinkLinkConnection",
                 SqlQuery = "SELECT * FROM linkbundles lb WHERE LOWER(lb.vanityUrl) = LOWER({vanityUrl})"
                 )] IEnumerable <LinkBundle> documents,
            [CosmosDB(ConnectionStringSetting = "LinkLinkConnection")] IDocumentClient docClient,
            string vanityUrl,
            ILogger log)
        {
            string handle = GetAccountInfo().HashedID;

            if (string.IsNullOrEmpty(handle))
            {
                return(new UnauthorizedResult());
            }

            if (!documents.Any())
            {
                log.LogInformation($"Bundle for {vanityUrl} not found.");
                return(new NotFoundResult());
            }

            try
            {
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                if (string.IsNullOrEmpty(requestBody))
                {
                    log.LogError("Request body is empty.");
                    return(new BadRequestResult());
                }

                JsonPatchDocument <LinkBundle> patchDocument = JsonConvert.DeserializeObject <JsonPatchDocument <LinkBundle> >(requestBody);

                if (!patchDocument.Operations.Any())
                {
                    log.LogError("Request body contained no operations.");
                    return(new NoContentResult());
                }

                LinkBundle bundle = documents.Single();
                patchDocument.ApplyTo(bundle);

                Uri            collUri    = UriFactory.CreateDocumentCollectionUri("linkylinkdb", "linkbundles");
                RequestOptions reqOptions = new RequestOptions {
                    PartitionKey = new PartitionKey(vanityUrl)
                };
                await docClient.UpsertDocumentAsync(collUri, bundle, reqOptions);
            }
            catch (JsonSerializationException ex)
            {
                log.LogError(ex, ex.Message);
                return(new BadRequestResult());
            }
            catch (Exception ex)
            {
                log.LogError(ex, ex.Message);
                return(new StatusCodeResult(StatusCodes.Status500InternalServerError));
            }

            return(new NoContentResult());
        }