-
-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
411 additions
and
213 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
src/WingetIntune/GraphExtensions/GraphServiceClientExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using Microsoft.Graph.Beta; | ||
using Microsoft.Graph.Beta.Models; | ||
using Microsoft.Graph.Beta.Models.ODataErrors; | ||
using Microsoft.Kiota.Abstractions; | ||
using Microsoft.Kiota.Abstractions.Serialization; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Text.Json; | ||
using System.Threading.Tasks; | ||
using WingetIntune.Intune; | ||
|
||
namespace WingetIntune.GraphExtensions; | ||
internal static class GraphServiceClientExtensions | ||
{ | ||
// These extensions are on the service client, not the request builder. | ||
// until this issue is resolved: https://github.com/microsoft/kiota-abstractions-dotnet/issues/113 | ||
|
||
public static Task<Entity?> Intune_CreateWin32LobAppContentVersionAsync(this GraphServiceClient graphServiceClient, string win32LobAppId, CancellationToken cancellationToken) | ||
{ | ||
var requestInfo = new RequestInformation | ||
{ | ||
HttpMethod = Method.POST, | ||
URI = new Uri($"https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/{win32LobAppId}/microsoft.graph.win32LobApp/contentVersions"), | ||
}; | ||
requestInfo.Headers.Add("Content-Type", "application/json"); | ||
requestInfo.Content = new MemoryStream(Encoding.UTF8.GetBytes("{}")); | ||
|
||
return graphServiceClient.RequestAdapter.SendAsync<Entity>(requestInfo, Entity.CreateFromDiscriminatorValue, errorMapping: ErrorMapping, cancellationToken: cancellationToken); | ||
|
||
} | ||
|
||
public static Task<MobileAppContentFile?> Intune_CreateWin32LobAppContentVersionFileAsync(this GraphServiceClient graphServiceClient, string win32LobAppId, string contentVersionId, MobileAppContentFile mobileAppContentFile, CancellationToken cancellationToken) | ||
{ | ||
var requestInfo = new RequestInformation | ||
{ | ||
HttpMethod = Method.POST, | ||
URI = new Uri($"https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/{win32LobAppId}/microsoft.graph.win32LobApp/contentVersions/{contentVersionId}/files"), | ||
}; | ||
requestInfo.SetContentFromParsable(graphServiceClient.RequestAdapter, "application/json", mobileAppContentFile); | ||
return graphServiceClient.RequestAdapter.SendAsync<MobileAppContentFile>(requestInfo, MobileAppContentFile.CreateFromDiscriminatorValue, errorMapping: ErrorMapping, cancellationToken: cancellationToken); | ||
} | ||
|
||
public static Task<MobileAppContentFile?> Intune_GetWin32LobAppContentVersionFileAsync(this GraphServiceClient graphServiceClient, string win32LobAppId, string contentVersionId, string mobileAppContentFileId, CancellationToken cancellationToken) | ||
{ | ||
var requestInfo = new RequestInformation | ||
{ | ||
HttpMethod = Method.GET, | ||
URI = new Uri($"https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/{win32LobAppId}/microsoft.graph.win32LobApp/contentVersions/{contentVersionId}/files/{mobileAppContentFileId}"), | ||
}; | ||
return graphServiceClient.RequestAdapter.SendAsync<MobileAppContentFile>(requestInfo, MobileAppContentFile.CreateFromDiscriminatorValue, errorMapping: ErrorMapping, cancellationToken: cancellationToken); | ||
} | ||
|
||
public static async Task<MobileAppContentFile?> Intune_WaitForFinalCommitStateAsync(this GraphServiceClient graphServiceClient, string win32LobAppId, string contentVersionId, string mobileAppContentFileId, CancellationToken cancellationToken) | ||
{ | ||
while(true) | ||
{ | ||
var result = await graphServiceClient.Intune_GetWin32LobAppContentVersionFileAsync(win32LobAppId, contentVersionId, mobileAppContentFileId, cancellationToken)!; | ||
switch(result!.UploadState) | ||
{ | ||
case MobileAppContentFileUploadState.CommitFileSuccess: | ||
return result; | ||
case MobileAppContentFileUploadState.CommitFilePending: | ||
await Task.Delay(1000, cancellationToken); | ||
break; | ||
case MobileAppContentFileUploadState.CommitFileFailed: | ||
throw new Exception("Commit failed"); | ||
case MobileAppContentFileUploadState.CommitFileTimedOut: | ||
throw new Exception("Commit timed out"); | ||
|
||
default: | ||
throw new Exception("Unexpected state"); | ||
} | ||
} | ||
} | ||
|
||
public static Task Intune_CommitWin32LobAppContentVersionFileAsync(this GraphServiceClient graphServiceClient, string win32LobAppId, string contentVersionId, string mobileAppContentFileId, FileEncryptionInfo fileEncryptionInfo, CancellationToken cancellationToken) | ||
{ | ||
var body = new MobileAppContentFileCommitBody | ||
{ | ||
FileEncryptionInfo = fileEncryptionInfo, | ||
}; | ||
var data = JsonSerializer.SerializeToUtf8Bytes(body, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); | ||
var requestInfo = new RequestInformation | ||
{ | ||
HttpMethod = Method.POST, | ||
Content = new MemoryStream(data), | ||
URI = new Uri($"https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/{win32LobAppId}/microsoft.graph.win32LobApp/contentVersions/{contentVersionId}/files/{mobileAppContentFileId}/commit"), | ||
}; | ||
requestInfo.Headers.Add("Content-Type", "application/json"); | ||
return graphServiceClient.RequestAdapter.SendNoContentAsync(requestInfo, errorMapping: ErrorMapping, cancellationToken: cancellationToken); | ||
} | ||
|
||
public static Dictionary<string, ParsableFactory<IParsable>> ErrorMapping => new Dictionary<string, ParsableFactory<IParsable>> { | ||
{"4XX", ODataError.CreateFromDiscriminatorValue}, | ||
{"5XX", ODataError.CreateFromDiscriminatorValue}, | ||
}; | ||
} |
25 changes: 25 additions & 0 deletions
25
src/WingetIntune/GraphExtensions/MobileAppsRequestBuilderExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using Microsoft.Graph.Beta.DeviceAppManagement.MobileApps; | ||
using Microsoft.Graph.Beta.Models; | ||
using Microsoft.Graph.Beta.Models.ODataErrors; | ||
using Microsoft.Kiota.Abstractions.Serialization; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace WingetIntune.GraphExtensions; | ||
internal static class MobileAppsRequestBuilderExtensions | ||
{ | ||
public static async Task<Win32LobApp?> PostAsync(this MobileAppsRequestBuilder builder, Win32LobApp win32LobApp, CancellationToken cancellationToken) | ||
{ | ||
return await builder.PostAsync(win32LobApp, cancellationToken: cancellationToken) as Win32LobApp; | ||
} | ||
|
||
public static async Task<Win32LobApp?> PatchAsync(this MobileAppsRequestBuilder builder, Win32LobApp win32LobApp, CancellationToken cancellationToken) | ||
{ | ||
return await builder.PatchAsync(win32LobApp, cancellationToken: cancellationToken) as Win32LobApp; | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using Microsoft.Extensions.Logging; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace WingetIntune; | ||
internal class AzCopyAzureUploader : IAzureFileUploader | ||
{ | ||
private readonly string azCopyPath; | ||
private readonly ILogger<AzCopyAzureUploader> logger; | ||
private readonly IProcessManager processManager; | ||
private readonly IFileManager fileManager; | ||
|
||
public AzCopyAzureUploader(ILogger<AzCopyAzureUploader> logger, IProcessManager processManager, IFileManager fileManager) | ||
{ | ||
azCopyPath = Path.Combine(Path.GetTempPath(), "intunewin", "azcopy.exe"); | ||
this.logger = logger; | ||
this.processManager = processManager; | ||
this.fileManager = fileManager; | ||
} | ||
|
||
private async Task DownloadAzCopyIfNeeded(CancellationToken cancellationToken) | ||
{ | ||
if(!fileManager.FileExists(azCopyPath)) | ||
{ | ||
logger.LogInformation("Downloading AzCopy to {azCopyPath}", azCopyPath); | ||
var azCopyDownloadUrl = "https://aka.ms/downloadazcopy-v10-windows"; | ||
var downloadPath = Path.GetTempFileName(); | ||
await fileManager.DownloadFileAsync(azCopyDownloadUrl, downloadPath, overrideFile: true, cancellationToken); | ||
|
||
|
||
var extractFolder = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); | ||
logger.LogInformation("Extracting AzCopy to {path}", extractFolder); | ||
fileManager.ExtractFileToFolder(downloadPath, extractFolder); | ||
var azCopyExe = fileManager.FindFile(extractFolder, "azcopy.exe"); | ||
fileManager.CopyFile(azCopyExe, azCopyPath); | ||
fileManager.DeleteFileOrFolder(extractFolder); | ||
fileManager.DeleteFileOrFolder(downloadPath); | ||
} | ||
} | ||
|
||
public async Task UploadFileToAzureAsync(string filename, Uri sasUri, CancellationToken cancellationToken) | ||
{ | ||
await DownloadAzCopyIfNeeded(cancellationToken); | ||
var args = $"copy \"{filename}\" \"{sasUri}\" --output-type \"json\""; | ||
var result = await processManager.RunProcessAsync(azCopyPath, args, cancellationToken); | ||
logger.LogInformation("AzCopy result: {result}", result); | ||
if (result.ExitCode != 0) | ||
{ | ||
var exception = new Exception($"AzCopy resulted in a non-zero exitcode."); | ||
exception.Data.Add("ExitCode", result.ExitCode); | ||
exception.Data.Add("Output", result.Output); | ||
exception.Data.Add("Error", result.Error); | ||
logger.LogWarning(exception, "AzCopy resulted in a non-zero exitcode."); | ||
throw exception; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace WingetIntune; | ||
public interface IAzureFileUploader | ||
{ | ||
Task UploadFileToAzureAsync(string filename, Uri sasUri, CancellationToken cancellationToken); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.