diff --git a/MegaApiClient.Tests/Context/AnonymousAsyncTestContext.cs b/MegaApiClient.Tests/Context/AnonymousAsyncTestContext.cs index 10ba03c..7566702 100644 --- a/MegaApiClient.Tests/Context/AnonymousAsyncTestContext.cs +++ b/MegaApiClient.Tests/Context/AnonymousAsyncTestContext.cs @@ -10,7 +10,7 @@ public class AnonymousAsyncTestContext : AnonymousTestContext, IDisposable { public void Dispose() { - ((MegaApiClientAsyncWrapper)this.Client).Dispose(); + ((MegaApiClientAsyncWrapper)Client).Dispose(); } protected override IMegaApiClient CreateClient() diff --git a/MegaApiClient.Tests/Context/AnonymousTestContext.cs b/MegaApiClient.Tests/Context/AnonymousTestContext.cs index 275cb3f..0da5caf 100644 --- a/MegaApiClient.Tests/Context/AnonymousTestContext.cs +++ b/MegaApiClient.Tests/Context/AnonymousTestContext.cs @@ -16,7 +16,7 @@ protected override void ConnectClient(IMegaApiClient client) protected override IEnumerable GetProtectedNodes() { - return this.Client.GetNodes() + return Client.GetNodes() .Where(x => x.Type == NodeType.Inbox || x.Type == NodeType.Root || x.Type == NodeType.Trash) .Select(x => x.Id); } diff --git a/MegaApiClient.Tests/Context/AuthenticatedAsyncTestContext.cs b/MegaApiClient.Tests/Context/AuthenticatedAsyncTestContext.cs index 27f5bbd..d653b06 100644 --- a/MegaApiClient.Tests/Context/AuthenticatedAsyncTestContext.cs +++ b/MegaApiClient.Tests/Context/AuthenticatedAsyncTestContext.cs @@ -1,13 +1,11 @@ -using Xunit; - -namespace CG.Web.MegaApiClient.Tests.Context +namespace CG.Web.MegaApiClient.Tests.Context { public class AuthenticatedAsyncTestContext : AuthenticatedTestContext { public override void Dispose() { base.Dispose(); - ((MegaApiClientAsyncWrapper)this.Client).Dispose(); + ((MegaApiClientAsyncWrapper)Client).Dispose(); } protected override IMegaApiClient CreateClient() diff --git a/MegaApiClient.Tests/Context/AuthenticatedTestContext.cs b/MegaApiClient.Tests/Context/AuthenticatedTestContext.cs index ac99243..dce657d 100644 --- a/MegaApiClient.Tests/Context/AuthenticatedTestContext.cs +++ b/MegaApiClient.Tests/Context/AuthenticatedTestContext.cs @@ -27,7 +27,7 @@ static AuthenticatedTestContext() public virtual void Dispose() { - this.Client.Logout(); + Client.Logout(); } protected override void ConnectClient(IMegaApiClient client) diff --git a/MegaApiClient.Tests/Context/TestContext.cs b/MegaApiClient.Tests/Context/TestContext.cs index fe4b00e..2c38d31 100644 --- a/MegaApiClient.Tests/Context/TestContext.cs +++ b/MegaApiClient.Tests/Context/TestContext.cs @@ -13,29 +13,26 @@ public abstract class TestContext : ITestContext { private const int MaxRetry = 3; - private readonly Lazy lazyClient; - private readonly Lazy> lazyProtectedNodes; - private readonly Lazy> lazyPermanentNodes; - private readonly Action logMessageAction; - private ITestOutputHelper testOutputHelper; + private readonly Lazy _lazyClient; + private readonly Lazy> _lazyProtectedNodes; + private readonly Lazy> _lazyPermanentNodes; + private readonly Action _logMessageAction; + private ITestOutputHelper _testOutputHelper; protected TestContext() { - this.WebTimeout = 60000; - this.lazyClient = new Lazy(this.InitializeClient); - this.lazyProtectedNodes = new Lazy>(() => this.GetProtectedNodes().ToArray()); - this.lazyPermanentNodes = new Lazy>(() => this.GetPermanentNodes().ToArray()); - this.logMessageAction = x => + WebTimeout = 60000; + _lazyClient = new Lazy(InitializeClient); + _lazyProtectedNodes = new Lazy>(() => GetProtectedNodes().ToArray()); + _lazyPermanentNodes = new Lazy>(() => GetPermanentNodes().ToArray()); + _logMessageAction = x => { Debug.WriteLine(x); - testOutputHelper?.WriteLine(x); + _testOutputHelper?.WriteLine(x); }; } - public IMegaApiClient Client - { - get { return this.lazyClient.Value; } - } + public IMegaApiClient Client => _lazyClient.Value; public IWebClient WebClient { get; private set; } @@ -43,32 +40,26 @@ public IMegaApiClient Client public int WebTimeout { get; } - public IEnumerable ProtectedNodes - { - get { return this.lazyProtectedNodes.Value; } - } + public IEnumerable ProtectedNodes => _lazyProtectedNodes.Value; - public IEnumerable PermanentRootNodes - { - get { return this.lazyPermanentNodes.Value; } - } + public IEnumerable PermanentRootNodes => _lazyPermanentNodes.Value; public void SetLogger(ITestOutputHelper testOutputHelper) { - this.testOutputHelper = testOutputHelper; + _testOutputHelper = testOutputHelper; } public void ClearLogger() { - this.testOutputHelper = null; + _testOutputHelper = null; } protected virtual IMegaApiClient CreateClient() { - this.Options = new Options(applicationKey: "ewZQFBBC"); - this.WebClient = new TestWebClient(new WebClient(this.WebTimeout, null, new TestMessageHandler(this.logMessageAction), false), MaxRetry, this.logMessageAction); + Options = new Options(applicationKey: "ewZQFBBC"); + WebClient = new TestWebClient(new WebClient(WebTimeout, null, new TestMessageHandler(), false), MaxRetry, _logMessageAction); - return new MegaApiClient(this.Options, this.WebClient); + return new MegaApiClient(Options, WebClient); } protected abstract IEnumerable GetProtectedNodes(); @@ -79,29 +70,22 @@ protected virtual IMegaApiClient CreateClient() private IMegaApiClient InitializeClient() { - var client = this.CreateClient(); - client.ApiRequestFailed += this.OnApiRequestFailed; - this.ConnectClient(client); + var client = CreateClient(); + client.ApiRequestFailed += OnApiRequestFailed; + ConnectClient(client); - this.logMessageAction($"Client created for context {this.GetType().Name}"); + _logMessageAction($"Client created for context {GetType().Name}"); return client; } - private void OnApiRequestFailed(object sender, ApiRequestFailedEventArgs e) + private void OnApiRequestFailed(object _, ApiRequestFailedEventArgs e) { - this.logMessageAction($"ApiRequestFailed: {e.ApiResult}, {e.ApiUrl}, {e.AttemptNum}, {e.RetryDelay}, {e.ResponseJson}, {e.Exception} {e.Exception?.Message}"); + _logMessageAction($"ApiRequestFailed: {e.ApiResult}, {e.ApiUrl}, {e.AttemptNum}, {e.RetryDelay}, {e.ResponseJson}, {e.Exception} {e.Exception?.Message}"); } private class TestMessageHandler : HttpClientHandler { - private readonly Action logMessageAction; - - public TestMessageHandler(Action logMessageAction) - { - this.logMessageAction = logMessageAction; - } - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return await base.SendAsync(request, cancellationToken); diff --git a/MegaApiClient.Tests/DownloadUpload.cs b/MegaApiClient.Tests/DownloadUpload.cs index 238f760..52664fc 100644 --- a/MegaApiClient.Tests/DownloadUpload.cs +++ b/MegaApiClient.Tests/DownloadUpload.cs @@ -14,19 +14,19 @@ namespace CG.Web.MegaApiClient.Tests public abstract class DownloadUpload : TestsBase { - protected readonly Random random = new Random(); + protected readonly Random Random = new(); - private readonly int savedChunksPackSize; + private readonly int _savedChunksPackSize; protected DownloadUpload(ITestContext context, ITestOutputHelper testOutputHelper) : base(context, testOutputHelper) { - this.savedChunksPackSize = this.context.Options.ChunksPackSize; + _savedChunksPackSize = Context.Options.ChunksPackSize; } public override void Dispose() { - this.context.Options.ChunksPackSize = this.savedChunksPackSize; + Context.Options.ChunksPackSize = _savedChunksPackSize; base.Dispose(); } @@ -34,12 +34,12 @@ public override void Dispose() public void UploadStream_InvalidParameters_Throws(bool hasStream, string name, NodeType? nodeType, Type expectedExceptionType) { var stream = hasStream ? new MemoryStream() : null; - INode parent = nodeType == null + var parent = nodeType == null ? null : nodeType == NodeType.Directory ? Mock.Of(x => x.Type == NodeType.Directory) : Mock.Of(x => x.Type == NodeType.File); - Assert.Throws(expectedExceptionType, () => this.context.Client.Upload(stream, name, parent)); + Assert.Throws(expectedExceptionType, () => Context.Client.Upload(stream, name, parent)); } public static IEnumerable InvalidUploadStreamParameters @@ -67,15 +67,15 @@ public static IEnumerable InvalidUploadStreamParameters [InlineData(NodeType.Trash)] public void UploadStream_DifferentParent_Succeeds(NodeType parentType) { - byte[] data = new byte[123]; - this.random.NextBytes(data); + var data = new byte[123]; + Random.NextBytes(data); - INode parent = this.GetNode(parentType); + var parent = GetNode(parentType); INode node; using (Stream stream = new MemoryStream(data)) { - node = this.context.Client.Upload(stream, "test", parent); + node = Context.Client.Upload(stream, "test", parent); } Assert.NotNull(node); @@ -83,7 +83,7 @@ public void UploadStream_DifferentParent_Succeeds(NodeType parentType) Assert.Equal(parent.Id, node.ParentId); Assert.Equal("test", node.Name); Assert.Equal(data.Length, node.Size); - Assert.Single(this.context.Client.GetNodes(), x => x.Id == node.Id); + Assert.Single(Context.Client.GetNodes(), x => x.Id == node.Id); } [Theory] @@ -96,45 +96,43 @@ public void UploadStream_DifferentParent_Succeeds(NodeType parentType) [InlineData(2000000, -1, 1)] public void UploadStream_ValidateContent_Succeeds(int dataSize, int chunksPackSize, int expectedUploadCalls) { - byte[] uploadedData = new byte[dataSize]; - this.random.NextBytes(uploadedData); + var uploadedData = new byte[dataSize]; + Random.NextBytes(uploadedData); - INode parent = this.GetNode(NodeType.Root); + var parent = GetNode(NodeType.Root); - using (Stream stream = new MemoryStream(uploadedData)) + using Stream stream = new MemoryStream(uploadedData); + var uploadCalls = 0; + void OnCall(TestWebClient.CallType callType, Uri url) { - int uploadCalls = 0; - Action onCall = (callType, url) => + if (callType == TestWebClient.CallType.PostRequestRaw) { - if (callType == TestWebClient.CallType.PostRequestRaw) - { - uploadCalls++; - } - }; - - this.context.Options.ChunksPackSize = chunksPackSize; - INode node = null; - try - { - ((TestWebClient)this.context.WebClient).OnCalled += onCall; - node = this.context.Client.Upload(stream, "test", parent); - } - finally - { - ((TestWebClient)this.context.WebClient).OnCalled -= onCall; - Assert.Equal(expectedUploadCalls, uploadCalls); + uploadCalls++; } + } - stream.Position = 0; - this.AreStreamsEquivalent(this.context.Client.Download(node), stream); + Context.Options.ChunksPackSize = chunksPackSize; + INode node = null; + try + { + ((TestWebClient)Context.WebClient).OnCalled += OnCall; + node = Context.Client.Upload(stream, "test", parent); } + finally + { + ((TestWebClient)Context.WebClient).OnCalled -= OnCall; + Assert.Equal(expectedUploadCalls, uploadCalls); + } + + stream.Position = 0; + AreStreamsEquivalent(Context.Client.Download(node), stream); } [Theory, MemberData(nameof(DownloadLinkInvalidParameter))] public void DownloadLink_ToStream_InvalidParameter_Throws(string uriString, Type expectedExceptionType) { var uri = uriString == null ? null : new Uri(uriString); - Assert.Throws(expectedExceptionType, () => this.context.Client.Download(uri)); + Assert.Throws(expectedExceptionType, () => Context.Client.Download(uri)); } public static IEnumerable DownloadLinkInvalidParameter() @@ -149,41 +147,37 @@ public static IEnumerable DownloadLinkInvalidParameter() [Fact] public void DownloadLink_ToStream_Succeeds() { - const string expectedResultFile = "Data/SampleFile.jpg"; + const string ExpectedResultFile = "Data/SampleFile.jpg"; - using (Stream stream = new FileStream(this.GetAbsoluteFilePath(expectedResultFile), FileMode.Open, FileAccess.Read)) - { - this.AreStreamsEquivalent(this.context.Client.Download(new Uri(AuthenticatedTestContext.Inputs.FileLink)), stream); - } + using Stream stream = new FileStream(GetAbsoluteFilePath(ExpectedResultFile), FileMode.Open, FileAccess.Read); + AreStreamsEquivalent(Context.Client.Download(new Uri(AuthenticatedTestContext.Inputs.FileLink)), stream); } [RetryFact] public void Download_ValidateStream_Succeeds() { - using (Stream stream = this.context.Client.Download(new Uri(AuthenticatedTestContext.Inputs.FileLink))) - { - Assert.NotNull(stream); - Assert.Equal(AuthenticatedTestContext.Inputs.SharedFile.Size, stream.Length); - Assert.True(stream.CanRead); - Assert.False(stream.CanSeek); - Assert.False(stream.CanTimeout); - Assert.False(stream.CanWrite); - Assert.Equal(0, stream.Position); - } + using var stream = Context.Client.Download(new Uri(AuthenticatedTestContext.Inputs.FileLink)); + Assert.NotNull(stream); + Assert.Equal(AuthenticatedTestContext.Inputs.SharedFile.Size, stream.Length); + Assert.True(stream.CanRead); + Assert.False(stream.CanSeek); + Assert.False(stream.CanTimeout); + Assert.False(stream.CanWrite); + Assert.Equal(0, stream.Position); } [Theory, MemberData(nameof(DownloadLinkToFileInvalidParameter))] public void DownloadLink_ToFile_InvalidParameter_Throws(string uriString, string outFile, Type expectedExceptionType) { var uri = uriString == null ? null : new Uri(uriString); - Assert.Throws(expectedExceptionType, () => this.context.Client.DownloadFile(uri, outFile)); + Assert.Throws(expectedExceptionType, () => Context.Client.DownloadFile(uri, outFile)); } public static IEnumerable DownloadLinkToFileInvalidParameter { get { - string outFile = Path.GetTempFileName(); + var outFile = Path.GetTempFileName(); yield return new object[] { null, null, typeof(ArgumentNullException) }; yield return new object[] { null, outFile, typeof(ArgumentNullException) }; @@ -200,61 +194,55 @@ public static IEnumerable DownloadLinkToFileInvalidParameter [Fact] public void DownloadLink_ToFile_Succeeds() { - const string expectedResultFile = "Data/SampleFile.jpg"; + const string ExpectedResultFile = "Data/SampleFile.jpg"; - string outFile = this.GetTempFileName(); - this.context.Client.DownloadFile(new Uri(AuthenticatedTestContext.Inputs.FileLink), outFile); + var outFile = GetTempFileName(); + Context.Client.DownloadFile(new Uri(AuthenticatedTestContext.Inputs.FileLink), outFile); - Assert.Equal(File.ReadAllBytes(this.GetAbsoluteFilePath(expectedResultFile)), File.ReadAllBytes(outFile)); + Assert.Equal(File.ReadAllBytes(GetAbsoluteFilePath(ExpectedResultFile)), File.ReadAllBytes(outFile)); } [Fact] public void GetNodesFromLink_Download_Succeeds() { - const string expectedResultFile = "Data/SampleFile.jpg"; - var nodes = this.context.Client.GetNodesFromLink(new Uri(AuthenticatedTestContext.Inputs.FolderLink)); + const string ExpectedResultFile = "Data/SampleFile.jpg"; + var nodes = Context.Client.GetNodesFromLink(new Uri(AuthenticatedTestContext.Inputs.FolderLink)); var node = nodes.Single(x => x.Name == "SharedFile.jpg"); - using (Stream stream = new FileStream(this.GetAbsoluteFilePath(expectedResultFile), FileMode.Open, FileAccess.Read)) - { - this.AreStreamsEquivalent(this.context.Client.Download(node), stream); - } + using Stream stream = new FileStream(GetAbsoluteFilePath(ExpectedResultFile), FileMode.Open, FileAccess.Read); + AreStreamsEquivalent(Context.Client.Download(node), stream); } - protected void AreStreamsEquivalent(Stream stream1, Stream stream2) + protected static void AreStreamsEquivalent(Stream stream1, Stream stream2) { - byte[] stream1data = new byte[stream1.Length]; - byte[] stream2data = new byte[stream2.Length]; + var stream1data = new byte[stream1.Length]; + var stream2data = new byte[stream2.Length]; - int readStream1 = stream1.Read(stream1data, 0, stream1data.Length); + var readStream1 = stream1.Read(stream1data, 0, stream1data.Length); Assert.Equal(stream1data.Length, readStream1); - int readStream2 = stream2.Read(stream2data, 0, stream2data.Length); + var readStream2 = stream2.Read(stream2data, 0, stream2data.Length); Assert.Equal(stream2data.Length, readStream2); Assert.Equal(stream1data, stream2data); } - protected void AreFileEquivalent(string file1, string file2) + protected static void AreFileEquivalent(string file1, string file2) { - using (Stream stream1 = new FileStream(file1, FileMode.Open, FileAccess.Read)) - { - using (Stream stream2 = new FileStream(file2, FileMode.Open, FileAccess.Read)) - { - this.AreStreamsEquivalent(stream1, stream2); - } - } + using Stream stream1 = new FileStream(file1, FileMode.Open, FileAccess.Read); + using Stream stream2 = new FileStream(file2, FileMode.Open, FileAccess.Read); + AreStreamsEquivalent(stream1, stream2); } protected string GetAbsoluteFilePath(string relativeFilePath) { - var currentAssembly = this.GetType().GetTypeInfo().Assembly.Location; + var currentAssembly = GetType().GetTypeInfo().Assembly.Location; var assemblyDirectory = Path.GetDirectoryName(currentAssembly); return Path.Combine(assemblyDirectory, relativeFilePath); } - protected string GetTempFileName() + protected static string GetTempFileName() { var file = Path.GetTempFileName(); File.Delete(file); diff --git a/MegaApiClient.Tests/DownloadUploadAuthenticated.cs b/MegaApiClient.Tests/DownloadUploadAuthenticated.cs index 096a5fb..5b93a31 100644 --- a/MegaApiClient.Tests/DownloadUploadAuthenticated.cs +++ b/MegaApiClient.Tests/DownloadUploadAuthenticated.cs @@ -22,20 +22,16 @@ public void DownloadNode_ToStream_Succeeds() { var node = this.GetNode(AuthenticatedTestContext.Inputs.SharedFile.Id); - using (Stream stream = this.context.Client.Download(node)) - { - using (Stream expectedStream = new FileStream(this.GetAbsoluteFilePath("Data/SampleFile.jpg"), FileMode.Open, FileAccess.Read)) - { - this.AreStreamsEquivalent(stream, expectedStream); - } - } + using Stream stream = Context.Client.Download(node); + using Stream expectedStream = new FileStream(GetAbsoluteFilePath("Data/SampleFile.jpg"), FileMode.Open, FileAccess.Read); + AreStreamsEquivalent(stream, expectedStream); } [Theory, MemberData(nameof(GetDownloadLinkInvalidParameter))] public void GetDownloadLink_InvalidNode_Throws(NodeType? nodeType, Type expectedExceptionType, string expectedMessage) { - INode node = nodeType == null ? null : Mock.Of(x => x.Type == nodeType.Value); - var exception = Assert.Throws(expectedExceptionType, () => this.context.Client.GetDownloadLink(node)); + var node = nodeType == null ? null : Mock.Of(x => x.Type == nodeType.Value); + var exception = Assert.Throws(expectedExceptionType, () => Context.Client.GetDownloadLink(node)); if (expectedExceptionType == typeof(ArgumentException)) { Assert.Equal(expectedMessage, exception.Message); @@ -46,31 +42,29 @@ public static IEnumerable GetDownloadLinkInvalidParameter { get { - yield return new object[] {null, typeof(ArgumentNullException), null}; - yield return new object[] {NodeType.Inbox, typeof(ArgumentException), "Invalid node"}; - yield return new object[] {NodeType.Root, typeof(ArgumentException), "Invalid node"}; - yield return new object[] {NodeType.Trash, typeof(ArgumentException), "Invalid node"}; - yield return new object[] {NodeType.File, typeof(ArgumentException), "node must implement INodeCrypto"}; + yield return new object[] { null, typeof(ArgumentNullException), null }; + yield return new object[] { NodeType.Inbox, typeof(ArgumentException), "Invalid node" }; + yield return new object[] { NodeType.Root, typeof(ArgumentException), "Invalid node" }; + yield return new object[] { NodeType.Trash, typeof(ArgumentException), "Invalid node" }; + yield return new object[] { NodeType.File, typeof(ArgumentException), "node must implement INodeCrypto" }; } } [Fact] public void UploadStream_DownloadLink_Succeeds() { - byte[] data = new byte[123]; - this.random.NextBytes(data); + var data = new byte[123]; + Random.NextBytes(data); - var parent = this.GetNode(NodeType.Root); + var parent = GetNode(NodeType.Root); - using (Stream stream = new MemoryStream(data)) - { - var node = this.context.Client.Upload(stream, "test", parent); + using Stream stream = new MemoryStream(data); + var node = Context.Client.Upload(stream, "test", parent); - var uri = this.context.Client.GetDownloadLink(node); + var uri = Context.Client.GetDownloadLink(node); - stream.Position = 0; - this.AreStreamsEquivalent(this.context.Client.Download(uri), stream); - } + stream.Position = 0; + AreStreamsEquivalent(Context.Client.Download(uri), stream); } [Theory] @@ -78,9 +72,9 @@ public void UploadStream_DownloadLink_Succeeds() [JsonInputsData("SharedFolder.Id", "FolderLink")] public void GetDownloadLink_ExistingLinks_Succeeds(string id, string expectedLink) { - var node = this.GetNode(id); + var node = GetNode(id); - var link = this.context.Client.GetDownloadLink(node); + var link = Context.Client.GetDownloadLink(node); Assert.Equal(expectedLink, link.AbsoluteUri); } @@ -89,20 +83,20 @@ public void GetDownloadLink_FolderNewLink_Succeeds() { // Create folders structure with subdirectories and file to ensure // SharedKey is distributed on all children - var rootNode = this.GetNode(NodeType.Root); - var folderNode = this.CreateFolderNode(rootNode, "Test"); - var subFolderNode = this.CreateFolderNode(folderNode, "AA"); - var subFolderNode2 = this.CreateFolderNode(folderNode, "BB"); - var subSubFolderNode = this.CreateFolderNode(subFolderNode, "subAA"); - var subSubFileNode = this.context.Client.UploadFile(this.GetAbsoluteFilePath("Data/SampleFile.jpg"), subSubFolderNode); + var rootNode = GetNode(NodeType.Root); + var folderNode = CreateFolderNode(rootNode, "Test"); + var subFolderNode = CreateFolderNode(folderNode, "AA"); + var subFolderNode2 = CreateFolderNode(folderNode, "BB"); + var subSubFolderNode = CreateFolderNode(subFolderNode, "subAA"); + var subSubFileNode = Context.Client.UploadFile(GetAbsoluteFilePath("Data/SampleFile.jpg"), subSubFolderNode); - this.context.Client.GetDownloadLink(folderNode); + Context.Client.GetDownloadLink(folderNode); - var nodes = this.context.Client.GetNodes().ToArray(); - foreach (var node in new[] {folderNode, subFolderNode, subFolderNode2, subSubFolderNode, subSubFileNode}) + var nodes = Context.Client.GetNodes().ToArray(); + foreach (var node in new[] { folderNode, subFolderNode, subFolderNode2, subSubFolderNode, subSubFileNode }) { var updatedNode = nodes.First(x => x.Id == node.Id); - Assert.NotNull(((INodeCrypto) updatedNode).SharedKey); + Assert.NotNull(((INodeCrypto)updatedNode).SharedKey); } } @@ -113,13 +107,9 @@ public void DownloadFileAttribute_ToStream_Succeeds(FileAttributeType fileAttrib { var node = this.GetNode(AuthenticatedTestContext.Inputs.SharedFile.Id); - using (Stream stream = this.context.Client.DownloadFileAttribute(node, fileAttributeType)) - { - using (Stream expectedStream = new FileStream(this.GetAbsoluteFilePath(expectedFileContent), FileMode.Open, FileAccess.Read)) - { - this.AreStreamsEquivalent(stream, expectedStream); - } - } + using Stream stream = Context.Client.DownloadFileAttribute(node, fileAttributeType); + using Stream expectedStream = new FileStream(GetAbsoluteFilePath(expectedFileContent), FileMode.Open, FileAccess.Read); + AreStreamsEquivalent(stream, expectedStream); } } } diff --git a/MegaApiClient.Tests/DownloadUploadAuthenticatedAsync.cs b/MegaApiClient.Tests/DownloadUploadAuthenticatedAsync.cs index 7cced72..e347be7 100644 --- a/MegaApiClient.Tests/DownloadUploadAuthenticatedAsync.cs +++ b/MegaApiClient.Tests/DownloadUploadAuthenticatedAsync.cs @@ -12,17 +12,17 @@ namespace CG.Web.MegaApiClient.Tests [Collection(nameof(AuthenticatedTestContext))] public class DownloadUploadAuthenticatedAsync : DownloadUploadAuthenticated { - private readonly long savedReportProgressChunkSize; + private readonly long _savedReportProgressChunkSize; public DownloadUploadAuthenticatedAsync(AuthenticatedAsyncTestContext context, ITestOutputHelper testOutputHelper) : base(context, testOutputHelper) { - this.savedReportProgressChunkSize = this.context.Options.ReportProgressChunkSize; + _savedReportProgressChunkSize = Context.Options.ReportProgressChunkSize; } public override void Dispose() { - this.context.Options.ReportProgressChunkSize = this.savedReportProgressChunkSize; + Context.Options.ReportProgressChunkSize = _savedReportProgressChunkSize; base.Dispose(); } @@ -34,21 +34,21 @@ public override void Dispose() public void DownloadFileAsync_FromNode_Succeeds(long? reportProgressChunkSize, long expectedResult) { // Arrange - this.context.Options.ReportProgressChunkSize = reportProgressChunkSize.GetValueOrDefault(this.context.Options.ReportProgressChunkSize); + Context.Options.ReportProgressChunkSize = reportProgressChunkSize.GetValueOrDefault(Context.Options.ReportProgressChunkSize); var node = this.GetNode(AuthenticatedTestContext.Inputs.SharedFile.Id); - EventTester eventTester = new EventTester(); + var eventTester = new EventTester(); IProgress progress = new SyncProgress(eventTester.OnRaised); - string outputFile = this.GetTempFileName(); + var outputFile = GetTempFileName(); // Act - Task task = this.context.Client.DownloadFileAsync(node, outputFile, progress); - bool result = task.Wait(this.Timeout); + Task task = Context.Client.DownloadFileAsync(node, outputFile, progress); + var result = task.Wait(Timeout); // Assert Assert.True(result); - this.AreFileEquivalent(this.GetAbsoluteFilePath("Data/SampleFile.jpg"), outputFile); + AreFileEquivalent(GetAbsoluteFilePath("Data/SampleFile.jpg"), outputFile); Assert.Equal(expectedResult, eventTester.Calls); } @@ -57,21 +57,21 @@ public void DownloadFileAsync_FromNode_Succeeds(long? reportProgressChunkSize, l public void DownloadFileAsync_FromLink_Succeeds() { // Arrange - const string expectedResultFile = "Data/SampleFile.jpg"; + const string ExpectedResultFile = "Data/SampleFile.jpg"; - EventTester eventTester = new EventTester(); + var eventTester = new EventTester(); IProgress progress = new SyncProgress(eventTester.OnRaised); - string outputFile = this.GetTempFileName(); + var outputFile = GetTempFileName(); // Act - Task task = this.context.Client.DownloadFileAsync(new Uri(AuthenticatedTestContext.Inputs.FileLink), outputFile, progress); - bool result = task.Wait(this.Timeout); + var task = Context.Client.DownloadFileAsync(new Uri(AuthenticatedTestContext.Inputs.FileLink), outputFile, progress); + var result = task.Wait(Timeout); // Assert Assert.True(result); Assert.Equal(8, eventTester.Calls); - this.AreFileEquivalent(this.GetAbsoluteFilePath(expectedResultFile), outputFile); + AreFileEquivalent(GetAbsoluteFilePath(ExpectedResultFile), outputFile); } [Theory] @@ -79,84 +79,76 @@ public void DownloadFileAsync_FromLink_Succeeds() public void UploadStreamAsync_DownloadLink_Succeeds(int dataSize, int expectedProgressionCalls) { //Arrange - byte[] data = new byte[dataSize]; - this.random.NextBytes(data); + var data = new byte[dataSize]; + Random.NextBytes(data); - INode parent = this.GetNode(NodeType.Root); + var parent = GetNode(NodeType.Root); - using (Stream stream = new MemoryStream(data)) + using Stream stream = new MemoryStream(data); + double previousProgression = 0; + var eventTester = new EventTester(); + IProgress progress = new SyncProgress(x => { - double previousProgression = 0; - EventTester eventTester = new EventTester(); - IProgress progress = new SyncProgress(x => + if (previousProgression > x) { - if (previousProgression > x) - { - // Reset eventTester (because upload was restarted) - eventTester.Reset(); - } - - previousProgression = x; - eventTester.OnRaised(x); - }); - - // Act - Task task = this.context.Client.UploadAsync(stream, "test", parent, progress); - bool result = task.Wait(this.Timeout); - - // Assert - Assert.True(result); - Assert.NotNull(task.Result); - Assert.Equal(expectedProgressionCalls, eventTester.Calls); - - Uri uri = this.context.Client.GetDownloadLink(task.Result); - stream.Position = 0; - this.AreStreamsEquivalent(this.context.Client.Download(uri), stream); - } + // Reset eventTester (because upload was restarted) + eventTester.Reset(); + } + + previousProgression = x; + eventTester.OnRaised(x); + }); + + // Act + var task = Context.Client.UploadAsync(stream, "test", parent, progress); + var result = task.Wait(Timeout); + + // Assert + Assert.True(result); + Assert.NotNull(task.Result); + Assert.Equal(expectedProgressionCalls, eventTester.Calls); + + var uri = Context.Client.GetDownloadLink(task.Result); + stream.Position = 0; + AreStreamsEquivalent(Context.Client.Download(uri), stream); } [RetryFact] public void AsyncMethods_WithoutProgression_Succeeds() { - var root = this.GetNode(NodeType.Root); + var root = GetNode(NodeType.Root); var node = this.GetNode(AuthenticatedTestContext.Inputs.SharedFile.Id); var uri = new Uri(AuthenticatedTestContext.Inputs.FileLink); - var sampleFilePath = this.GetAbsoluteFilePath("Data/SampleFile.jpg"); + var sampleFilePath = GetAbsoluteFilePath("Data/SampleFile.jpg"); var sampleFileStream = new FileStream(sampleFilePath, FileMode.Open, FileAccess.Read); - var task1 = this.context.Client.DownloadAsync(node); - var result1 = task1.Wait(this.Timeout); + var task1 = Context.Client.DownloadAsync(node); + var result1 = task1.Wait(Timeout); Assert.True(result1); - var task2 = this.context.Client.DownloadAsync(uri); - var result2 = task2.Wait(this.Timeout); + var task2 = Context.Client.DownloadAsync(uri); + var result2 = task2.Wait(Timeout); Assert.True(result2); - var outputFile3 = this.GetTempFileName(); - var task3 = this.context.Client.DownloadFileAsync(node, outputFile3); - var result3 = task3.Wait(this.Timeout); + var outputFile3 = GetTempFileName(); + var task3 = Context.Client.DownloadFileAsync(node, outputFile3); + var result3 = task3.Wait(Timeout); Assert.True(result3); - var outputFile4 = this.GetTempFileName(); - var task4 = this.context.Client.DownloadFileAsync(uri, outputFile4); - var result4 = task4.Wait(this.Timeout); + var outputFile4 = GetTempFileName(); + var task4 = Context.Client.DownloadFileAsync(uri, outputFile4); + var result4 = task4.Wait(Timeout); Assert.True(result4); - var task5 = this.context.Client.UploadAsync(sampleFileStream, Guid.NewGuid().ToString("N"), root); - var result5 = task5.Wait(this.Timeout); + var task5 = Context.Client.UploadAsync(sampleFileStream, Guid.NewGuid().ToString("N"), root); + var result5 = task5.Wait(Timeout); Assert.True(result5); - var task6 = this.context.Client.UploadFileAsync(sampleFilePath, root); - var result6 = task6.Wait(this.Timeout); + var task6 = Context.Client.UploadFileAsync(sampleFilePath, root); + var result6 = task6.Wait(Timeout); Assert.True(result6); } - private int Timeout - { - get - { - return (int)(this.context.WebTimeout * 0.9); - } - } + private int Timeout => (int)(Context.WebTimeout * 0.9); } } diff --git a/MegaApiClient.Tests/EventTester.cs b/MegaApiClient.Tests/EventTester.cs index a697f68..13ee827 100644 --- a/MegaApiClient.Tests/EventTester.cs +++ b/MegaApiClient.Tests/EventTester.cs @@ -2,42 +2,36 @@ namespace CG.Web.MegaApiClient.Tests { - using System.Threading; + using System.Threading; - public class EventTester + public class EventTester + { + private readonly Action _callback; + + private long _counter; + + public EventTester() { - private readonly Action callback; - - private long counter; - - public EventTester() - { - } - - public EventTester(Action callback) - { - this.callback = callback; - } - - public void OnRaised(T value) - { - Interlocked.Increment(ref this.counter); - this.callback?.Invoke(value); - } - - public void Reset() - { - Interlocked.Exchange(ref this.counter, 0); - } - - public bool Raised - { - get { return this.Calls > 0; } - } - - public long Calls - { - get { return Interlocked.Read(ref this.counter); } - } } + + public EventTester(Action callback) + { + _callback = callback; + } + + public void OnRaised(T value) + { + Interlocked.Increment(ref _counter); + _callback?.Invoke(value); + } + + public void Reset() + { + Interlocked.Exchange(ref _counter, 0); + } + + public bool Raised => Calls > 0; + + public long Calls => Interlocked.Read(ref _counter); + } } diff --git a/MegaApiClient.Tests/JsonInputsDataAttribute.cs b/MegaApiClient.Tests/JsonInputsDataAttribute.cs index 55f8b75..74d3630 100644 --- a/MegaApiClient.Tests/JsonInputsDataAttribute.cs +++ b/MegaApiClient.Tests/JsonInputsDataAttribute.cs @@ -10,14 +10,14 @@ public class JsonInputsDataAttribute : DataAttribute { - private static readonly JObject JsonData; + private static readonly JObject s_jsonData; private readonly string[] _jsonPropertyNames; private readonly object[] _constantArguments; static JsonInputsDataAttribute() { - JsonData = JObject.Parse(AuthenticatedTestContext.InputsJson); + s_jsonData = JObject.Parse(AuthenticatedTestContext.InputsJson); } public JsonInputsDataAttribute(string jsonPropertyName) @@ -43,9 +43,9 @@ public override IEnumerable GetData(MethodInfo testMethod) yield return data.ToArray(); } - private object GetValue(string jsonPropertyName) + private static object GetValue(string jsonPropertyName) { - JToken token = JsonData; + JToken token = s_jsonData; var parts = jsonPropertyName.Split('.'); foreach (var part in parts) { diff --git a/MegaApiClient.Tests/Login.cs b/MegaApiClient.Tests/Login.cs index 81b0544..63b4f66 100644 --- a/MegaApiClient.Tests/Login.cs +++ b/MegaApiClient.Tests/Login.cs @@ -22,9 +22,9 @@ public Login(NotLoggedTestContext context, ITestOutputHelper testOutputHelper) public override void Dispose() { - if (this.context.Client.IsLoggedIn) + if (Context.Client.IsLoggedIn) { - this.context.Client.Logout(); + Context.Client.Logout(); } base.Dispose(); @@ -51,14 +51,14 @@ public void ClientCtor_NullOptionsAndNullWebClient_Throws() [Theory, MemberData(nameof(InvalidCredentials))] public void Login_UnsupportedCredentials_Throws(string email, string password, string expectedMessage) { - Assert.Throws(expectedMessage, () => this.context.Client.Login(email, password)); + Assert.Throws(expectedMessage, () => Context.Client.Login(email, password)); } public static IEnumerable InvalidCredentials { get { - yield return new object[] { null, null, "email"}; + yield return new object[] { null, null, "email" }; yield return new object[] { null, "", "email" }; yield return new object[] { "", null, "email" }; yield return new object[] { "", "", "email" }; @@ -72,15 +72,15 @@ public static IEnumerable InvalidCredentials [InlineData("username@example.com", "password", ApiResultCode.RequestIncomplete)] public void Login_InvalidCredentials_Throws(string email, string password, ApiResultCode expectedErrorCode) { - var exception = Assert.Throws(() => this.context.Client.Login(email, password)); + var exception = Assert.Throws(() => Context.Client.Login(email, password)); Assert.Equal(expectedErrorCode, exception.ApiResultCode); } [Theory, MemberData(nameof(AllValidCredentials))] public void Login_ValidCredentials_Succeeds(string email, string password) { - Assert.NotNull(this.context.Client.Login(email, password)); - Assert.True(this.context.Client.IsLoggedIn); + Assert.NotNull(Context.Client.Login(email, password)); + Assert.True(Context.Client.IsLoggedIn); } public static IEnumerable GetCredentials(bool includeMasterKeyHash) @@ -88,7 +88,7 @@ public static IEnumerable GetCredentials(bool includeMasterKeyHash) Assert.NotEmpty(AuthenticatedTestContext.Inputs.UsernameAccount); Assert.NotEmpty(AuthenticatedTestContext.Password); - var credentials = new object[] {AuthenticatedTestContext.Inputs.UsernameAccount, AuthenticatedTestContext.Password, AuthenticatedTestContext.Inputs.MasterKeyHash }; + var credentials = new object[] { AuthenticatedTestContext.Inputs.UsernameAccount, AuthenticatedTestContext.Password, AuthenticatedTestContext.Inputs.MasterKeyHash }; yield return includeMasterKeyHash ? credentials : credentials.Take(2).ToArray(); } @@ -99,105 +99,103 @@ public static IEnumerable GetCredentials(bool includeMasterKeyHash) [Theory, MemberData(nameof(AllValidCredentials))] public void LoginTwice_ValidCredentials_Throws(string email, string password) { - this.context.Client.Login(email, password); + Context.Client.Login(email, password); - var exception = Assert.Throws(() => this.context.Client.Login(email, password)); + var exception = Assert.Throws(() => Context.Client.Login(email, password)); Assert.Equal("Already logged in", exception.Message); } [Fact] public void LoginAnonymous_Succeeds() { - this.context.Client.LoginAnonymous(); - Assert.True(this.context.Client.IsLoggedIn); + Context.Client.LoginAnonymous(); + Assert.True(Context.Client.IsLoggedIn); } [Fact] public void LoginAnonymousTwice_Throws() { - this.context.Client.LoginAnonymous(); + Context.Client.LoginAnonymous(); - var exception = Assert.Throws(() => this.context.Client.LoginAnonymous()); + var exception = Assert.Throws(() => Context.Client.LoginAnonymous()); Assert.Equal("Already logged in", exception.Message); } [Theory, MemberData(nameof(AllValidCredentials))] public void LogoutAfterLogin_Succeeds(string email, string password) { - this.context.Client.Login(email, password); - Assert.True(this.context.Client.IsLoggedIn); + Context.Client.Login(email, password); + Assert.True(Context.Client.IsLoggedIn); - this.context.Client.Logout(); - Assert.False(this.context.Client.IsLoggedIn); + Context.Client.Logout(); + Assert.False(Context.Client.IsLoggedIn); } [Theory, MemberData(nameof(AllValidCredentials))] public void LogoutTwiceAfterLogin_Throws(string email, string password) { - this.context.Client.Login(email, password); - this.context.Client.Logout(); + Context.Client.Login(email, password); + Context.Client.Logout(); - var exception = Assert.Throws(() => this.context.Client.Logout()); + var exception = Assert.Throws(() => Context.Client.Logout()); Assert.Equal("Not logged in", exception.Message); } [Fact] public void LogoutWithoutLogin_Throws() { - var exception = Assert.Throws(() => this.context.Client.Logout()); + var exception = Assert.Throws(() => Context.Client.Logout()); Assert.Equal("Not logged in", exception.Message); } [Theory, MemberData(nameof(AllValidCredentialsWithHash))] public void GetRecoveryKeyAfterLogin_Succeeds(string email, string password, string expectedRecoveryKeyHash) { - this.context.Client.Login(email, password); - Assert.True(this.context.Client.IsLoggedIn); + Context.Client.Login(email, password); + Assert.True(Context.Client.IsLoggedIn); - var recoveryKey = this.context.Client.GetRecoveryKey(); - using (var sha256 = SHA256.Create()) - { - var recoveryKeyHash = sha256.ComputeHash(Encoding.UTF8.GetBytes(recoveryKey)).ToBase64(); - Assert.Equal(expectedRecoveryKeyHash, recoveryKeyHash); - } + var recoveryKey = Context.Client.GetRecoveryKey(); + using var sha256 = SHA256.Create(); + var recoveryKeyHash = sha256.ComputeHash(Encoding.UTF8.GetBytes(recoveryKey)).ToBase64(); + Assert.Equal(expectedRecoveryKeyHash, recoveryKeyHash); } [Fact] public void GetRecoveryKeyWithoutLogin_Throws() { - var exception = Assert.Throws(() => this.context.Client.GetRecoveryKey()); + var exception = Assert.Throws(() => Context.Client.GetRecoveryKey()); Assert.Equal("Not logged in", exception.Message); } [Fact] public void GetRecoveryKeyWithAnonymousLogin_Throws() { - this.context.Client.LoginAnonymous(); - var exception = Assert.Throws(() => this.context.Client.GetRecoveryKey()); + Context.Client.LoginAnonymous(); + var exception = Assert.Throws(() => Context.Client.GetRecoveryKey()); Assert.Equal("Anonymous login is not supported", exception.Message); } [Fact] public void Login_NullAuthInfos_Throws() { - Assert.Throws("authInfos", () => this.context.Client.Login((MegaApiClient.AuthInfos)null)); + Assert.Throws("authInfos", () => Context.Client.Login((MegaApiClient.AuthInfos)null)); } [Theory, MemberData(nameof(AllValidCredentials))] public void Login_DeserializedAuthInfos_Succeeds(string email, string password) { - var authInfos = this.context.Client.GenerateAuthInfos(email, password); + var authInfos = Context.Client.GenerateAuthInfos(email, password); var serializedAuthInfos = JsonConvert.SerializeObject(authInfos, Formatting.None).Replace('\"', '\''); var deserializedAuthInfos = JsonConvert.DeserializeObject(serializedAuthInfos); - this.context.Client.Login(deserializedAuthInfos); - Assert.True(this.context.Client.IsLoggedIn); + Context.Client.Login(deserializedAuthInfos); + Assert.True(Context.Client.IsLoggedIn); } [Theory, MemberData(nameof(InvalidCredentials))] public void GenerateAuthInfos_InvalidCredentials_Throws(string email, string password, string expectedMessage) { - Assert.Throws(expectedMessage, () => this.context.Client.GenerateAuthInfos(email, password)); + Assert.Throws(expectedMessage, () => Context.Client.GenerateAuthInfos(email, password)); } [Theory] @@ -205,7 +203,7 @@ public void GenerateAuthInfos_InvalidCredentials_Throws(string email, string pas [InlineData("username@example.com", "password", "mfa", "{'Email':'username@example.com','Hash':'ObELy57HULI','PasswordAesKey':'ZAM5cl5uvROiXwBSEp98sQ==','MFAKey':'mfa'}")] public void GenerateAuthInfos_ValidCredentials_Succeeds(string email, string password, string mfa, string expectedResult) { - var authInfos = this.context.Client.GenerateAuthInfos(email, password, mfa); + var authInfos = Context.Client.GenerateAuthInfos(email, password, mfa); var result = JsonConvert.SerializeObject(authInfos, Formatting.None).Replace('\"', '\''); Assert.Equal(expectedResult, result); @@ -214,24 +212,24 @@ public void GenerateAuthInfos_ValidCredentials_Succeeds(string email, string pas [Theory, MemberData(nameof(MethodsWithMandatoryLogin))] public void Methods_LoginRequired_Throws(Action testMethod) { - var exception = Assert.Throws(() => testMethod(this.context.Client)); + var exception = Assert.Throws(() => testMethod(Context.Client)); Assert.Equal("Not logged in", exception.Message); } public static IEnumerable MethodsWithMandatoryLogin() { - Mock nodeDirectoryMock = new Mock(); + var nodeDirectoryMock = new Mock(); nodeDirectoryMock.SetupGet(x => x.Type).Returns(NodeType.Directory); nodeDirectoryMock.As(); - INode nodeDirectory = nodeDirectoryMock.Object; + var nodeDirectory = nodeDirectoryMock.Object; - Mock nodeFileMock = new Mock(); + var nodeFileMock = new Mock(); nodeFileMock.SetupGet(x => x.Type).Returns(NodeType.File); nodeFileMock.As(); - INode nodeFile = nodeFileMock.Object; + var nodeFile = nodeFileMock.Object; - Uri uri = new Uri("http://www.example.com"); - string tempFile = Path.GetTempFileName(); + var uri = new Uri("http://www.example.com"); + var tempFile = Path.GetTempFileName(); yield return new object[] { (Action)(x => x.Delete(nodeDirectory)) }; yield return new object[] { (Action)(x => x.Delete(nodeDirectory, false)) }; @@ -253,13 +251,13 @@ public static IEnumerable MethodsWithMandatoryLogin() [Theory, MemberData(nameof(GetCredentials), false)] public void GetAccountInformation_AuthenticatedUser_Succeeds(string email, string password) { - this.context.Client.Login(email, password); + Context.Client.Login(email, password); var authenticatedTestContext = new AuthenticatedTestContext(); var protectedNodes = authenticatedTestContext.ProtectedNodes; - this.SanitizeStorage(protectedNodes); + SanitizeStorage(protectedNodes); - IAccountInformation accountInformation = this.context.Client.GetAccountInformation(); + var accountInformation = Context.Client.GetAccountInformation(); Assert.NotNull(accountInformation); Assert.Equal(AuthenticatedTestContext.Inputs.TotalQuota, accountInformation.TotalQuota); @@ -269,12 +267,12 @@ public void GetAccountInformation_AuthenticatedUser_Succeeds(string email, strin [Theory, MemberData(nameof(GetCredentials), false)] public void GetSessionHistory_AuthenticatedUser_Succeeds(string email, string password) { - this.context.Client.Login(email, password); + Context.Client.Login(email, password); - IEnumerable sessionsHistory = this.context.Client.GetSessionsHistory(); + var sessionsHistory = Context.Client.GetSessionsHistory(); Assert.NotNull(sessionsHistory); - ISession first = sessionsHistory.First(); + var first = sessionsHistory.First(); Assert.NotNull(first); Assert.Equal(SessionStatus.Current | SessionStatus.Active, first.Status); Assert.Equal(DateTime.UtcNow, first.LoginTime.ToUniversalTime(), TimeSpan.FromSeconds(30)); @@ -284,9 +282,9 @@ public void GetSessionHistory_AuthenticatedUser_Succeeds(string email, string pa [Fact] public void GetAccountInformation_AnonymousUser_Succeeds() { - this.context.Client.LoginAnonymous(); + Context.Client.LoginAnonymous(); - IAccountInformation accountInformation = this.context.Client.GetAccountInformation(); + var accountInformation = Context.Client.GetAccountInformation(); Assert.NotNull(accountInformation); Assert.Equal(AuthenticatedTestContext.Inputs.TotalQuota, accountInformation.TotalQuota); diff --git a/MegaApiClient.Tests/MegaAesCtrStream_Tests.cs b/MegaApiClient.Tests/MegaAesCtrStream_Tests.cs index defd742..9a89123 100644 --- a/MegaApiClient.Tests/MegaAesCtrStream_Tests.cs +++ b/MegaApiClient.Tests/MegaAesCtrStream_Tests.cs @@ -4,33 +4,31 @@ using System.IO; using Xunit; - public class MegaAesCtrStream_Tests : IDisposable + public class MegaAesCtrStreamTests : IDisposable { - private readonly byte[] originalData; - private readonly Stream decryptedStream; - - public MegaAesCtrStream_Tests() + private readonly byte[] _originalData; + private readonly Stream _decryptedStream; + + public MegaAesCtrStreamTests() { - this.originalData = new byte[123]; - new Random().NextBytes(this.originalData); + _originalData = new byte[123]; + new Random().NextBytes(_originalData); - byte[] encryptedData = new byte[this.originalData.Length]; - using (var encryptedStream = new MegaAesCtrStreamCrypter(new MemoryStream(this.originalData))) - { - encryptedStream.Read(encryptedData, 0, encryptedData.Length); + var encryptedData = new byte[_originalData.Length]; + using var encryptedStream = new MegaAesCtrStreamCrypter(new MemoryStream(_originalData)); + encryptedStream.Read(encryptedData, 0, encryptedData.Length); - this.decryptedStream = new MegaAesCtrStreamDecrypter( - new MemoryStream(encryptedData), - encryptedData.Length, - encryptedStream.FileKey, - encryptedStream.Iv, - encryptedStream.MetaMac); - } + _decryptedStream = new MegaAesCtrStreamDecrypter( + new MemoryStream(encryptedData), + encryptedData.Length, + encryptedStream.FileKey, + encryptedStream.Iv, + encryptedStream.MetaMac); } public void Dispose() { - this.decryptedStream.Dispose(); + _decryptedStream.Dispose(); } [Theory] @@ -43,20 +41,20 @@ public void Dispose() public void Read_DifferentBufferSize_Succeeds(int bufferSize) { // Arrange - byte[] decryptedData = new byte[decryptedStream.Length]; + var decryptedData = new byte[_decryptedStream.Length]; var subBuffer = new byte[bufferSize]; - int read = 0; - int pos = 0; - + var pos = 0; + + int read; // Act - while ((read = decryptedStream.Read(subBuffer, 0, subBuffer.Length)) > 0) + while ((read = _decryptedStream.Read(subBuffer, 0, subBuffer.Length)) > 0) { Array.Copy(subBuffer, 0, decryptedData, pos, read); pos += read; } - + // Assert - Assert.Equal(this.originalData, decryptedData); + Assert.Equal(_originalData, decryptedData); } [Fact] @@ -64,34 +62,33 @@ public void Read_TooSmallBufferSize_Throws() { // Arrange var subBuffer = new byte[15]; - + // Act + Assert - var exception = Assert.Throws(() => decryptedStream.Read(subBuffer, 0, subBuffer.Length)); + var exception = Assert.Throws(() => _decryptedStream.Read(subBuffer, 0, subBuffer.Length)); Assert.Equal("Invalid 'count' argument. Minimal read operation must be greater than 16 bytes (except for last read operation).", exception.Message); } - + [Theory] [InlineData(120)] [InlineData(16)] public void Read_MixedBuffersSize_Succeeds(int firstBufferSize) { // Arrange - byte[] decryptedData = new byte[decryptedStream.Length]; - int pos = 0; - int read = 0; - + var decryptedData = new byte[_decryptedStream.Length]; + var pos = 0; + // Act var subBuffer = new byte[firstBufferSize]; - read = decryptedStream.Read(subBuffer, 0, subBuffer.Length); + var read = _decryptedStream.Read(subBuffer, 0, subBuffer.Length); Array.Copy(subBuffer, 0, decryptedData, pos, read); pos += read; - + subBuffer = new byte[decryptedData.Length - firstBufferSize + (decryptedData.Length - read)]; - read = decryptedStream.Read(subBuffer, 0, subBuffer.Length); + read = _decryptedStream.Read(subBuffer, 0, subBuffer.Length); Array.Copy(subBuffer, 0, decryptedData, pos, read); // Assert - Assert.Equal(this.originalData, decryptedData); + Assert.Equal(_originalData, decryptedData); } } } diff --git a/MegaApiClient.Tests/MegaApiClientAsyncWrapper.cs b/MegaApiClient.Tests/MegaApiClientAsyncWrapper.cs index 2189abb..47a2ee5 100644 --- a/MegaApiClient.Tests/MegaApiClientAsyncWrapper.cs +++ b/MegaApiClient.Tests/MegaApiClientAsyncWrapper.cs @@ -8,313 +8,310 @@ public class MegaApiClientAsyncWrapper : IMegaApiClient, IDisposable { - private readonly IMegaApiClient client; + private readonly IMegaApiClient _client; public MegaApiClientAsyncWrapper(IMegaApiClient client) { - this.client = client; - this.client.ApiRequestFailed += this.OnApiRequestFailed; + _client = client; + _client.ApiRequestFailed += OnApiRequestFailed; } public void Dispose() { - this.client.ApiRequestFailed -= this.OnApiRequestFailed; + _client.ApiRequestFailed -= OnApiRequestFailed; } public event EventHandler ApiRequestFailed; - public bool IsLoggedIn - { - get { return this.client.IsLoggedIn; } - } + public bool IsLoggedIn => _client.IsLoggedIn; public MegaApiClient.LogonSessionToken Login(string email, string password) { - return this.UnwrapException(() => this.client.LoginAsync(email, password).Result); + return UnwrapException(() => _client.LoginAsync(email, password).Result); } public MegaApiClient.LogonSessionToken Login(string email, string password, string mfaKey) { - return this.UnwrapException(() => this.client.LoginAsync(email, password, mfaKey).Result); + return UnwrapException(() => _client.LoginAsync(email, password, mfaKey).Result); } public MegaApiClient.LogonSessionToken Login(MegaApiClient.AuthInfos authInfos) { - return this.UnwrapException(() => this.client.LoginAsync(authInfos).Result); + return UnwrapException(() => _client.LoginAsync(authInfos).Result); } public void Login(MegaApiClient.LogonSessionToken logonSessionToken) { - this.UnwrapException(() => this.client.LoginAsync(logonSessionToken).Wait()); + UnwrapException(() => _client.LoginAsync(logonSessionToken).Wait()); } public void Login() { - this.UnwrapException(() => this.client.LoginAsync().Wait()); + UnwrapException(() => _client.LoginAsync().Wait()); } public void LoginAnonymous() { - this.UnwrapException(() => this.client.LoginAnonymousAsync().Wait()); + UnwrapException(() => _client.LoginAnonymousAsync().Wait()); } public void Logout() { - this.UnwrapException(() => this.client.LogoutAsync().Wait()); + UnwrapException(() => _client.LogoutAsync().Wait()); } public string GetRecoveryKey() { - return this.UnwrapException(() => this.client.GetRecoveryKeyAsync().Result); + return UnwrapException(() => _client.GetRecoveryKeyAsync().Result); } public IAccountInformation GetAccountInformation() { - return this.UnwrapException(() => this.client.GetAccountInformationAsync().Result); + return UnwrapException(() => _client.GetAccountInformationAsync().Result); } public IEnumerable GetSessionsHistory() { - return this.UnwrapException(() => this.client.GetSessionsHistoryAsync().Result); + return UnwrapException(() => _client.GetSessionsHistoryAsync().Result); } public IEnumerable GetNodes() { - return this.UnwrapException(() => this.client.GetNodesAsync().Result); + return UnwrapException(() => _client.GetNodesAsync().Result); } public IEnumerable GetNodes(INode parent) { - return this.UnwrapException(() => this.client.GetNodesAsync(parent).Result); + return UnwrapException(() => _client.GetNodesAsync(parent).Result); } public void Delete(INode node, bool moveToTrash) { - this.UnwrapException(() => this.client.DeleteAsync(node, moveToTrash).Wait()); + UnwrapException(() => _client.DeleteAsync(node, moveToTrash).Wait()); } public INode CreateFolder(string name, INode parent) { - return this.UnwrapException(() => this.client.CreateFolderAsync(name, parent).Result); + return UnwrapException(() => _client.CreateFolderAsync(name, parent).Result); } public Uri GetDownloadLink(INode node) { - return this.UnwrapException(() => this.client.GetDownloadLinkAsync(node).Result); + return UnwrapException(() => _client.GetDownloadLinkAsync(node).Result); } public void DownloadFile(INode node, string outputFile, CancellationToken? cancellationToken = null) { - Progress progress = new Progress(); - this.UnwrapException(() => this.client.DownloadFileAsync(node, outputFile, progress, cancellationToken).Wait()); + var progress = new Progress(); + UnwrapException(() => _client.DownloadFileAsync(node, outputFile, progress, cancellationToken).Wait()); } public void DownloadFile(Uri uri, string outputFile, CancellationToken? cancellationToken = null) { - Progress progress = new Progress(); - this.UnwrapException(() => this.client.DownloadFileAsync(uri, outputFile, progress, cancellationToken).Wait()); + var progress = new Progress(); + UnwrapException(() => _client.DownloadFileAsync(uri, outputFile, progress, cancellationToken).Wait()); } public Stream Download(INode node, CancellationToken? cancellationToken = null) { - Progress progress = new Progress(); - return this.UnwrapException(() => this.client.DownloadAsync(node, progress, cancellationToken).Result); + var progress = new Progress(); + return UnwrapException(() => _client.DownloadAsync(node, progress, cancellationToken).Result); } public Stream Download(Uri uri, CancellationToken? cancellationToken = null) { - Progress progress = new Progress(); - return this.UnwrapException(() => this.client.DownloadAsync(uri, progress, cancellationToken).Result); + var progress = new Progress(); + return UnwrapException(() => _client.DownloadAsync(uri, progress, cancellationToken).Result); } public INodeInfo GetNodeFromLink(Uri uri) { - return this.UnwrapException(() => this.client.GetNodeFromLinkAsync(uri).Result); + return UnwrapException(() => _client.GetNodeFromLinkAsync(uri).Result); } public IEnumerable GetNodesFromLink(Uri uri) { - return this.UnwrapException(() => this.client.GetNodesFromLinkAsync(uri).Result); + return UnwrapException(() => _client.GetNodesFromLinkAsync(uri).Result); } public INode UploadFile(string filename, INode parent, CancellationToken? cancellationToken = null) { - Progress progress = new Progress(); - return this.UnwrapException(() => this.client.UploadFileAsync(filename, parent, progress, cancellationToken).Result); + var progress = new Progress(); + return UnwrapException(() => _client.UploadFileAsync(filename, parent, progress, cancellationToken).Result); } public INode Upload(Stream stream, string name, INode parent, DateTime? modificationDate = null, CancellationToken? cancellationToken = null) { - Progress progress = new Progress(); - return this.UnwrapException(() => this.client.UploadAsync(stream, name, parent, progress, modificationDate).Result); + var progress = new Progress(); + return UnwrapException(() => _client.UploadAsync(stream, name, parent, progress, modificationDate).Result); } public INode Move(INode node, INode destinationParentNode) { - return this.UnwrapException(() => this.client.MoveAsync(node, destinationParentNode).Result); + return UnwrapException(() => _client.MoveAsync(node, destinationParentNode).Result); } public INode Rename(INode node, string newName) { - return this.UnwrapException(() => this.client.RenameAsync(node, newName).Result); + return UnwrapException(() => _client.RenameAsync(node, newName).Result); } public MegaApiClient.AuthInfos GenerateAuthInfos(string email, string password) { - return this.UnwrapException(() => this.client.GenerateAuthInfosAsync(email, password).Result); + return UnwrapException(() => _client.GenerateAuthInfosAsync(email, password).Result); } public MegaApiClient.AuthInfos GenerateAuthInfos(string email, string password, string mfaKey) { - return this.UnwrapException(() => this.client.GenerateAuthInfosAsync(email, password, mfaKey).Result); + return UnwrapException(() => _client.GenerateAuthInfosAsync(email, password, mfaKey).Result); } public Stream DownloadFileAttribute(INode node, FileAttributeType fileAttributeType, CancellationToken? cancellationToken = null) { - return this.UnwrapException(() => this.client.DownloadFileAttributeAsync(node, fileAttributeType, cancellationToken).Result); + return UnwrapException(() => _client.DownloadFileAttributeAsync(node, fileAttributeType, cancellationToken).Result); } public Task LoginAsync(string email, string password) { - return this.client.LoginAsync(email, password); + return _client.LoginAsync(email, password); } public Task LoginAsync(string email, string password, string mfaKey) { - return this.client.LoginAsync(email, password, mfaKey); + return _client.LoginAsync(email, password, mfaKey); } public Task LoginAsync(MegaApiClient.AuthInfos authInfos) { - return this.client.LoginAsync(authInfos); + return _client.LoginAsync(authInfos); } public Task LoginAsync(MegaApiClient.LogonSessionToken authInfos) { - return this.client.LoginAsync(authInfos); + return _client.LoginAsync(authInfos); } public Task LoginAsync() { - return this.client.LoginAsync(); + return _client.LoginAsync(); } public Task LoginAnonymousAsync() { - return this.client.LoginAnonymousAsync(); + return _client.LoginAnonymousAsync(); } public Task LogoutAsync() { - return this.client.LogoutAsync(); + return _client.LogoutAsync(); } public Task GetRecoveryKeyAsync() { - return this.client.GetRecoveryKeyAsync(); + return _client.GetRecoveryKeyAsync(); } public Task GetAccountInformationAsync() { - return this.client.GetAccountInformationAsync(); + return _client.GetAccountInformationAsync(); } public Task> GetSessionsHistoryAsync() { - return this.client.GetSessionsHistoryAsync(); + return _client.GetSessionsHistoryAsync(); } public Task> GetNodesAsync() { - return this.client.GetNodesAsync(); + return _client.GetNodesAsync(); } public Task> GetNodesAsync(INode parent) { - return this.client.GetNodesAsync(parent); + return _client.GetNodesAsync(parent); } public Task CreateFolderAsync(string name, INode parent) { - return this.client.CreateFolderAsync(name, parent); + return _client.CreateFolderAsync(name, parent); } public Task DeleteAsync(INode node, bool moveToTrash = true) { - return this.client.DeleteAsync(node, moveToTrash); + return _client.DeleteAsync(node, moveToTrash); } public Task MoveAsync(INode sourceNode, INode destinationParentNode) { - return this.client.MoveAsync(sourceNode, destinationParentNode); + return _client.MoveAsync(sourceNode, destinationParentNode); } public Task RenameAsync(INode sourceNode, string newName) { - return this.client.RenameAsync(sourceNode, newName); + return _client.RenameAsync(sourceNode, newName); } public Task GetDownloadLinkAsync(INode node) { - return this.client.GetDownloadLinkAsync(node); + return _client.GetDownloadLinkAsync(node); } public Task DownloadAsync(INode node, IProgress progress = null, CancellationToken? cancellationToken = null) { - return this.client.DownloadAsync(node, progress, cancellationToken); + return _client.DownloadAsync(node, progress, cancellationToken); } public Task DownloadAsync(Uri uri, IProgress progress = null, CancellationToken? cancellationToken = null) { - return this.client.DownloadAsync(uri, progress, cancellationToken); + return _client.DownloadAsync(uri, progress, cancellationToken); } public Task DownloadFileAsync(INode node, string outputFile, IProgress progress = null, CancellationToken? cancellationToken = null) { - return this.client.DownloadFileAsync(node, outputFile, progress, cancellationToken); + return _client.DownloadFileAsync(node, outputFile, progress, cancellationToken); } public Task DownloadFileAsync(Uri uri, string outputFile, IProgress progress = null, CancellationToken? cancellationToken = null) { - return this.client.DownloadFileAsync(uri, outputFile, progress, cancellationToken); + return _client.DownloadFileAsync(uri, outputFile, progress, cancellationToken); } public Task UploadFileAsync(string filename, INode parent, IProgress progress = null, CancellationToken? cancellationToken = null) { - return this.client.UploadFileAsync(filename, parent, progress, cancellationToken); + return _client.UploadFileAsync(filename, parent, progress, cancellationToken); } public Task UploadAsync(Stream stream, string name, INode parent, IProgress progress = null, DateTime? modificationDate = null, CancellationToken? cancellationToken = null) { - return this.client.UploadAsync(stream, name, parent, progress, modificationDate, cancellationToken); + return _client.UploadAsync(stream, name, parent, progress, modificationDate, cancellationToken); } public Task GetNodeFromLinkAsync(Uri uri) { - return this.client.GetNodeFromLinkAsync(uri); + return _client.GetNodeFromLinkAsync(uri); } public Task> GetNodesFromLinkAsync(Uri uri) { - return this.client.GetNodesFromLinkAsync(uri); + return _client.GetNodesFromLinkAsync(uri); } public Task GenerateAuthInfosAsync(string email, string password) { - return this.client.GenerateAuthInfosAsync(email, password); + return _client.GenerateAuthInfosAsync(email, password); } public Task GenerateAuthInfosAsync(string email, string password, string mfaKey) { - return this.client.GenerateAuthInfosAsync(email, password, mfaKey); + return _client.GenerateAuthInfosAsync(email, password, mfaKey); } public Task DownloadFileAttributeAsync(INode node, FileAttributeType fileAttributeType, CancellationToken? cancellationToken = null) { - return this.client.DownloadFileAttributeAsync(node, fileAttributeType, cancellationToken); + return _client.DownloadFileAttributeAsync(node, fileAttributeType, cancellationToken); } - private T UnwrapException(Func action) + private static T UnwrapException(Func action) { try { @@ -326,9 +323,9 @@ private T UnwrapException(Func action) } } - private void UnwrapException(Action action) + private static void UnwrapException(Action action) { - this.UnwrapException( + UnwrapException( () => { action(); @@ -338,7 +335,7 @@ private void UnwrapException(Action action) private void OnApiRequestFailed(object sender, ApiRequestFailedEventArgs e) { - this.ApiRequestFailed?.Invoke(sender, e); + ApiRequestFailed?.Invoke(sender, e); } } } diff --git a/MegaApiClient.Tests/NodeOperations.cs b/MegaApiClient.Tests/NodeOperations.cs index 388d07e..9de4643 100644 --- a/MegaApiClient.Tests/NodeOperations.cs +++ b/MegaApiClient.Tests/NodeOperations.cs @@ -25,10 +25,10 @@ protected NodeOperations(ITestContext context, ITestOutputHelper testOutputHelpe public void Validate_DefaultNodes_Succeeds(NodeType nodeType) { // Arrange + Act - var nodes = this.context.Client.GetNodes().ToArray(); + var nodes = Context.Client.GetNodes().ToArray(); // Assert - Assert.Equal(this.context.ProtectedNodes.Count(), nodes.Length); + Assert.Equal(Context.ProtectedNodes.Count(), nodes.Length); var node = Assert.Single(nodes, x => x.Type == nodeType); Assert.Empty(node.ParentId); Assert.Null(node.Name); @@ -42,10 +42,10 @@ public void Validate_DefaultNodes_Succeeds(NodeType nodeType) public void CreateFolder_Succeeds(NodeType parentNodeType) { // Arrange - var parentNode = this.GetNode(parentNodeType); + var parentNode = GetNode(parentNodeType); // Act - var createdNode = this.CreateFolderNode(parentNode); + var createdNode = CreateFolderNode(parentNode); // Assert Assert.NotNull(createdNode); @@ -54,14 +54,14 @@ public void CreateFolder_Succeeds(NodeType parentNodeType) Assert.Equal(0, createdNode.Size); Assert.NotNull(createdNode.ParentId); Assert.Equal(parentNode.Id, createdNode.ParentId); - Assert.Single(this.context.Client.GetNodes(), x => x.Name == DefaultNodeName); + Assert.Single(Context.Client.GetNodes(), x => x.Name == DefaultNodeName); } [Theory, MemberData(nameof(InvalidCreateFolderParameters))] public void CreateFolder_InvalidParameters_Throws(string name, NodeType? parentNodeType, Type expectedExceptionType, string expectedMessage) { var parentNode = parentNodeType == null ? null : Mock.Of(x => x.Type == parentNodeType.Value); - var exception = Assert.Throws(expectedExceptionType, () => this.context.Client.CreateFolder(name, parentNode)); + var exception = Assert.Throws(expectedExceptionType, () => Context.Client.CreateFolder(name, parentNode)); Assert.Equal(expectedMessage, exception.GetType() == typeof(ArgumentNullException) ? ((ArgumentNullException)exception).ParamName : exception.Message); } @@ -83,11 +83,11 @@ public static IEnumerable InvalidCreateFolderParameters public void CreateFolder_SameName_Succeeds(string nodeName1, string nodeName2) { // Arrange - var parentNode = this.GetNode(NodeType.Root); + var parentNode = GetNode(NodeType.Root); // Act - var node1 = this.CreateFolderNode(parentNode, nodeName1); - var node2 = this.CreateFolderNode(parentNode, nodeName2); + var node1 = CreateFolderNode(parentNode, nodeName1); + var node2 = CreateFolderNode(parentNode, nodeName2); // Assert Assert.NotEqual(node1, node2); @@ -98,20 +98,20 @@ public void CreateFolder_SameName_Succeeds(string nodeName1, string nodeName2) public void GetNodes_Succeeds() { // Arrange - var parentNode = this.GetNode(NodeType.Root); + var parentNode = GetNode(NodeType.Root); // Act - var createdNode = this.CreateFolderNode(parentNode); + var createdNode = CreateFolderNode(parentNode); // Assert - Assert.Equal(this.context.ProtectedNodes.Count() + 1, this.context.Client.GetNodes().Count()); - Assert.Single(this.context.Client.GetNodes(parentNode), x => x.Equals(createdNode)); + Assert.Equal(Context.ProtectedNodes.Count() + 1, Context.Client.GetNodes().Count()); + Assert.Single(Context.Client.GetNodes(parentNode), x => x.Equals(createdNode)); } [Fact] public void GetNodes_NullParentNode_Throws() { - Assert.Throws("parent", () => this.context.Client.GetNodes(null)); + Assert.Throws("parent", () => Context.Client.GetNodes(null)); } [Theory] @@ -121,44 +121,44 @@ public void GetNodes_NullParentNode_Throws() public void Delete_Succeeds(bool? moveToTrash) { // Arrange - var parentNode = this.GetNode(NodeType.Root); - var trashNode = this.GetNode(NodeType.Trash); - var createdNode = this.CreateFolderNode(parentNode); + var parentNode = GetNode(NodeType.Root); + var trashNode = GetNode(NodeType.Trash); + var createdNode = CreateFolderNode(parentNode); // Assert - var nodes = this.context.Client.GetNodes(parentNode).ToArray(); - Assert.Equal(this.context.PermanentRootNodes.Count() + 1, nodes.Length); + var nodes = Context.Client.GetNodes(parentNode).ToArray(); + Assert.Equal(Context.PermanentRootNodes.Count() + 1, nodes.Length); Assert.Single(nodes, x => x.Equals(createdNode)); - Assert.Empty(this.context.Client.GetNodes(trashNode)); + Assert.Empty(Context.Client.GetNodes(trashNode)); // Act if (moveToTrash == null) { - this.context.Client.Delete(createdNode); + Context.Client.Delete(createdNode); } else { - this.context.Client.Delete(createdNode, moveToTrash.Value); + Context.Client.Delete(createdNode, moveToTrash.Value); } // Assert - Assert.Equal(this.context.PermanentRootNodes.Count(), this.context.Client.GetNodes(parentNode).Count()); + Assert.Equal(Context.PermanentRootNodes.Count(), Context.Client.GetNodes(parentNode).Count()); if (moveToTrash.GetValueOrDefault(true)) { - Assert.Single(this.context.Client.GetNodes(trashNode), x => x.Equals(createdNode)); + Assert.Single(Context.Client.GetNodes(trashNode), x => x.Equals(createdNode)); } else { - Assert.Empty(this.context.Client.GetNodes(trashNode)); + Assert.Empty(Context.Client.GetNodes(trashNode)); } } [Fact] public void Delete_NullNode_Throws() { - Assert.Throws(() => this.context.Client.Delete(null)); + Assert.Throws(() => Context.Client.Delete(null)); } [Theory] @@ -167,9 +167,9 @@ public void Delete_NullNode_Throws() [InlineData(NodeType.Trash)] public void Delete_InvalidNode_Throws(NodeType nodeType) { - var node = this.GetNode(nodeType); + var node = GetNode(nodeType); - var exception = Assert.Throws(() => this.context.Client.Delete(node)); + var exception = Assert.Throws(() => Context.Client.Delete(node)); Assert.Equal("Invalid node type", exception.Message); } @@ -179,8 +179,8 @@ public void Delete_InvalidNode_Throws(NodeType nodeType) [InlineData(NodeType.Inbox)] public void SameNode_Equality_Succeeds(NodeType nodeType) { - var node1 = this.GetNode(nodeType); - var node2 = this.GetNode(nodeType); + var node1 = GetNode(nodeType); + var node2 = GetNode(nodeType); Assert.Equal(node1, node2); Assert.Equal(node1.GetHashCode(), node2.GetHashCode()); @@ -192,7 +192,7 @@ public void Move_InvalidParameters_Throws(NodeType? nodeType, NodeType? destinat { var node = nodeType == null ? null : Mock.Of(x => x.Type == nodeType.Value); var destinationParentNode = destinationParentNodeType == null ? null : Mock.Of(x => x.Type == destinationParentNodeType.Value); - var exception = Assert.Throws(expectedExceptionType, () => this.context.Client.Move(node, destinationParentNode)); + var exception = Assert.Throws(expectedExceptionType, () => Context.Client.Move(node, destinationParentNode)); Assert.Equal(expectedMessage, exception.GetType() == typeof(ArgumentNullException) ? ((ArgumentNullException)exception).ParamName : exception.Message); } @@ -216,20 +216,20 @@ public static IEnumerable InvalidMoveParameters public void Move_Succeeds(NodeType destinationParentNodeType) { // Arrange - var parentNode = this.GetNode(NodeType.Root); - var destinationParentNode = this.GetNode(destinationParentNodeType); - var node = this.CreateFolderNode(parentNode); + var parentNode = GetNode(NodeType.Root); + var destinationParentNode = GetNode(destinationParentNodeType); + var node = CreateFolderNode(parentNode); // Assert - Assert.Single(this.context.Client.GetNodes(parentNode), x => x.Equals(node)); - Assert.Empty(this.context.Client.GetNodes(destinationParentNode)); + Assert.Single(Context.Client.GetNodes(parentNode), x => x.Equals(node)); + Assert.Empty(Context.Client.GetNodes(destinationParentNode)); // Act - var movedNode = this.context.Client.Move(node, destinationParentNode); + var movedNode = Context.Client.Move(node, destinationParentNode); // Assert - Assert.Empty(this.context.Client.GetNodes(parentNode).Where(x => x.Equals(node))); - Assert.Single(this.context.Client.GetNodes(destinationParentNode), x => x.Equals(movedNode)); + Assert.Empty(Context.Client.GetNodes(parentNode).Where(x => x.Equals(node))); + Assert.Single(Context.Client.GetNodes(destinationParentNode), x => x.Equals(movedNode)); } [Theory] @@ -238,23 +238,24 @@ public void Move_Succeeds(NodeType destinationParentNodeType) public void Rename_Succeeds(NodeType nodeType) { // Arrange - var parentNode = this.GetNode(NodeType.Root); + var parentNode = GetNode(NodeType.Root); INode createdNode; - DateTime modificationDate = new DateTime(2000, 01, 02, 03, 04, 05); + var modificationDate = new DateTime(2000, 01, 02, 03, 04, 05); switch (nodeType) { case NodeType.Directory: - createdNode = this.context.Client.CreateFolder("Data", parentNode); + createdNode = Context.Client.CreateFolder("Data", parentNode); break; case NodeType.File: - byte[] data = new byte[123]; + var data = new byte[123]; new Random().NextBytes(data); - using (MemoryStream stream = new MemoryStream(data)) + using (var stream = new MemoryStream(data)) { - createdNode = this.context.Client.Upload(stream, "Data", parentNode, modificationDate); + createdNode = Context.Client.Upload(stream, "Data", parentNode, modificationDate); } + break; default: @@ -262,8 +263,8 @@ public void Rename_Succeeds(NodeType nodeType) } // Assert - var nodes = this.context.Client.GetNodes(parentNode).ToArray(); - Assert.Equal(this.context.PermanentRootNodes.Count() + 1, nodes.Length); + var nodes = Context.Client.GetNodes(parentNode).ToArray(); + Assert.Equal(Context.PermanentRootNodes.Count() + 1, nodes.Length); Assert.Single(nodes, x => x.Equals(createdNode)); if (nodeType == NodeType.File) { @@ -271,12 +272,12 @@ public void Rename_Succeeds(NodeType nodeType) } // Act - var renamedNode = this.context.Client.Rename(createdNode, "Data2"); + var renamedNode = Context.Client.Rename(createdNode, "Data2"); // Assert Assert.Equal("Data2", renamedNode.Name); - nodes = this.context.Client.GetNodes(parentNode).ToArray(); - Assert.Equal(this.context.PermanentRootNodes.Count() + 1, nodes.Length); + nodes = Context.Client.GetNodes(parentNode).ToArray(); + Assert.Equal(Context.PermanentRootNodes.Count() + 1, nodes.Length); Assert.Single(nodes, x => x.Equals(createdNode)); if (nodeType == NodeType.File) { @@ -288,7 +289,7 @@ public void Rename_Succeeds(NodeType nodeType) [JsonInputsDataAttribute("FileLink")] public void GetNodeFromLink_Browse_Succeeds(string fileLink) { - var node = this.context.Client.GetNodeFromLink(new Uri(fileLink)); + var node = Context.Client.GetNodeFromLink(new Uri(fileLink)); Assert.NotNull(node); Assert.Equal("SharedFile.jpg", node.Name); @@ -302,7 +303,7 @@ public void GetNodeFromLink_Browse_Succeeds(string fileLink) [JsonInputsDataAttribute(new object[] { "/folder/SELECTED_FOLDER_NODE_ID" }, new string[] { "FolderLink" })] public void GetNodesFromLink_Succeeds(string suffix, string folderLink) { - var nodes = this.context.Client.GetNodesFromLink(new Uri(folderLink + suffix)); + var nodes = Context.Client.GetNodesFromLink(new Uri(folderLink + suffix)); Assert.Equal(4, nodes.Count()); INode node; diff --git a/MegaApiClient.Tests/NodeOperationsAuthenticated.cs b/MegaApiClient.Tests/NodeOperationsAuthenticated.cs index a62d230..575a949 100644 --- a/MegaApiClient.Tests/NodeOperationsAuthenticated.cs +++ b/MegaApiClient.Tests/NodeOperationsAuthenticated.cs @@ -37,10 +37,10 @@ public void Validate_PermanentNodes_Succeeds( DateTime? expectedModificationDate ) { - var node = this.GetNode(id); + var node = GetNode(id); Assert.Equal(expectedNodeType, node.Type); - Assert.Equal(expectedParent,node.ParentId); + Assert.Equal(expectedParent, node.ParentId); Assert.Equal(expectedName, node.Name); Assert.Equal(expectedSize, node.Size); Assert.Equal(expectedCreationDate, node.CreationDate); @@ -53,23 +53,23 @@ public void Validate_PermanentNodes_Succeeds( [InlineData(NodeType.Trash, 0, 0)] public void GetFoldersize_FromNodeType_Succeeds(NodeType nodeType, long sharedFileSize, long sharedFileUpSideDownSize) { - var node = this.GetNode(nodeType); + var node = GetNode(nodeType); var expectedSize = sharedFileSize + sharedFileUpSideDownSize; - Assert.Equal(expectedSize, node.GetFolderSize(this.context.Client)); - Assert.Equal(expectedSize, node.GetFolderSizeAsync(this.context.Client).Result); - Assert.Equal(expectedSize, node.GetFolderSize(this.context.Client.GetNodes())); - Assert.Equal(expectedSize, node.GetFolderSizeAsync(this.context.Client.GetNodes()).Result); + Assert.Equal(expectedSize, node.GetFolderSize(Context.Client)); + Assert.Equal(expectedSize, node.GetFolderSizeAsync(Context.Client).Result); + Assert.Equal(expectedSize, node.GetFolderSize(Context.Client.GetNodes())); + Assert.Equal(expectedSize, node.GetFolderSizeAsync(Context.Client.GetNodes()).Result); } [Fact] public void GetFoldersize_FromFile_Throws() { - var node = this.context.Client.GetNodes().First(x => x.Type == NodeType.File); - Assert.Throws(() => node.GetFolderSize(this.context.Client)); - var aggregateException = Assert.Throws(() => node.GetFolderSizeAsync(this.context.Client).Result); + var node = Context.Client.GetNodes().First(x => x.Type == NodeType.File); + Assert.Throws(() => node.GetFolderSize(Context.Client)); + var aggregateException = Assert.Throws(() => node.GetFolderSizeAsync(Context.Client).Result); Assert.IsType(aggregateException.GetBaseException()); - Assert.Throws(() => node.GetFolderSize(this.context.Client.GetNodes())); - aggregateException = Assert.Throws(() => node.GetFolderSizeAsync(this.context.Client.GetNodes()).Result); + Assert.Throws(() => node.GetFolderSize(Context.Client.GetNodes())); + aggregateException = Assert.Throws(() => node.GetFolderSizeAsync(Context.Client.GetNodes()).Result); Assert.IsType(aggregateException.GetBaseException()); } @@ -78,12 +78,12 @@ public void GetFoldersize_FromFile_Throws() [JsonInputsData("SharedSubFolder.Id", null, "SharedFileUpSideDown.Size")] public void GetFoldersize_FromDirectory_Succeeds(string nodeId, long size1, long size2) { - var node = this.GetNode(nodeId); + var node = GetNode(nodeId); var expectedSize = size1 + size2; - Assert.Equal(expectedSize, node.GetFolderSize(this.context.Client)); - Assert.Equal(expectedSize, node.GetFolderSizeAsync(this.context.Client).Result); - Assert.Equal(expectedSize, node.GetFolderSize(this.context.Client.GetNodes())); - Assert.Equal(expectedSize, node.GetFolderSizeAsync(this.context.Client.GetNodes()).Result); + Assert.Equal(expectedSize, node.GetFolderSize(Context.Client)); + Assert.Equal(expectedSize, node.GetFolderSizeAsync(Context.Client).Result); + Assert.Equal(expectedSize, node.GetFolderSize(Context.Client.GetNodes())); + Assert.Equal(expectedSize, node.GetFolderSizeAsync(Context.Client.GetNodes()).Result); } [Fact] diff --git a/MegaApiClient.Tests/SyncProgress.cs b/MegaApiClient.Tests/SyncProgress.cs index f59bcf1..29d6f9c 100644 --- a/MegaApiClient.Tests/SyncProgress.cs +++ b/MegaApiClient.Tests/SyncProgress.cs @@ -4,16 +4,16 @@ namespace CG.Web.MegaApiClient.Tests { internal class SyncProgress : IProgress { - private readonly Action callback; + private readonly Action _callback; public SyncProgress(Action callback) { - this.callback = callback; + _callback = callback; } public void Report(T value) { - this.callback(value); + _callback(value); } } } diff --git a/MegaApiClient.Tests/TestWebClient.cs b/MegaApiClient.Tests/TestWebClient.cs index e0cb8cf..fb63dcc 100644 --- a/MegaApiClient.Tests/TestWebClient.cs +++ b/MegaApiClient.Tests/TestWebClient.cs @@ -13,16 +13,16 @@ internal class TestWebClient : IWebClient private readonly Policy _policy; private readonly Action _logMessageAction; - public TestWebClient(IWebClient webClient, int maxRetry, Action _logMessageAction) + public TestWebClient(IWebClient webClient, int maxRetry, Action logMessageAction) { - this._webClient = webClient; - this._policy = Policy + _webClient = webClient; + _policy = Policy .Handle() .Or() .Or() .Or() - .WaitAndRetry(maxRetry, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), this.OnRetry); - this._logMessageAction = _logMessageAction; + .WaitAndRetry(maxRetry, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), OnRetry); + _logMessageAction = logMessageAction; } public enum CallType @@ -37,16 +37,16 @@ public enum CallType public int BufferSize { - get { return this._webClient.BufferSize; } - set { this._webClient.BufferSize = value; } + get => _webClient.BufferSize; + set => _webClient.BufferSize = value; } public string PostRequestJson(Uri url, string jsonData) { - return this._policy.Execute(() => + return _policy.Execute(() => { - var result = this._webClient.PostRequestJson(url, jsonData); - this.OnCalled?.Invoke(CallType.PostRequestJson, url); + var result = _webClient.PostRequestJson(url, jsonData); + OnCalled?.Invoke(CallType.PostRequestJson, url); return result; }); @@ -54,14 +54,14 @@ public string PostRequestJson(Uri url, string jsonData) public string PostRequestRaw(Uri url, Stream dataStream) { - return this._policy.Execute(() => + return _policy.Execute(() => { // Create a copy of the stream because webClient can dispose it // It's useful in case of retries - Stream dataStreamCopy = this.CloneStream(dataStream); + var dataStreamCopy = CloneStream(dataStream); - var result = this._webClient.PostRequestRaw(url, dataStreamCopy); - this.OnCalled?.Invoke(CallType.PostRequestRaw, url); + var result = _webClient.PostRequestRaw(url, dataStreamCopy); + OnCalled?.Invoke(CallType.PostRequestRaw, url); return result; }); @@ -69,14 +69,14 @@ public string PostRequestRaw(Uri url, Stream dataStream) public Stream PostRequestRawAsStream(Uri url, Stream dataStream) { - return this._policy.Execute(() => + return _policy.Execute(() => { // Create a copy of the stream because webClient can dispose it // It's useful in case of retries - Stream dataStreamCopy = this.CloneStream(dataStream); + var dataStreamCopy = CloneStream(dataStream); - var result = this._webClient.PostRequestRawAsStream(url, dataStreamCopy); - this.OnCalled?.Invoke(CallType.PostRequestRawAsStream, url); + var result = _webClient.PostRequestRawAsStream(url, dataStreamCopy); + OnCalled?.Invoke(CallType.PostRequestRawAsStream, url); return result; }); @@ -84,19 +84,19 @@ public Stream PostRequestRawAsStream(Uri url, Stream dataStream) public Stream GetRequestRaw(Uri url) { - return this._policy.Execute(() => + return _policy.Execute(() => { - var result = this._webClient.GetRequestRaw(url); - this.OnCalled?.Invoke(CallType.GetRequestRaw, url); + var result = _webClient.GetRequestRaw(url); + OnCalled?.Invoke(CallType.GetRequestRaw, url); return result; }); } - private Stream CloneStream(Stream dataStream) + private static Stream CloneStream(Stream dataStream) { - byte[] buffer = new byte[dataStream.Length]; - MemoryStream cloneStream = new MemoryStream(buffer); + var buffer = new byte[dataStream.Length]; + var cloneStream = new MemoryStream(buffer); dataStream.CopyTo(cloneStream); dataStream.Position = 0; @@ -109,12 +109,12 @@ private void OnRetry(Exception ex, TimeSpan ts) { if (ex is AggregateException aEx) { - this._logMessageAction("AggregateException..."); + _logMessageAction("AggregateException..."); ex = aEx.InnerException; if (ex is TaskCanceledException tEx) { - this._logMessageAction("TaskCanceledException..."); + _logMessageAction("TaskCanceledException..."); if (tEx.InnerException != null) { ex = tEx.InnerException; @@ -122,7 +122,7 @@ private void OnRetry(Exception ex, TimeSpan ts) } } - this._logMessageAction($"Request failed: {ts.TotalSeconds}, {ex}, {ex.Message}"); + _logMessageAction($"Request failed: {ts.TotalSeconds}, {ex}, {ex.Message}"); } } } diff --git a/MegaApiClient.Tests/TestsBase.cs b/MegaApiClient.Tests/TestsBase.cs index 760ab10..02c5b33 100644 --- a/MegaApiClient.Tests/TestsBase.cs +++ b/MegaApiClient.Tests/TestsBase.cs @@ -9,27 +9,27 @@ namespace CG.Web.MegaApiClient.Tests { public abstract class TestsBase : IDisposable { - protected readonly ITestContext context; + protected readonly ITestContext Context; protected TestsBase(ITestContext context, ITestOutputHelper testOutputHelper) { - this.context = context; - this.context.SetLogger(testOutputHelper); + Context = context; + Context.SetLogger(testOutputHelper); - if (this.context.Client.IsLoggedIn) + if (Context.Client.IsLoggedIn) { - this.SanitizeStorage(); + SanitizeStorage(); } } public virtual void Dispose() { - this.context.ClearLogger(); + Context.ClearLogger(); } protected INode GetNode(NodeType nodeType) { - var node = this.context.Client.GetNodes().SingleOrDefault(x => x.Type == nodeType); + var node = Context.Client.GetNodes().SingleOrDefault(x => x.Type == nodeType); Assert.NotNull(node); return node; @@ -37,7 +37,7 @@ protected INode GetNode(NodeType nodeType) protected INode GetNode(string nodeId) { - var node = this.context.Client.GetNodes().Single(x => x.Id == nodeId); + var node = Context.Client.GetNodes().Single(x => x.Id == nodeId); Assert.NotNull(node); return node; @@ -45,19 +45,19 @@ protected INode GetNode(string nodeId) protected INode CreateFolderNode(INode parentNode, string name = "NodeName") { - return this.context.Client.CreateFolder(name, parentNode); + return Context.Client.CreateFolder(name, parentNode); } protected void SanitizeStorage(IEnumerable protectedNodes = null) { - IEnumerable nodes = this.context.Client.GetNodes().ToArray(); + IEnumerable nodes = Context.Client.GetNodes().ToArray(); - IEnumerable nodesToRemove = nodes.Where(x => this.IsProtectedNode(protectedNodes ?? this.context.ProtectedNodes, x) == false); - foreach (INode node in nodesToRemove) + var nodesToRemove = nodes.Where(x => IsProtectedNode(protectedNodes ?? Context.ProtectedNodes, x) == false); + foreach (var node in nodesToRemove) { try { - this.context.Client.Delete(node, false); + Context.Client.Delete(node, false); } catch (ApiException ex) { @@ -69,10 +69,10 @@ protected void SanitizeStorage(IEnumerable protectedNodes = null) } } - Assert.Equal((protectedNodes ?? this.context.ProtectedNodes).Count(), this.context.Client.GetNodes().Count()); + Assert.Equal((protectedNodes ?? Context.ProtectedNodes).Count(), Context.Client.GetNodes().Count()); } - private bool IsProtectedNode(IEnumerable protectedNodes, INode node) + private static bool IsProtectedNode(IEnumerable protectedNodes, INode node) { return node.Type == NodeType.Inbox || node.Type == NodeType.Root diff --git a/MegaApiClient/ApiRequestFailedEventArgs.cs b/MegaApiClient/ApiRequestFailedEventArgs.cs index f412ce1..ccc1439 100644 --- a/MegaApiClient/ApiRequestFailedEventArgs.cs +++ b/MegaApiClient/ApiRequestFailedEventArgs.cs @@ -1,4 +1,4 @@ -namespace CG.Web.MegaApiClient +namespace CG.Web.MegaApiClient { using System; @@ -16,12 +16,12 @@ public ApiRequestFailedEventArgs(Uri url, int attemptNum, TimeSpan retryDelay, A private ApiRequestFailedEventArgs(Uri url, int attemptNum, TimeSpan retryDelay, ApiResultCode apiResult, string responseJson, Exception exception) { - this.ApiUrl = url; - this.AttemptNum = attemptNum; - this.RetryDelay = retryDelay; - this.ApiResult = apiResult; - this.ResponseJson = responseJson; - this.Exception = exception; + ApiUrl = url; + AttemptNum = attemptNum; + RetryDelay = retryDelay; + ApiResult = apiResult; + ResponseJson = responseJson; + Exception = exception; } public Uri ApiUrl { get; } diff --git a/MegaApiClient/Cryptography/BigInteger.cs b/MegaApiClient/Cryptography/BigInteger.cs index 1037886..30707ec 100644 --- a/MegaApiClient/Cryptography/BigInteger.cs +++ b/MegaApiClient/Cryptography/BigInteger.cs @@ -1,5 +1,6 @@ using System; using System.Security.Cryptography; +// ReSharper disable All // compile with: /doc:BigIntegerDocComment.xml @@ -3173,4 +3174,4 @@ private static BigInteger[] LucasSequenceHelper(BigInteger P, BigInteger Q, // //Console.WriteLine(System.Environment.TickCount - dwStart); //} -} \ No newline at end of file +} diff --git a/MegaApiClient/Cryptography/CachedCryptoTransform.cs b/MegaApiClient/Cryptography/CachedCryptoTransform.cs index 3baf3f7..bb08340 100644 --- a/MegaApiClient/Cryptography/CachedCryptoTransform.cs +++ b/MegaApiClient/Cryptography/CachedCryptoTransform.cs @@ -5,50 +5,50 @@ internal class CachedCryptoTransform : ICryptoTransform { - private readonly Func factory; - private readonly bool isKnownReusable; - private ICryptoTransform cachedInstance; + private readonly Func _factory; + private readonly bool _isKnownReusable; + private ICryptoTransform _cachedInstance; public CachedCryptoTransform(Func factory, bool isKnownReusable) { - this.factory = factory; - this.isKnownReusable = isKnownReusable; + _factory = factory; + _isKnownReusable = isKnownReusable; } public void Dispose() { - this.cachedInstance?.Dispose(); + _cachedInstance?.Dispose(); } public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { - return this.Forward(x => x.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset)); + return Forward(x => x.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset)); } public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { - if (isKnownReusable && cachedInstance != null) + if (_isKnownReusable && _cachedInstance != null) { // Fast path. - return cachedInstance.TransformFinalBlock(inputBuffer, inputOffset, inputCount); + return _cachedInstance.TransformFinalBlock(inputBuffer, inputOffset, inputCount); } else { - return this.Forward(x => x.TransformFinalBlock(inputBuffer, inputOffset, inputCount)); + return Forward(x => x.TransformFinalBlock(inputBuffer, inputOffset, inputCount)); } } - public int InputBlockSize { get { return this.Forward(x => x.InputBlockSize); } } + public int InputBlockSize => Forward(x => x.InputBlockSize); - public int OutputBlockSize { get { return this.Forward(x => x.OutputBlockSize); } } + public int OutputBlockSize => Forward(x => x.OutputBlockSize); - public bool CanTransformMultipleBlocks { get { return this.Forward(x => x.CanTransformMultipleBlocks); } } + public bool CanTransformMultipleBlocks => Forward(x => x.CanTransformMultipleBlocks); - public bool CanReuseTransform { get { return this.Forward(x => x.CanReuseTransform); } } + public bool CanReuseTransform => Forward(x => x.CanReuseTransform); private T Forward(Func action) { - ICryptoTransform instance = this.cachedInstance ?? this.factory(); + var instance = _cachedInstance ?? _factory(); try { @@ -56,13 +56,13 @@ private T Forward(Func action) } finally { - if (!isKnownReusable && instance.CanReuseTransform == false) // Try to avoid a virtual call to CanReuseTransform. + if (!_isKnownReusable && instance.CanReuseTransform == false) // Try to avoid a virtual call to CanReuseTransform. { instance.Dispose(); } else { - this.cachedInstance = instance; + _cachedInstance = instance; } } } diff --git a/MegaApiClient/Cryptography/Crc32.cs b/MegaApiClient/Cryptography/Crc32.cs index 1224ff5..f292029 100644 --- a/MegaApiClient/Cryptography/Crc32.cs +++ b/MegaApiClient/Cryptography/Crc32.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; +// ReSharper disable All namespace DamienG.Security.Cryptography { @@ -230,4 +231,4 @@ static byte[] UInt32ToBigEndianBytes(UInt32 uint32) return result; } } -} \ No newline at end of file +} diff --git a/MegaApiClient/Cryptography/Crypto.cs b/MegaApiClient/Cryptography/Crypto.cs index 2c089d9..26c5450 100644 --- a/MegaApiClient/Cryptography/Crypto.cs +++ b/MegaApiClient/Cryptography/Crypto.cs @@ -1,43 +1,42 @@ -namespace CG.Web.MegaApiClient +namespace CG.Web.MegaApiClient.Cryptography { using System; using System.Security.Cryptography; - using CG.Web.MegaApiClient.Cryptography; using CG.Web.MegaApiClient.Serialization; using Newtonsoft.Json; internal class Crypto { - private static readonly Aes AesCbc; - private static readonly bool IsKnownReusable; - private static readonly byte[] DefaultIv = new byte[16]; + private static readonly Aes s_aesCbc; + private static readonly bool s_isKnownReusable; + private static readonly byte[] s_defaultIv = new byte[16]; static Crypto() { #if NETSTANDARD1_3 || NETSTANDARD2_0 - AesCbc = Aes.Create(); // More per-call overhead but supported everywhere. - IsKnownReusable = false; + s_aesCbc = Aes.Create(); // More per-call overhead but supported everywhere. + s_isKnownReusable = false; #else - AesCbc = new AesManaged(); - IsKnownReusable = true; + s_aesCbc = new AesManaged(); + s_isKnownReusable = true; #endif - AesCbc.Padding = PaddingMode.None; - AesCbc.Mode = CipherMode.CBC; + s_aesCbc.Padding = PaddingMode.None; + s_aesCbc.Mode = CipherMode.CBC; } #region Key public static byte[] DecryptKey(byte[] data, byte[] key) { - byte[] result = new byte[data.Length]; + var result = new byte[data.Length]; - for (int idx = 0; idx < data.Length; idx += 16) + for (var idx = 0; idx < data.Length; idx += 16) { - byte[] block = data.CopySubArray(16, idx); - byte[] decryptedBlock = DecryptAes(block, key); + var block = data.CopySubArray(16, idx); + var decryptedBlock = DecryptAes(block, key); Array.Copy(decryptedBlock, 0, result, idx, 16); } @@ -46,13 +45,13 @@ public static byte[] DecryptKey(byte[] data, byte[] key) public static byte[] EncryptKey(byte[] data, byte[] key) { - byte[] result = new byte[data.Length]; + var result = new byte[data.Length]; using (var encryptor = CreateAesEncryptor(key)) { - for (int idx = 0; idx < data.Length; idx += 16) + for (var idx = 0; idx < data.Length; idx += 16) { - byte[] block = data.CopySubArray(16, idx); - byte[] encryptedBlock = EncryptAes(block, encryptor); + var block = data.CopySubArray(16, idx); + var encryptedBlock = EncryptAes(block, encryptor); Array.Copy(encryptedBlock, 0, result, idx, 16); } } @@ -70,7 +69,7 @@ public static void GetPartsFromDecryptedKey(byte[] decryptedKey, out byte[] iv, // For files, key is 256 bits long. Compute the key to retrieve 128 AES key fileKey = new byte[16]; - for (int idx = 0; idx < 16; idx++) + for (var idx = 0; idx < 16; idx++) { fileKey[idx] = (byte)(decryptedKey[idx] ^ decryptedKey[idx + 16]); } @@ -82,7 +81,7 @@ public static void GetPartsFromDecryptedKey(byte[] decryptedKey, out byte[] iv, public static byte[] DecryptAes(byte[] data, byte[] key) { - using (ICryptoTransform decryptor = AesCbc.CreateDecryptor(key, DefaultIv)) + using (var decryptor = s_aesCbc.CreateDecryptor(key, s_defaultIv)) { return decryptor.TransformFinalBlock(data, 0, data.Length); } @@ -90,7 +89,7 @@ public static byte[] DecryptAes(byte[] data, byte[] key) public static ICryptoTransform CreateAesEncryptor(byte[] key) { - return new CachedCryptoTransform(() => AesCbc.CreateEncryptor(key, DefaultIv), IsKnownReusable); + return new CachedCryptoTransform(() => s_aesCbc.CreateEncryptor(key, s_defaultIv), s_isKnownReusable); } public static byte[] EncryptAes(byte[] data, ICryptoTransform encryptor) @@ -100,7 +99,7 @@ public static byte[] EncryptAes(byte[] data, ICryptoTransform encryptor) public static byte[] EncryptAes(byte[] data, byte[] key) { - using (ICryptoTransform encryptor = CreateAesEncryptor(key)) + using (var encryptor = CreateAesEncryptor(key)) { return encryptor.TransformFinalBlock(data, 0, data.Length); } @@ -108,7 +107,7 @@ public static byte[] EncryptAes(byte[] data, byte[] key) public static byte[] CreateAesKey() { - using (Aes aes = Aes.Create()) + using (var aes = Aes.Create()) { aes.Mode = CipherMode.CBC; aes.KeySize = 128; @@ -124,8 +123,8 @@ public static byte[] CreateAesKey() public static byte[] EncryptAttributes(Attributes attributes, byte[] nodeKey) { - string data = "MEGA" + JsonConvert.SerializeObject(attributes, Formatting.None); - byte[] dataBytes = data.ToBytes(); + var data = "MEGA" + JsonConvert.SerializeObject(attributes, Formatting.None); + var dataBytes = data.ToBytes(); dataBytes = dataBytes.CopySubArray(dataBytes.Length + 16 - (dataBytes.Length % 16)); return EncryptAes(dataBytes, nodeKey); @@ -133,13 +132,13 @@ public static byte[] EncryptAttributes(Attributes attributes, byte[] nodeKey) public static Attributes DecryptAttributes(byte[] attributes, byte[] nodeKey) { - byte[] decryptedAttributes = DecryptAes(attributes, nodeKey); + var decryptedAttributes = DecryptAes(attributes, nodeKey); // Remove MEGA prefix try { - string json = decryptedAttributes.ToUTF8String().Substring(4); - int nullTerminationIndex = json.IndexOf('\0'); + var json = decryptedAttributes.ToUTF8String().Substring(4); + var nullTerminationIndex = json.IndexOf('\0'); if (nullTerminationIndex != -1) { json = json.Substring(0, nullTerminationIndex); @@ -161,18 +160,18 @@ public static BigInteger[] GetRsaPrivateKeyComponents(byte[] encodedRsaPrivateKe { // We need to add padding to obtain multiple of 16 encodedRsaPrivateKey = encodedRsaPrivateKey.CopySubArray(encodedRsaPrivateKey.Length + (16 - encodedRsaPrivateKey.Length % 16)); - byte[] rsaPrivateKey = DecryptKey(encodedRsaPrivateKey, masterKey); + var rsaPrivateKey = DecryptKey(encodedRsaPrivateKey, masterKey); // rsaPrivateKeyComponents[0] => First factor p // rsaPrivateKeyComponents[1] => Second factor q // rsaPrivateKeyComponents[2] => Private exponent d - BigInteger[] rsaPrivateKeyComponents = new BigInteger[4]; - for (int i = 0; i < 4; i++) + var rsaPrivateKeyComponents = new BigInteger[4]; + for (var i = 0; i < 4; i++) { rsaPrivateKeyComponents[i] = rsaPrivateKey.FromMPINumber(); // Remove already retrieved part - int dataLength = ((rsaPrivateKey[0] * 256 + rsaPrivateKey[1] + 7) / 8); + var dataLength = ((rsaPrivateKey[0] * 256 + rsaPrivateKey[1] + 7) / 8); rsaPrivateKey = rsaPrivateKey.CopySubArray(rsaPrivateKey.Length - dataLength - 2, dataLength + 2); } diff --git a/MegaApiClient/Cryptography/PBKDF2.cs b/MegaApiClient/Cryptography/PBKDF2.cs index 2d6ebf7..d6df6aa 100644 --- a/MegaApiClient/Cryptography/PBKDF2.cs +++ b/MegaApiClient/Cryptography/PBKDF2.cs @@ -1,6 +1,7 @@ //Copyright (c) 2012 Josip Medved // From https://www.medo64.com/2012/04/pbkdf2-with-sha-256-and-others/ //2012-04-12: Initial version. +// ReSharper disable All namespace Medo.Security.Cryptography { using System; @@ -183,4 +184,4 @@ private static byte[] GetBytesFromInt(uint i) } } -} \ No newline at end of file +} diff --git a/MegaApiClient/Exceptions.cs b/MegaApiClient/Exceptions.cs index fb5d819..9644595 100644 --- a/MegaApiClient/Exceptions.cs +++ b/MegaApiClient/Exceptions.cs @@ -6,15 +6,12 @@ public class ApiException : Exception { internal ApiException(ApiResultCode apiResultCode) { - this.ApiResultCode = apiResultCode; + ApiResultCode = apiResultCode; } public ApiResultCode ApiResultCode { get; private set; } - public override string Message - { - get { return string.Format("API response: {0}", this.ApiResultCode); } - } + public override string Message => string.Format("API response: {0}", ApiResultCode); } public class DownloadException : Exception diff --git a/MegaApiClient/Extensions.cs b/MegaApiClient/Extensions.cs index f6f3f77..d0f07a2 100644 --- a/MegaApiClient/Extensions.cs +++ b/MegaApiClient/Extensions.cs @@ -1,17 +1,16 @@ namespace CG.Web.MegaApiClient { using System; - using System.IO; using System.Linq; using System.Text; internal static class Extensions { - private static readonly DateTime EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, 0); + private static readonly DateTime s_epochStart = new DateTime(1970, 1, 1, 0, 0, 0, 0); public static string ToBase64(this byte[] data) { - StringBuilder sb = new StringBuilder(); + var sb = new StringBuilder(); sb.Append(Convert.ToBase64String(data)); sb.Replace('+', '-'); sb.Replace('/', '_'); @@ -22,7 +21,7 @@ public static string ToBase64(this byte[] data) public static byte[] FromBase64(this string data) { - StringBuilder sb = new StringBuilder(); + var sb = new StringBuilder(); sb.Append(data); sb.Append(string.Empty.PadRight((4 - data.Length % 4) % 4, '=')); sb.Replace('-', '+'); @@ -43,7 +42,7 @@ public static byte[] ToBytes(this string data) } public static byte[] ToBytesPassword(this string data) - { + { // Store bytes characters in uint array // discards bits 8-31 of multibyte characters for backwards compatibility var array = new uint[(data.Length + 3) >> 2]; @@ -66,7 +65,7 @@ public static byte[] ToBytesPassword(this string data) public static T[] CopySubArray(this T[] source, int length, int offset = 0) { - T[] result = new T[length]; + var result = new T[length]; while (--length >= 0) { if (source.Length > offset + length) @@ -81,9 +80,9 @@ public static T[] CopySubArray(this T[] source, int length, int offset = 0) public static BigInteger FromMPINumber(this byte[] data) { // First 2 bytes defines the size of the component - int dataLength = (data[0] * 256 + data[1] + 7) / 8; + var dataLength = (data[0] * 256 + data[1] + 7) / 8; - byte[] result = new byte[dataLength]; + var result = new byte[dataLength]; Array.Copy(data, 2, result, 0, result.Length); return new BigInteger(result); @@ -91,26 +90,25 @@ public static BigInteger FromMPINumber(this byte[] data) public static DateTime ToDateTime(this long seconds) { - return EpochStart.AddSeconds(seconds).ToLocalTime(); + return s_epochStart.AddSeconds(seconds).ToLocalTime(); } public static long ToEpoch(this DateTime datetime) { - return (long)datetime.ToUniversalTime().Subtract(EpochStart).TotalSeconds; + return (long)datetime.ToUniversalTime().Subtract(s_epochStart).TotalSeconds; } public static long DeserializeToLong(this byte[] data, int index, int length) { - byte p = data[index]; + var p = data[index]; long result = 0; - if ((p > sizeof(UInt64)) || (p >= length)) + if ((p > sizeof(ulong)) || (p >= length)) { throw new ArgumentException("Invalid value"); } - while (p > 0) { result = (result << 8) + data[index + p--]; @@ -121,7 +119,7 @@ public static long DeserializeToLong(this byte[] data, int index, int length) public static byte[] SerializeToBytes(this long data) { - byte[] result = new byte[sizeof(long) + 1]; + var result = new byte[sizeof(long) + 1]; byte p = 0; while (data != 0) @@ -136,4 +134,4 @@ public static byte[] SerializeToBytes(this long data) return result; } } -} \ No newline at end of file +} diff --git a/MegaApiClient/Interface/IAccountInformation.cs b/MegaApiClient/Interface/IAccountInformation.cs index 220b945..82c480b 100644 --- a/MegaApiClient/Interface/IAccountInformation.cs +++ b/MegaApiClient/Interface/IAccountInformation.cs @@ -1,4 +1,4 @@ -namespace CG.Web.MegaApiClient +namespace CG.Web.MegaApiClient { using System.Collections.Generic; @@ -21,4 +21,4 @@ public interface IStorageMetrics long FoldersCount { get; } } -} \ No newline at end of file +} diff --git a/MegaApiClient/MegaApiClient.cs b/MegaApiClient/MegaApiClient.cs index facb418..8f8a063 100644 --- a/MegaApiClient/MegaApiClient.cs +++ b/MegaApiClient/MegaApiClient.cs @@ -9,29 +9,27 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; - - using CG.Web.MegaApiClient.Serialization; - + using CG.Web.MegaApiClient.Cryptography; using Medo.Security.Cryptography; - using Newtonsoft.Json; using Newtonsoft.Json.Linq; + using Serialization; public partial class MegaApiClient : IMegaApiClient { - private static readonly Uri BaseApiUri = new Uri("https://g.api.mega.co.nz/cs"); - private static readonly Uri BaseUri = new Uri("https://mega.nz"); + private static readonly Uri s_baseApiUri = new Uri("https://g.api.mega.co.nz/cs"); + private static readonly Uri s_baseUri = new Uri("https://mega.nz"); - private readonly Options options; - private readonly IWebClient webClient; + private readonly Options _options; + private readonly IWebClient _webClient; - private readonly Object apiRequestLocker = new Object(); + private readonly object _apiRequestLocker = new object(); - private Node trashNode; - private string sessionId; - private byte[] masterKey; - private uint sequenceIndex = (uint)(uint.MaxValue * new Random().NextDouble()); - private bool authenticatedLogin; + private Node _trashNode; + private string _sessionId; + private byte[] _masterKey; + private uint _sequenceIndex = (uint)(uint.MaxValue * new Random().NextDouble()); + private bool _authenticatedLogin; #region Constructors @@ -64,19 +62,9 @@ public MegaApiClient(IWebClient webClient) /// public MegaApiClient(Options options, IWebClient webClient) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - if (webClient == null) - { - throw new ArgumentNullException(nameof(webClient)); - } - - this.options = options; - this.webClient = webClient; - this.webClient.BufferSize = options.BufferSize; + _options = options ?? throw new ArgumentNullException(nameof(options)); + _webClient = webClient ?? throw new ArgumentNullException(nameof(webClient)); + _webClient.BufferSize = options.BufferSize; } #endregion @@ -104,8 +92,8 @@ public AuthInfos GenerateAuthInfos(string email, string password, string mfaKey } // Prelogin to retrieve account version - PreLoginRequest preLoginRequest = new PreLoginRequest(email); - PreLoginResponse preLoginResponse = this.Request(preLoginRequest); + var preLoginRequest = new PreLoginRequest(email); + var preLoginResponse = Request(preLoginRequest); if (preLoginResponse.Version == 2 && !string.IsNullOrEmpty(preLoginResponse.Salt)) { @@ -122,7 +110,7 @@ public AuthInfos GenerateAuthInfos(string email, string password, string mfaKey } // Derived key contains master key (0-16) and password hash (16-32) - if(!string.IsNullOrEmpty(mfaKey)) + if (!string.IsNullOrEmpty(mfaKey)) { return new AuthInfos( email, @@ -130,6 +118,7 @@ public AuthInfos GenerateAuthInfos(string email, string password, string mfaKey derivedKeyBytes.Take(16).ToArray(), mfaKey); } + return new AuthInfos( email, derivedKeyBytes.Skip(16).ToArray().ToBase64(), @@ -138,17 +127,18 @@ public AuthInfos GenerateAuthInfos(string email, string password, string mfaKey else if (preLoginResponse.Version == 1) { // Retrieve password as UTF8 byte array - byte[] passwordBytes = password.ToBytesPassword(); + var passwordBytes = password.ToBytesPassword(); // Encrypt password to use password as key for the hash - byte[] passwordAesKey = PrepareKey(passwordBytes); + var passwordAesKey = PrepareKey(passwordBytes); // Hash email and password to decrypt master key on Mega servers - string hash = GenerateHash(email.ToLowerInvariant(), passwordAesKey); + var hash = GenerateHash(email.ToLowerInvariant(), passwordAesKey); if (!string.IsNullOrEmpty(mfaKey)) { return new AuthInfos(email, hash, passwordAesKey, mfaKey); } + return new AuthInfos(email, hash, passwordAesKey); } else @@ -159,10 +149,7 @@ public AuthInfos GenerateAuthInfos(string email, string password, string mfaKey public event EventHandler ApiRequestFailed; - public bool IsLoggedIn - { - get { return this.sessionId != null; } - } + public bool IsLoggedIn => _sessionId != null; /// /// Login to Mega.co.nz service using email/password credentials @@ -174,7 +161,7 @@ public bool IsLoggedIn /// Already logged in public LogonSessionToken Login(string email, string password) { - return this.Login(GenerateAuthInfos(email, password)); + return Login(GenerateAuthInfos(email, password)); } /// @@ -188,7 +175,7 @@ public LogonSessionToken Login(string email, string password) /// Already logged in public LogonSessionToken Login(string email, string password, string mfaKey) { - return this.Login(GenerateAuthInfos(email, password, mfaKey)); + return Login(GenerateAuthInfos(email, password, mfaKey)); } /// @@ -205,8 +192,8 @@ public LogonSessionToken Login(AuthInfos authInfos) throw new ArgumentNullException("authInfos"); } - this.EnsureLoggedOut(); - this.authenticatedLogin = true; + EnsureLoggedOut(); + _authenticatedLogin = true; // Request Mega Api LoginRequest request; @@ -218,33 +205,34 @@ public LogonSessionToken Login(AuthInfos authInfos) { request = new LoginRequest(authInfos.Email, authInfos.Hash); } - LoginResponse response = this.Request(request); + + var response = Request(request); // Decrypt master key using our password key - byte[] cryptedMasterKey = response.MasterKey.FromBase64(); - this.masterKey = Crypto.DecryptKey(cryptedMasterKey, authInfos.PasswordAesKey); + var cryptedMasterKey = response.MasterKey.FromBase64(); + _masterKey = Crypto.DecryptKey(cryptedMasterKey, authInfos.PasswordAesKey); // Decrypt RSA private key using decrypted master key - byte[] cryptedRsaPrivateKey = response.PrivateKey.FromBase64(); - BigInteger[] rsaPrivateKeyComponents = Crypto.GetRsaPrivateKeyComponents(cryptedRsaPrivateKey, this.masterKey); + var cryptedRsaPrivateKey = response.PrivateKey.FromBase64(); + var rsaPrivateKeyComponents = Crypto.GetRsaPrivateKeyComponents(cryptedRsaPrivateKey, _masterKey); // Decrypt session id - byte[] encryptedSid = response.SessionId.FromBase64(); - byte[] sid = Crypto.RsaDecrypt(encryptedSid.FromMPINumber(), rsaPrivateKeyComponents[0], rsaPrivateKeyComponents[1], rsaPrivateKeyComponents[2]); + var encryptedSid = response.SessionId.FromBase64(); + var sid = Crypto.RsaDecrypt(encryptedSid.FromMPINumber(), rsaPrivateKeyComponents[0], rsaPrivateKeyComponents[1], rsaPrivateKeyComponents[2]); // Session id contains only the first 43 bytes - this.sessionId = sid.Take(43).ToArray().ToBase64(); + _sessionId = sid.Take(43).ToArray().ToBase64(); - return new LogonSessionToken(this.sessionId, this.masterKey); + return new LogonSessionToken(_sessionId, _masterKey); } public void Login(LogonSessionToken logonSessionToken) { - this.EnsureLoggedOut(); - this.authenticatedLogin = true; + EnsureLoggedOut(); + _authenticatedLogin = true; - this.sessionId = logonSessionToken.SessionId; - this.masterKey = logonSessionToken.MasterKey; + _sessionId = logonSessionToken.SessionId; + _masterKey = logonSessionToken.MasterKey; } /// @@ -253,7 +241,7 @@ public void Login(LogonSessionToken logonSessionToken) /// Throws if service is not available public void Login() { - this.LoginAnonymous(); + LoginAnonymous(); } /// @@ -262,40 +250,40 @@ public void Login() /// Throws if service is not available public void LoginAnonymous() { - this.EnsureLoggedOut(); - this.authenticatedLogin = false; + EnsureLoggedOut(); + _authenticatedLogin = false; - Random random = new Random(); + var random = new Random(); // Generate random master key - this.masterKey = new byte[16]; - random.NextBytes(this.masterKey); + _masterKey = new byte[16]; + random.NextBytes(_masterKey); // Generate a random password used to encrypt the master key - byte[] passwordAesKey = new byte[16]; + var passwordAesKey = new byte[16]; random.NextBytes(passwordAesKey); // Generate a random session challenge - byte[] sessionChallenge = new byte[16]; + var sessionChallenge = new byte[16]; random.NextBytes(sessionChallenge); - byte[] encryptedMasterKey = Crypto.EncryptAes(this.masterKey, passwordAesKey); + var encryptedMasterKey = Crypto.EncryptAes(_masterKey, passwordAesKey); // Encrypt the session challenge with our generated master key - byte[] encryptedSessionChallenge = Crypto.EncryptAes(sessionChallenge, this.masterKey); - byte[] encryptedSession = new byte[32]; + var encryptedSessionChallenge = Crypto.EncryptAes(sessionChallenge, _masterKey); + var encryptedSession = new byte[32]; Array.Copy(sessionChallenge, 0, encryptedSession, 0, 16); Array.Copy(encryptedSessionChallenge, 0, encryptedSession, 16, encryptedSessionChallenge.Length); // Request Mega Api to obtain a temporary user handle - AnonymousLoginRequest request = new AnonymousLoginRequest(encryptedMasterKey.ToBase64(), encryptedSession.ToBase64()); - string userHandle = this.Request(request); + var request = new AnonymousLoginRequest(encryptedMasterKey.ToBase64(), encryptedSession.ToBase64()); + var userHandle = Request(request); // Request Mega Api to retrieve our temporary session id - LoginRequest request2 = new LoginRequest(userHandle, null); - LoginResponse response2 = this.Request(request2); + var request2 = new LoginRequest(userHandle, null); + var response2 = Request(request2); - this.sessionId = response2.TemporarySessionId; + _sessionId = response2.TemporarySessionId; } /// @@ -304,16 +292,16 @@ public void LoginAnonymous() /// Not logged in public void Logout() { - this.EnsureLoggedIn(); + EnsureLoggedIn(); - if (this.authenticatedLogin == true) + if (_authenticatedLogin == true) { - this.Request(new LogoutRequest()); + Request(new LogoutRequest()); } // Reset values retrieved by Login methods - this.masterKey = null; - this.sessionId = null; + _masterKey = null; + _sessionId = null; } /// @@ -322,14 +310,14 @@ public void Logout() /// Not logged in public string GetRecoveryKey() { - this.EnsureLoggedIn(); + EnsureLoggedIn(); - if (!this.authenticatedLogin) + if (!_authenticatedLogin) { throw new NotSupportedException("Anonymous login is not supported"); } - return this.masterKey.ToBase64(); + return _masterKey.ToBase64(); } /// @@ -340,10 +328,10 @@ public string GetRecoveryKey() /// Mega.co.nz service reports an error public IAccountInformation GetAccountInformation() { - this.EnsureLoggedIn(); + EnsureLoggedIn(); - AccountInformationRequest request = new AccountInformationRequest(); - return this.Request(request); + var request = new AccountInformationRequest(); + return Request(request); } /// @@ -354,10 +342,10 @@ public IAccountInformation GetAccountInformation() /// Mega.co.nz service reports an error public IEnumerable GetSessionsHistory() { - this.EnsureLoggedIn(); + EnsureLoggedIn(); - SessionHistoryRequest request = new SessionHistoryRequest(); - return this.Request(request); + var request = new SessionHistoryRequest(); + return Request(request); } /// @@ -368,15 +356,15 @@ public IEnumerable GetSessionsHistory() /// Mega.co.nz service reports an error public IEnumerable GetNodes() { - this.EnsureLoggedIn(); + EnsureLoggedIn(); - GetNodesRequest request = new GetNodesRequest(); - GetNodesResponse response = this.Request(request, this.masterKey); + var request = new GetNodesRequest(); + var response = Request(request, _masterKey); - Node[] nodes = response.Nodes; - if (this.trashNode == null) + var nodes = response.Nodes; + if (_trashNode == null) { - this.trashNode = nodes.First(n => n.Type == NodeType.Trash); + _trashNode = nodes.First(n => n.Type == NodeType.Trash); } return nodes.Distinct().OfType(); @@ -396,7 +384,7 @@ public IEnumerable GetNodes(INode parent) throw new ArgumentNullException("parent"); } - return this.GetNodes().Where(n => n.ParentId == parent.Id); + return GetNodes().Where(n => n.ParentId == parent.Id); } /// @@ -423,15 +411,15 @@ public void Delete(INode node, bool moveToTrash = true) throw new ArgumentException("Invalid node type"); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); if (moveToTrash) { - this.Move(node, this.trashNode); + Move(node, _trashNode); } else { - this.Request(new DeleteRequest(node)); + Request(new DeleteRequest(node)); } } @@ -461,14 +449,14 @@ public INode CreateFolder(string name, INode parent) throw new ArgumentException("Invalid parent node"); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); - byte[] key = Crypto.CreateAesKey(); - byte[] attributes = Crypto.EncryptAttributes(new Attributes(name), key); - byte[] encryptedKey = Crypto.EncryptAes(key, this.masterKey); + var key = Crypto.CreateAesKey(); + var attributes = Crypto.EncryptAttributes(new Attributes(name), key); + var encryptedKey = Crypto.EncryptAes(key, _masterKey); - CreateNodeRequest request = CreateNodeRequest.CreateFolderNodeRequest(parent, attributes.ToBase64(), encryptedKey.ToBase64(), key); - GetNodesResponse response = this.Request(request, this.masterKey); + var request = CreateNodeRequest.CreateFolderNodeRequest(parent, attributes.ToBase64(), encryptedKey.ToBase64(), key); + var response = Request(request, _masterKey); return response.Nodes[0]; } @@ -493,26 +481,25 @@ public Uri GetDownloadLink(INode node) throw new ArgumentException("Invalid node"); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); if (node.Type == NodeType.Directory) { // Request an export share on the node or we will receive an AccessDenied - this.Request(new ShareNodeRequest(node, this.masterKey, this.GetNodes())); + Request(new ShareNodeRequest(node, _masterKey, GetNodes())); - node = this.GetNodes().First(x => x.Equals(node)); + node = GetNodes().First(x => x.Equals(node)); } - INodeCrypto nodeCrypto = node as INodeCrypto; - if (nodeCrypto == null) + if (!(node is INodeCrypto nodeCrypto)) { throw new ArgumentException("node must implement INodeCrypto"); } - GetDownloadLinkRequest request = new GetDownloadLinkRequest(node); - string response = this.Request(request); + var request = new GetDownloadLinkRequest(node); + var response = Request(request); - return new Uri(BaseUri, string.Format( + return new Uri(s_baseUri, string.Format( "/{0}/{1}#{2}", node.Type == NodeType.Directory ? "folder" : "file", response, @@ -542,9 +529,9 @@ public void DownloadFile(INode node, string outputFile, CancellationToken? cance throw new ArgumentNullException("outputFile"); } - using (Stream stream = this.Download(node, cancellationToken)) + using (var stream = Download(node, cancellationToken)) { - this.SaveStream(stream, outputFile); + SaveStream(stream, outputFile); } } @@ -571,9 +558,9 @@ public void DownloadFile(Uri uri, string outputFile, CancellationToken? cancella throw new ArgumentNullException("outputFile"); } - using (Stream stream = this.Download(uri, cancellationToken)) + using (var stream = Download(uri, cancellationToken)) { - this.SaveStream(stream, outputFile); + SaveStream(stream, outputFile); } } @@ -599,19 +586,18 @@ public Stream Download(INode node, CancellationToken? cancellationToken = null) throw new ArgumentException("Invalid node"); } - INodeCrypto nodeCrypto = node as INodeCrypto; - if (nodeCrypto == null) + if (!(node is INodeCrypto nodeCrypto)) { throw new ArgumentException("node must implement INodeCrypto"); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); // Retrieve download URL - DownloadUrlRequest downloadRequest = new DownloadUrlRequest(node); - DownloadUrlResponse downloadResponse = this.Request(downloadRequest); + var downloadRequest = new DownloadUrlRequest(node); + var downloadResponse = Request(downloadRequest); - Stream dataStream = new BufferedStream(this.webClient.GetRequestRaw(new Uri(downloadResponse.Url))); + Stream dataStream = new BufferedStream(_webClient.GetRequestRaw(new Uri(downloadResponse.Url))); Stream resultStream = new MegaAesCtrStreamDecrypter(dataStream, downloadResponse.Size, nodeCrypto.Key, nodeCrypto.Iv, nodeCrypto.MetaMac); @@ -640,17 +626,15 @@ public Stream Download(Uri uri, CancellationToken? cancellationToken = null) throw new ArgumentNullException("uri"); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); - string id; - byte[] iv, metaMac, key; - this.GetPartsFromUri(uri, out id, out iv, out metaMac, out key); + GetPartsFromUri(uri, out var id, out var iv, out var metaMac, out var key); // Retrieve download URL - DownloadUrlRequestFromId downloadRequest = new DownloadUrlRequestFromId(id); - DownloadUrlResponse downloadResponse = this.Request(downloadRequest); + var downloadRequest = new DownloadUrlRequestFromId(id); + var downloadResponse = Request(downloadRequest); - Stream dataStream = new BufferedStream(this.webClient.GetRequestRaw(new Uri(downloadResponse.Url))); + Stream dataStream = new BufferedStream(_webClient.GetRequestRaw(new Uri(downloadResponse.Url))); Stream resultStream = new MegaAesCtrStreamDecrypter(dataStream, downloadResponse.Size, key, iv, metaMac); @@ -677,20 +661,17 @@ public INodeInfo GetNodeFromLink(Uri uri) throw new ArgumentNullException("uri"); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); - string id; - byte[] iv, metaMac, key; - this.GetPartsFromUri(uri, out id, out iv, out metaMac, out key); + GetPartsFromUri(uri, out var id, out _, out _, out var key); // Retrieve attributes - DownloadUrlRequestFromId downloadRequest = new DownloadUrlRequestFromId(id); - DownloadUrlResponse downloadResponse = this.Request(downloadRequest); + var downloadRequest = new DownloadUrlRequestFromId(id); + var downloadResponse = Request(downloadRequest); return new NodeInfo(id, downloadResponse, key); } - /// /// Retrieve list of nodes from a specified Uri /// @@ -706,15 +687,13 @@ public IEnumerable GetNodesFromLink(Uri uri) throw new ArgumentNullException("uri"); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); - string shareId; - byte[] iv, metaMac, key; - this.GetPartsFromUri(uri, out shareId, out iv, out metaMac, out key); + GetPartsFromUri(uri, out var shareId, out _, out _, out var key); // Retrieve attributes - GetNodesRequest getNodesRequest = new GetNodesRequest(shareId); - GetNodesResponse getNodesResponse = this.Request(getNodesRequest, key); + var getNodesRequest = new GetNodesRequest(shareId); + var getNodesResponse = Request(getNodesRequest, key); return getNodesResponse.Nodes.Select(x => new PublicNode(x, shareId)).OfType(); } @@ -748,12 +727,12 @@ public INode UploadFile(string filename, INode parent, CancellationToken? cancel throw new FileNotFoundException(filename); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); - DateTime modificationDate = File.GetLastWriteTime(filename); - using (FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read)) + var modificationDate = File.GetLastWriteTime(filename); + using (var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { - return this.Upload(fileStream, Path.GetFileName(filename), parent, modificationDate, cancellationToken); + return Upload(fileStream, Path.GetFileName(filename), parent, modificationDate, cancellationToken); } } @@ -792,50 +771,49 @@ public INode Upload(Stream stream, string name, INode parent, DateTime? modifica throw new ArgumentException("Invalid parent node"); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); if (cancellationToken.HasValue) { stream = new CancellableStream(stream, cancellationToken.Value); } - string completionHandle = string.Empty; - int attempt = 0; - while (this.options.ComputeApiRequestRetryWaitDelay(++attempt, out var retryDelay)) + var completionHandle = string.Empty; + var attempt = 0; + while (_options.ComputeApiRequestRetryWaitDelay(++attempt, out var retryDelay)) { // Retrieve upload URL - UploadUrlRequest uploadRequest = new UploadUrlRequest(stream.Length); - UploadUrlResponse uploadResponse = this.Request(uploadRequest); + var uploadRequest = new UploadUrlRequest(stream.Length); + var uploadResponse = Request(uploadRequest); - ApiResultCode apiResult = ApiResultCode.Ok; - using (MegaAesCtrStreamCrypter encryptedStream = new MegaAesCtrStreamCrypter(stream)) + var apiResult = ApiResultCode.Ok; + using (var encryptedStream = new MegaAesCtrStreamCrypter(stream)) { long chunkStartPosition = 0; - var chunksSizesToUpload = this.ComputeChunksSizesToUpload(encryptedStream.ChunksPositions, encryptedStream.Length).ToArray(); + var chunksSizesToUpload = ComputeChunksSizesToUpload(encryptedStream.ChunksPositions, encryptedStream.Length).ToArray(); Uri uri = null; - for (int i = 0; i < chunksSizesToUpload.Length; i++) + for (var i = 0; i < chunksSizesToUpload.Length; i++) { completionHandle = string.Empty; - int chunkSize = chunksSizesToUpload[i]; - byte[] chunkBuffer = new byte[chunkSize]; + var chunkSize = chunksSizesToUpload[i]; + var chunkBuffer = new byte[chunkSize]; encryptedStream.Read(chunkBuffer, 0, chunkSize); - using (MemoryStream chunkStream = new MemoryStream(chunkBuffer)) + using (var chunkStream = new MemoryStream(chunkBuffer)) { uri = new Uri(uploadResponse.Url + "/" + chunkStartPosition); chunkStartPosition += chunkSize; try { - completionHandle = this.webClient.PostRequestRaw(uri, chunkStream); + completionHandle = _webClient.PostRequestRaw(uri, chunkStream); if (string.IsNullOrEmpty(completionHandle)) { apiResult = ApiResultCode.Ok; continue; } - long retCode; - if (completionHandle.FromBase64().Length != 27 && long.TryParse(completionHandle, out retCode)) + if (completionHandle.FromBase64().Length != 27 && long.TryParse(completionHandle, out var retCode)) { apiResult = (ApiResultCode)retCode; break; @@ -844,7 +822,7 @@ public INode Upload(Stream stream, string name, INode parent, DateTime? modifica catch (Exception ex) { apiResult = ApiResultCode.RequestFailedRetry; - this.ApiRequestFailed?.Invoke(this, new ApiRequestFailedEventArgs(uri, attempt, retryDelay, apiResult, ex)); + ApiRequestFailed?.Invoke(this, new ApiRequestFailedEventArgs(uri, attempt, retryDelay, apiResult, ex)); break; } @@ -853,12 +831,12 @@ public INode Upload(Stream stream, string name, INode parent, DateTime? modifica if (apiResult != ApiResultCode.Ok) { - this.ApiRequestFailed?.Invoke(this, new ApiRequestFailedEventArgs(uri, attempt, retryDelay, apiResult, completionHandle)); + ApiRequestFailed?.Invoke(this, new ApiRequestFailedEventArgs(uri, attempt, retryDelay, apiResult, completionHandle)); if (apiResult == ApiResultCode.RequestFailedRetry || apiResult == ApiResultCode.RequestFailedPermanetly || apiResult == ApiResultCode.TooManyRequests) { // Restart upload from the beginning - this.Wait(retryDelay); + Wait(retryDelay); // Reset steam position stream.Seek(0, SeekOrigin.Begin); @@ -870,26 +848,26 @@ public INode Upload(Stream stream, string name, INode parent, DateTime? modifica } // Encrypt attributes - byte[] cryptedAttributes = Crypto.EncryptAttributes(new Attributes(name, stream, modificationDate), encryptedStream.FileKey); + var cryptedAttributes = Crypto.EncryptAttributes(new Attributes(name, stream, modificationDate), encryptedStream.FileKey); // Compute the file key - byte[] fileKey = new byte[32]; - for (int i = 0; i < 8; i++) + var fileKey = new byte[32]; + for (var i = 0; i < 8; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.Iv[i]); fileKey[i + 16] = encryptedStream.Iv[i]; } - for (int i = 8; i < 16; i++) + for (var i = 8; i < 16; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.MetaMac[i - 8]); fileKey[i + 16] = encryptedStream.MetaMac[i - 8]; } - byte[] encryptedKey = Crypto.EncryptKey(fileKey, this.masterKey); + var encryptedKey = Crypto.EncryptKey(fileKey, _masterKey); - CreateNodeRequest createNodeRequest = CreateNodeRequest.CreateFileNodeRequest(parent, cryptedAttributes.ToBase64(), encryptedKey.ToBase64(), fileKey, completionHandle); - GetNodesResponse createNodeResponse = this.Request(createNodeRequest, this.masterKey); + var createNodeRequest = CreateNodeRequest.CreateFileNodeRequest(parent, cryptedAttributes.ToBase64(), encryptedKey.ToBase64(), fileKey, completionHandle); + var createNodeResponse = Request(createNodeRequest, _masterKey); return createNodeResponse.Nodes[0]; } } @@ -930,10 +908,10 @@ public INode Move(INode node, INode destinationParentNode) throw new ArgumentException("Invalid destination parent node"); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); - this.Request(new MoveRequest(node, destinationParentNode)); - return this.GetNodes().First(n => n.Equals(node)); + Request(new MoveRequest(node, destinationParentNode)); + return GetNodes().First(n => n.Equals(node)); } public INode Rename(INode node, string newName) @@ -953,17 +931,16 @@ public INode Rename(INode node, string newName) throw new ArgumentNullException("newName"); } - INodeCrypto nodeCrypto = node as INodeCrypto; - if (nodeCrypto == null) + if (!(node is INodeCrypto nodeCrypto)) { throw new ArgumentException("node must implement INodeCrypto"); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); - byte[] encryptedAttributes = Crypto.EncryptAttributes(new Attributes(newName, ((Node)node).Attributes), nodeCrypto.Key); - this.Request(new RenameRequest(node, encryptedAttributes.ToBase64())); - return this.GetNodes().First(n => n.Equals(node)); + var encryptedAttributes = Crypto.EncryptAttributes(new Attributes(newName, ((Node)node).Attributes), nodeCrypto.Key); + Request(new RenameRequest(node, encryptedAttributes.ToBase64())); + return GetNodes().First(n => n.Equals(node)); } /// @@ -989,13 +966,12 @@ public Stream DownloadFileAttribute(INode node, FileAttributeType fileAttributeT throw new ArgumentException("Invalid node"); } - INodeCrypto nodeCrypto = node as INodeCrypto; - if (nodeCrypto == null) + if (!(node is INodeCrypto nodeCrypto)) { throw new ArgumentException("node must implement INodeCrypto"); } - this.EnsureLoggedIn(); + EnsureLoggedIn(); var fileAttribute = node.FileAttributes.FirstOrDefault(_ => _.Type == fileAttributeType); if (fileAttribute == null) @@ -1004,17 +980,17 @@ public Stream DownloadFileAttribute(INode node, FileAttributeType fileAttributeT } var downloadRequest = new DownloadFileAttributeRequest(fileAttribute.Handle); - var downloadResponse = this.Request(downloadRequest); + var downloadResponse = Request(downloadRequest); var fileAttributeHandle = fileAttribute.Handle.FromBase64(); - using (var stream = this.webClient.PostRequestRawAsStream(new Uri(downloadResponse.Url + "/0"), new MemoryStream(fileAttributeHandle))) + using (var stream = _webClient.PostRequestRawAsStream(new Uri(downloadResponse.Url + "/0"), new MemoryStream(fileAttributeHandle))) { using (var memoryStream = new MemoryStream()) { stream.CopyTo(memoryStream); memoryStream.Position = 0; - const int dataOffset = 12; // handle (8) + position (4) + const int DataOffset = 12; // handle (8) + position (4) var data = memoryStream.ToArray(); var dataHandle = data.CopySubArray(8, 0); if (!dataHandle.SequenceEqual(fileAttributeHandle)) @@ -1023,12 +999,12 @@ public Stream DownloadFileAttribute(INode node, FileAttributeType fileAttributeT } var dataSize = BitConverter.ToUInt32(data.CopySubArray(4, 8), 0); - if (dataSize != data.Length - dataOffset) + if (dataSize != data.Length - DataOffset) { - throw new InvalidOperationException($"File attribute size mismatch ({dataSize} expected but {data.Length - dataOffset} received)"); + throw new InvalidOperationException($"File attribute size mismatch ({dataSize} expected but {data.Length - DataOffset} received)"); } - data = data.CopySubArray(data.Length - dataOffset, dataOffset); + data = data.CopySubArray(data.Length - DataOffset, DataOffset); Stream resultStream = new MemoryStream(Crypto.DecryptAes(data, nodeCrypto.Key)); if (cancellationToken.HasValue) { @@ -1040,17 +1016,17 @@ public Stream DownloadFileAttribute(INode node, FileAttributeType fileAttributeT } } -#endregion + #endregion -#region Private static methods + #region Private static methods private static string GenerateHash(string email, byte[] passwordAesKey) { - byte[] emailBytes = email.ToBytes(); - byte[] hash = new byte[16]; + var emailBytes = email.ToBytes(); + var hash = new byte[16]; // Compute email in 16 bytes array - for (int i = 0; i < emailBytes.Length; i++) + for (var i = 0; i < emailBytes.Length; i++) { hash[i % 16] ^= emailBytes[i]; } @@ -1058,14 +1034,14 @@ private static string GenerateHash(string email, byte[] passwordAesKey) // Encrypt hash using password key using (var encryptor = Crypto.CreateAesEncryptor(passwordAesKey)) { - for (int it = 0; it < 16384; it++) + for (var it = 0; it < 16384; it++) { hash = Crypto.EncryptAes(hash, encryptor); } } // Retrieve bytes 0-4 and 8-12 from the hash - byte[] result = new byte[8]; + var result = new byte[8]; Array.Copy(hash, 0, result, 0, 4); Array.Copy(hash, 8, result, 4, 4); @@ -1074,14 +1050,14 @@ private static string GenerateHash(string email, byte[] passwordAesKey) private static byte[] PrepareKey(byte[] data) { - byte[] pkey = new byte[] { 0x93, 0xC4, 0x67, 0xE3, 0x7D, 0xB0, 0xC7, 0xA4, 0xD1, 0xBE, 0x3F, 0x81, 0x01, 0x52, 0xCB, 0x56 }; + var pkey = new byte[] { 0x93, 0xC4, 0x67, 0xE3, 0x7D, 0xB0, 0xC7, 0xA4, 0xD1, 0xBE, 0x3F, 0x81, 0x01, 0x52, 0xCB, 0x56 }; - for (int it = 0; it < 65536; it++) + for (var it = 0; it < 65536; it++) { - for (int idx = 0; idx < data.Length; idx += 16) + for (var idx = 0; idx < data.Length; idx += 16) { // Pad the data to 16 bytes blocks - byte[] key = data.CopySubArray(16, idx); + var key = data.CopySubArray(16, idx); pkey = Crypto.EncryptAes(pkey, key); } @@ -1090,61 +1066,61 @@ private static byte[] PrepareKey(byte[] data) return pkey; } -#endregion + #endregion -#region Web + #region Web private string Request(RequestBase request) { - return this.Request(request); + return Request(request); } - private TResponse Request(RequestBase request, byte[] key= null) + private TResponse Request(RequestBase request, byte[] key = null) where TResponse : class { - if (this.options.SynchronizeApiRequests) + if (_options.SynchronizeApiRequests) { - lock (this.apiRequestLocker) + lock (_apiRequestLocker) { - return this.RequestCore(request, key); + return RequestCore(request, key); } } else { - return this.RequestCore(request, key); + return RequestCore(request, key); } } private TResponse RequestCore(RequestBase request, byte[] key) where TResponse : class { - string dataRequest = JsonConvert.SerializeObject(new object[] { request }); - Uri uri = this.GenerateUrl(request.QueryArguments); + var dataRequest = JsonConvert.SerializeObject(new object[] { request }); + var uri = GenerateUrl(request.QueryArguments); object jsonData = null; - int attempt = 0; - while (this.options.ComputeApiRequestRetryWaitDelay(++attempt, out var retryDelay)) + var attempt = 0; + while (_options.ComputeApiRequestRetryWaitDelay(++attempt, out var retryDelay)) { - string dataResult = this.webClient.PostRequestJson(uri, dataRequest); + var dataResult = _webClient.PostRequestJson(uri, dataRequest); if (string.IsNullOrEmpty(dataResult) || (jsonData = JsonConvert.DeserializeObject(dataResult)) == null || jsonData is long - || (jsonData is JArray && ((JArray)jsonData)[0].Type == JTokenType.Integer)) + || jsonData is JArray array && array[0].Type == JTokenType.Integer) { - ApiResultCode apiCode = jsonData == null + var apiCode = jsonData == null ? ApiResultCode.RequestFailedRetry : jsonData is long - ?(ApiResultCode)Enum.ToObject(typeof(ApiResultCode), jsonData) + ? (ApiResultCode)Enum.ToObject(typeof(ApiResultCode), jsonData) : (ApiResultCode)((JArray)jsonData)[0].Value(); if (apiCode != ApiResultCode.Ok) { - this.ApiRequestFailed?.Invoke(this, new ApiRequestFailedEventArgs(uri, attempt, retryDelay, apiCode, dataResult)); + ApiRequestFailed?.Invoke(this, new ApiRequestFailedEventArgs(uri, attempt, retryDelay, apiCode, dataResult)); } if (apiCode == ApiResultCode.RequestFailedRetry) { - this.Wait(retryDelay); + Wait(retryDelay); continue; } @@ -1157,7 +1133,7 @@ private TResponse RequestCore(RequestBase request, byte[] key) break; } - string data = ((JArray)jsonData)[0].ToString(); + var data = ((JArray)jsonData)[0].ToString(); return (typeof(TResponse) == typeof(string)) ? data as TResponse : JsonConvert.DeserializeObject(data, new GetNodesResponseConverter(key)); } @@ -1174,46 +1150,49 @@ private void Wait(TimeSpan retryDelay) private Uri GenerateUrl(Dictionary queryArguments) { - var query = new Dictionary(queryArguments); - query["id"] = (this.sequenceIndex++ % uint.MaxValue).ToString(CultureInfo.InvariantCulture); - query["ak"] = this.options.ApplicationKey; + var query = new Dictionary(queryArguments) + { + ["id"] = (_sequenceIndex++ % uint.MaxValue).ToString(CultureInfo.InvariantCulture), + ["ak"] = _options.ApplicationKey + }; - if (!string.IsNullOrEmpty(this.sessionId)) + if (!string.IsNullOrEmpty(_sessionId)) { - query["sid"] = this.sessionId; + query["sid"] = _sessionId; } #if NETSTANDARD1_3 - return new Uri(Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(BaseApiUri.AbsoluteUri, query)); + return new Uri(Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(s_baseApiUri.AbsoluteUri, query)); #else - UriBuilder builder = new UriBuilder(BaseApiUri); + var builder = new UriBuilder(s_baseApiUri); var arguments = ""; foreach (var item in query) { arguments = arguments + item.Key + "=" + item.Value + "&"; } + arguments = arguments.Substring(0, arguments.Length - 1); - builder.Query = arguments.ToString(); + builder.Query = arguments; return builder.Uri; #endif } private void SaveStream(Stream stream, string outputFile) { - using (FileStream fs = new FileStream(outputFile, FileMode.CreateNew, FileAccess.Write)) + using (var fs = new FileStream(outputFile, FileMode.CreateNew, FileAccess.Write)) { - stream.CopyTo(fs, this.options.BufferSize); + stream.CopyTo(fs, _options.BufferSize); } } -#endregion + #endregion -#region Private methods + #region Private methods private void EnsureLoggedIn() { - if (this.sessionId == null) + if (_sessionId == null) { throw new NotSupportedException("Not logged in"); } @@ -1221,7 +1200,7 @@ private void EnsureLoggedIn() private void EnsureLoggedOut() { - if (this.sessionId != null) + if (_sessionId != null) { throw new NotSupportedException("Already logged in"); } @@ -1229,8 +1208,8 @@ private void EnsureLoggedOut() private void GetPartsFromUri(Uri uri, out string id, out byte[] iv, out byte[] metaMac, out byte[] key) { - if (!this.TryGetPartsFromUri(uri, out id, out var decryptedKey, out var isFolder) - && !this.TryGetPartsFromLegacyUri(uri, out id, out decryptedKey, out isFolder)) + if (!TryGetPartsFromUri(uri, out id, out var decryptedKey, out var isFolder) + && !TryGetPartsFromLegacyUri(uri, out id, out decryptedKey, out isFolder)) { throw new ArgumentException(string.Format("Invalid uri. Unable to extract Id and Key from the uri {0}", uri)); } @@ -1249,8 +1228,8 @@ private void GetPartsFromUri(Uri uri, out string id, out byte[] iv, out byte[] m private bool TryGetPartsFromUri(Uri uri, out string id, out byte[] decryptedKey, out bool isFolder) { - Regex uriRegex = new Regex(@"/(?(file|folder))/(?[^#]+)#(?[^$/]+)"); - Match match = uriRegex.Match(uri.PathAndQuery + uri.Fragment); + var uriRegex = new Regex(@"/(?(file|folder))/(?[^#]+)#(?[^$/]+)"); + var match = uriRegex.Match(uri.PathAndQuery + uri.Fragment); if (match.Success) { id = match.Groups["id"].Value; @@ -1269,8 +1248,8 @@ private bool TryGetPartsFromUri(Uri uri, out string id, out byte[] decryptedKey, private bool TryGetPartsFromLegacyUri(Uri uri, out string id, out byte[] decryptedKey, out bool isFolder) { - Regex uriRegex = new Regex(@"#(?F?)!(?[^!]+)!(?[^$!\?]+)"); - Match match = uriRegex.Match(uri.Fragment); + var uriRegex = new Regex(@"#(?F?)!(?[^!]+)!(?[^$!\?]+)"); + var match = uriRegex.Match(uri.Fragment); if (match.Success) { id = match.Groups["id"].Value; @@ -1289,15 +1268,15 @@ private bool TryGetPartsFromLegacyUri(Uri uri, out string id, out byte[] decrypt private IEnumerable ComputeChunksSizesToUpload(long[] chunksPositions, long streamLength) { - for (int i = 0; i < chunksPositions.Length; i++) + for (var i = 0; i < chunksPositions.Length; i++) { - long currentChunkPosition = chunksPositions[i]; - long nextChunkPosition = i == chunksPositions.Length - 1 + var currentChunkPosition = chunksPositions[i]; + var nextChunkPosition = i == chunksPositions.Length - 1 ? streamLength : chunksPositions[i + 1]; // Pack multiple chunks in a single upload - while (((int)(nextChunkPosition - currentChunkPosition) < this.options.ChunksPackSize || this.options.ChunksPackSize == -1) && i < chunksPositions.Length - 1) + while (((int)(nextChunkPosition - currentChunkPosition) < _options.ChunksPackSize || _options.ChunksPackSize == -1) && i < chunksPositions.Length - 1) { i++; nextChunkPosition = i == chunksPositions.Length - 1 @@ -1309,18 +1288,18 @@ private IEnumerable ComputeChunksSizesToUpload(long[] chunksPositions, long } } -#endregion + #endregion -#region AuthInfos + #region AuthInfos public class AuthInfos { public AuthInfos(string email, string hash, byte[] passwordAesKey, string mfaKey = null) { - this.Email = email; - this.Hash = hash; - this.PasswordAesKey = passwordAesKey; - this.MFAKey = mfaKey; + Email = email; + Hash = hash; + PasswordAesKey = passwordAesKey; + MFAKey = mfaKey; } [JsonProperty] @@ -1350,8 +1329,8 @@ private LogonSessionToken() public LogonSessionToken(string sessionId, byte[] masterKey) { - this.SessionId = sessionId; - this.MasterKey = masterKey; + SessionId = sessionId; + MasterKey = masterKey; } public bool Equals(LogonSessionToken other) @@ -1361,21 +1340,21 @@ public bool Equals(LogonSessionToken other) return false; } - if (this.SessionId == null || other.SessionId == null || string.Compare(this.SessionId, other.SessionId) != 0) + if (SessionId == null || other.SessionId == null || string.CompareOrdinal(SessionId, other.SessionId) != 0) { - return false; + return false; } - if (this.MasterKey == null || other.MasterKey == null || !Enumerable.SequenceEqual(MasterKey, other.MasterKey)) + if (MasterKey == null || other.MasterKey == null || !Enumerable.SequenceEqual(MasterKey, other.MasterKey)) { - return false; + return false; } return true; } } -#endregion + #endregion } } diff --git a/MegaApiClient/MegaApiClientAsync.cs b/MegaApiClient/MegaApiClientAsync.cs index 61e0368..9bd6eda 100644 --- a/MegaApiClient/MegaApiClientAsync.cs +++ b/MegaApiClient/MegaApiClientAsync.cs @@ -13,89 +13,89 @@ public partial class MegaApiClient : IMegaApiClient public Task LoginAsync(string email, string password, string mfaKey = null) { - return Task.Run(() => this.Login(email, password, mfaKey)); + return Task.Run(() => Login(email, password, mfaKey)); } public Task LoginAsync(AuthInfos authInfos) { - return Task.Run(() => this.Login(authInfos)); + return Task.Run(() => Login(authInfos)); } public Task LoginAsync(LogonSessionToken logonSessionToken) { - return Task.Run(() => this.Login(logonSessionToken)); + return Task.Run(() => Login(logonSessionToken)); } public Task LoginAsync() { - return Task.Run(() => this.Login()); + return Task.Run(() => Login()); } public Task LoginAnonymousAsync() { - return Task.Run(() => this.LoginAnonymous()); + return Task.Run(() => LoginAnonymous()); } public Task LogoutAsync() { - return Task.Run(() => this.Logout()); + return Task.Run(() => Logout()); } public Task GetRecoveryKeyAsync() { - return Task.FromResult(this.GetRecoveryKey()); + return Task.FromResult(GetRecoveryKey()); } public Task GetAccountInformationAsync() { - return Task.Run(() => this.GetAccountInformation()); + return Task.Run(() => GetAccountInformation()); } public Task> GetSessionsHistoryAsync() { - return Task.Run(() => this.GetSessionsHistory()); + return Task.Run(() => GetSessionsHistory()); } public Task> GetNodesAsync() { - return Task.Run(() => this.GetNodes()); + return Task.Run(() => GetNodes()); } public Task> GetNodesAsync(INode parent) { - return Task.Run(() => this.GetNodes(parent)); + return Task.Run(() => GetNodes(parent)); } public Task CreateFolderAsync(string name, INode parent) { - return Task.Run(() => this.CreateFolder(name, parent)); + return Task.Run(() => CreateFolder(name, parent)); } public Task DeleteAsync(INode node, bool moveToTrash = true) { - return Task.Run(() => this.Delete(node, moveToTrash)); + return Task.Run(() => Delete(node, moveToTrash)); } public Task MoveAsync(INode sourceNode, INode destinationParentNode) { - return Task.Run(() => this.Move(sourceNode, destinationParentNode)); + return Task.Run(() => Move(sourceNode, destinationParentNode)); } public Task RenameAsync(INode sourceNode, string newName) { - return Task.Run(() => this.Rename(sourceNode, newName)); + return Task.Run(() => Rename(sourceNode, newName)); } public Task GetDownloadLinkAsync(INode node) { - return Task.Run(() => this.GetDownloadLink(node)); + return Task.Run(() => GetDownloadLink(node)); } public Task DownloadAsync(INode node, IProgress progress = null, CancellationToken? cancellationToken = null) { return Task.Run(() => { - return (Stream)new ProgressionStream(this.Download(node, cancellationToken), progress, this.options.ReportProgressChunkSize); + return (Stream)new ProgressionStream(Download(node, cancellationToken), progress, _options.ReportProgressChunkSize); }, cancellationToken.GetValueOrDefault()); } @@ -103,7 +103,7 @@ public Task DownloadAsync(Uri uri, IProgress progress = null, Ca { return Task.Run(() => { - return (Stream)new ProgressionStream(this.Download(uri, cancellationToken), progress, this.options.ReportProgressChunkSize); + return (Stream)new ProgressionStream(Download(uri, cancellationToken), progress, _options.ReportProgressChunkSize); }, cancellationToken.GetValueOrDefault()); } @@ -111,9 +111,9 @@ public Task DownloadFileAsync(INode node, string outputFile, IProgress p { return Task.Run(() => { - using (Stream stream = new ProgressionStream(this.Download(node, cancellationToken), progress, this.options.ReportProgressChunkSize)) + using (Stream stream = new ProgressionStream(Download(node, cancellationToken), progress, _options.ReportProgressChunkSize)) { - this.SaveStream(stream, outputFile); + SaveStream(stream, outputFile); } }, cancellationToken.GetValueOrDefault()); } @@ -127,9 +127,9 @@ public Task DownloadFileAsync(Uri uri, string outputFile, IProgress prog throw new ArgumentNullException("outputFile"); } - using (Stream stream = new ProgressionStream(this.Download(uri, cancellationToken), progress, this.options.ReportProgressChunkSize)) + using (Stream stream = new ProgressionStream(Download(uri, cancellationToken), progress, _options.ReportProgressChunkSize)) { - this.SaveStream(stream, outputFile); + SaveStream(stream, outputFile); } }, cancellationToken.GetValueOrDefault()); } @@ -143,9 +143,9 @@ public Task UploadAsync(Stream stream, string name, INode parent, IProgre throw new ArgumentNullException("stream"); } - using (Stream progressionStream = new ProgressionStream(stream, progress, this.options.ReportProgressChunkSize)) + using (Stream progressionStream = new ProgressionStream(stream, progress, _options.ReportProgressChunkSize)) { - return this.Upload(progressionStream, name, parent, modificationDate, cancellationToken); + return Upload(progressionStream, name, parent, modificationDate, cancellationToken); } }, cancellationToken.GetValueOrDefault()); } @@ -154,37 +154,37 @@ public Task UploadFileAsync(string filename, INode parent, IProgress { - DateTime modificationDate = File.GetLastWriteTime(filename); - using (Stream stream = new ProgressionStream(new FileStream(filename, FileMode.Open, FileAccess.Read), progress, this.options.ReportProgressChunkSize)) + var modificationDate = File.GetLastWriteTime(filename); + using (Stream stream = new ProgressionStream(new FileStream(filename, FileMode.Open, FileAccess.Read), progress, _options.ReportProgressChunkSize)) { - return this.Upload(stream, Path.GetFileName(filename), parent, modificationDate, cancellationToken); + return Upload(stream, Path.GetFileName(filename), parent, modificationDate, cancellationToken); } }, cancellationToken.GetValueOrDefault()); } public Task GetNodeFromLinkAsync(Uri uri) { - return Task.Run(() => this.GetNodeFromLink(uri)); + return Task.Run(() => GetNodeFromLink(uri)); } public Task> GetNodesFromLinkAsync(Uri uri) { - return Task.Run(() => this.GetNodesFromLink(uri)); + return Task.Run(() => GetNodesFromLink(uri)); } - public Task GenerateAuthInfosAsync(string email, string password) + public Task GenerateAuthInfosAsync(string email, string password) { - return Task.Run(() => this.GenerateAuthInfos(email, password)); + return Task.Run(() => GenerateAuthInfos(email, password)); } - public Task GenerateAuthInfosAsync(string email, string password, string mfaKey) + public Task GenerateAuthInfosAsync(string email, string password, string mfaKey) { - return Task.Run(() => this.GenerateAuthInfos(email, password, mfaKey)); + return Task.Run(() => GenerateAuthInfos(email, password, mfaKey)); } public Task DownloadFileAttributeAsync(INode node, FileAttributeType fileAttributeType, CancellationToken? cancellationToken = null) { - return Task.Run(() => this.DownloadFileAttribute(node, fileAttributeType, cancellationToken)); + return Task.Run(() => DownloadFileAttribute(node, fileAttributeType, cancellationToken)); } #endregion } diff --git a/MegaApiClient/Node.cs b/MegaApiClient/Node.cs index 35a1809..7e9df66 100644 --- a/MegaApiClient/Node.cs +++ b/MegaApiClient/Node.cs @@ -1,4 +1,5 @@ -namespace CG.Web.MegaApiClient + +namespace CG.Web.MegaApiClient { using System; using System.Collections.Generic; @@ -6,9 +7,9 @@ using System.Linq; using System.Runtime.Serialization; using System.Text.RegularExpressions; - using CG.Web.MegaApiClient.Serialization; - + using Cryptography; using Newtonsoft.Json; + using Serialization; [DebuggerDisplay("NodeInfo - Type: {Type} - Name: {Name} - Id: {Id}")] internal class NodeInfo : INodeInfo @@ -19,17 +20,14 @@ protected NodeInfo() internal NodeInfo(string id, DownloadUrlResponse downloadResponse, byte[] key) { - this.Id = id; - this.Attributes = Crypto.DecryptAttributes(downloadResponse.SerializedAttributes.FromBase64(), key); - this.Size = downloadResponse.Size; - this.Type = NodeType.File; + Id = id; + Attributes = Crypto.DecryptAttributes(downloadResponse.SerializedAttributes.FromBase64(), key); + Size = downloadResponse.Size; + Type = NodeType.File; } [JsonIgnore] - public string Name - { - get { return this.Attributes?.Name; } - } + public string Name => Attributes?.Name; [JsonProperty("s")] public long Size { get; protected set; } @@ -41,16 +39,10 @@ public string Name public string Id { get; private set; } [JsonIgnore] - public DateTime? ModificationDate - { - get { return this.Attributes?.ModificationDate; } - } + public DateTime? ModificationDate => Attributes?.ModificationDate; [JsonIgnore] - public string SerializedFingerprint - { - get { return this.Attributes?.SerializedFingerprint; } - } + public string SerializedFingerprint => Attributes?.SerializedFingerprint; [JsonIgnore] public Attributes Attributes { get; protected set; } @@ -59,17 +51,17 @@ public string SerializedFingerprint public bool Equals(INodeInfo other) { - return other != null && this.Id == other.Id; + return other != null && Id == other.Id; } public override int GetHashCode() { - return this.Id.GetHashCode(); + return Id.GetHashCode(); } public override bool Equals(object obj) { - return this.Equals(obj as INodeInfo); + return Equals(obj as INodeInfo); } #endregion @@ -78,15 +70,15 @@ public override bool Equals(object obj) [DebuggerDisplay("Node - Type: {Type} - Name: {Name} - Id: {Id}")] internal class Node : NodeInfo, INode, INodeCrypto { - private static readonly Regex FileAttributeRegex = new Regex(@"(?\d+):(?\d+)\*(?[a-zA-Z0-9-_]+)"); + private static readonly Regex s_fileAttributeRegex = new Regex(@"(?\d+):(?\d+)\*(?[a-zA-Z0-9-_]+)"); - private byte[] masterKey; - private List sharedKeys; + private byte[] _masterKey; + private readonly List _sharedKeys; public Node(byte[] masterKey, ref List sharedKeys) { - this.masterKey = masterKey; - this.sharedKeys = sharedKeys; + _masterKey = masterKey; + _sharedKeys = sharedKeys; } #region Public properties @@ -147,19 +139,19 @@ public Node(byte[] masterKey, ref List sharedKeys) public void OnDeserialized(StreamingContext ctx) { // Add key from incoming sharing. - if (this.SharingKey != null && this.sharedKeys.Any(x => x.Id == this.Id) == false) + if (SharingKey != null && _sharedKeys.Any(x => x.Id == Id) == false) { - this.sharedKeys.Add(new SharedKey(this.Id, this.SharingKey)); + _sharedKeys.Add(new SharedKey(Id, SharingKey)); } - this.CreationDate = this.SerializedCreationDate.ToDateTime(); + CreationDate = SerializedCreationDate.ToDateTime(); - if (this.Type == NodeType.File || this.Type == NodeType.Directory) + if (Type == NodeType.File || Type == NodeType.Directory) { // Check if file is not yet decrypted - if (string.IsNullOrEmpty(this.SerializedKey)) + if (string.IsNullOrEmpty(SerializedKey)) { - this.EmptyKey = true; + EmptyKey = true; return; } @@ -167,56 +159,55 @@ public void OnDeserialized(StreamingContext ctx) // There are cases where the SerializedKey property contains multiple keys separated with / // This can occur when a folder is shared and the parent is shared too. // Both keys are working so we use the first one - string serializedKey = this.SerializedKey.Split('/')[0]; - int splitPosition = serializedKey.IndexOf(":", StringComparison.Ordinal); - byte[] encryptedKey = serializedKey.Substring(splitPosition + 1).FromBase64(); + var serializedKey = SerializedKey.Split('/')[0]; + var splitPosition = serializedKey.IndexOf(":", StringComparison.Ordinal); + var encryptedKey = serializedKey.Substring(splitPosition + 1).FromBase64(); // If node is shared, we need to retrieve shared masterkey - if (this.sharedKeys != null) + if (_sharedKeys != null) { - string handle = serializedKey.Substring(0, splitPosition); - SharedKey sharedKey = this.sharedKeys.FirstOrDefault(x => x.Id == handle); + var handle = serializedKey.Substring(0, splitPosition); + var sharedKey = _sharedKeys.FirstOrDefault(x => x.Id == handle); if (sharedKey != null) { - this.masterKey = Crypto.DecryptKey(sharedKey.Key.FromBase64(), this.masterKey); - if (this.Type == NodeType.Directory) + _masterKey = Crypto.DecryptKey(sharedKey.Key.FromBase64(), _masterKey); + if (Type == NodeType.Directory) { - this.SharedKey = this.masterKey; + SharedKey = _masterKey; } else { - this.SharedKey = Crypto.DecryptKey(encryptedKey, this.masterKey); + SharedKey = Crypto.DecryptKey(encryptedKey, _masterKey); } } } - this.FullKey = Crypto.DecryptKey(encryptedKey, this.masterKey); + FullKey = Crypto.DecryptKey(encryptedKey, _masterKey); - if (this.Type == NodeType.File) + if (Type == NodeType.File) { - byte[] iv, metaMac, fileKey; - Crypto.GetPartsFromDecryptedKey(this.FullKey, out iv, out metaMac, out fileKey); + Crypto.GetPartsFromDecryptedKey(FullKey, out var iv, out var metaMac, out var fileKey); - this.Iv = iv; - this.MetaMac = metaMac; - this.Key = fileKey; + Iv = iv; + MetaMac = metaMac; + Key = fileKey; } else { - this.Key = this.FullKey; + Key = FullKey; } - this.Attributes = Crypto.DecryptAttributes(this.SerializedAttributes.FromBase64(), this.Key); + Attributes = Crypto.DecryptAttributes(SerializedAttributes.FromBase64(), Key); - if (this.SerializedFileAttributes != null) + if (SerializedFileAttributes != null) { - var attributes = this.SerializedFileAttributes.Split('/'); - this.FileAttributes = attributes - .Select(_ => FileAttributeRegex.Match(_)) + var attributes = SerializedFileAttributes.Split('/'); + FileAttributes = attributes + .Select(_ => s_fileAttributeRegex.Match(_)) .Where(_ => _.Success) .Select(_ => new FileAttribute( int.Parse(_.Groups["id"].Value), - (FileAttributeType) Enum.Parse(typeof(FileAttributeType), _.Groups["type"].Value), + (FileAttributeType)Enum.Parse(typeof(FileAttributeType), _.Groups["type"].Value), _.Groups["handle"].Value)) .ToArray(); } @@ -229,9 +220,9 @@ public bool IsShareRoot { get { - string serializedKey = this.SerializedKey.Split('/')[0]; - int splitPosition = serializedKey.IndexOf(":", StringComparison.Ordinal); - return serializedKey.Substring(0, splitPosition) == this.Id; + var serializedKey = SerializedKey.Split('/')[0]; + var splitPosition = serializedKey.IndexOf(":", StringComparison.Ordinal); + return serializedKey.Substring(0, splitPosition) == Id; } } } @@ -239,40 +230,40 @@ public bool IsShareRoot [DebuggerDisplay("PublicNode - Type: {Type} - Name: {Name} - Id: {Id}")] internal class PublicNode : INode, INodeCrypto { - private readonly Node node; + private readonly Node _node; internal PublicNode(Node node, string shareId) { - this.node = node; - this.ShareId = shareId; + _node = node; + ShareId = shareId; } public string ShareId { get; } public bool Equals(INodeInfo other) { - return this.node.Equals(other) && this.ShareId == (other as PublicNode)?.ShareId; + return _node.Equals(other) && ShareId == (other as PublicNode)?.ShareId; } #region Forward - public long Size { get { return this.node.Size; } } - public string Name { get { return this.node.Name; } } - public DateTime? ModificationDate { get { return this.node.ModificationDate; } } - public string SerializedFingerprint { get { return this.node.Attributes.SerializedFingerprint; } } - public string Id { get { return this.node.Id; } } - public string ParentId { get { return this.node.IsShareRoot ? null : this.node.ParentId; } } - public string Owner { get { return this.node.Owner; } } - public NodeType Type { get { return this.node.IsShareRoot && this.node.Type == NodeType.Directory ? NodeType.Root : this.node.Type; } } - public DateTime CreationDate { get { return this.node.CreationDate; } } + public long Size => _node.Size; + public string Name => _node.Name; + public DateTime? ModificationDate => _node.ModificationDate; + public string SerializedFingerprint => _node.Attributes.SerializedFingerprint; + public string Id => _node.Id; + public string ParentId => _node.IsShareRoot ? null : _node.ParentId; + public string Owner => _node.Owner; + public NodeType Type => _node.IsShareRoot && _node.Type == NodeType.Directory ? NodeType.Root : _node.Type; + public DateTime CreationDate => _node.CreationDate; - public byte[] Key { get { return this.node.Key; } } - public byte[] SharedKey { get { return this.node.SharedKey; } } - public byte[] Iv { get { return this.node.Iv; } } - public byte[] MetaMac { get { return this.node.MetaMac; } } - public byte[] FullKey { get { return this.node.FullKey; } } + public byte[] Key => _node.Key; + public byte[] SharedKey => _node.SharedKey; + public byte[] Iv => _node.Iv; + public byte[] MetaMac => _node.MetaMac; + public byte[] FullKey => _node.FullKey; - public IFileAttribute[] FileAttributes { get { return this.node.FileAttributes; } } + public IFileAttribute[] FileAttributes => _node.FileAttributes; #endregion } @@ -281,9 +272,9 @@ internal class FileAttribute : IFileAttribute { public FileAttribute(int id, FileAttributeType type, string handle) { - this.Id = id; - this.Type = type; - this.Handle = handle; + Id = id; + Type = type; + Handle = handle; } public int Id { get; } diff --git a/MegaApiClient/NodeExtensions.cs b/MegaApiClient/NodeExtensions.cs index 12ec579..703d103 100644 --- a/MegaApiClient/NodeExtensions.cs +++ b/MegaApiClient/NodeExtensions.cs @@ -32,7 +32,7 @@ public static long GetFolderSize(this INodeInfo node, IEnumerable allNode } else if (childNode.Type == NodeType.Directory) { - long size = childNode.GetFolderSize(allNodes); + var size = childNode.GetFolderSize(allNodes); folderSize += size; } } @@ -48,7 +48,6 @@ public static async Task GetFolderSizeAsync(this INodeInfo node, IMegaApiC return await node.GetFolderSizeAsync(allNodes); } - public static async Task GetFolderSizeAsync(this INodeInfo node, IEnumerable allNodes) { if (node.Type == NodeType.File) @@ -66,7 +65,7 @@ public static async Task GetFolderSizeAsync(this INodeInfo node, IEnumerab } else if (childNode.Type == NodeType.Directory) { - long size = await childNode.GetFolderSizeAsync(allNodes); + var size = await childNode.GetFolderSizeAsync(allNodes); folderSize += size; } } diff --git a/MegaApiClient/Options.cs b/MegaApiClient/Options.cs index 6ec691a..7345085 100644 --- a/MegaApiClient/Options.cs +++ b/MegaApiClient/Options.cs @@ -33,22 +33,23 @@ public Options( #endif ) { - this.ApplicationKey = applicationKey; - this.SynchronizeApiRequests = synchronizeApiRequests; + ApplicationKey = applicationKey; + SynchronizeApiRequests = synchronizeApiRequests; - this.ComputeApiRequestRetryWaitDelay = computeApiRequestRetryWaitDelay ?? this.ComputeDefaultApiRequestRetryWaitDelay; + ComputeApiRequestRetryWaitDelay = computeApiRequestRetryWaitDelay ?? ComputeDefaultApiRequestRetryWaitDelay; - this.BufferSize = bufferSize; - this.ChunksPackSize = chunksPackSize; + BufferSize = bufferSize; + ChunksPackSize = chunksPackSize; #if !NET40 - if (reportProgressChunkSize < this.BufferSize) + if (reportProgressChunkSize < BufferSize) { throw new ArgumentException( $"ReportProgressChunkSize ({reportProgressChunkSize}) cannot have a value lower than BufferSize ({bufferSize})", nameof(reportProgressChunkSize)); } - this.ReportProgressChunkSize = reportProgressChunkSize; + + ReportProgressChunkSize = reportProgressChunkSize; #endif } diff --git a/MegaApiClient/Serialization/AccountInformation.cs b/MegaApiClient/Serialization/AccountInformation.cs index ee5a6be..fa35337 100644 --- a/MegaApiClient/Serialization/AccountInformation.cs +++ b/MegaApiClient/Serialization/AccountInformation.cs @@ -13,13 +13,13 @@ public AccountInformationRequest() } [JsonProperty("strg")] - public int Storage { get { return 1; } } + public int Storage => 1; [JsonProperty("xfer")] - public int Transfer { get { return 0; } } + public int Transfer => 0; [JsonProperty("pro")] - public int AccountType { get { return 0; } } + public int AccountType => 0; } internal class AccountInformationResponse : IAccountInformation @@ -35,21 +35,20 @@ internal class AccountInformationResponse : IAccountInformation public IEnumerable Metrics { get; private set; } - [OnDeserialized] public void OnDeserialized(StreamingContext context) { - this.Metrics = this.MetricsSerialized.Select(x => (IStorageMetrics)new StorageMetrics(x.Key, x.Value)); + Metrics = MetricsSerialized.Select(x => (IStorageMetrics)new StorageMetrics(x.Key, x.Value)); } private class StorageMetrics : IStorageMetrics { public StorageMetrics(string nodeId, long[] metrics) { - this.NodeId = nodeId; - this.BytesUsed = metrics[0]; - this.FilesCount = metrics[1]; - this.FoldersCount = metrics[2]; + NodeId = nodeId; + BytesUsed = metrics[0]; + FilesCount = metrics[1]; + FoldersCount = metrics[2]; } public string NodeId { get; } diff --git a/MegaApiClient/Serialization/AnonymousLogin.cs b/MegaApiClient/Serialization/AnonymousLogin.cs index f52f1a7..1884381 100644 --- a/MegaApiClient/Serialization/AnonymousLogin.cs +++ b/MegaApiClient/Serialization/AnonymousLogin.cs @@ -7,8 +7,8 @@ internal class AnonymousLoginRequest : RequestBase public AnonymousLoginRequest(string masterKey, string temporarySession) : base("up") { - this.MasterKey = masterKey; - this.TemporarySession = temporarySession; + MasterKey = masterKey; + TemporarySession = temporarySession; } [JsonProperty("k")] diff --git a/MegaApiClient/Serialization/Attributes.cs b/MegaApiClient/Serialization/Attributes.cs index 7729f21..bd483ed 100644 --- a/MegaApiClient/Serialization/Attributes.cs +++ b/MegaApiClient/Serialization/Attributes.cs @@ -11,7 +11,7 @@ internal class Attributes private const int CrcArrayLength = 4; private const int CrcSize = sizeof(uint) * CrcArrayLength; private const int FingerprintMaxSize = CrcSize + 1 + sizeof(long); - private const int MAXFULL = 8192; + private const int MaxFull = 8192; private const uint CryptoPPCRC32Polynomial = 0xEDB88320; [JsonConstructor] @@ -21,32 +21,32 @@ private Attributes() public Attributes(string name) { - this.Name = name; + Name = name; } public Attributes(string name, Attributes originalAttributes) { - this.Name = name; - this.SerializedFingerprint = originalAttributes.SerializedFingerprint; + Name = name; + SerializedFingerprint = originalAttributes.SerializedFingerprint; } public Attributes(string name, Stream stream, DateTime? modificationDate = null) { - this.Name = name; + Name = name; if (modificationDate.HasValue) { - byte[] fingerprintBuffer = new byte[FingerprintMaxSize]; + var fingerprintBuffer = new byte[FingerprintMaxSize]; - uint[] crc = this.ComputeCrc(stream); + var crc = ComputeCrc(stream); Buffer.BlockCopy(crc, 0, fingerprintBuffer, 0, CrcSize); - byte[] serializedModificationDate = modificationDate.Value.ToEpoch().SerializeToBytes(); + var serializedModificationDate = modificationDate.Value.ToEpoch().SerializeToBytes(); Buffer.BlockCopy(serializedModificationDate, 0, fingerprintBuffer, CrcSize, serializedModificationDate.Length); Array.Resize(ref fingerprintBuffer, fingerprintBuffer.Length - (sizeof(long) + 1) + serializedModificationDate.Length); - this.SerializedFingerprint = fingerprintBuffer.ToBase64(); + SerializedFingerprint = fingerprintBuffer.ToBase64(); } } @@ -65,10 +65,10 @@ public DateTime? ModificationDate [OnDeserialized] public void OnDeserialized(StreamingContext context) { - if (this.SerializedFingerprint != null) + if (SerializedFingerprint != null) { - var fingerprintBytes = this.SerializedFingerprint.FromBase64(); - this.ModificationDate = fingerprintBytes.DeserializeToLong(CrcSize, fingerprintBytes.Length - CrcSize).ToDateTime(); + var fingerprintBytes = SerializedFingerprint.FromBase64(); + ModificationDate = fingerprintBytes.DeserializeToLong(CrcSize, fingerprintBytes.Length - CrcSize).ToDateTime(); } } @@ -78,8 +78,8 @@ private uint[] ComputeCrc(Stream stream) stream.Seek(0, SeekOrigin.Begin); - uint[] crc = new uint[CrcArrayLength]; - byte[] newCrcBuffer = new byte[CrcSize]; + var crc = new uint[CrcArrayLength]; + var newCrcBuffer = new byte[CrcSize]; uint crcVal = 0; if (stream.Length <= CrcSize) @@ -90,45 +90,50 @@ private uint[] ComputeCrc(Stream stream) Buffer.BlockCopy(newCrcBuffer, 0, crc, 0, newCrcBuffer.Length); } } - else if (stream.Length <= MAXFULL) + else if (stream.Length <= MaxFull) { // small file: full coverage, four full CRC32s - byte[] fileBuffer = new byte[stream.Length]; - int read = 0; - while ((read += stream.Read(fileBuffer, read, (int)stream.Length - read)) < stream.Length) ; - for (int i = 0; i < crc.Length; i++) + var fileBuffer = new byte[stream.Length]; + var read = 0; + while ((read += stream.Read(fileBuffer, read, (int)stream.Length - read)) < stream.Length) { - int begin = (int)(i * stream.Length / crc.Length); - int end = (int)((i + 1) * stream.Length / crc.Length); + ; + } + + for (var i = 0; i < crc.Length; i++) + { + var begin = (int)(i * stream.Length / crc.Length); + var end = (int)((i + 1) * stream.Length / crc.Length); using (var crc32Hasher = new Crc32(CryptoPPCRC32Polynomial, Crc32.DefaultSeed)) { var crcValBytes = crc32Hasher.ComputeHash(fileBuffer, begin, end - begin); crcVal = BitConverter.ToUInt32(crcValBytes, 0); } + crc[i] = crcVal; } } else { // large file: sparse coverage, four sparse CRC32s - byte[] block = new byte[4 * CrcSize]; - uint blocks = (uint)(MAXFULL / (block.Length * CrcArrayLength)); + var block = new byte[4 * CrcSize]; + var blocks = (uint)(MaxFull / (block.Length * CrcArrayLength)); long current = 0; for (uint i = 0; i < CrcArrayLength; i++) { byte[] crc32ValBytes = null; - uint seed = Crc32.DefaultSeed; + var seed = Crc32.DefaultSeed; for (uint j = 0; j < blocks; j++) { - long offset = (stream.Length - block.Length) * (i * blocks + j) / (CrcArrayLength * blocks - 1); + var offset = (stream.Length - block.Length) * (i * blocks + j) / (CrcArrayLength * blocks - 1); stream.Seek(offset - current, SeekOrigin.Current); current += (offset - current); - int blockWritten = stream.Read(block, 0, block.Length); + var blockWritten = stream.Read(block, 0, block.Length); current += blockWritten; using (var crc32Hasher = new Crc32(CryptoPPCRC32Polynomial, seed)) @@ -137,7 +142,9 @@ private uint[] ComputeCrc(Stream stream) var seedBytes = new byte[crc32ValBytes.Length]; crc32ValBytes.CopyTo(seedBytes, 0); if (BitConverter.IsLittleEndian) + { Array.Reverse(seedBytes); + } seed = BitConverter.ToUInt32(seedBytes, 0); seed = ~seed; @@ -146,7 +153,6 @@ private uint[] ComputeCrc(Stream stream) crcVal = BitConverter.ToUInt32(crc32ValBytes, 0); - crc[i] = crcVal; } } diff --git a/MegaApiClient/Serialization/CreateNode.cs b/MegaApiClient/Serialization/CreateNode.cs index 6e7a007..08cce06 100644 --- a/MegaApiClient/Serialization/CreateNode.cs +++ b/MegaApiClient/Serialization/CreateNode.cs @@ -8,8 +8,8 @@ internal class CreateNodeRequest : RequestBase private CreateNodeRequest(INode parentNode, NodeType type, string attributes, string encryptedKey, byte[] key, string completionHandle) : base("p") { - this.ParentId = parentNode.Id; - this.Nodes = new[] + ParentId = parentNode.Id; + Nodes = new[] { new CreateNodeRequestData { @@ -20,16 +20,15 @@ private CreateNodeRequest(INode parentNode, NodeType type, string attributes, st } }; - INodeCrypto parentNodeCrypto = parentNode as INodeCrypto; - if (parentNodeCrypto == null) + if (!(parentNode is INodeCrypto parentNodeCrypto)) { throw new ArgumentException("parentNode node must implement INodeCrypto"); } if (parentNodeCrypto.SharedKey != null) { - this.Share = new ShareData(parentNode.Id); - this.Share.AddItem(completionHandle, key, parentNodeCrypto.SharedKey); + Share = new ShareData(parentNode.Id); + Share.AddItem(completionHandle, key, parentNodeCrypto.SharedKey); } } diff --git a/MegaApiClient/Serialization/Delete.cs b/MegaApiClient/Serialization/Delete.cs index 3a0c687..1a76676 100644 --- a/MegaApiClient/Serialization/Delete.cs +++ b/MegaApiClient/Serialization/Delete.cs @@ -7,7 +7,7 @@ internal class DeleteRequest : RequestBase public DeleteRequest(INode node) : base("d") { - this.Node = node.Id; + Node = node.Id; } [JsonProperty("n")] diff --git a/MegaApiClient/Serialization/DownloadFileAttribute.cs b/MegaApiClient/Serialization/DownloadFileAttribute.cs index e67a02a..2743f0e 100644 --- a/MegaApiClient/Serialization/DownloadFileAttribute.cs +++ b/MegaApiClient/Serialization/DownloadFileAttribute.cs @@ -7,12 +7,14 @@ internal class DownloadFileAttributeRequest : RequestBase public DownloadFileAttributeRequest(string fileAttributeHandle) : base("ufa") { - this.Id = fileAttributeHandle; + Id = fileAttributeHandle; } - public int ssl { get { return 2; } } + [JsonProperty("ssl")] + public int Ssl => 2; - public int r { get { return 1; } } + [JsonProperty("r")] + public int R => 1; [JsonProperty("fah")] public string Id { get; private set; } diff --git a/MegaApiClient/Serialization/DownloadUrl.cs b/MegaApiClient/Serialization/DownloadUrl.cs index c4d250a..254e263 100644 --- a/MegaApiClient/Serialization/DownloadUrl.cs +++ b/MegaApiClient/Serialization/DownloadUrl.cs @@ -7,16 +7,16 @@ internal class DownloadUrlRequest : RequestBase public DownloadUrlRequest(INode node) : base("g") { - this.Id = node.Id; + Id = node.Id; - PublicNode publicNode = node as PublicNode; - if (publicNode != null) + if (node is PublicNode publicNode) { - this.QueryArguments["n"] = publicNode.ShareId; + QueryArguments["n"] = publicNode.ShareId; } } - public int g { get { return 1; } } + [JsonProperty("g")] + public int G => 1; [JsonProperty("n")] public string Id { get; private set; } @@ -27,10 +27,11 @@ internal class DownloadUrlRequestFromId : RequestBase public DownloadUrlRequestFromId(string id) : base("g") { - this.Id = id; + Id = id; } - public int g { get { return 1; } } + [JsonProperty("g")] + public int G => 1; [JsonProperty("p")] public string Id { get; private set; } diff --git a/MegaApiClient/Serialization/GetDownloadLink.cs b/MegaApiClient/Serialization/GetDownloadLink.cs index 9f8ae9d..9aacca9 100644 --- a/MegaApiClient/Serialization/GetDownloadLink.cs +++ b/MegaApiClient/Serialization/GetDownloadLink.cs @@ -7,7 +7,7 @@ internal class GetDownloadLinkRequest : RequestBase public GetDownloadLinkRequest(INode node) : base("l") { - this.Id = node.Id; + Id = node.Id; } [JsonProperty("n")] diff --git a/MegaApiClient/Serialization/GetNodes.cs b/MegaApiClient/Serialization/GetNodes.cs index 19a1263..8c3b5f2 100644 --- a/MegaApiClient/Serialization/GetNodes.cs +++ b/MegaApiClient/Serialization/GetNodes.cs @@ -11,29 +11,32 @@ internal class GetNodesRequest : RequestBase public GetNodesRequest(string shareId = null) : base("f") { - this.c = 1; + C = 1; if (shareId != null) { - this.QueryArguments["n"] = shareId; + QueryArguments["n"] = shareId; // Retrieve all nodes in all subfolders - this.r = 1; + R = 1; } } - public int c { get; private set; } - public int r { get; private set; } + [JsonProperty("c")] + public int C { get; private set; } + + [JsonProperty("r")] + public int R { get; private set; } } internal class GetNodesResponse { - private readonly byte[] masterKey; - private List sharedKeys; + private readonly byte[] _masterKey; + private List _sharedKeys; public GetNodesResponse(byte[] masterKey) { - this.masterKey = masterKey; + _masterKey = masterKey; } public Node[] Nodes { get; private set; } @@ -46,17 +49,17 @@ public GetNodesResponse(byte[] masterKey) [JsonProperty("ok")] public List SharedKeys { - get { return this.sharedKeys; } - private set { this.sharedKeys = value; } + get => _sharedKeys; + private set => _sharedKeys = value; } [OnDeserialized] public void OnDeserialized(StreamingContext ctx) { - var tempNodes = JsonConvert.DeserializeObject(this.NodesSerialized.ToString(), new NodeConverter(this.masterKey, ref this.sharedKeys)); + var tempNodes = JsonConvert.DeserializeObject(NodesSerialized.ToString(), new NodeConverter(_masterKey, ref _sharedKeys)); - this.UndecryptedNodes = tempNodes.Where(x => x.EmptyKey).ToArray(); - this.Nodes = tempNodes.Where(x => !x.EmptyKey).ToArray(); + UndecryptedNodes = tempNodes.Where(x => x.EmptyKey).ToArray(); + Nodes = tempNodes.Where(x => !x.EmptyKey).ToArray(); } } } diff --git a/MegaApiClient/Serialization/GetNodesResponseConverter.cs b/MegaApiClient/Serialization/GetNodesResponseConverter.cs index 030029d..2905bb8 100644 --- a/MegaApiClient/Serialization/GetNodesResponseConverter.cs +++ b/MegaApiClient/Serialization/GetNodesResponseConverter.cs @@ -1,17 +1,16 @@ namespace CG.Web.MegaApiClient.Serialization { using System; - using System.Collections.Generic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; internal class GetNodesResponseConverter : JsonConverter { - private readonly byte[] masterKey; + private readonly byte[] _masterKey; public GetNodesResponseConverter(byte[] masterKey) { - this.masterKey = masterKey; + _masterKey = masterKey; } public override bool CanConvert(Type objectType) @@ -26,11 +25,11 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist return null; } - JObject jObject = JObject.Load(reader); + var jObject = JObject.Load(reader); - GetNodesResponse target = new GetNodesResponse(this.masterKey); + var target = new GetNodesResponse(_masterKey); - JsonReader jObjectReader = jObject.CreateReader(); + var jObjectReader = jObject.CreateReader(); jObjectReader.Culture = reader.Culture; jObjectReader.DateFormatString = reader.DateFormatString; jObjectReader.DateParseHandling = reader.DateParseHandling; diff --git a/MegaApiClient/Serialization/Login.cs b/MegaApiClient/Serialization/Login.cs index c8a3921..db5a3a5 100644 --- a/MegaApiClient/Serialization/Login.cs +++ b/MegaApiClient/Serialization/Login.cs @@ -7,16 +7,16 @@ internal class LoginRequest : RequestBase public LoginRequest(string userHandle, string passwordHash) : base("us") { - this.UserHandle = userHandle; - this.PasswordHash = passwordHash; + UserHandle = userHandle; + PasswordHash = passwordHash; } public LoginRequest(string userHandle, string passwordHash, string mfaKey) : base("us") { - this.UserHandle = userHandle; - this.PasswordHash = passwordHash; - this.MFAKey = mfaKey; + UserHandle = userHandle; + PasswordHash = passwordHash; + MFAKey = mfaKey; } [JsonProperty("user")] diff --git a/MegaApiClient/Serialization/Move.cs b/MegaApiClient/Serialization/Move.cs index ac9f9e8..34573f2 100644 --- a/MegaApiClient/Serialization/Move.cs +++ b/MegaApiClient/Serialization/Move.cs @@ -7,8 +7,8 @@ internal class MoveRequest : RequestBase public MoveRequest(INode node, INode destinationParentNode) : base("m") { - this.Id = node.Id; - this.DestinationParentId = destinationParentNode.Id; + Id = node.Id; + DestinationParentId = destinationParentNode.Id; } [JsonProperty("n")] diff --git a/MegaApiClient/Serialization/NodeConverter.cs b/MegaApiClient/Serialization/NodeConverter.cs index e7e2543..7d3741a 100644 --- a/MegaApiClient/Serialization/NodeConverter.cs +++ b/MegaApiClient/Serialization/NodeConverter.cs @@ -7,13 +7,13 @@ internal class NodeConverter : JsonConverter { - private readonly byte[] masterKey; - private List sharedKeys; + private readonly byte[] _masterKey; + private List _sharedKeys; public NodeConverter(byte[] masterKey, ref List sharedKeys) { - this.masterKey = masterKey; - this.sharedKeys = sharedKeys; + _masterKey = masterKey; + _sharedKeys = sharedKeys; } public override bool CanConvert(Type objectType) @@ -28,11 +28,11 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist return null; } - JObject jObject = JObject.Load(reader); + var jObject = JObject.Load(reader); - Node target = new Node(this.masterKey, ref this.sharedKeys); + var target = new Node(_masterKey, ref _sharedKeys); - JsonReader jObjectReader = jObject.CreateReader(); + var jObjectReader = jObject.CreateReader(); jObjectReader.Culture = reader.Culture; jObjectReader.DateFormatString = reader.DateFormatString; jObjectReader.DateParseHandling = reader.DateParseHandling; diff --git a/MegaApiClient/Serialization/PreLogin.cs b/MegaApiClient/Serialization/PreLogin.cs index 70eff05..33395cc 100644 --- a/MegaApiClient/Serialization/PreLogin.cs +++ b/MegaApiClient/Serialization/PreLogin.cs @@ -7,7 +7,7 @@ internal class PreLoginRequest : RequestBase public PreLoginRequest(string userHandle) : base("us0") { - this.UserHandle = userHandle; + UserHandle = userHandle; } [JsonProperty("user")] diff --git a/MegaApiClient/Serialization/Rename.cs b/MegaApiClient/Serialization/Rename.cs index 10e0a91..c43a117 100644 --- a/MegaApiClient/Serialization/Rename.cs +++ b/MegaApiClient/Serialization/Rename.cs @@ -7,8 +7,8 @@ internal class RenameRequest : RequestBase public RenameRequest(INode node, string attributes) : base("a") { - this.Id = node.Id; - this.SerializedAttributes = attributes; + Id = node.Id; + SerializedAttributes = attributes; } [JsonProperty("n")] diff --git a/MegaApiClient/Serialization/RequestBase.cs b/MegaApiClient/Serialization/RequestBase.cs index 169b29b..b14eae9 100644 --- a/MegaApiClient/Serialization/RequestBase.cs +++ b/MegaApiClient/Serialization/RequestBase.cs @@ -7,8 +7,8 @@ internal abstract class RequestBase { protected RequestBase(string action) { - this.Action = action; - this.QueryArguments = new Dictionary(); + Action = action; + QueryArguments = new Dictionary(); } [JsonProperty("a")] diff --git a/MegaApiClient/Serialization/SessionHistory.cs b/MegaApiClient/Serialization/SessionHistory.cs index 8694527..aaf9b56 100644 --- a/MegaApiClient/Serialization/SessionHistory.cs +++ b/MegaApiClient/Serialization/SessionHistory.cs @@ -16,7 +16,7 @@ public SessionHistoryRequest() } [JsonProperty("x")] - public int LoadSessionIds { get { return 1; } } + public int LoadSessionIds => 1; } [JsonConverter(typeof(SessionHistoryConverter))] @@ -36,10 +36,10 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist return null; } - SessionHistoryResponse response = new SessionHistoryResponse(); + var response = new SessionHistoryResponse(); - JArray jArray = JArray.Load(reader); - foreach (JArray sessionArray in jArray.OfType()) + var jArray = JArray.Load(reader); + foreach (var sessionArray in jArray.OfType()) { response.Add(new Session(sessionArray)); } @@ -58,29 +58,31 @@ public Session(JArray jArray) { try { - this.LoginTime = jArray.Value(0).ToDateTime(); - this.LastSeenTime = jArray.Value(1).ToDateTime(); - this.Client = jArray.Value(2); - this.IpAddress = IPAddress.Parse(jArray.Value(3)); - this.Country = jArray.Value(4); - this.SessionId = jArray.Value(6); - bool isActive = jArray.Value(7) == 1; + LoginTime = jArray.Value(0).ToDateTime(); + LastSeenTime = jArray.Value(1).ToDateTime(); + Client = jArray.Value(2); + IpAddress = IPAddress.Parse(jArray.Value(3)); + Country = jArray.Value(4); + SessionId = jArray.Value(6); + var isActive = jArray.Value(7) == 1; if (jArray.Value(5) == 1) { - this.Status |= SessionStatus.Current; + Status |= SessionStatus.Current; } + if (jArray.Value(7) == 1) { - this.Status |= SessionStatus.Active; + Status |= SessionStatus.Active; } - if (this.Status == SessionStatus.Undefined) + + if (Status == SessionStatus.Undefined) { - this.Status = SessionStatus.Expired; + Status = SessionStatus.Expired; } } catch (Exception ex) { - this.Client = "Deserialization error: " + ex.Message; + Client = "Deserialization error: " + ex.Message; } } diff --git a/MegaApiClient/Serialization/Share.cs b/MegaApiClient/Serialization/Share.cs index f49ac52..030c5cb 100644 --- a/MegaApiClient/Serialization/Share.cs +++ b/MegaApiClient/Serialization/Share.cs @@ -3,33 +3,34 @@ using System; using System.Collections.Generic; using System.Diagnostics; + using CG.Web.MegaApiClient.Cryptography; using Newtonsoft.Json; [JsonConverter(typeof(ShareDataConverter))] internal class ShareData { - private IList items; + private readonly IList _items; public ShareData(string nodeId) { - this.NodeId = nodeId; - this.items = new List(); + NodeId = nodeId; + _items = new List(); } public string NodeId { get; private set; } - public IEnumerable Items { get { return this.items; } } + public IEnumerable Items => _items; public void AddItem(string nodeId, byte[] data, byte[] key) { - ShareDataItem item = new ShareDataItem + var item = new ShareDataItem { NodeId = nodeId, Data = data, Key = key }; - this.items.Add(item); + _items.Add(item); } public class ShareDataItem @@ -46,8 +47,7 @@ internal class ShareDataConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - ShareData data = value as ShareData; - if (data == null) + if (!(value is ShareData data)) { throw new ArgumentException("invalid data to serialize"); } @@ -63,16 +63,18 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s { writer.WriteValue(item.NodeId); } + writer.WriteEndArray(); writer.WriteStartArray(); - int counter = 0; + var counter = 0; foreach (var item in data.Items) { writer.WriteValue(0); writer.WriteValue(counter++); writer.WriteValue(Crypto.EncryptKey(item.Data, item.Key).ToBase64()); } + writer.WriteEndArray(); writer.WriteEndArray(); @@ -94,8 +96,8 @@ internal class SharedKey { public SharedKey(string id, string key) { - this.Id = id; - this.Key = key; + Id = id; + Key = key; } [JsonProperty("h")] diff --git a/MegaApiClient/Serialization/ShareNode.cs b/MegaApiClient/Serialization/ShareNode.cs index 84513b4..fa62178 100644 --- a/MegaApiClient/Serialization/ShareNode.cs +++ b/MegaApiClient/Serialization/ShareNode.cs @@ -2,6 +2,7 @@ { using System.Collections.Generic; using System.Linq; + using CG.Web.MegaApiClient.Cryptography; using Newtonsoft.Json; internal class ShareNodeRequest : RequestBase @@ -9,41 +10,41 @@ internal class ShareNodeRequest : RequestBase public ShareNodeRequest(INode node, byte[] masterKey, IEnumerable nodes) : base("s2") { - this.Id = node.Id; - this.Options = new object[] { new { r = 0, u = "EXP" } }; + Id = node.Id; + Options = new object[] { new { r = 0, u = "EXP" } }; - INodeCrypto nodeCrypto = (INodeCrypto)node; - byte[] uncryptedSharedKey = nodeCrypto.SharedKey; + var nodeCrypto = (INodeCrypto)node; + var uncryptedSharedKey = nodeCrypto.SharedKey; if (uncryptedSharedKey == null) { uncryptedSharedKey = Crypto.CreateAesKey(); } - this.SharedKey = Crypto.EncryptKey(uncryptedSharedKey, masterKey).ToBase64(); + SharedKey = Crypto.EncryptKey(uncryptedSharedKey, masterKey).ToBase64(); if (nodeCrypto.SharedKey == null) { - this.Share = new ShareData(node.Id); + Share = new ShareData(node.Id); - this.Share.AddItem(node.Id, nodeCrypto.FullKey, uncryptedSharedKey); + Share.AddItem(node.Id, nodeCrypto.FullKey, uncryptedSharedKey); // Add all children - IEnumerable allChildren = this.GetRecursiveChildren(nodes.ToArray(), node); + var allChildren = GetRecursiveChildren(nodes.ToArray(), node); foreach (var child in allChildren) { - this.Share.AddItem(child.Id, ((INodeCrypto)child).FullKey, uncryptedSharedKey); + Share.AddItem(child.Id, ((INodeCrypto)child).FullKey, uncryptedSharedKey); } } - byte[] handle = (node.Id + node.Id).ToBytes(); - this.HandleAuth = Crypto.EncryptKey(handle, masterKey).ToBase64(); + var handle = (node.Id + node.Id).ToBytes(); + HandleAuth = Crypto.EncryptKey(handle, masterKey).ToBase64(); } private IEnumerable GetRecursiveChildren(INode[] nodes, INode parent) { foreach (var node in nodes.Where(x => x.Type == NodeType.Directory || x.Type == NodeType.File)) { - string parentId = node.Id; + var parentId = node.Id; do { parentId = nodes.FirstOrDefault(x => x.Id == parentId)?.ParentId; diff --git a/MegaApiClient/Serialization/UploadUrl.cs b/MegaApiClient/Serialization/UploadUrl.cs index d4de68c..e5a4194 100644 --- a/MegaApiClient/Serialization/UploadUrl.cs +++ b/MegaApiClient/Serialization/UploadUrl.cs @@ -7,7 +7,7 @@ internal class UploadUrlRequest : RequestBase public UploadUrlRequest(long fileSize) : base("u") { - this.Size = fileSize; + Size = fileSize; } [JsonProperty("s")] diff --git a/MegaApiClient/Stream/BufferedStream.cs b/MegaApiClient/Stream/BufferedStream.cs index a02666a..cf2bec3 100644 --- a/MegaApiClient/Stream/BufferedStream.cs +++ b/MegaApiClient/Stream/BufferedStream.cs @@ -1,28 +1,25 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Linq; namespace CG.Web.MegaApiClient { - class BufferedStream : Stream + internal class BufferedStream : Stream { - const int BufferSize = 65536; - - Stream innerStream; - byte[] streamBuffer = new byte[BufferSize]; - int streamBufferDataStartIndex; - int streamBufferDataCount; + private const int BufferSize = 65536; + private readonly Stream _innerStream; + private readonly byte[] _streamBuffer = new byte[BufferSize]; + private int _streamBufferDataStartIndex; + private int _streamBufferDataCount; public BufferedStream(Stream innerStream) { - this.innerStream = innerStream; + _innerStream = innerStream; } - public byte[] Buffer => streamBuffer; - public int BufferOffset => streamBufferDataStartIndex; - public int AvailableCount => streamBufferDataCount; + public byte[] Buffer => _streamBuffer; + public int BufferOffset => _streamBufferDataStartIndex; + public int AvailableCount => _streamBufferDataCount; public override void Flush() { @@ -45,27 +42,33 @@ public override int Read(byte[] buffer, int offset, int count) while (true) { - var copyCount = Math.Min(this.streamBufferDataCount, count); + var copyCount = Math.Min(_streamBufferDataCount, count); if (copyCount != 0) { - Array.Copy(this.streamBuffer, this.streamBufferDataStartIndex, buffer, offset, copyCount); + Array.Copy(_streamBuffer, _streamBufferDataStartIndex, buffer, offset, copyCount); offset += copyCount; count -= copyCount; - this.streamBufferDataStartIndex += copyCount; - this.streamBufferDataCount -= copyCount; + _streamBufferDataStartIndex += copyCount; + _streamBufferDataCount -= copyCount; totalReadCount += copyCount; } - if (count == 0) break; // Request has been filled. + if (count == 0) + { + break; // Request has been filled. + } - Debug.Assert(this.streamBufferDataCount == 0); // Buffer is currently empty. + Debug.Assert(_streamBufferDataCount == 0); // Buffer is currently empty. - this.streamBufferDataStartIndex = 0; - this.streamBufferDataCount = 0; + _streamBufferDataStartIndex = 0; + _streamBufferDataCount = 0; FillBuffer(); - if (this.streamBufferDataCount == 0) break; // End of stream. + if (_streamBufferDataCount == 0) + { + break; // End of stream. + } } return totalReadCount; @@ -75,15 +78,21 @@ public void FillBuffer() { while (true) { - var startOfFreeSpace = this.streamBufferDataStartIndex + this.streamBufferDataCount; + var startOfFreeSpace = _streamBufferDataStartIndex + _streamBufferDataCount; - var availableSpaceInBuffer = this.streamBuffer.Length - startOfFreeSpace; - if (availableSpaceInBuffer == 0) break; // Buffer is full. + var availableSpaceInBuffer = _streamBuffer.Length - startOfFreeSpace; + if (availableSpaceInBuffer == 0) + { + break; // Buffer is full. + } - var readCount = innerStream.Read(this.streamBuffer, startOfFreeSpace, availableSpaceInBuffer); - if (readCount == 0) break; // End of stream. + var readCount = _innerStream.Read(_streamBuffer, startOfFreeSpace, availableSpaceInBuffer); + if (readCount == 0) + { + break; // End of stream. + } - this.streamBufferDataCount += readCount; + _streamBufferDataCount += readCount; } } diff --git a/MegaApiClient/Stream/CancellableStream.cs b/MegaApiClient/Stream/CancellableStream.cs index 52b32cd..195bfd2 100644 --- a/MegaApiClient/Stream/CancellableStream.cs +++ b/MegaApiClient/Stream/CancellableStream.cs @@ -1,4 +1,4 @@ -namespace CG.Web.MegaApiClient +namespace CG.Web.MegaApiClient { using System; using System.IO; @@ -6,26 +6,21 @@ namespace CG.Web.MegaApiClient public class CancellableStream : Stream { - private Stream stream; - private readonly CancellationToken cancellationToken; + private Stream _stream; + private readonly CancellationToken _cancellationToken; public CancellableStream(Stream stream, CancellationToken cancellationToken) { - if (stream == null) - { - throw new ArgumentNullException(nameof(stream)); - } - - this.stream = stream; - this.cancellationToken = cancellationToken; + _stream = stream ?? throw new ArgumentNullException(nameof(stream)); + _cancellationToken = cancellationToken; } public override bool CanRead { get { - this.cancellationToken.ThrowIfCancellationRequested(); - return this.stream.CanRead; + _cancellationToken.ThrowIfCancellationRequested(); + return _stream.CanRead; } } @@ -33,8 +28,8 @@ public override bool CanSeek { get { - this.cancellationToken.ThrowIfCancellationRequested(); - return this.stream.CanSeek; + _cancellationToken.ThrowIfCancellationRequested(); + return _stream.CanSeek; } } @@ -42,23 +37,23 @@ public override bool CanWrite { get { - this.cancellationToken.ThrowIfCancellationRequested(); - return this.stream.CanWrite; + _cancellationToken.ThrowIfCancellationRequested(); + return _stream.CanWrite; } } public override void Flush() { - this.cancellationToken.ThrowIfCancellationRequested(); - this.stream.Flush(); + _cancellationToken.ThrowIfCancellationRequested(); + _stream.Flush(); } public override long Length { get { - this.cancellationToken.ThrowIfCancellationRequested(); - return this.stream.Length; + _cancellationToken.ThrowIfCancellationRequested(); + return _stream.Length; } } @@ -66,48 +61,48 @@ public override long Position { get { - this.cancellationToken.ThrowIfCancellationRequested(); - return this.stream.Position; + _cancellationToken.ThrowIfCancellationRequested(); + return _stream.Position; } set { - this.cancellationToken.ThrowIfCancellationRequested(); - this.stream.Position = value; + _cancellationToken.ThrowIfCancellationRequested(); + _stream.Position = value; } } public override int Read(byte[] buffer, int offset, int count) { - this.cancellationToken.ThrowIfCancellationRequested(); - return this.stream.Read(buffer, offset, count); + _cancellationToken.ThrowIfCancellationRequested(); + return _stream.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { - this.cancellationToken.ThrowIfCancellationRequested(); - return this.stream.Seek(offset, origin); + _cancellationToken.ThrowIfCancellationRequested(); + return _stream.Seek(offset, origin); } public override void SetLength(long value) { - this.cancellationToken.ThrowIfCancellationRequested(); - this.stream.SetLength(value); + _cancellationToken.ThrowIfCancellationRequested(); + _stream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { - this.cancellationToken.ThrowIfCancellationRequested(); - this.stream.Write(buffer, offset, count); + _cancellationToken.ThrowIfCancellationRequested(); + _stream.Write(buffer, offset, count); } protected override void Dispose(bool disposing) { if (disposing) { - this.stream?.Dispose(); - this.stream = null; + _stream?.Dispose(); + _stream = null; } } } -} \ No newline at end of file +} diff --git a/MegaApiClient/Stream/MegaAesCtrStream.cs b/MegaApiClient/Stream/MegaAesCtrStream.cs index e59268c..05e3e35 100644 --- a/MegaApiClient/Stream/MegaAesCtrStream.cs +++ b/MegaApiClient/Stream/MegaAesCtrStream.cs @@ -6,6 +6,8 @@ using System.Linq; using System.Security.Cryptography; + using Cryptography; + internal class MegaAesCtrStreamCrypter : MegaAesCtrStream { public MegaAesCtrStreamCrypter(Stream stream) @@ -13,33 +15,27 @@ public MegaAesCtrStreamCrypter(Stream stream) { } - public byte[] FileKey - { - get { return this.fileKey; } - } + public new byte[] FileKey => base.FileKey; - public byte[] Iv - { - get { return this.iv; } - } + public new byte[] Iv => base.Iv; - public byte[] MetaMac + public new byte[] MetaMac { get { - if (this.position != this.streamLength) + if (_position != StreamLength) { throw new NotSupportedException("Stream must be fully read to obtain computed FileMac"); } - return this.metaMac; + return base.MetaMac; } } } internal class MegaAesCtrStreamDecrypter : MegaAesCtrStream { - private readonly byte[] expectedMetaMac; + private readonly byte[] _expectedMetaMac; public MegaAesCtrStreamDecrypter(Stream stream, long streamLength, byte[] fileKey, byte[] iv, byte[] expectedMetaMac) : base(stream, streamLength, Mode.Decrypt, fileKey, iv) @@ -49,12 +45,12 @@ public MegaAesCtrStreamDecrypter(Stream stream, long streamLength, byte[] fileKe throw new ArgumentException("Invalid expectedMetaMac"); } - this.expectedMetaMac = expectedMetaMac; + _expectedMetaMac = expectedMetaMac; } protected override void OnStreamRead() { - if (!this.expectedMetaMac.SequenceEqual(this.metaMac)) + if (!_expectedMetaMac.SequenceEqual(MetaMac)) { throw new DownloadException(); } @@ -63,28 +59,23 @@ protected override void OnStreamRead() internal abstract class MegaAesCtrStream : Stream { - protected readonly byte[] fileKey; - protected readonly byte[] iv; - protected readonly long streamLength; - protected long position = 0; - protected byte[] metaMac = new byte[8]; - - private readonly Stream stream; - private readonly Mode mode; - private readonly HashSet chunksPositionsCache; - private readonly byte[] counter = new byte[8]; - private readonly ICryptoTransform encryptor; - private long currentCounter = 0; // Represents the next counter value to use. - private byte[] currentChunkMac = new byte[16]; - private byte[] fileMac = new byte[16]; + protected readonly byte[] FileKey; + protected readonly byte[] Iv; + protected readonly long StreamLength; + protected readonly byte[] MetaMac = new byte[8]; + protected long _position = 0; + + private readonly Stream _stream; + private readonly Mode _mode; + private readonly HashSet _chunksPositionsCache; + private readonly byte[] _counter = new byte[8]; + private readonly ICryptoTransform _encryptor; + private long _currentCounter = 0; // Represents the next counter value to use. + private byte[] _currentChunkMac = new byte[16]; + private byte[] _fileMac = new byte[16]; protected MegaAesCtrStream(Stream stream, long streamLength, Mode mode, byte[] fileKey, byte[] iv) { - if (stream == null) - { - throw new ArgumentNullException("stream"); - } - if (fileKey == null || fileKey.Length != 16) { throw new ArgumentException("Invalid fileKey"); @@ -95,22 +86,22 @@ protected MegaAesCtrStream(Stream stream, long streamLength, Mode mode, byte[] f throw new ArgumentException("Invalid Iv"); } - this.stream = stream; - this.streamLength = streamLength; - this.mode = mode; - this.fileKey = fileKey; - this.iv = iv; + _stream = stream ?? throw new ArgumentNullException(nameof(stream)); + StreamLength = streamLength; + _mode = mode; + FileKey = fileKey; + Iv = iv; - this.ChunksPositions = this.GetChunksPositions(this.streamLength).ToArray(); - this.chunksPositionsCache = new HashSet(this.ChunksPositions); + ChunksPositions = GetChunksPositions(StreamLength).ToArray(); + _chunksPositionsCache = new HashSet(ChunksPositions); - this.encryptor = Crypto.CreateAesEncryptor(this.fileKey); + _encryptor = Crypto.CreateAesEncryptor(FileKey); } protected override void Dispose(bool disposing) { base.Dispose(disposing); - this.encryptor.Dispose(); + _encryptor.Dispose(); } protected enum Mode @@ -121,36 +112,21 @@ protected enum Mode public long[] ChunksPositions { get; } - public override bool CanRead - { - get { return true; } - } + public override bool CanRead => true; - public override bool CanSeek - { - get { return false; } - } + public override bool CanSeek => false; - public override bool CanWrite - { - get { return false; } - } + public override bool CanWrite => false; - public override long Length - { - get { return this.streamLength; } - } + public override long Length => StreamLength; public override long Position { - get - { - return this.position; - } + get => _position; set { - if (this.position != value) + if (_position != value) { throw new NotSupportedException("Seek is not supported"); } @@ -159,88 +135,88 @@ public override long Position public override int Read(byte[] buffer, int offset, int count) { - if (this.position == this.streamLength) + if (_position == StreamLength) { return 0; } - if (this.position + count < this.streamLength && count < 16) + if (_position + count < StreamLength && count < 16) { throw new NotSupportedException($"Invalid '{nameof(count)}' argument. Minimal read operation must be greater than 16 bytes (except for last read operation)."); } - - // Validate count boundaries - count = (this.position + count < this.streamLength) + + // Validate count boundaries + count = (_position + count < StreamLength) ? count - (count % 16) // Make count divisible by 16 for partial reads (as the minimal block is 16) : count; - for (long pos = this.position; pos < Math.Min(this.position + count, this.streamLength); pos += 16) + for (var pos = _position; pos < Math.Min(_position + count, StreamLength); pos += 16) { // We are on a chunk bondary - if (this.chunksPositionsCache.Contains(pos)) + if (_chunksPositionsCache.Contains(pos)) { if (pos != 0) { // Compute the current chunk mac data on each chunk bondary - this.ComputeChunk(encryptor); + ComputeChunk(_encryptor); } // Init chunk mac with Iv values - for (int i = 0; i < 8; i++) + for (var i = 0; i < 8; i++) { - this.currentChunkMac[i] = this.iv[i]; - this.currentChunkMac[i + 8] = this.iv[i]; + _currentChunkMac[i] = Iv[i]; + _currentChunkMac[i + 8] = Iv[i]; } } - this.IncrementCounter(); + IncrementCounter(); // Iterate each AES 16 bytes block - byte[] input = new byte[16]; - byte[] output = new byte[input.Length]; - int inputLength = this.stream.Read(input, 0, input.Length); + var input = new byte[16]; + var output = new byte[input.Length]; + var inputLength = _stream.Read(input, 0, input.Length); if (inputLength != input.Length) { // Sometimes, the stream is not finished but the read is not complete - inputLength += this.stream.Read(input, inputLength, input.Length - inputLength); + inputLength += _stream.Read(input, inputLength, input.Length - inputLength); } // Merge Iv and counter - byte[] ivCounter = new byte[16]; - Array.Copy(this.iv, ivCounter, 8); - Array.Copy(this.counter, 0, ivCounter, 8, 8); + var ivCounter = new byte[16]; + Array.Copy(Iv, ivCounter, 8); + Array.Copy(_counter, 0, ivCounter, 8, 8); - byte[] encryptedIvCounter = Crypto.EncryptAes(ivCounter, encryptor); + var encryptedIvCounter = Crypto.EncryptAes(ivCounter, _encryptor); - for (int inputPos = 0; inputPos < inputLength; inputPos++) + for (var inputPos = 0; inputPos < inputLength; inputPos++) { output[inputPos] = (byte)(encryptedIvCounter[inputPos] ^ input[inputPos]); - this.currentChunkMac[inputPos] ^= (this.mode == Mode.Crypt) ? input[inputPos] : output[inputPos]; + _currentChunkMac[inputPos] ^= (_mode == Mode.Crypt) ? input[inputPos] : output[inputPos]; } // Copy to buffer - Array.Copy(output, 0, buffer, (int)(offset + pos - this.position), (int)Math.Min(output.Length, this.streamLength - pos)); + Array.Copy(output, 0, buffer, (int)(offset + pos - _position), (int)Math.Min(output.Length, StreamLength - pos)); // Crypt to current chunk mac - this.currentChunkMac = Crypto.EncryptAes(this.currentChunkMac, encryptor); + _currentChunkMac = Crypto.EncryptAes(_currentChunkMac, _encryptor); } - long len = Math.Min(count, this.streamLength - this.position); - this.position += len; + var len = Math.Min(count, StreamLength - _position); + _position += len; // When stream is fully processed, we compute the last chunk - if (this.position == this.streamLength) + if (_position == StreamLength) { - this.ComputeChunk(encryptor); + ComputeChunk(_encryptor); // Compute Meta MAC - for (int i = 0; i < 4; i++) + for (var i = 0; i < 4; i++) { - this.metaMac[i] = (byte)(this.fileMac[i] ^ this.fileMac[i + 4]); - this.metaMac[i + 4] = (byte)(this.fileMac[i + 8] ^ this.fileMac[i + 12]); + MetaMac[i] = (byte)(_fileMac[i] ^ _fileMac[i + 4]); + MetaMac[i + 4] = (byte)(_fileMac[i + 8] ^ _fileMac[i + 12]); } - this.OnStreamRead(); + OnStreamRead(); } return (int)len; @@ -272,33 +248,33 @@ protected virtual void OnStreamRead() private void IncrementCounter() { - if ((this.currentCounter & 0xFF) != 0xFF && (this.currentCounter & 0xFF) != 0x00) + if ((_currentCounter & 0xFF) != 0xFF && (_currentCounter & 0xFF) != 0x00) { // Fast path - no wrapping. - this.counter[7]++; + _counter[7]++; } else { - byte[] counter = BitConverter.GetBytes(this.currentCounter); + var counter = BitConverter.GetBytes(_currentCounter); if (BitConverter.IsLittleEndian) { Array.Reverse(counter); } - Array.Copy(counter, this.counter, 8); + Array.Copy(counter, _counter, 8); } - this.currentCounter++; + _currentCounter++; } private void ComputeChunk(ICryptoTransform encryptor) { - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { - this.fileMac[i] ^= this.currentChunkMac[i]; + _fileMac[i] ^= _currentChunkMac[i]; } - this.fileMac = Crypto.EncryptAes(this.fileMac, encryptor); + _fileMac = Crypto.EncryptAes(_fileMac, encryptor); } private IEnumerable GetChunksPositions(long size) @@ -306,7 +282,7 @@ private IEnumerable GetChunksPositions(long size) yield return 0; long chunkStartPosition = 0; - for (int idx = 1; (idx <= 8) && (chunkStartPosition < (size - (idx * 131072))); idx++) + for (var idx = 1; (idx <= 8) && (chunkStartPosition < (size - (idx * 131072))); idx++) { chunkStartPosition += idx * 131072; yield return chunkStartPosition; diff --git a/MegaApiClient/Stream/ProgressionStream.cs b/MegaApiClient/Stream/ProgressionStream.cs index 8d4d161..ede069e 100644 --- a/MegaApiClient/Stream/ProgressionStream.cs +++ b/MegaApiClient/Stream/ProgressionStream.cs @@ -6,30 +6,30 @@ namespace CG.Web.MegaApiClient internal class ProgressionStream : Stream { - private readonly Stream baseStream; - private readonly IProgress progress; - private readonly long reportProgressChunkSize; + private readonly Stream _baseStream; + private readonly IProgress _progress; + private readonly long _reportProgressChunkSize; - private long chunkSize; + private long _chunkSize; public ProgressionStream(Stream baseStream, IProgress progress, long reportProgressChunkSize) { - this.baseStream = baseStream; - this.progress = progress ?? new Progress(); - this.reportProgressChunkSize = reportProgressChunkSize; + _baseStream = baseStream; + _progress = progress ?? new Progress(); + _reportProgressChunkSize = reportProgressChunkSize; } public override int Read(byte[] array, int offset, int count) { - int bytesRead = this.baseStream.Read(array, offset, count); - this.ReportProgress(bytesRead); + var bytesRead = _baseStream.Read(array, offset, count); + ReportProgress(bytesRead); return bytesRead; } public override void Write(byte[] buffer, int offset, int count) { - this.baseStream.Write(buffer, offset, count); + _baseStream.Write(buffer, offset, count); } protected override void Dispose(bool disposing) @@ -37,52 +37,52 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); // Report 100% progress only if it was not already sent - if (this.chunkSize != 0) + if (_chunkSize != 0) { - this.progress.Report(100); + _progress.Report(100); } } - #region Forwards +#region Forwards public override void Flush() { - this.baseStream.Flush(); + _baseStream.Flush(); } public override long Seek(long offset, SeekOrigin origin) { - return this.baseStream.Seek(offset, origin); + return _baseStream.Seek(offset, origin); } public override void SetLength(long value) { - this.baseStream.SetLength(value); + _baseStream.SetLength(value); } - public override bool CanRead => this.baseStream.CanRead; + public override bool CanRead => _baseStream.CanRead; - public override bool CanSeek => this.baseStream.CanSeek; + public override bool CanSeek => _baseStream.CanSeek; - public override bool CanWrite => this.baseStream.CanWrite; + public override bool CanWrite => _baseStream.CanWrite; - public override long Length => this.baseStream.Length; + public override long Length => _baseStream.Length; public override long Position { - get { return this.baseStream.Position; } - set { this.baseStream.Position = value; } + get => _baseStream.Position; + set => _baseStream.Position = value; } - #endregion +#endregion private void ReportProgress(int count) { - this.chunkSize += count; - if (this.chunkSize >= this.reportProgressChunkSize) + _chunkSize += count; + if (_chunkSize >= _reportProgressChunkSize) { - this.chunkSize = 0; - this.progress.Report(this.Position / (double)this.Length * 100); + _chunkSize = 0; + _progress.Report(Position / (double)Length * 100); } } } diff --git a/MegaApiClient/WebClient_HttpClient.cs b/MegaApiClient/WebClient_HttpClient.cs index 29f1f1c..c7ad035 100644 --- a/MegaApiClient/WebClient_HttpClient.cs +++ b/MegaApiClient/WebClient_HttpClient.cs @@ -15,7 +15,7 @@ public class WebClient : IWebClient { private const int DefaultResponseTimeout = Timeout.Infinite; - private readonly HttpClient httpClient; + private readonly HttpClient _httpClient; public WebClient(int responseTimeout = DefaultResponseTimeout, ProductInfoHeaderValue userAgent = null) : this(responseTimeout, userAgent, null, false) @@ -24,54 +24,56 @@ public WebClient(int responseTimeout = DefaultResponseTimeout, ProductInfoHeader internal WebClient(int responseTimeout, ProductInfoHeaderValue userAgent, HttpMessageHandler messageHandler, bool connectionClose) { - this.BufferSize = Options.DefaultBufferSize; - this.httpClient = messageHandler == null ? new HttpClient() : new HttpClient(messageHandler); - this.httpClient.Timeout = TimeSpan.FromMilliseconds(responseTimeout); - this.httpClient.DefaultRequestHeaders.UserAgent.Add(userAgent ?? this.GenerateUserAgent()); - this.httpClient.DefaultRequestHeaders.ConnectionClose = connectionClose; + BufferSize = Options.DefaultBufferSize; + _httpClient = messageHandler == null ? new HttpClient() : new HttpClient(messageHandler); + _httpClient.Timeout = TimeSpan.FromMilliseconds(responseTimeout); + _httpClient.DefaultRequestHeaders.UserAgent.Add(userAgent ?? GenerateUserAgent()); + _httpClient.DefaultRequestHeaders.ConnectionClose = connectionClose; } public int BufferSize { get; set; } public string PostRequestJson(Uri url, string jsonData) { - using (MemoryStream jsonStream = new MemoryStream(jsonData.ToBytes())) + using (var jsonStream = new MemoryStream(jsonData.ToBytes())) { - using (var responseStream = this.PostRequest(url, jsonStream, "application/json")) + using (var responseStream = PostRequest(url, jsonStream, "application/json")) { - return this.StreamToString(responseStream); + return StreamToString(responseStream); } } } public string PostRequestRaw(Uri url, Stream dataStream) { - using (var responseStream = this.PostRequest(url, dataStream, "application/json")) + using (var responseStream = PostRequest(url, dataStream, "application/json")) { - return this.StreamToString(responseStream); + return StreamToString(responseStream); } } public Stream PostRequestRawAsStream(Uri url, Stream dataStream) { - return this.PostRequest(url, dataStream, "application/octet-stream"); + return PostRequest(url, dataStream, "application/octet-stream"); } public Stream GetRequestRaw(Uri url) { - return this.httpClient.GetStreamAsync(url).Result; + return _httpClient.GetStreamAsync(url).Result; } private Stream PostRequest(Uri url, Stream dataStream, string contentType) { - using (StreamContent content = new StreamContent(dataStream, this.BufferSize)) + using (var content = new StreamContent(dataStream, BufferSize)) { content.Headers.ContentType = new MediaTypeHeaderValue(contentType); - var requestMessage = new HttpRequestMessage(HttpMethod.Post, url); - requestMessage.Content = content; + var requestMessage = new HttpRequestMessage(HttpMethod.Post, url) + { + Content = content + }; - HttpResponseMessage response = this.httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead).Result; + var response = _httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead).Result; if (!response.IsSuccessStatusCode && response.StatusCode == HttpStatusCode.InternalServerError && response.ReasonPhrase == "Server Too Busy") @@ -87,7 +89,7 @@ private Stream PostRequest(Uri url, Stream dataStream, string contentType) private string StreamToString(Stream stream) { - using (StreamReader streamReader = new StreamReader(stream, Encoding.UTF8)) + using (var streamReader = new StreamReader(stream, Encoding.UTF8)) { return streamReader.ReadToEnd(); } @@ -95,7 +97,7 @@ private string StreamToString(Stream stream) private ProductInfoHeaderValue GenerateUserAgent() { - AssemblyName assemblyName = this.GetType().GetTypeInfo().Assembly.GetName(); + var assemblyName = GetType().GetTypeInfo().Assembly.GetName(); return new ProductInfoHeaderValue(assemblyName.Name, assemblyName.Version.ToString(2)); } } diff --git a/MegaApiClient/WebClient_HttpWebRequest.cs b/MegaApiClient/WebClient_HttpWebRequest.cs index 49b690b..b84506f 100644 --- a/MegaApiClient/WebClient_HttpWebRequest.cs +++ b/MegaApiClient/WebClient_HttpWebRequest.cs @@ -12,45 +12,45 @@ public class WebClient : IWebClient { private const int DefaultResponseTimeout = Timeout.Infinite; - private readonly int responseTimeout; - private readonly string userAgent; + private readonly int _responseTimeout; + private readonly string _userAgent; public WebClient(int responseTimeout = DefaultResponseTimeout, string userAgent = null) { - this.BufferSize = Options.DefaultBufferSize; - this.responseTimeout = responseTimeout; - this.userAgent = userAgent ?? this.GenerateUserAgent(); + BufferSize = Options.DefaultBufferSize; + _responseTimeout = responseTimeout; + _userAgent = userAgent ?? GenerateUserAgent(); } public int BufferSize { get; set; } public string PostRequestJson(Uri url, string jsonData) { - using (MemoryStream jsonStream = new MemoryStream(jsonData.ToBytes())) + using (var jsonStream = new MemoryStream(jsonData.ToBytes())) { - using (var responseStream = this.PostRequest(url, jsonStream, "application/json")) + using (var responseStream = PostRequest(url, jsonStream, "application/json")) { - return this.StreamToString(responseStream); + return StreamToString(responseStream); } } } public string PostRequestRaw(Uri url, Stream dataStream) { - using (var responseStream = this.PostRequest(url, dataStream, "application/octet-stream")) + using (var responseStream = PostRequest(url, dataStream, "application/octet-stream")) { - return this.StreamToString(responseStream); + return StreamToString(responseStream); } } public Stream PostRequestRawAsStream(Uri url, Stream dataStream) { - return this.PostRequest(url, dataStream, "application/octet-stream"); + return PostRequest(url, dataStream, "application/octet-stream"); } public Stream GetRequestRaw(Uri url) { - HttpWebRequest request = this.CreateRequest(url); + var request = CreateRequest(url); request.Method = "GET"; return request.GetResponse().GetResponseStream(); @@ -58,39 +58,39 @@ public Stream GetRequestRaw(Uri url) private Stream PostRequest(Uri url, Stream dataStream, string contentType) { - HttpWebRequest request = this.CreateRequest(url); + var request = CreateRequest(url); request.ContentLength = dataStream.Length; request.Method = "POST"; request.ContentType = contentType; - using (Stream requestStream = request.GetRequestStream()) + using (var requestStream = request.GetRequestStream()) { dataStream.Position = 0; - dataStream.CopyTo(requestStream, this.BufferSize); + dataStream.CopyTo(requestStream, BufferSize); } - HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + var response = (HttpWebResponse)request.GetResponse(); return response.GetResponseStream(); } private HttpWebRequest CreateRequest(Uri url) { - HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); - request.Timeout = this.responseTimeout; - request.UserAgent = this.userAgent; + var request = (HttpWebRequest)WebRequest.Create(url); + request.Timeout = _responseTimeout; + request.UserAgent = _userAgent; return request; } private string GenerateUserAgent() { - AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName(); + var assemblyName = Assembly.GetExecutingAssembly().GetName(); return string.Format("{0} v{1}", assemblyName.Name, assemblyName.Version.ToString(2)); } private string StreamToString(Stream stream) { - using (StreamReader streamReader = new StreamReader(stream, Encoding.UTF8)) + using (var streamReader = new StreamReader(stream, Encoding.UTF8)) { return streamReader.ReadToEnd(); } diff --git a/format.ps1 b/format.ps1 index ce2441a..7a9f2fb 100644 --- a/format.ps1 +++ b/format.ps1 @@ -1,4 +1,4 @@ # Install dotnet-format if needed # dotnet tool install -g dotnet-format --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json -dotnet format --fix-whitespace --fix-style info MegaApiClient.sln \ No newline at end of file +dotnet format --fix-whitespace --fix-style info MegaApiClient.sln --exclude MegaApiClient\Cryptography\BigInteger.cs MegaApiClient\Cryptography\Crc32.cs MegaApiClient\Cryptography\PBKDF2.cs \ No newline at end of file