示例#1
0
        public async Task HandleAsync_(string title, string description, string groupName, string version, string owner, string fileName, string extension, ulong sizeInBytes, string contentHash)
        {
            var cancellationToken = CancellationToken.None;

            var file = FutureNHS.WOPIHost.File.With(fileName, version);

            var services = new ServiceCollection();

            var endpointForFileExtension = new Uri("https://domain.com/path?param=value", UriKind.Absolute);

            var wopiDiscoveryDocument = new Moq.Mock <IWopiDiscoveryDocument>();

            wopiDiscoveryDocument.Setup(o => o.GetEndpointForFileExtension(extension, "view", Moq.It.IsAny <Uri>())).Returns(endpointForFileExtension);
            wopiDiscoveryDocument.Setup(o => o.IsEmpty).Returns(false);
            wopiDiscoveryDocument.Setup(o => o.IsTainted).Returns(false);

            var wopiDiscoveryDocumentFactory = new Moq.Mock <IWopiDiscoveryDocumentFactory>();

            wopiDiscoveryDocumentFactory.Setup(o => o.CreateDocumentAsync(cancellationToken)).Returns(Task.FromResult(wopiDiscoveryDocument.Object));

            var fileId = Guid.NewGuid();

            var fileMetadata = new UserFileMetadata()
            {
                FileId                = fileId,
                Title                 = title,
                Description           = description,
                GroupName             = groupName,
                FileVersion           = version,
                OwnerUserName         = owner,
                Name                  = fileName,
                Extension             = extension,
                BlobName              = fileName,
                SizeInBytes           = sizeInBytes,
                LastWriteTimeUtc      = DateTimeOffset.UtcNow,
                ContentHash           = Convert.FromBase64String("aGFzaA == "),
                UserHasViewPermission = true,
                UserHasEditPermission = false
            };

            var authenticatedUser = new AuthenticatedUser(Guid.NewGuid(), default)
            {
                FileMetadata = fileMetadata
            };

            var wopiConfiguration = new WopiConfiguration {
                HostFilesUrl = new Uri("https://hostfiles.net/path", UriKind.Absolute)
            };

            var wopiConfigurationSnapshot = new Moq.Mock <IOptionsSnapshot <WopiConfiguration> >();

            wopiConfigurationSnapshot.Setup(o => o.Value).Returns(wopiConfiguration);

            var userAuthenticationService = new Moq.Mock <IUserAuthenticationService>();

            var permission = FileAccessPermission.View;

            var userFileAccessToken = new UserFileAccessToken(Guid.NewGuid(), authenticatedUser, permission, DateTimeOffset.UtcNow.AddDays(1));

            userAuthenticationService.Setup(x => x.GenerateAccessToken(authenticatedUser, file, permission, cancellationToken)).Returns(Task.FromResult(userFileAccessToken));

            services.AddScoped(sp => wopiDiscoveryDocumentFactory.Object);
            services.AddScoped(sp => wopiConfigurationSnapshot.Object);
            services.AddScoped(sp => new Moq.Mock <IAzureTableStoreClient>().Object);
            services.AddScoped(sp => userAuthenticationService.Object);
            services.AddScoped(sp => new Moq.Mock <IUserFileAccessTokenRepository>().Object);

            var httpContext = new DefaultHttpContext
            {
                RequestServices = services.BuildServiceProvider()
            };

            using var responseBodyStream = new MemoryStream();

            httpContext.Response.Body = responseBodyStream;

            var postAuthoriseUserRequestHandler = AuthoriseUserRequestHandler.With(authenticatedUser, permission, file);



            await postAuthoriseUserRequestHandler.HandleAsync(httpContext, cancellationToken);

            Assert.AreEqual((int)HttpStatusCode.OK, httpContext.Response.StatusCode);

            Assert.AreEqual("application/json; charset=utf-8", httpContext.Response.ContentType);

            Assert.AreSame(responseBodyStream, httpContext.Response.Body);

            responseBodyStream.Position = 0;

            dynamic responseBody = await JsonSerializer.DeserializeAsync <ExpandoObject>(responseBodyStream, cancellationToken : cancellationToken);

            Assert.IsNotNull(responseBody);

            var accessToken = ((JsonElement)(responseBody.accessToken)).GetString();

            Assert.IsNotNull(accessToken);

            var wopiClientUrlForFile = ((JsonElement)(responseBody.wopiClientUrlForFile)).GetString();

            Assert.IsTrue(Uri.IsWellFormedUriString(wopiClientUrlForFile, UriKind.Absolute));

            Assert.AreEqual(endpointForFileExtension, new Uri(wopiClientUrlForFile, UriKind.Absolute));
        }
    }
        async Task <FileContentMetadata> IFileContentMetadataRepository.GetDetailsAndPutContentIntoStreamAsync(UserFileMetadata fileMetadata, Stream streamToWriteTo, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (fileMetadata is null)
            {
                throw new ArgumentNullException(nameof(fileMetadata));
            }

            Debug.Assert(!string.IsNullOrWhiteSpace(fileMetadata.BlobName));
            Debug.Assert(fileMetadata.ContentHash is not null);

            if (streamToWriteTo is null)
            {
                throw new ArgumentNullException(nameof(streamToWriteTo));
            }

            Debug.Assert(streamToWriteTo.CanWrite);

            var downloadDetails = await _azureBlobStoreClient.FetchBlobAndWriteToStream(_blobContainerName, fileMetadata.BlobName, fileMetadata.FileVersion, fileMetadata.ContentHash, streamToWriteTo, cancellationToken);

            return(new FileContentMetadata(
                       contentVersion: downloadDetails.VersionId,
                       contentHash: downloadDetails.ContentHash,
                       contentEncoding: downloadDetails.ContentEncoding,
                       contentLanguage: downloadDetails.ContentLanguage,
                       contentType: downloadDetails.ContentType,
                       contentLength: 0 > downloadDetails.ContentLength ? 0 : (ulong)downloadDetails.ContentLength,
                       lastAccessed: DateTimeOffset.MinValue == downloadDetails.LastAccessed ? default : downloadDetails.LastAccessed,
                       lastModified: downloadDetails.LastModified,
                       fileMetadata: fileMetadata
                       ));
        }
示例#3
0
        public FileContentMetadata(string contentVersion, string contentType, byte[] contentHash, ulong contentLength, string?contentEncoding, string?contentLanguage, DateTimeOffset?lastAccessed, DateTimeOffset lastModified, UserFileMetadata fileMetadata)
        {
            if (string.IsNullOrWhiteSpace(contentVersion))
            {
                throw new ArgumentNullException(nameof(contentVersion));
            }
            if (string.IsNullOrWhiteSpace(contentType))
            {
                throw new ArgumentNullException(nameof(contentType));
            }

            if (0 > contentLength)
            {
                throw new ArgumentOutOfRangeException(nameof(contentLength), "Must be greater than zero");
            }

            ContentVersion  = contentVersion;
            ContentLength   = contentLength;
            ContentType     = contentType;
            ContentEncoding = contentEncoding;
            ContentLanguage = contentLanguage;
            LastAccessed    = lastAccessed;
            LastModified    = lastModified;

            ContentHash = Convert.ToBase64String(contentHash);

            FileMetadata = fileMetadata ?? throw new ArgumentNullException(nameof(fileMetadata));
        }
示例#4
0
        public async Task HandleAsync_FormsWOPICompliantResponseUsingFileMetadataAndUserContextAndFeatures(string title, string description, string groupName, string owner, string fileName, string extension, ulong sizeInBytes, string contentHash)
        {
            var cancellationToken = new CancellationToken();

            var services = new ServiceCollection();

            var fileMetadataRepository = new Moq.Mock <IUserFileMetadataProvider>();

            var fileRepositoryInvoked = false;

            services.AddScoped(sp => fileMetadataRepository.Object);

            var httpContext = new DefaultHttpContext {
                RequestServices = services.BuildServiceProvider()
            };

            using var responseBodyStream = new MemoryStream();

            httpContext.Response.Body = responseBodyStream;

            var authenticatedUser = new AuthenticatedUser(Guid.NewGuid(), default);

            var fileId      = Guid.NewGuid();
            var fileVersion = Guid.NewGuid().ToString();

            var file = FutureNHS.WOPIHost.File.With(fileName, fileVersion);

            var fileMetadata = new UserFileMetadata()
            {
                FileId                = fileId,
                Title                 = title,
                Description           = description,
                GroupName             = groupName,
                FileVersion           = fileVersion,
                OwnerUserName         = owner,
                Name                  = fileName,
                Extension             = extension,
                BlobName              = fileId.ToString() + extension,
                SizeInBytes           = sizeInBytes,
                LastWriteTimeUtc      = DateTimeOffset.UtcNow,
                ContentHash           = Convert.FromBase64String("aGFzaA == "),
                UserHasViewPermission = true,
                UserHasEditPermission = false
            };

            fileMetadataRepository.
            Setup(x => x.GetForFileAsync(Moq.It.IsAny <FutureNHS.WOPIHost.File>(), Moq.It.IsAny <AuthenticatedUser>(), Moq.It.IsAny <CancellationToken>())).
            Callback((FutureNHS.WOPIHost.File givenFile, AuthenticatedUser givenAuthenticatedUser, CancellationToken givenCancellationToken) => {
                Assert.IsFalse(givenFile.IsEmpty);

                Assert.IsFalse(givenCancellationToken.IsCancellationRequested, "Expected the cancellation token to not be cancelled");

                Assert.AreEqual(file.Id, givenFile.Id, "Expected the SUT to request the file from the repository whose id it was provided with");
                Assert.AreEqual(fileName, givenFile.Name, "Expected the SUT to request the file from the repository whose name it was provided with");
                Assert.AreEqual(fileVersion, givenFile.Version, "Expected the SUT to request the file version from the repository that it was provided with");
                Assert.AreEqual(authenticatedUser, givenAuthenticatedUser, "Expected the SUT to pass to the repository the authenticated user that it was provided with");
                Assert.AreEqual(cancellationToken, givenCancellationToken, "Expected the same cancellation token to propagate between service interfaces");

                fileRepositoryInvoked = true;
            }).
            Returns(Task.FromResult(fileMetadata));

            var features = new Features();


            var checkFileInfoWopiRequestHandler = CheckFileInfoWopiRequestHandler.With(authenticatedUser, file, features);

            await checkFileInfoWopiRequestHandler.HandleAsync(httpContext, cancellationToken);

            Assert.IsTrue(fileRepositoryInvoked);

            Assert.AreEqual("application/json; charset=utf-8", httpContext.Response.ContentType);

            Assert.AreSame(responseBodyStream, httpContext.Response.Body);

            responseBodyStream.Position = 0;

            dynamic responseBody = await JsonSerializer.DeserializeAsync <ExpandoObject>(responseBodyStream, cancellationToken : cancellationToken);

            Assert.IsNotNull(responseBody);

            Assert.AreEqual(fileMetadata.Title, ((JsonElement)(responseBody.BaseFileName)).GetString());
            Assert.AreEqual(fileMetadata.FileVersion, ((JsonElement)(responseBody.Version)).GetString());
            Assert.AreEqual(fileMetadata.OwnerUserName, ((JsonElement)(responseBody.OwnerId)).GetString());
            Assert.AreEqual(fileMetadata.Extension, ((JsonElement)(responseBody.FileExtension)).GetString());
            Assert.AreEqual(fileMetadata.SizeInBytes, ((JsonElement)(responseBody.Size)).GetUInt64());
            Assert.AreEqual(fileMetadata.LastWriteTimeUtc.ToIso8601(), ((JsonElement)(responseBody.LastModifiedTime)).GetString());

            Assert.AreEqual(FutureNHS.WOPIHost.File.FILENAME_MAXIMUM_LENGTH, ((JsonElement)(responseBody.FileNameMaxLength)).GetInt32());
        }