├── .clang-format ├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── Bug_Report.yml │ ├── Documentation_Issue.yml │ ├── Feature_Request.yml │ ├── Translation_Issue.yml │ └── config.yml ├── policies │ ├── labelManagement.issueOpened.yml │ ├── labelManagement.issueUpdated.yml │ ├── moderatorTriggers.yml │ ├── scheduledSearch.closeNoRecentActivity.yml │ └── scheduledSearch.markNoRecentActivity.yml ├── pull_request_template.md └── workflows │ └── ADOExt-CI.yml ├── .gitignore ├── .vsconfig ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DevHomeAzureExtension.sln ├── Directory.Build.props ├── LICENSE ├── README.md ├── SECURITY.md ├── SUPPORT.md ├── TestingScenarios.md ├── ToolingVersions.props ├── build ├── Build.cmd ├── EnsureOutputLayout.props ├── SyncMirror-Steps.yml ├── SyncMirroredRepository.yml ├── Test.cmd ├── TriggerReleaseBuild.yml ├── TriggerStagingBuild.yml ├── azure-pipelines.yml ├── nuget.config.internal ├── scripts │ ├── Build.ps1 │ ├── CertSignAndInstall.ps1 │ ├── Create-AppxBundle.ps1 │ ├── CreateBuildInfo.ps1 │ ├── Test.ps1 │ └── Unstub.ps1 ├── store │ ├── canary │ │ ├── PDPs │ │ │ └── en-us │ │ │ │ └── PDP.xml │ │ ├── SBConfig.json │ │ └── media │ │ │ ├── de-DE │ │ │ ├── azure-dashboard.png │ │ │ └── azure-repo.png │ │ │ ├── en-us │ │ │ ├── azure-dashboard.png │ │ │ └── azure-repo.png │ │ │ ├── es-ES │ │ │ ├── azure-dashboard.png │ │ │ └── azure-repo.png │ │ │ ├── fr-FR │ │ │ ├── azure-dashboard.png │ │ │ └── azure-repo.png │ │ │ ├── it-IT │ │ │ ├── azure-dashboard.png │ │ │ └── azure-repo.png │ │ │ ├── ja-JP │ │ │ ├── azure-dashboard.png │ │ │ └── azure-repo.png │ │ │ ├── ko-KR │ │ │ ├── azure-dashboard.png │ │ │ └── azure-repo.png │ │ │ ├── pt-BR │ │ │ ├── azure-dashboard.png │ │ │ └── azure-repo.png │ │ │ ├── ru-RU │ │ │ ├── azure-dashboard.png │ │ │ └── azure-repo.png │ │ │ ├── zh-CN │ │ │ ├── azure-dashboard.png │ │ │ └── azure-repo.png │ │ │ └── zh-TW │ │ │ ├── azure-dashboard.png │ │ │ └── azure-repo.png │ └── preview │ │ ├── PDPs │ │ └── en-us │ │ │ └── PDP.xml │ │ ├── SBConfig.json │ │ └── media │ │ ├── de-DE │ │ ├── azure-dashboard.png │ │ └── azure-repo.png │ │ ├── en-us │ │ ├── azure-dashboard.png │ │ └── azure-repo.png │ │ ├── es-ES │ │ ├── azure-dashboard.png │ │ └── azure-repo.png │ │ ├── fr-FR │ │ ├── azure-dashboard.png │ │ └── azure-repo.png │ │ ├── it-IT │ │ ├── azure-dashboard.png │ │ └── azure-repo.png │ │ ├── ja-JP │ │ ├── azure-dashboard.png │ │ └── azure-repo.png │ │ ├── ko-KR │ │ ├── azure-dashboard.png │ │ └── azure-repo.png │ │ ├── pt-BR │ │ ├── azure-dashboard.png │ │ └── azure-repo.png │ │ ├── ru-RU │ │ ├── azure-dashboard.png │ │ └── azure-repo.png │ │ ├── zh-CN │ │ ├── azure-dashboard.png │ │ └── azure-repo.png │ │ └── zh-TW │ │ ├── azure-dashboard.png │ │ └── azure-repo.png ├── surrogate.xml └── templates │ └── EsrpSigning-Steps.yml ├── codeAnalysis ├── GlobalSuppressions.cs ├── Rules.ruleset ├── StyleCop.json └── format_sources.ps1 ├── docs ├── readme.md ├── specs │ └── spec-template.md └── style.md ├── exclusion.dic ├── guardian └── SDL │ └── .gdnbaselines ├── nuget.config ├── src ├── AzureExtension │ ├── Assets │ │ ├── AzureExtensionDark.png │ │ ├── DevBoxProvider.png │ │ └── DevBoxThumbnail.png │ ├── AzureExtension.cs │ ├── AzureExtension.csproj │ ├── Client │ │ ├── AzureClientHelpers.cs │ │ ├── AzureClientProvider.cs │ │ ├── AzureHostType.cs │ │ ├── AzureUri.cs │ │ ├── ConnectionResult.cs │ │ ├── ErrorType.cs │ │ ├── InfoResult.cs │ │ ├── InfoType.cs │ │ └── ResultType.cs │ ├── Configuration │ │ ├── DeveloperOAuthConfiguration.cs │ │ └── OAuthConfiguration.cs │ ├── Constants.cs │ ├── Contracts │ │ ├── IArmTokenService.cs │ │ ├── IDataTokenService.cs │ │ ├── IDevBoxAuthService.cs │ │ ├── IDevBoxCreationManager.cs │ │ ├── IDevBoxManagementService.cs │ │ ├── IDevBoxOperationWatcher.cs │ │ ├── IInstalledAppsService.cs │ │ ├── IPackagesService.cs │ │ └── ITimeSpanService.cs │ ├── DataManager │ │ ├── AzureDataManager.cs │ │ ├── AzureDataManagerCache.cs │ │ ├── AzureDataManagerUpdate.cs │ │ ├── CacheManager.cs │ │ ├── CacheManagerUpdateEventArgs.cs │ │ ├── DataManagerUpdateEventArgs.cs │ │ ├── DataStoreOperationParameters.cs │ │ ├── DataUpdater.cs │ │ ├── IAzureDataManager.cs │ │ └── RequestOptions.cs │ ├── DataModel │ │ ├── AzureDataStoreSchema.cs │ │ ├── DataObjects │ │ │ ├── Identity.cs │ │ │ ├── MetaData.cs │ │ │ ├── Notification.cs │ │ │ ├── Organization.cs │ │ │ ├── Project.cs │ │ │ ├── ProjectReference.cs │ │ │ ├── PullRequestPolicyStatus.cs │ │ │ ├── PullRequests.cs │ │ │ ├── Query.cs │ │ │ ├── Repository.cs │ │ │ ├── RepositoryReference.cs │ │ │ └── WorkItemType.cs │ │ ├── DataStore.cs │ │ ├── DataStoreOptions.cs │ │ ├── DataStoreTransaction.cs │ │ ├── Enums │ │ │ ├── NotificationType.cs │ │ │ ├── PolicyStatus.cs │ │ │ └── PullRequestView.cs │ │ ├── IDataStoreSchema.cs │ │ └── IDataStoreTransaction.cs │ ├── DevBox │ │ ├── Constants.cs │ │ ├── DevBoxInstance.cs │ │ ├── DevBoxJsonToCsClasses │ │ │ ├── DevBoxCreationPoolName.cs │ │ │ ├── DevBoxHardwareProfile.cs │ │ │ ├── DevBoxImageReference.cs │ │ │ ├── DevBoxLongRunningOperation.cs │ │ │ ├── DevBoxMachineState.cs │ │ │ ├── DevBoxMachines.cs │ │ │ ├── DevBoxOperation.cs │ │ │ ├── DevBoxOperationList.cs │ │ │ ├── DevBoxOperationResult.cs │ │ │ ├── DevBoxOsDisk.cs │ │ │ ├── DevBoxPool.cs │ │ │ ├── DevBoxPoolRoot.cs │ │ │ ├── DevBoxPoolStopOnDisconnect.cs │ │ │ ├── DevBoxProject.cs │ │ │ ├── DevBoxProjectProperties.cs │ │ │ ├── DevBoxProjects.cs │ │ │ ├── DevBoxRemoteConnectionData.cs │ │ │ ├── DevBoxStorageProfile.cs │ │ │ └── JsonSourceGenerationContext.cs │ │ ├── DevBoxProvider.cs │ │ ├── Exceptions │ │ │ ├── DevBoxCreationException.cs │ │ │ ├── DevBoxNameInvalidException.cs │ │ │ ├── DevBoxOperationMonitorException.cs │ │ │ ├── DevBoxProjectNameInvalidException.cs │ │ │ └── WingetConfigurationException.cs │ │ ├── Helpers │ │ │ ├── AbilitiesJSONToCSClasses.cs │ │ │ ├── AdaptiveCardJSONToCSClass.cs │ │ │ ├── DevBoxOperationHelper.cs │ │ │ ├── DevCenterOperationStatusConverter.cs │ │ │ ├── TaskJSONToCSClasses.cs │ │ │ ├── TaskYAMLToCSClasses.cs │ │ │ ├── WaitingForUserAdaptiveCardSession.cs │ │ │ └── WingetConfigWrapper.cs │ │ ├── Models │ │ │ ├── CreateComputeSystemOperation.cs │ │ │ ├── CreationAdaptiveCardSession.cs │ │ │ ├── DevBoxCreationParameters.cs │ │ │ ├── DevBoxHttpsRequestResult.cs │ │ │ ├── DevBoxOperationResponseHeader.cs │ │ │ ├── DevBoxOperationWatcherTimer.cs │ │ │ ├── DevBoxProjectAndPoolContainer.cs │ │ │ └── DevCenterOperationBase.cs │ │ └── Templates │ │ │ ├── Caution.png │ │ │ ├── CreationForm.json │ │ │ ├── ReviewForm.json │ │ │ └── WaitingForUserSessionTemplate.json │ ├── DeveloperId │ │ ├── AuthenticationHelper.cs │ │ ├── AuthenticationSettings.cs │ │ ├── DeveloperId.cs │ │ ├── DeveloperIdProvider.cs │ │ ├── IAuthenticationHelper.cs │ │ ├── IAuthenticationSettings.cs │ │ └── MSALLogger.cs │ ├── Exceptions │ │ ├── AzureAuthorizationException.cs │ │ ├── AzureClientException.cs │ │ ├── DataStoreException.cs │ │ ├── DataStoreInaccessibleException.cs │ │ ├── InvalidApiException.cs │ │ └── RepositoryNotFoundException.cs │ ├── Helpers │ │ ├── AzureRepositoryHierarchy.cs │ │ ├── DateTimeExtensions.cs │ │ ├── FileHelper.cs │ │ ├── IconLoader.cs │ │ ├── Json.cs │ │ ├── Links.cs │ │ ├── LocalSettings.cs │ │ ├── Resources.cs │ │ ├── RuntimeHelper.cs │ │ ├── StringExtensions.cs │ │ └── TimeSpanHelper.cs │ ├── NativeMethods.txt │ ├── Notifications │ │ ├── NotificationHandler.cs │ │ └── NotificationManager.cs │ ├── Providers │ │ ├── DevHomeRepository.cs │ │ ├── RepositoryProvider.cs │ │ ├── SettingsCardData.cs │ │ ├── SettingsCardSerializerContext.cs │ │ ├── SettingsCardTemplate.json │ │ ├── SettingsProvider.cs │ │ └── SettingsUIController.cs │ ├── Services │ │ └── DevBox │ │ │ ├── ARMTokenService.cs │ │ │ ├── AuthService.cs │ │ │ ├── DataTokenService.cs │ │ │ ├── DevBoxCreationManager.cs │ │ │ ├── DevBoxManagementService.cs │ │ │ ├── DevBoxOperationWatcher.cs │ │ │ ├── PackagesService.cs │ │ │ └── TimeSpanService.cs │ ├── Strings │ │ └── en-US │ │ │ └── Resources.resw │ └── Widgets │ │ ├── Assets │ │ ├── ADO.png │ │ ├── BlueBackground.png │ │ ├── Bug.png │ │ ├── ChangeRequest.png │ │ ├── Epic.png │ │ ├── Feature.png │ │ ├── Impediment.png │ │ ├── Issue.png │ │ ├── ProductBacklogItem.png │ │ ├── PullRequest.png │ │ ├── PullRequestApproved.png │ │ ├── PullRequestRejected.png │ │ ├── PullRequestReviewNotStarted.png │ │ ├── PullRequestWaiting.png │ │ ├── PullRequestsScreenshotDark.png │ │ ├── PullRequestsScreenshotLight.png │ │ ├── QueryResultScreenshotDark.png │ │ ├── QueryResultScreenshotLight.png │ │ ├── QueryTilesScreenshotDark.png │ │ ├── QueryTilesScreenshotLight.png │ │ ├── Requirement.png │ │ ├── Review.png │ │ ├── Risk.png │ │ ├── StatusBlue.png │ │ ├── StatusGray.png │ │ ├── StatusGreen.png │ │ ├── StatusOrange.png │ │ ├── StatusRed.png │ │ ├── Task.png │ │ ├── TestCase.png │ │ ├── TestPlan.png │ │ ├── TestSuite.png │ │ ├── UserStory.png │ │ ├── arrow.png │ │ ├── azureIcon.png │ │ └── screenshot.png │ │ ├── AzurePullRequestsBaseWidget.cs │ │ ├── AzurePullRequestsDeveloperWidget.cs │ │ ├── AzurePullRequestsRepositoryWidget.cs │ │ ├── AzureQueryListWidget.cs │ │ ├── AzureQueryTilesWidget.cs │ │ ├── AzureWidget.cs │ │ ├── Enums │ │ ├── WidgetAction.cs │ │ ├── WidgetActivityState.cs │ │ ├── WidgetDataState.cs │ │ └── WidgetPageState.cs │ │ ├── Guids.cs │ │ ├── IWidgetImplFactory.cs │ │ ├── Templates │ │ ├── AzureLoadingTemplate.json │ │ ├── AzurePullRequestsConfigurationTemplate.json │ │ ├── AzurePullRequestsTemplate.json │ │ ├── AzureQueryListConfigurationTemplate.json │ │ ├── AzureQueryListTemplate.json │ │ ├── AzureQueryTilesConfigurationTemplate.json │ │ ├── AzureQueryTilesTemplate.json │ │ └── AzureSignInTemplate.json │ │ ├── WidgetImpl.cs │ │ ├── WidgetImplFactory.cs │ │ ├── WidgetProvider.cs │ │ ├── WidgetProviderFactory.cs │ │ └── WidgetServer.cs ├── AzureExtensionServer │ ├── Assets │ │ ├── AppList.scale-100.png │ │ ├── AppList.scale-125.png │ │ ├── AppList.scale-150.png │ │ ├── AppList.scale-200.png │ │ ├── AppList.scale-400.png │ │ ├── AppList.targetsize-16.png │ │ ├── AppList.targetsize-16_altform-lightunplated.png │ │ ├── AppList.targetsize-16_altform-unplated.png │ │ ├── AppList.targetsize-20.png │ │ ├── AppList.targetsize-20_altform-lightunplated.png │ │ ├── AppList.targetsize-20_altform-unplated.png │ │ ├── AppList.targetsize-24.png │ │ ├── AppList.targetsize-24_altform-lightunplated.png │ │ ├── AppList.targetsize-24_altform-unplated.png │ │ ├── AppList.targetsize-256.png │ │ ├── AppList.targetsize-256_altform-lightunplated.png │ │ ├── AppList.targetsize-256_altform-unplated.png │ │ ├── AppList.targetsize-30.png │ │ ├── AppList.targetsize-30_altform-lightunplated.png │ │ ├── AppList.targetsize-30_altform-unplated.png │ │ ├── AppList.targetsize-32.png │ │ ├── AppList.targetsize-32_altform-lightunplated.png │ │ ├── AppList.targetsize-32_altform-unplated.png │ │ ├── AppList.targetsize-36.png │ │ ├── AppList.targetsize-36_altform-lightunplated.png │ │ ├── AppList.targetsize-36_altform-unplated.png │ │ ├── AppList.targetsize-40.png │ │ ├── AppList.targetsize-40_altform-lightunplated.png │ │ ├── AppList.targetsize-40_altform-unplated.png │ │ ├── AppList.targetsize-48.png │ │ ├── AppList.targetsize-48_altform-lightunplated.png │ │ ├── AppList.targetsize-48_altform-unplated.png │ │ ├── AppList.targetsize-56.png │ │ ├── AppList.targetsize-56_altform-lightunplated.png │ │ ├── AppList.targetsize-56_altform-unplated.png │ │ ├── AppList.targetsize-60.png │ │ ├── AppList.targetsize-60_altform-lightunplated.png │ │ ├── AppList.targetsize-60_altform-unplated.png │ │ ├── AppList.targetsize-64.png │ │ ├── AppList.targetsize-64_altform-lightunplated.png │ │ ├── AppList.targetsize-64_altform-unplated.png │ │ ├── AppList.targetsize-72.png │ │ ├── AppList.targetsize-72_altform-lightunplated.png │ │ ├── AppList.targetsize-72_altform-unplated.png │ │ ├── AppList.targetsize-80.png │ │ ├── AppList.targetsize-80_altform-lightunplated.png │ │ ├── AppList.targetsize-80_altform-unplated.png │ │ ├── AppList.targetsize-96.png │ │ ├── AppList.targetsize-96_altform-lightunplated.png │ │ ├── AppList.targetsize-96_altform-unplated.png │ │ ├── LargeTile.scale-100.png │ │ ├── LargeTile.scale-400.png │ │ ├── MedTile.scale-100.png │ │ ├── MedTile.scale-400.png │ │ ├── SmallTile.scale-100.png │ │ ├── SmallTile.scale-400.png │ │ ├── SplashScreen.scale-100.png │ │ ├── SplashScreen.scale-125.png │ │ ├── SplashScreen.scale-150.png │ │ ├── SplashScreen.scale-200.png │ │ ├── SplashScreen.scale-400.png │ │ ├── StoreDisplay-150.png │ │ ├── StoreDisplay-300.png │ │ ├── StoreDisplay-71.png │ │ ├── StoreLogo.scale-100.png │ │ ├── StoreLogo.scale-125.png │ │ ├── StoreLogo.scale-150.png │ │ ├── StoreLogo.scale-200.png │ │ ├── StoreLogo.scale-400.png │ │ ├── WideTile.scale-100.png │ │ └── WideTile.scale-400.png │ ├── AzureExtensionServer.csproj │ ├── Package-Can.appxmanifest │ ├── Package-Dev.appxmanifest │ ├── Package.appxmanifest │ ├── Program.cs │ ├── Properties │ │ ├── PublishProfiles │ │ │ ├── win10-arm64.pubxml │ │ │ ├── win10-x64.pubxml │ │ │ └── win10-x86.pubxml │ │ └── launchSettings.json │ ├── Strings │ │ └── en-us │ │ │ └── Resources.resw │ ├── app.manifest │ └── appsettings.json └── Telemetry │ ├── AzureExtension.Telemetry.csproj │ ├── ILogger.cs │ ├── LogLevel.cs │ ├── Logger.cs │ ├── LoggerFactory.cs │ └── TelemetryEventSource.cs └── test ├── AzureExtension ├── AzureExtension.Test.csproj ├── DataStore │ ├── DataManagerTests.cs │ ├── DataObjectTests.cs │ └── DataStoreTestsSetup.cs ├── DevBox │ ├── ArmTestTokenService.cs │ ├── DataTestTokenService.cs │ ├── DevBoxTests.cs │ ├── DevBoxTestsSetup.cs │ ├── EmptyDeveloperId.cs │ └── TimeSpanServiceMock.cs ├── DeveloperId │ ├── DeveloperIdProviderTests.cs │ ├── DeveloperIdTests.cs │ ├── DeveloperIdTestsSetup.cs │ └── Mocks │ │ ├── MockAuthenticationHelper.cs │ │ └── MockAuthenticationSettings.cs ├── Helpers │ ├── FileHelpers.cs │ ├── FileSystem.cs │ ├── TestOptions.cs │ └── TestSetupHelpers.cs ├── Initialize.cs ├── README.md ├── RepositoryProvider │ ├── Mocks │ │ └── MockRepository.cs │ ├── RepositoryProviderTests.cs │ └── RepositoryProviderTestsSetup.cs ├── TestContextSink │ ├── TestContextSink.cs │ └── TestContextSinkExtensions.cs ├── Usings.cs └── Widgets │ ├── Icons.cs │ ├── Validation.cs │ └── WidgetTestsSetup.cs ├── Console ├── Assets │ ├── LockScreenLogo.scale-200.png │ ├── SplashScreen.scale-200.png │ ├── Square150x150Logo.scale-200.png │ ├── Square44x44Logo.scale-200.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── StoreLogo.png │ └── Wide310x150Logo.scale-200.png ├── AzureExtension.TestConsole.csproj ├── Package.appxmanifest ├── Program.cs ├── Properties │ └── launchSettings.json ├── README.md ├── app.manifest └── appsettings.json └── scripts ├── CleanDevHome.ps1 └── CleanWidgets.ps1 /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=crlf 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Documentation_Issue.yml: -------------------------------------------------------------------------------- 1 | name: "Documentation issue 📄" 2 | description: Report issues on our documentation 3 | labels: 4 | - Issue-Docs 5 | body: 6 | - type: textarea 7 | attributes: 8 | label: Provide a description of requested docs changes 9 | placeholder: Briefly describe which document needs to be corrected and why. 10 | validations: 11 | required: true -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_Request.yml: -------------------------------------------------------------------------------- 1 | name: "Suggest a new feature or improvement 🚀" 2 | description: Suggest a new feature or improvement (this does not mean you have to implement 3 | it) 4 | labels: 5 | - Issue-Feature 6 | body: 7 | - id: description 8 | type: textarea 9 | attributes: 10 | label: Suggested new feature or improvement 11 | placeholder: Tell us about the new feature or improvement you'd like to see. 12 | validations: 13 | required: true 14 | 15 | - id: scenario 16 | type: textarea 17 | attributes: 18 | label: Scenario 19 | placeholder: How could this new feature be used? Feel free to provide examples. 20 | validations: 21 | required: true 22 | 23 | - id: supportinginfo 24 | type: textarea 25 | attributes: 26 | label: Additional details 27 | placeholder: Enter more info or links to give us more details. 28 | validations: 29 | required: false 30 | 31 | - type: markdown 32 | attributes: 33 | value: Please limit one request per issue. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Translation_Issue.yml: -------------------------------------------------------------------------------- 1 | name: "Report a translation problem 🌐" 2 | description: Report incorrect translations 3 | labels: 4 | - Issue-Translation 5 | 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: Please make sure to [search for existing issues](https://github.com/microsoft/devhomeazureextension/issues) before filing a new one! 10 | 11 | - id: devhomeversion 12 | type: input 13 | attributes: 14 | label: Dev Home version 15 | placeholder: "0.1.3651.0" 16 | description: 17 | validations: 18 | required: false 19 | 20 | - id: adoextensionversion 21 | type: input 22 | attributes: 23 | label: Azure Extension (for Dev Home) version 24 | placeholder: "0.1.3651.0" 25 | description: 26 | validations: 27 | required: false 28 | 29 | - id: languageaffected 30 | type: input 31 | attributes: 32 | label: 🌐 Language 33 | placeholder: "Example: German" 34 | validations: 35 | required: true 36 | 37 | - type: textarea 38 | attributes: 39 | label: ❌ Actual phrase(s) 40 | placeholder: What is there? Please include a screenshot - it's very helpful to us! 41 | validations: 42 | required: true 43 | 44 | - type: textarea 45 | attributes: 46 | label: ✔️ Expected phrase(s) 47 | placeholder: What phrase was expected? 48 | validations: 49 | required: false 50 | 51 | - type: textarea 52 | attributes: 53 | label: Why is the current translation wrong 54 | placeholder: Why do you feel this translation is incorrect? 55 | validations: 56 | required: true -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | 3 | contact_links: 4 | - name: Microsoft Security Response Center 🔐 5 | url: https://msrc.microsoft.com/create-report 6 | about: Please report security vulnerabilities here. 7 | -------------------------------------------------------------------------------- /.github/policies/labelManagement.issueOpened.yml: -------------------------------------------------------------------------------- 1 | id: labelManagement.issueOpened 2 | name: GitOps.PullRequestIssueManagement 3 | description: GitOps.PullRequestIssueManagement primitive 4 | owner: 5 | resource: repository 6 | disabled: false 7 | where: 8 | configuration: 9 | resourceManagementConfiguration: 10 | eventResponderTasks: 11 | - description: Add Needs-Triage to new issues 12 | if: 13 | - payloadType: Issues 14 | - isAction: 15 | action: Opened 16 | then: 17 | - addLabel: 18 | label: Needs-Triage 19 | onFailure: 20 | onSuccess: 21 | -------------------------------------------------------------------------------- /.github/policies/labelManagement.issueUpdated.yml: -------------------------------------------------------------------------------- 1 | id: labelManagement.issueUpdated 2 | name: GitOps.PullRequestIssueManagement 3 | description: GitOps.PullRequestIssueManagement primitive 4 | owner: 5 | resource: repository 6 | disabled: false 7 | where: 8 | configuration: 9 | resourceManagementConfiguration: 10 | eventResponderTasks: 11 | - description: >- 12 | If an author responds to an issue which needs author feedback 13 | * Remove the Needs-Author-Feedback Label 14 | * Add the Needs-Team-Response 15 | if: 16 | - payloadType: Issue_Comment 17 | - isAction: 18 | action: Created 19 | - isActivitySender: 20 | issueAuthor: True 21 | - hasLabel: 22 | label: Needs-Author-Feedback 23 | - isOpen 24 | then: 25 | - removeLabel: 26 | label: Needs-Author-Feedback 27 | - addLabel: 28 | label: Needs-Team-Response 29 | - description: Remove "Status-No recent activity" when a pull request or issue is updated 30 | if: 31 | - payloadType: Issue_Comment 32 | - hasLabel: 33 | label: Status-No recent activity 34 | then: 35 | - removeLabel: 36 | label: Status-No recent activity 37 | - description: Clean email replies on every comment 38 | if: 39 | - payloadType: Issue_Comment 40 | then: 41 | - cleanEmailReply 42 | - description: Add In-PR when an issue has a linked PR that will close it 43 | if: 44 | - payloadType: Pull_Request 45 | then: 46 | - inPrLabel: 47 | label: In-PR 48 | onFailure: 49 | onSuccess: 50 | -------------------------------------------------------------------------------- /.github/policies/scheduledSearch.closeNoRecentActivity.yml: -------------------------------------------------------------------------------- 1 | id: scheduledSearch.closeNoRecentActivity 2 | name: GitOps.PullRequestIssueManagement 3 | description: Closes issues that are inactive 4 | owner: 5 | resource: repository 6 | disabled: false 7 | where: 8 | configuration: 9 | resourceManagementConfiguration: 10 | scheduledSearches: 11 | - description: >- 12 | Search for Issues where - 13 | * Issue is Open 14 | * Issue has the label Needs-Author-Feedback 15 | * Issue has the label Status-No recent activity 16 | * Issue does not have the label Issue-Feature 17 | * Has not had activity in the last 5 days 18 | Then - 19 | * Close the Issue 20 | frequencies: 21 | - hourly: 22 | hour: 6 23 | filters: 24 | - isIssue 25 | - isOpen 26 | - hasLabel: 27 | label: Needs-Author-Feedback 28 | - hasLabel: 29 | label: Status-No recent activity 30 | - isNotLabeledWith: 31 | label: Issue-Feature 32 | - noActivitySince: 33 | days: 5 34 | actions: 35 | - closeIssue 36 | onFailure: 37 | onSuccess: 38 | -------------------------------------------------------------------------------- /.github/policies/scheduledSearch.markNoRecentActivity.yml: -------------------------------------------------------------------------------- 1 | id: scheduledSearch.markNoRecentActivity 2 | name: GitOps.PullRequestIssueManagement 3 | description: Marks issues that are inactive 4 | owner: 5 | resource: repository 6 | disabled: false 7 | where: 8 | configuration: 9 | resourceManagementConfiguration: 10 | scheduledSearches: 11 | - description: >- 12 | Search for Issues where - 13 | * Issue is Open 14 | * Issue has the label Needs-Author-Feedback 15 | * Issue does not have the label Status-No recent activity 16 | * Issue does not have the label Issue-Feature 17 | * Has not had activity in the last 5 days 18 | Then - 19 | * Mark the issue as Status-No recent activity 20 | frequencies: 21 | - hourly: 22 | hour: 6 23 | filters: 24 | - isIssue 25 | - isOpen 26 | - hasLabel: 27 | label: Needs-Author-Feedback 28 | - noActivitySince: 29 | days: 5 30 | - isNotLabeledWith: 31 | label: Status-No recent activity 32 | - isNotLabeledWith: 33 | label: Issue-Feature 34 | actions: 35 | - addLabel: 36 | label: Status-No recent activity 37 | - addReply: 38 | reply: This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **5 days**. It will be closed if no further activity occurs **within 5 days of this comment**. 39 | onFailure: 40 | onSuccess: 41 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Summary of the pull request 2 | 3 | ## References and relevant issues 4 | 5 | ## Detailed description of the pull request / Additional comments 6 | 7 | ## Validation steps performed 8 | 9 | ## PR checklist 10 | - [ ] Closes #xxx 11 | - [ ] Tests added/passed 12 | - [ ] Documentation updated 13 | -------------------------------------------------------------------------------- /.vsconfig: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "components": [ 4 | "Microsoft.Component.MSBuild", 5 | "Microsoft.NetCore.Component.Runtime.6.0", 6 | "Microsoft.NetCore.Component.SDK", 7 | "Microsoft.VisualStudio.Component.ManagedDesktop.Core", 8 | "Microsoft.VisualStudio.Component.ManagedDesktop.Prerequisites", 9 | "Microsoft.VisualStudio.Component.NuGet", 10 | "Microsoft.VisualStudio.Component.Windows10SDK.19041", 11 | "Microsoft.VisualStudio.Component.Windows10SDK", 12 | "Microsoft.VisualStudio.ComponentGroup.MSIX.Packaging", 13 | "Microsoft.VisualStudio.ComponentGroup.WindowsAppSDK.Cs", 14 | "Microsoft.VisualStudio.Workload.ManagedDesktop" 15 | ] 16 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | ## How to file issues and get help 4 | 5 | This project uses [GitHub issues][gh-issue] to [track bugs][gh-bug] and [feature requests][gh-feature]. Please search the existing issues before filing new issues to avoid duplicates. For new topics, file your bug or feature request as a new issue. 6 | 7 | For help and questions about using this project, please look at the [docs site for Dev Home Azure Extension][docs] and our [Contributor's Guide][contributor] if you want to work on Dev Home Azure Extension. 8 | 9 | ## Microsoft Support Policy 10 | 11 | Support for Dev Home Azure Extension is limited to the resources listed above. 12 | 13 | [gh-issue]: https://github.com/microsoft/devhomeazureextension/issues/new/choose 14 | [gh-bug]: https://github.com/microsoft/devhomeazureextension/issues/new?assignees=&labels=Issue-Bug&projects=&template=Bug_Report.yml 15 | [gh-feature]: https://github.com/microsoft/devhomeazureextension/issues/new?assignees=&labels=Issue-Bug&projects=&template=Feature_Request.yml 16 | [docs]: https://docs.microsoft.com/windows/devhomeazureextension 17 | [contributor]: https://github.com/microsoft/devhomeazureextension/blob/main/CONTRIBUTING.md 18 | -------------------------------------------------------------------------------- /TestingScenarios.md: -------------------------------------------------------------------------------- 1 | ## Testing Scenarios 2 | 3 | These are the testing scenarios that need to be validated before shipping a new release. When an automated test is added, please remove it from the below lists. 4 | 5 | ### Widgets 6 | 7 | 1. For each widget: user can configure the widget immediately after first pin 8 | 1. For each widget: user can customize (reconfigure) the widget after it was initially configured 9 | 1. For each widget that supports customization: can be customized and persist after restart 10 | 1. Widgets have correct data 11 | 1. Widgets are adequately performant 12 | 1. Notificaitons can be enabled/disabled in Dev Home settings 13 | 1. Notifications are displayed 14 | 15 | ### Clone repositories 16 | 17 | 1. User can log in and get the list of repositories 18 | -------------------------------------------------------------------------------- /ToolingVersions.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | net8.0-windows10.0.22000.0 6 | 10.0.19041.0 7 | 10.0.19041.0 8 | 9 | -------------------------------------------------------------------------------- /build/Build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | powershell -ExecutionPolicy Unrestricted -NoLogo -NoProfile -File %~dp0\scripts\Build.ps1 %* 4 | 5 | exit /b %ERRORLEVEL% -------------------------------------------------------------------------------- /build/SyncMirror-Steps.yml: -------------------------------------------------------------------------------- 1 | # This yml template is use to facilitate syncing public repositories to private mirrored repository. 2 | # These steps must be run on the target repository that is being synced. 3 | 4 | # Requirements: 5 | # The pipeline agent that runs this must have "Contribute" permissions on the target repository. 6 | 7 | parameters: 8 | - name: SourceRepository 9 | type: string 10 | default: "" 11 | - name: SourceBranch 12 | type: string 13 | default: "" 14 | - name: TargetBranch 15 | type: string 16 | default: "" 17 | 18 | steps: 19 | - checkout: self 20 | persistCredentials: true 21 | 22 | - task: powershell@2 23 | inputs: 24 | targetType: 'inline' 25 | script: | 26 | Write-Host "Sourcebranch " + "${{ parameters.SourceBranch }}" 27 | Write-Host "TargetBranch " + "${{ parameters.TargetBranch }}" 28 | 29 | $repo = "${{ parameters.SourceRepository }}" 30 | git remote add mirror $repo 31 | git remote 32 | 33 | $target = "${{ parameters.TargetBranch }}" 34 | git fetch origin $target 35 | git checkout $target 36 | git pull origin $target 37 | 38 | $source = "${{ parameters.SourceBranch }}" 39 | git fetch mirror $source 40 | git pull mirror $source 41 | 42 | - task: CmdLine@2 43 | inputs: 44 | script: | 45 | git push 46 | -------------------------------------------------------------------------------- /build/SyncMirroredRepository.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | DisableDockerDetector: true 3 | cfsNpmWarnLevel: 'warn' 4 | cfsCargoWarnLevel: 'warn' 5 | 6 | resources: 7 | repositories: 8 | - repository: m365Pipelines 9 | type: git 10 | name: 1ESPipelineTemplates/M365GPT 11 | ref: refs/tags/release 12 | extends: 13 | template: v1/M365.Official.PipelineTemplate.yml@m365Pipelines 14 | parameters: 15 | sdl: 16 | roslyn: 17 | enabled: true 18 | arrow: 19 | serviceConnection: DevHome Build VM Generation 20 | pool: 21 | name: Azure-Pipelines-1ESPT-ExDShared 22 | image: windows-2022 23 | os: windows 24 | customBuildTags: 25 | - ES365AIMigrationTooling 26 | stages: 27 | - stage: SyncMirror 28 | jobs: 29 | - job: SyncMirror 30 | dependsOn: [] 31 | steps: 32 | - task: AzureKeyVault@1 33 | inputs: 34 | azureSubscription: 'DevHomeAzureServiceConnection' 35 | KeyVaultName: 'DevHomeKeyVault' 36 | SecretsFilter: 'GitHubPAT' 37 | RunAsPreJob: false 38 | 39 | - template: /build/SyncMirror-Steps.yml@self 40 | parameters: 41 | SourceRepository: "https://$(GitHubPAT)@github.com/microsoft/DevHomeAzureExtension.git" 42 | TargetBranch: "$(SourceToTargetBranch)" 43 | SourceBranch: "$(SourceToTargetBranch)" 44 | -------------------------------------------------------------------------------- /build/Test.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | powershell -ExecutionPolicy Unrestricted -NoLogo -NoProfile -File %~dp0\scripts\Test.ps1 %* 4 | 5 | exit /b %ERRORLEVEL% -------------------------------------------------------------------------------- /build/TriggerReleaseBuild.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | - release 3 | 4 | resources: 5 | repositories: 6 | - repository: templates_onebranch 7 | type: git 8 | name: OneBranch.Pipelines/GovernedTemplates 9 | ref: refs/heads/main 10 | - repository: m365Pipelines 11 | type: git 12 | name: 1ESPipelineTemplates/M365GPT 13 | ref: refs/tags/release 14 | 15 | extends: 16 | template: v1/M365.Official.PipelineTemplate.yml@m365Pipelines 17 | parameters: 18 | sdl: 19 | roslyn: 20 | enabled: true 21 | arrow: 22 | serviceConnection: DevHome Build VM Generation 23 | baseline: 24 | baselineFile: $(Build.SourcesDirectory)\guardian\SDL\.gdnbaselines 25 | pool: 26 | name: Azure-Pipelines-1ESPT-ExDShared 27 | image: windows-2022 28 | os: windows 29 | customBuildTags: 30 | - ES365AIMigrationTooling 31 | stages: 32 | - stage: Trigger_Build 33 | dependsOn: [] 34 | jobs: 35 | - job: Trigger_Build 36 | steps: 37 | - script: echo Triggering ADO Build 38 | displayName: 'Triggering ADO Build' -------------------------------------------------------------------------------- /build/TriggerStagingBuild.yml: -------------------------------------------------------------------------------- 1 | trigger: 2 | - staging 3 | 4 | resources: 5 | repositories: 6 | - repository: templates_onebranch 7 | type: git 8 | name: OneBranch.Pipelines/GovernedTemplates 9 | ref: refs/heads/main 10 | - repository: m365Pipelines 11 | type: git 12 | name: 1ESPipelineTemplates/M365GPT 13 | ref: refs/tags/release 14 | 15 | extends: 16 | template: v1/M365.Official.PipelineTemplate.yml@m365Pipelines 17 | parameters: 18 | sdl: 19 | roslyn: 20 | enabled: true 21 | arrow: 22 | serviceConnection: DevHome Build VM Generation 23 | baseline: 24 | baselineFile: $(Build.SourcesDirectory)\guardian\SDL\.gdnbaselines 25 | pool: 26 | name: Azure-Pipelines-1ESPT-ExDShared 27 | image: windows-2022 28 | os: windows 29 | customBuildTags: 30 | - ES365AIMigrationTooling 31 | stages: 32 | - stage: Trigger_Build 33 | dependsOn: [] 34 | jobs: 35 | - job: Trigger_Build 36 | steps: 37 | - script: echo Triggering ADO Build 38 | displayName: 'Triggering ADO Build' -------------------------------------------------------------------------------- /build/nuget.config.internal: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /build/scripts/Create-AppxBundle.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [Parameter(Mandatory, 3 | HelpMessage="Base name for input .appx files")] 4 | [string] 5 | $ProjectName, 6 | 7 | [Parameter(Mandatory, 8 | HelpMessage="Appx Bundle Version")] 9 | [version] 10 | $BundleVersion, 11 | 12 | [Parameter(Mandatory, 13 | HelpMessage="Path under which to locate appx/msix files")] 14 | [string] 15 | $InputPath, 16 | 17 | [Parameter(Mandatory, 18 | HelpMessage="Output Path")] 19 | [string] 20 | $OutputPath, 21 | 22 | [Parameter(HelpMessage="Path to makeappx.exe")] 23 | [ValidateScript({Test-Path $_ -Type Leaf})] 24 | [string] 25 | $MakeAppxPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x86\MakeAppx.exe" 26 | ) 27 | 28 | If ($null -Eq (Get-Item $MakeAppxPath -EA:SilentlyContinue)) { 29 | Write-Error "Could not find MakeAppx.exe at `"$MakeAppxPath`".`nMake sure that -MakeAppxPath points to a valid SDK." 30 | Exit 1 31 | } 32 | 33 | # Enumerates a set of appx files beginning with a project name 34 | # and generates a temporary file containing a bundle content map. 35 | Function Create-AppxBundleMapping { 36 | Param( 37 | [Parameter(Mandatory)] 38 | [string] 39 | $InputPath, 40 | 41 | [Parameter(Mandatory)] 42 | [string] 43 | $ProjectName 44 | ) 45 | 46 | $lines = @("[Files]") 47 | Get-ChildItem -Path:$InputPath -Recurse -Filter:*$ProjectName* -Include *.appx, *.msix | % { 48 | $lines += ("`"{0}`" `"{1}`"" -f ($_.FullName, $_.Name)) 49 | } 50 | 51 | $outputFile = New-TemporaryFile 52 | $lines | Out-File -Encoding:ASCII $outputFile 53 | $outputFile 54 | } 55 | 56 | $NewMapping = Create-AppxBundleMapping -InputPath:$InputPath -ProjectName:$ProjectName 57 | 58 | & $MakeAppxPath bundle /v /bv $BundleVersion.ToString() /f $NewMapping.FullName /p $OutputPath 59 | -------------------------------------------------------------------------------- /build/scripts/CreateBuildInfo.ps1: -------------------------------------------------------------------------------- 1 | [CmdLetBinding()] 2 | Param( 3 | [string]$Version, 4 | [bool]$IsAzurePipelineBuild = $false 5 | ) 6 | 7 | $Major = "0" 8 | $Minor = "14" 9 | $Patch = "99" # default to 99 for local builds 10 | 11 | $versionSplit = $Version.Split("."); 12 | if ($versionSplit.length -gt 3) { $Build = $versionSplit[3] } 13 | if ($versionSplit.length -gt 2) { $Elapsed = $versionSplit[2] } 14 | if ($versionSplit.length -gt 1) { 15 | if ($versionSplit[1].length -gt 2) { 16 | $Minor = $versionSplit[1].SubString(0,$versionSplit[1].length-2); 17 | $Patch = $versionSplit[1].SubString($versionSplit[1].length-2, 2); 18 | } else { 19 | $Minor = $versionSplit[1] 20 | } 21 | } 22 | if ($versionSplit.length -gt 0) { $Major = $versionSplit[0] } 23 | 24 | # Compute/Verify the MSIX version 25 | # 26 | # MSIX Version = M.NPP.E.B 27 | # where 28 | # M = Major (max <= 65535) 29 | # N = Minor (max <= 654) 30 | # P = Patch (max <= 99) 31 | # E = Elapsed (max <= 65535) 32 | # B = Build (max <= 65535) 33 | # 34 | # NOTE: Elapsed is the number of days since the epoch (Jan'1, 2023). 35 | # NOTE: Make sure to compute Elapsed using Universal Time (UTC). 36 | # 37 | # NOTE: Build is computed as HHMM i.e. the time (hour and minute) when building locally, 0 otherwise. 38 | # 39 | $epoch = (Get-Date -Year 2023 -Month 1 -Day 1).ToUniversalTime() 40 | $now = (Get-Date).ToUniversalTime() 41 | if ([string]::IsNullOrWhiteSpace($Elapsed)) { 42 | $Elapsed = $(New-Timespan -Start $epoch -End $now).Days 43 | } 44 | # 45 | $version_h = $now.Hour 46 | $version_m = $now.Minute 47 | if (-not($IsAzurePipelineBuild) -And [string]::IsNullOrWhiteSpace($Build)) { 48 | $Build = ($version_h * 100 + $version_m).ToString() 49 | } 50 | # 51 | $version_dotquad = [int[]]($Major, ($Minor + $Patch), $Elapsed, $Build) 52 | return ($version_dotquad -Join ".") 53 | -------------------------------------------------------------------------------- /build/scripts/Unstub.ps1: -------------------------------------------------------------------------------- 1 | # This script unstubs the telemetry at build time and replaces the stubbed file with a reference internal nuget package 2 | 3 | Remove-Item "$($PSScriptRoot)\..\..\src\Telemetry\TelemetryEventSource.cs" 4 | 5 | $projFile = "$($PSScriptRoot)\..\..\src\Telemetry\AzureExtension.Telemetry.csproj" 6 | $projFileContent = Get-Content $projFile -Encoding UTF8 -Raw 7 | 8 | if ($projFileContent.Contains('Microsoft.Telemetry.Inbox.Managed')) { 9 | Write-Output "Project file already contains a reference to the internal package." 10 | return; 11 | } 12 | 13 | $xml = [System.Xml.XmlDocument]$projFileContent 14 | $xml.PreserveWhitespace = $true 15 | $itemGroup = $xml.CreateElement("ItemGroup") 16 | $packageRef = $xml.CreateElement("PackageReference") 17 | $packageRef.SetAttribute("Include", "Microsoft.Telemetry.Inbox.Managed") 18 | $packageRef.SetAttribute("Version", "10.0.25148.1001-220626-1600.rs-fun-deploy-dev5") 19 | $itemGroup.AppendChild($packageRef) 20 | $xml.Project.AppendChild($itemGroup) 21 | $xml.Save($projFile) -------------------------------------------------------------------------------- /build/store/canary/media/de-DE/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/de-DE/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/canary/media/de-DE/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/de-DE/azure-repo.png -------------------------------------------------------------------------------- /build/store/canary/media/en-us/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/en-us/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/canary/media/en-us/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/en-us/azure-repo.png -------------------------------------------------------------------------------- /build/store/canary/media/es-ES/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/es-ES/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/canary/media/es-ES/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/es-ES/azure-repo.png -------------------------------------------------------------------------------- /build/store/canary/media/fr-FR/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/fr-FR/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/canary/media/fr-FR/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/fr-FR/azure-repo.png -------------------------------------------------------------------------------- /build/store/canary/media/it-IT/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/it-IT/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/canary/media/it-IT/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/it-IT/azure-repo.png -------------------------------------------------------------------------------- /build/store/canary/media/ja-JP/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/ja-JP/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/canary/media/ja-JP/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/ja-JP/azure-repo.png -------------------------------------------------------------------------------- /build/store/canary/media/ko-KR/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/ko-KR/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/canary/media/ko-KR/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/ko-KR/azure-repo.png -------------------------------------------------------------------------------- /build/store/canary/media/pt-BR/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/pt-BR/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/canary/media/pt-BR/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/pt-BR/azure-repo.png -------------------------------------------------------------------------------- /build/store/canary/media/ru-RU/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/ru-RU/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/canary/media/ru-RU/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/ru-RU/azure-repo.png -------------------------------------------------------------------------------- /build/store/canary/media/zh-CN/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/zh-CN/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/canary/media/zh-CN/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/zh-CN/azure-repo.png -------------------------------------------------------------------------------- /build/store/canary/media/zh-TW/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/zh-TW/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/canary/media/zh-TW/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/canary/media/zh-TW/azure-repo.png -------------------------------------------------------------------------------- /build/store/preview/media/de-DE/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/de-DE/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/preview/media/de-DE/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/de-DE/azure-repo.png -------------------------------------------------------------------------------- /build/store/preview/media/en-us/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/en-us/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/preview/media/en-us/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/en-us/azure-repo.png -------------------------------------------------------------------------------- /build/store/preview/media/es-ES/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/es-ES/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/preview/media/es-ES/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/es-ES/azure-repo.png -------------------------------------------------------------------------------- /build/store/preview/media/fr-FR/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/fr-FR/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/preview/media/fr-FR/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/fr-FR/azure-repo.png -------------------------------------------------------------------------------- /build/store/preview/media/it-IT/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/it-IT/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/preview/media/it-IT/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/it-IT/azure-repo.png -------------------------------------------------------------------------------- /build/store/preview/media/ja-JP/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/ja-JP/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/preview/media/ja-JP/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/ja-JP/azure-repo.png -------------------------------------------------------------------------------- /build/store/preview/media/ko-KR/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/ko-KR/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/preview/media/ko-KR/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/ko-KR/azure-repo.png -------------------------------------------------------------------------------- /build/store/preview/media/pt-BR/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/pt-BR/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/preview/media/pt-BR/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/pt-BR/azure-repo.png -------------------------------------------------------------------------------- /build/store/preview/media/ru-RU/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/ru-RU/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/preview/media/ru-RU/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/ru-RU/azure-repo.png -------------------------------------------------------------------------------- /build/store/preview/media/zh-CN/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/zh-CN/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/preview/media/zh-CN/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/zh-CN/azure-repo.png -------------------------------------------------------------------------------- /build/store/preview/media/zh-TW/azure-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/zh-TW/azure-dashboard.png -------------------------------------------------------------------------------- /build/store/preview/media/zh-TW/azure-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/store/preview/media/zh-TW/azure-repo.png -------------------------------------------------------------------------------- /build/surrogate.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/build/surrogate.xml -------------------------------------------------------------------------------- /build/templates/EsrpSigning-Steps.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: displayName 3 | type: string 4 | default: ESRP Code Signing 5 | - name: inputs 6 | type: object 7 | default: {} 8 | 9 | steps: 10 | - task: EsrpCodeSigning@5 11 | displayName: ${{ parameters.displayName }} 12 | inputs: 13 | ConnectedServiceName: $(EsrpConnectedServiceName) 14 | AppRegistrationClientId: $(EsrpAppRegistrationClientId) 15 | AppRegistrationTenantId: $(EsrpAppRegistrationTenantId) 16 | AuthAKVName: $(EsrpAuthAKVName) 17 | AuthCertName: $(EsrpAuthCertName) 18 | AuthSignCertName: $(EsrpAuthSignCertName) 19 | SessionTimeout: '60' 20 | MaxConcurrency: '50' 21 | MaxRetryAttempts: '5' 22 | ${{ insert }}: ${{ parameters.inputs }} 23 | -------------------------------------------------------------------------------- /codeAnalysis/StyleCop.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", 3 | "settings": { 4 | "documentationRules": { 5 | "companyName": "Microsoft Corporation", 6 | "copyrightText": "Copyright (c) Microsoft Corporation.\r\nLicensed under the MIT License.", 7 | "xmlHeader": false, 8 | "headerDecoration": "", 9 | "fileNamingConvention": "metadata", 10 | "documentInterfaces": false, 11 | "documentExposedElements": false, 12 | "documentInternalElements": false 13 | }, 14 | "layoutRules": { 15 | "newlineAtEndOfFile": "require" 16 | }, 17 | "orderingRules": { 18 | "usingDirectivesPlacement": "outsideNamespace" 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /codeAnalysis/format_sources.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [switch]$all = $false 3 | ) 4 | 5 | if(!(Get-Command "git" -ErrorAction SilentlyContinue)) { 6 | throw "You need to have a git in path to be able to format only the dirty files!" 7 | } 8 | 9 | $clangFormat = "clang-format.exe" 10 | if(!(Get-Command $clangFormat -ErrorAction SilentlyContinue)) { 11 | Write-Information "Can't find clang-format.exe in %PATH%, trying to use %VCINSTALLDIR%..." 12 | $clangFormat="$env:VCINSTALLDIR\Tools\Llvm\bin\clang-format.exe" 13 | if(!(Test-Path -Path $clangFormat -PathType leaf)) { 14 | throw "Can't find clang-format.exe executable. Make sure you either have it in %PATH% or run this script from vcvars.bat!" 15 | } 16 | } 17 | 18 | $sourceExtensions = New-Object System.Collections.Generic.HashSet[string] 19 | $sourceExtensions.Add(".cpp") | Out-Null 20 | $sourceExtensions.Add(".h") | Out-Null 21 | 22 | function Get-Dirty-Files-From-Git() { 23 | $repo_root = & git rev-parse --show-toplevel 24 | 25 | $staged = & git diff --name-only --diff-filter=d --cached | % { $repo_root + "/" + $_ } 26 | $unstaged = & git ls-files -m 27 | $untracked = & git ls-files --others --exclude-standard 28 | $result = New-Object System.Collections.Generic.List[string] 29 | $staged, $unstaged, $untracked | % { 30 | $_.Split(" ") | 31 | where {Test-Path $_ -PathType Leaf} | 32 | where {$sourceExtensions.Contains((Get-Item $_).Extension)} | 33 | foreach {$result.Add($_)} 34 | } 35 | return $result 36 | } 37 | 38 | if($all) { 39 | $filesToFormat = 40 | Get-ChildItem -Recurse -File ..\src | 41 | Resolve-Path -Relative | 42 | where { (Get-Item $_).Directory -notmatch "(Generated Files)|node_modules" -And 43 | $sourceExtensions.Contains((Get-Item $_).Extension)} 44 | } 45 | else { 46 | $filesToFormat = Get-Dirty-Files-From-Git 47 | } 48 | 49 | $filesToFormat | % { 50 | Write-Host "Formatting $_" 51 | & $clangFormat -i -style=file -fallback-style=none $_ 2>&1 52 | } 53 | 54 | Write-Host "Done!" -------------------------------------------------------------------------------- /docs/specs/spec-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | author: / 3 | created on: 4 | last updated: 5 | issue id: 6 | --- 7 | 8 | # Spec Title 9 | 10 | ## Abstract 11 | 12 | [comment]: # Outline what this spec describes 13 | 14 | ## Inspiration 15 | 16 | [comment]: # What were the drivers/inspiration behind the creation of this spec. 17 | 18 | ## Solution Design 19 | 20 | [comment]: # Outline the design of the solution. Feel free to include ASCII-art diagrams, etc. 21 | 22 | ## UI/UX Design 23 | 24 | [comment]: # What will this fix/feature look like? How will it affect the end user? 25 | 26 | ## Capabilities 27 | 28 | [comment]: # Discuss how the proposed fixes/features impact the following key considerations: 29 | 30 | ### Accessibility 31 | 32 | [comment]: # How will the proposed change impact accessibility for users of screen readers, assistive input devices, etc. 33 | 34 | ### Security 35 | 36 | [comment]: # How will the proposed change impact security? 37 | 38 | ### Reliability 39 | 40 | [comment]: # Will the proposed change improve reliability? If not, why make the change? 41 | 42 | ### Compatibility 43 | 44 | [comment]: # Will the proposed change break existing code/behaviors? If so, how, and is the breaking change "worth it"? 45 | 46 | ### Performance, Power, and Efficiency 47 | 48 | ## Potential Issues 49 | 50 | [comment]: # What are some of the things that might cause problems with the fixes/features proposed? Consider how the user might be negatively impacted. 51 | 52 | ## Future considerations 53 | 54 | [comment]: # What are some of the things that the fixes/features might unlock in the future? Does the implementation of this spec enable scenarios? 55 | 56 | ## Resources 57 | 58 | [comment]: # Be sure to add links to references, resources, footnotes, etc. -------------------------------------------------------------------------------- /docs/style.md: -------------------------------------------------------------------------------- 1 | # Coding Style 2 | 3 | ## Philosophy 4 | 5 | 1. If it's inserting something into the existing classes/functions, try to follow the existing style as closely as possible. 6 | 1. If it's brand new code or refactoring a complete class or area of the code, please follow as Modern C# of a style as you can and reference the [.NET Engineering Guidelines](https://github.com/dotnet/aspnetcore/wiki/Engineering-guidelines) as much as you possibly can. 7 | 8 | ## Formatting 9 | 10 | - We use [`.clang-format`](/.clang-format) style file to enable automatic code formatting. You can [easily format source files from Visual Studio](https://devblogs.microsoft.com/cppblog/clangformat-support-in-visual-studio-2017-15-7-preview-1/). For example, `CTRL+K CTRL+D` formats the current document. 11 | - If you prefer another text editor or have ClangFormat disabled in Visual Studio, you could invoke [`format_sources`](/codeAnalysis/format_sources.ps1) PowerShell script from command line. It gets a list of all currently modified files from `git` and invokes clang-format on them. 12 | Please note that you should also have `clang-format.exe` in `%PATH%` for it to work. The script can infer the path of `clang-format.exe` version which is shipped with Visual Studio at `%VCINSTALLDIR%\Tools\Llvm\bin\`, if you launch it from the _Native Tools Command Prompt for VS_. 13 | - CI doesn't enforce code formatting yet, since we're gradually applying code formatting to the codebase, but please adhere to our formatting style for any new code. 14 | -------------------------------------------------------------------------------- /exclusion.dic: -------------------------------------------------------------------------------- 1 | devhome 2 | Impl 3 | Msal 4 | visualstudio 5 | vssps 6 | setx 7 | oauth 8 | pullrequest 9 | Sqls 10 | microsoft 11 | brokerplugin 12 | Entra 13 | riid 14 | enums 15 | Stdout 16 | foobar 17 | msix 18 | yaml 19 | Quickstart 20 | Tensorflow 21 | vscode 22 | codespace 23 | codespaces 24 | dhlog 25 | appsettings 26 | deserializer 27 | winget 28 | csharp 29 | -------------------------------------------------------------------------------- /nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/AzureExtension/Assets/AzureExtensionDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Assets/AzureExtensionDark.png -------------------------------------------------------------------------------- /src/AzureExtension/Assets/DevBoxProvider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Assets/DevBoxProvider.png -------------------------------------------------------------------------------- /src/AzureExtension/Assets/DevBoxThumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Assets/DevBoxThumbnail.png -------------------------------------------------------------------------------- /src/AzureExtension/Client/AzureHostType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Client; 5 | 6 | public enum AzureHostType 7 | { 8 | Unknown, 9 | NotHosted, 10 | Legacy, 11 | Modern, 12 | } 13 | -------------------------------------------------------------------------------- /src/AzureExtension/Client/ConnectionResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.WebApi; 5 | 6 | namespace DevHomeAzureExtension.Client; 7 | 8 | public class ConnectionResult 9 | { 10 | public ResultType Result { get; private set; } = ResultType.Unknown; 11 | 12 | public ErrorType Error { get; private set; } = ErrorType.Unknown; 13 | 14 | public Exception? Exception 15 | { 16 | get; private set; 17 | } 18 | 19 | public Uri? UriValue 20 | { 21 | get; private set; 22 | } 23 | 24 | public VssHttpClientBase? T 25 | { 26 | get; private set; 27 | } 28 | 29 | public VssConnection? Connection 30 | { 31 | get; private set; 32 | } 33 | 34 | public bool AttemptSilentReauthorization 35 | { 36 | get; 37 | set; 38 | } 39 | 40 | public ConnectionResult(Uri? uri, VssHttpClientBase? type, VssConnection? connection) 41 | { 42 | Result = ResultType.Success; 43 | Error = ErrorType.None; 44 | UriValue = uri; 45 | T = type; 46 | Connection = connection; 47 | } 48 | 49 | public ConnectionResult(ResultType result, ErrorType error, bool attemptSilentReauthorization, Exception? exception = null) 50 | { 51 | Result = result; 52 | Error = error; 53 | AttemptSilentReauthorization = attemptSilentReauthorization; 54 | Exception = exception; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/AzureExtension/Client/ErrorType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Client; 5 | 6 | public enum ErrorType 7 | { 8 | None, 9 | Unknown, 10 | InvalidArgument, 11 | EmptyUri, 12 | UriInvalidQuery, 13 | UriInvalidRepository, 14 | InvalidUri, 15 | NullDeveloperId, 16 | InvalidDeveloperId, 17 | QueryFailed, 18 | RepositoryFailed, 19 | FailedGettingClient, 20 | CredentialUIRequired, 21 | MsalServiceError, 22 | MsalClientError, 23 | GenericCredentialFailure, 24 | InitializeVssConnectionFailure, 25 | NullConnection, 26 | VssResourceNotFound, 27 | } 28 | -------------------------------------------------------------------------------- /src/AzureExtension/Client/InfoResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Client; 5 | 6 | public class InfoResult 7 | { 8 | public ResultType Result { get; } = ResultType.Unknown; 9 | 10 | public ErrorType Error { get; } = ErrorType.Unknown; 11 | 12 | public string Name { get; } = string.Empty; 13 | 14 | public string Description { get; } = string.Empty; 15 | 16 | public string ErrorMessage { get; } = string.Empty; 17 | 18 | public AzureUri AzureUri { get; } 19 | 20 | public InfoType InfoType { get; } = InfoType.Unknown; 21 | 22 | public Exception? Exception { get; } 23 | 24 | public InfoResult(AzureUri azureUri, InfoType type, string name, string description) 25 | { 26 | AzureUri = azureUri; 27 | Name = name; 28 | Description = description; 29 | InfoType = type; 30 | Result = ResultType.Success; 31 | Error = ErrorType.None; 32 | } 33 | 34 | public InfoResult(AzureUri azureUri, InfoType type, ResultType result, ErrorType error, Exception? exception = null) 35 | { 36 | AzureUri = azureUri; 37 | InfoType = type; 38 | Result = result; 39 | Error = error; 40 | Exception = exception; 41 | if (exception is not null) 42 | { 43 | ErrorMessage = exception.Message; 44 | } 45 | else 46 | { 47 | ErrorMessage = Error.ToString(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/AzureExtension/Client/InfoType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Client; 5 | 6 | public enum InfoType 7 | { 8 | Unknown, 9 | Query, 10 | Repository, 11 | } 12 | -------------------------------------------------------------------------------- /src/AzureExtension/Client/ResultType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Client; 5 | 6 | public enum ResultType 7 | { 8 | Unknown, 9 | Success, 10 | Failure, 11 | } 12 | -------------------------------------------------------------------------------- /src/AzureExtension/Configuration/DeveloperOAuthConfiguration.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension; 5 | 6 | internal static class DeveloperOAuthConfiguration 7 | { 8 | //// Follow this link https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app 9 | //// to create a Git OAuth app (with RedirectUri = "devhome://oauth_redirect_uri/"). 10 | //// The following info can be modified by setting the corresponding environment variables. 11 | //// How to set the environment variables: 12 | //// 13 | //// On an elevated cmd window: 14 | //// setx GITHUB_CLIENT_ID "Your OAuth App's ClientId" /m 15 | //// setx GITHUB_CLIENT_SECRET "Your OAuth App's ClientSecret" /m 16 | 17 | // GitHub OAuth Client ID and Secret values should not be checked in. Rather than modifying these values, 18 | // setting the environment variables like shown above will persist across branch switches. 19 | internal static readonly string? ClientID = Environment.GetEnvironmentVariable("GITHUB_CLIENT_ID"); 20 | 21 | internal static readonly string? ClientSecret = Environment.GetEnvironmentVariable("GITHUB_CLIENT_SECRET"); 22 | } 23 | -------------------------------------------------------------------------------- /src/AzureExtension/Constants.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension; 5 | 6 | internal sealed class Constants 7 | { 8 | #pragma warning disable SA1310 // Field names should not contain underscore 9 | public const string DEV_HOME_APPLICATION_NAME = "DevHome"; 10 | public const string GITHUB_REPOS_API = "https://api.github.com/repos/"; 11 | #pragma warning restore SA1310 // Field names should not contain underscore 12 | } 13 | -------------------------------------------------------------------------------- /src/AzureExtension/Contracts/IArmTokenService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Windows.DevHome.SDK; 5 | 6 | namespace DevHomeAzureExtension.Contracts; 7 | 8 | // ARMTokenService is a service that provides an Azure Resource Manager (ARM) token. 9 | public interface IArmTokenService 10 | { 11 | public Task GetTokenAsync(IDeveloperId? devId); 12 | } 13 | -------------------------------------------------------------------------------- /src/AzureExtension/Contracts/IDataTokenService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Windows.DevHome.SDK; 5 | 6 | namespace DevHomeAzureExtension.Contracts; 7 | 8 | public interface IDataTokenService 9 | { 10 | public Task GetTokenAsync(IDeveloperId? devId); 11 | } 12 | -------------------------------------------------------------------------------- /src/AzureExtension/Contracts/IDevBoxAuthService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Windows.DevHome.SDK; 5 | 6 | namespace DevHomeAzureExtension.Contracts; 7 | 8 | public interface IDevBoxAuthService 9 | { 10 | HttpClient GetManagementClient(IDeveloperId? devId); 11 | 12 | HttpClient GetDataPlaneClient(IDeveloperId? devId); 13 | } 14 | -------------------------------------------------------------------------------- /src/AzureExtension/Contracts/IDevBoxCreationManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.DevBox; 5 | using DevHomeAzureExtension.DevBox.Models; 6 | using Microsoft.Windows.DevHome.SDK; 7 | 8 | namespace DevHomeAzureExtension.Contracts; 9 | 10 | public interface IDevBoxCreationManager 11 | { 12 | public bool TryGetDevBoxInstanceIfBeingCreated(string id, out DevBoxInstance? devBox); 13 | 14 | /// 15 | /// Initiates the Dev box creation process. The operation is started, and a request is made to the Dev Center who will 16 | /// then create the Dev Box. 17 | /// 18 | /// An object that implements Dev Homes interface to relay progress data back to Dev Home 19 | /// The developer to authenticate with 20 | /// User json input provided from Dev Home 21 | public Task StartCreateDevBoxOperation(CreateComputeSystemOperation operation, IDeveloperId developerId, DevBoxCreationParameters parameters); 22 | 23 | /// 24 | /// Starts the process of monitoring the provisioning status of the Dev Box. This is needed for the cases where a Dev Box was created 25 | /// out side of the extension. But the creation operation is still in progress. 26 | /// 27 | /// The developer to authenticate with 28 | /// The Dev Box instance to monitor 29 | public void StartDevBoxProvisioningStateMonitor(IDeveloperId developerId, DevBoxInstance devBox); 30 | } 31 | -------------------------------------------------------------------------------- /src/AzureExtension/Contracts/IInstalledAppsService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Contracts; 5 | 6 | public interface IInstalledAppsService 7 | { 8 | public Task> CheckForMissingDependencies( 9 | HashSet msixPackageFamilies, 10 | HashSet win32AppDisplayNames, 11 | HashSet vsCodeExtensions, 12 | Dictionary> displayNameAndPathEntries); 13 | } 14 | -------------------------------------------------------------------------------- /src/AzureExtension/Contracts/IPackagesService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Contracts; 5 | 6 | using Windows.ApplicationModel; 7 | 8 | public interface IPackagesService 9 | { 10 | public bool IsPackageInstalled(string packageName); 11 | 12 | public PackageVersion GetPackageInstalledVersion(string packageName); 13 | } 14 | -------------------------------------------------------------------------------- /src/AzureExtension/Contracts/ITimeSpanService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.DevBox; 5 | 6 | namespace DevHomeAzureExtension.Contracts; 7 | 8 | /// 9 | /// Interface that an operation watcher can use to get the time span based on the action to perform. 10 | /// 11 | public interface ITimeSpanService 12 | { 13 | TimeSpan GetPeriodIntervalBasedOnAction(DevBoxActionToPerform actionToPerform); 14 | 15 | TimeSpan DevBoxOperationDeadline { get; } 16 | } 17 | -------------------------------------------------------------------------------- /src/AzureExtension/DataManager/CacheManagerUpdateEventArgs.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DataManager; 5 | 6 | public delegate void CacheManagerUpdateEventHandler(object? source, CacheManagerUpdateEventArgs e); 7 | 8 | public enum CacheManagerUpdateKind 9 | { 10 | Started, 11 | Updated, 12 | Cleared, 13 | Error, 14 | Cancel, 15 | Account, 16 | } 17 | 18 | public class CacheManagerUpdateEventArgs : EventArgs 19 | { 20 | private readonly CacheManagerUpdateKind _kind; 21 | private readonly Exception? _exception; 22 | 23 | public CacheManagerUpdateEventArgs(CacheManagerUpdateKind updateKind, Exception? exception = null) 24 | { 25 | _kind = updateKind; 26 | _exception = exception; 27 | } 28 | 29 | public CacheManagerUpdateKind Kind => _kind; 30 | 31 | public Exception? Exception => _exception; 32 | } 33 | -------------------------------------------------------------------------------- /src/AzureExtension/DataManager/DataManagerUpdateEventArgs.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DataManager; 5 | 6 | public delegate void DataManagerUpdateEventHandler(object? source, DataManagerUpdateEventArgs e); 7 | 8 | public enum DataManagerUpdateKind 9 | { 10 | Query, // A custom query was updated, which could be any amount of data in the datastore. 11 | PullRequest, 12 | Error, 13 | Cache, 14 | Account, 15 | Cancel, 16 | Developer, 17 | } 18 | 19 | public class DataManagerUpdateEventArgs : EventArgs 20 | { 21 | private readonly dynamic _context; 22 | private readonly DataManagerUpdateKind _kind; 23 | private readonly Guid _requestor; 24 | private readonly Exception? _exception; 25 | 26 | public DataManagerUpdateEventArgs(DataManagerUpdateKind updateKind, Guid requestor, dynamic context, Exception? exception = null) 27 | { 28 | _kind = updateKind; 29 | _requestor = requestor; 30 | _context = context; 31 | _exception = exception; 32 | } 33 | 34 | public DataManagerUpdateKind Kind => _kind; 35 | 36 | public dynamic Context => _context; 37 | 38 | public Guid Requestor => _requestor; 39 | 40 | public Exception? Exception => _exception; 41 | } 42 | -------------------------------------------------------------------------------- /src/AzureExtension/DataManager/DataStoreOperationParameters.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.Client; 5 | using DevHomeAzureExtension.DataModel; 6 | 7 | namespace DevHomeAzureExtension; 8 | 9 | public class DataStoreOperationParameters 10 | { 11 | public IEnumerable Uris { get; set; } = new List(); 12 | 13 | public string OperationName { get; set; } = string.Empty; 14 | 15 | public string LoginId { get; set; } = string.Empty; 16 | 17 | public Guid Requestor { get; set; } 18 | 19 | public DeveloperId.DeveloperId? DeveloperId { get; set; } 20 | 21 | public PullRequestView PullRequestView { get; set; } = PullRequestView.Unknown; 22 | 23 | public RequestOptions? RequestOptions { get; set; } 24 | 25 | public DataStoreOperationParameters() 26 | { 27 | } 28 | 29 | public override string ToString() => $"{OperationName} UriCount: {Uris.Count()} - {LoginId}"; 30 | } 31 | -------------------------------------------------------------------------------- /src/AzureExtension/DataManager/RequestOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension; 5 | 6 | public class RequestOptions 7 | { 8 | public List Fields { get; set; } 9 | 10 | public CancellationToken? CancellationToken { get; set; } 11 | 12 | public bool Refresh { get; set; } 13 | 14 | public RequestOptions() 15 | { 16 | Fields = new List(); 17 | } 18 | 19 | public static RequestOptions RequestOptionsDefault() 20 | { 21 | // Default options are a limited fetch of 10 items intended for widget display. 22 | var defaultOptions = new RequestOptions 23 | { 24 | Fields = new List 25 | { 26 | // "System.Id" is implicitly added. 27 | "System.State", 28 | "System.Reason", 29 | "System.AssignedTo", 30 | "System.CreatedDate", 31 | "System.CreatedBy", 32 | "System.ChangedDate", 33 | "System.ChangedBy", 34 | "System.Title", 35 | "System.WorkItemType", 36 | }, 37 | }; 38 | 39 | return defaultOptions; 40 | } 41 | 42 | public override string ToString() 43 | { 44 | return $"Request Fields: {string.Join(",", Fields.ToArray())}"; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/AzureExtension/DataModel/DataObjects/MetaData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Dapper; 5 | using Dapper.Contrib.Extensions; 6 | 7 | namespace DevHomeAzureExtension.DataModel; 8 | 9 | [Table("Metadata")] 10 | public class MetaData 11 | { 12 | [Key] 13 | public long Id { get; set; } = DataStore.NoForeignKey; 14 | 15 | public string Key { get; set; } = string.Empty; 16 | 17 | public string Value { get; set; } = string.Empty; 18 | 19 | public static void AddOrUpdate(DataStore dataStore, string key, string value) 20 | { 21 | // Do UPSERT 22 | var sql = @"INSERT INTO Metadata(Key, Value) VALUES ($Key, $Value) ON CONFLICT (Key) DO UPDATE SET Value=excluded.Value"; 23 | var command = dataStore.Connection!.CreateCommand(); 24 | command.CommandText = sql; 25 | command.Parameters.AddWithValue("$Key", key); 26 | command.Parameters.AddWithValue("$Value", value); 27 | command.ExecuteNonQuery(); 28 | } 29 | 30 | public static MetaData? GetByKey(DataStore dataStore, string key) 31 | { 32 | var sql = @"SELECT * FROM MetaData WHERE Key = @Key;"; 33 | var param = new 34 | { 35 | Key = key, 36 | }; 37 | 38 | return dataStore.Connection!.QueryFirstOrDefault(sql, param, null); 39 | } 40 | 41 | public static string? Get(DataStore dataStore, string key) 42 | { 43 | var metaData = GetByKey(dataStore, key); 44 | return metaData?.Value; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/AzureExtension/DataModel/DataStoreOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DataModel; 5 | 6 | public partial class DataStoreOptions 7 | { 8 | private const string DataStoreFileNameDefault = "AzureDataStore.db"; 9 | 10 | public string DataStoreFileName { get; set; } = DataStoreFileNameDefault; 11 | 12 | // The Temp Path is used for storage by default so tests can run this code without being packaged. 13 | // If we directly put in the ApplicationData folder, it would fail anytime the program was not packaged. 14 | // For use with packaged application, set in Options to: 15 | // ApplicationData.Current.LocalFolder.Path 16 | private readonly string _dataStoreFolderPathDefault = Path.Combine(Path.GetTempPath(), "AzureExtension"); 17 | 18 | // ApplicationData is not static, using a static folder for initialization. 19 | private string? _dataStoreFolderPath; 20 | 21 | public string DataStoreFolderPath 22 | { 23 | get => _dataStoreFolderPath is null ? _dataStoreFolderPathDefault : _dataStoreFolderPath; 24 | set => _dataStoreFolderPath = string.IsNullOrEmpty(value) ? _dataStoreFolderPathDefault : value; 25 | } 26 | 27 | public IDataStoreSchema? DataStoreSchema { get; set; } 28 | 29 | public bool RecreateDataStore { get; set; } 30 | } 31 | -------------------------------------------------------------------------------- /src/AzureExtension/DataModel/DataStoreTransaction.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Data.Sqlite; 5 | 6 | namespace DevHomeAzureExtension.DataModel; 7 | 8 | public class DataStoreTransaction : IDataStoreTransaction 9 | { 10 | private SqliteTransaction? _transaction; 11 | 12 | public static IDataStoreTransaction BeginTransaction(DataStore dataStore) 13 | { 14 | if (dataStore != null) 15 | { 16 | if (dataStore.Connection != null) 17 | { 18 | return new DataStoreTransaction(dataStore.Connection.BeginTransaction()); 19 | } 20 | } 21 | 22 | return new DataStoreTransaction(null); 23 | } 24 | 25 | private DataStoreTransaction(SqliteTransaction? tx) 26 | { 27 | _transaction = tx; 28 | } 29 | 30 | public void Commit() 31 | { 32 | _transaction?.Commit(); 33 | } 34 | 35 | public void Rollback() 36 | { 37 | _transaction?.Rollback(); 38 | } 39 | 40 | private bool _disposed; // To detect redundant calls. 41 | 42 | protected virtual void Dispose(bool disposing) 43 | { 44 | if (!_disposed) 45 | { 46 | if (disposing) 47 | { 48 | _transaction?.Dispose(); 49 | _transaction = null; 50 | } 51 | 52 | _disposed = true; 53 | } 54 | } 55 | 56 | // This code added to correctly implement the disposable pattern. 57 | public void Dispose() 58 | { 59 | // Do not change this code. Put cleanup code in Dispose(bool disposing) above. 60 | Dispose(true); 61 | GC.SuppressFinalize(this); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/AzureExtension/DataModel/Enums/NotificationType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DataModel; 5 | 6 | public enum NotificationType 7 | { 8 | Unknown = 0, 9 | PullRequestApproved = 1, 10 | PullRequestRejected = 2, 11 | NewReview = 3, 12 | } 13 | -------------------------------------------------------------------------------- /src/AzureExtension/DataModel/Enums/PolicyStatus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DataModel; 5 | 6 | public enum PolicyStatus 7 | { 8 | // Sorted by severity. Most severe is lowest. 9 | Broken = 1, 10 | Rejected = 2, 11 | Queued = 3, 12 | Running = 4, 13 | Approved = 5, 14 | NotApplicable = 6, 15 | Unknown = 7, 16 | } 17 | -------------------------------------------------------------------------------- /src/AzureExtension/DataModel/Enums/PullRequestView.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DataModel; 5 | 6 | public enum PullRequestView 7 | { 8 | Unknown, 9 | 10 | /// 11 | /// View all pull requests. 12 | /// 13 | All, 14 | 15 | /// 16 | /// View my pull requests. 17 | /// 18 | Mine, 19 | 20 | /// 21 | /// View pull requests assigned to me. 22 | /// 23 | Assigned, 24 | } 25 | -------------------------------------------------------------------------------- /src/AzureExtension/DataModel/IDataStoreSchema.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DataModel; 5 | 6 | public interface IDataStoreSchema 7 | { 8 | public long SchemaVersion 9 | { 10 | get; 11 | } 12 | 13 | public List SchemaSqls 14 | { 15 | get; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AzureExtension/DataModel/IDataStoreTransaction.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DataModel; 5 | 6 | public interface IDataStoreTransaction : IDisposable 7 | { 8 | void Commit(); 9 | 10 | void Rollback(); 11 | } 12 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxCreationPoolName.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// This is used to represent the json object that we send with the "create Dev Box" request. 8 | /// The only property we need is the pool name. 9 | /// See under Sample request in https://learn.microsoft.com/rest/api/devcenter/developer/dev-boxes/create-dev-box?view=rest-devcenter-developer-2023-04-01&tabs=HTTP#devboxes_createdevbox 10 | /// 11 | public class DevBoxCreationPoolName 12 | { 13 | public string PoolName { get; set; } = string.Empty; 14 | 15 | public DevBoxCreationPoolName(string poolName) 16 | { 17 | PoolName = poolName; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxHardwareProfile.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json.Serialization; 5 | 6 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 7 | 8 | /// 9 | /// Represents the HardwareProfile object within a response from a Dev Box rest API call. 10 | /// See API documentation 11 | /// 12 | public class DevBoxHardwareProfile 13 | { 14 | [JsonPropertyName("vCPUs")] 15 | public int VCPUs { get; set; } 16 | 17 | public string SkuName { get; set; } = string.Empty; 18 | 19 | public int MemoryGB { get; set; } 20 | } 21 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxImageReference.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents the ImageReference object within a response from a Dev Box rest API call. 8 | /// See API documentation 9 | /// 10 | public class DevBoxImageReference 11 | { 12 | public string Name { get; set; } = string.Empty; 13 | 14 | public string Version { get; set; } = string.Empty; 15 | 16 | public string OperatingSystem { get; set; } = string.Empty; 17 | 18 | public string OsBuildNumber { get; set; } = string.Empty; 19 | 20 | public DateTime PublishedDate { get; set; } 21 | } 22 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxLongRunningOperation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.DevBox.Models; 5 | 6 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 7 | 8 | /// 9 | /// https://azure.github.io/typespec-azure/docs/howtos/Azure%20Core/long-running-operations 10 | /// for move information on long running operations. This class is used to represent a long running operation. 11 | /// 12 | public class DevBoxLongRunningOperation : DevCenterOperationBase 13 | { 14 | public string Id { get; set; } = string.Empty; 15 | 16 | public string Name { get; set; } = string.Empty; 17 | } 18 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxMachineState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// This class represents the state of a DevBox machine. It is the class representation of 8 | /// the JSON response from the DevBox API. It is a snapshot of the state of the DevBox machine 9 | /// at the time of the response from the Dev Center. 10 | /// Should be kept in sync with the DevBox Json api definition. 11 | /// 12 | public class DevBoxMachineState 13 | { 14 | public string Uri { get; set; } = string.Empty; 15 | 16 | public string Name { get; set; } = string.Empty; 17 | 18 | public string ProjectName { get; set; } = string.Empty; 19 | 20 | public string PoolName { get; set; } = string.Empty; 21 | 22 | public string HibernateSupport { get; set; } = string.Empty; 23 | 24 | public string ProvisioningState { get; set; } = string.Empty; 25 | 26 | public string ActionState { get; set; } = string.Empty; 27 | 28 | public string PowerState { get; set; } = string.Empty; 29 | 30 | public string UniqueId { get; set; } = string.Empty; 31 | 32 | public string Location { get; set; } = string.Empty; 33 | 34 | public string OsType { get; set; } = string.Empty; 35 | 36 | public string User { get; set; } = string.Empty; 37 | 38 | public DevBoxHardwareProfile HardwareProfile { get; set; } = new(); 39 | 40 | public DevBoxStorageProfile StorageProfile { get; set; } = new(); 41 | 42 | public DevBoxImageReference ImageReference { get; set; } = new(); 43 | 44 | public string LocalAdministrator { get; set; } = string.Empty; 45 | 46 | public DateTime CreatedTime { get; set; } 47 | } 48 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxMachines.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents the response from the Dev Center API for getting a list of DevBoxes 8 | /// See API documentation 9 | /// 10 | public class DevBoxMachines 11 | { 12 | public DevBoxMachineState[]? Value { get; set; } 13 | } 14 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxOperation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json.Serialization; 5 | using DevHomeAzureExtension.DevBox.Models; 6 | 7 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 8 | 9 | /// 10 | /// Represents the DevBoxOperation object within a response from a Dev Box rest API call. 11 | /// See API documentation 12 | /// 13 | public class DevBoxOperation : DevCenterOperationBase 14 | { 15 | public string Uri { get; set; } = string.Empty; 16 | 17 | public string OperationId { get; set; } = string.Empty; 18 | 19 | public string Kind { get; set; } = string.Empty; 20 | 21 | public string CreatedByObjectId { get; set; } = string.Empty; 22 | 23 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] 24 | public DevBoxOperationResult? Result { get; set; } 25 | } 26 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxOperationList.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents a list of DevBoxOperation object's within a response from a Dev Box rest API call. 8 | /// See API documentation 9 | /// 10 | public class DevBoxOperationList 11 | { 12 | public List Value { get; set; } = new List(); 13 | } 14 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxOperationResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents a DevBoxOperationResult object within a response from a Dev Box rest API call. 8 | /// See API documentation 9 | /// 10 | public class DevBoxOperationResult 11 | { 12 | public string Code { get; set; } = string.Empty; 13 | 14 | public string Message { get; set; } = string.Empty; 15 | 16 | public string RepairOutcome { get; set; } = string.Empty; 17 | } 18 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxOsDisk.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents a OsDisk object within a response from a Dev Box rest API call. 8 | /// See API documentation 9 | /// 10 | public class DevBoxOsDisk 11 | { 12 | public int DiskSizeGB { get; set; } 13 | } 14 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxPool.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents a Pool object within a response from a Dev Box rest API call. 8 | /// See API documentation 9 | /// 10 | public class DevBoxPool 11 | { 12 | public string Name { get; set; } = string.Empty; 13 | 14 | public string Location { get; set; } = string.Empty; 15 | 16 | public string OsType { get; set; } = string.Empty; 17 | 18 | public DevBoxHardwareProfile HardwareProfile { get; set; } = new(); 19 | 20 | public DevBoxStorageProfile StorageProfile { get; set; } = new(); 21 | 22 | public string HibernateSupport { get; set; } = string.Empty; 23 | 24 | public DevBoxImageReference ImageReference { get; set; } = new(); 25 | 26 | public DevBoxPoolStopOnDisconnect StopOnDisconnect { get; set; } = new(); 27 | 28 | public string HealthStatus { get; set; } = string.Empty; 29 | } 30 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxPoolRoot.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents a list of Pool object's within a response from a Dev Box rest API call. 8 | /// See API documentation 9 | /// 10 | public class DevBoxPoolRoot 11 | { 12 | public List? Value { get; set; } 13 | } 14 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxPoolStopOnDisconnect.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents a StopOnDisconnect object within a response from a Dev Box rest API call. 8 | /// See API documentation 9 | /// 10 | public class DevBoxPoolStopOnDisconnect 11 | { 12 | public string Status { get; set; } = string.Empty; 13 | 14 | public int GracePeriodMinutes { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxProject.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents a DevBoxProject object within a response from a Dev Box rest API call. 8 | /// See API documentation 9 | /// 10 | public class DevBoxProject 11 | { 12 | public string Id { get; set; } = string.Empty; 13 | 14 | public string Location { get; set; } = string.Empty; 15 | 16 | public string TenantId { get; set; } = string.Empty; 17 | 18 | public string Name { get; set; } = string.Empty; 19 | 20 | public DevBoxProjectProperties Properties { get; set; } = new(); 21 | 22 | public string Type { get; set; } = string.Empty; 23 | } 24 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxProjectProperties.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents a ProjectProperties object within a response from a Dev Box rest API call. 8 | /// See API documentation 9 | /// 10 | public class DevBoxProjectProperties 11 | { 12 | public string ProvisioningState { get; set; } = string.Empty; 13 | 14 | public string DevCenterUri { get; set; } = string.Empty; 15 | 16 | public string DevCenterId { get; set; } = string.Empty; 17 | 18 | public string Description { get; set; } = string.Empty; 19 | 20 | public string DisplayName { get; set; } = string.Empty; 21 | } 22 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxProjects.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents a List of DevBoxProject objects within a response from a Dev Box rest API call. 8 | /// See API documentation 9 | /// 10 | public class DevBoxProjects 11 | { 12 | public DevBoxProject[]? Data { get; set; } 13 | } 14 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxRemoteConnectionData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents the data returned from a request to retrieve the remote connection information for a Dev Box. 8 | /// See API documentation 9 | /// 10 | public class DevBoxRemoteConnectionData 11 | { 12 | public string? WebUrl { get; set; } 13 | 14 | public string? RdpConnectionUrl { get; set; } 15 | 16 | // Example - ms-cloudpc:connect?cpcid={cloud-pc-id}&username={username}&environment={environment}&version={version}&rdlaunchurl={optional-rd-launch-url} 17 | public string? CloudPcConnectionUrl { get; set; } 18 | } 19 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/DevBoxStorageProfile.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | /// 7 | /// Represents the StorageProfile object within a response from a Dev Box rest API call. 8 | /// See API documentation 9 | /// 10 | public class DevBoxStorageProfile 11 | { 12 | public DevBoxOsDisk OsDisk { get; set; } = new(); 13 | } 14 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/DevBoxJsonToCsClasses/JsonSourceGenerationContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json.Serialization; 5 | using DevHomeAzureExtension.DevBox.Models; 6 | 7 | namespace DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 8 | 9 | /// 10 | /// Used to generate the source code for the classes that we deserialize Json to objects for the DevBox feature. 11 | /// .Net 8 requires a JsonSerializerContext to be used with the JsonSerializerOptions when 12 | /// deserializing JSON into objects. 13 | /// See : https://learn.microsoft.com/dotnet/standard/serialization/system-text-json/source-generation?pivots=dotnet-8-0 14 | /// for more information 15 | /// 16 | [JsonSerializable(typeof(DevBoxImageReference))] 17 | [JsonSerializable(typeof(DevBoxHardwareProfile))] 18 | [JsonSerializable(typeof(DevBoxLongRunningOperation))] 19 | [JsonSerializable(typeof(DevBoxMachines))] 20 | [JsonSerializable(typeof(DevBoxMachineState))] 21 | [JsonSerializable(typeof(DevBoxOperation))] 22 | [JsonSerializable(typeof(DevBoxOperationList))] 23 | [JsonSerializable(typeof(DevBoxOperationResult))] 24 | [JsonSerializable(typeof(DevBoxOsDisk))] 25 | [JsonSerializable(typeof(DevBoxPool))] 26 | [JsonSerializable(typeof(DevBoxPoolRoot))] 27 | [JsonSerializable(typeof(DevBoxPoolStopOnDisconnect))] 28 | [JsonSerializable(typeof(DevBoxProject))] 29 | [JsonSerializable(typeof(DevBoxProjectProperties))] 30 | [JsonSerializable(typeof(DevBoxProjects))] 31 | [JsonSerializable(typeof(DevBoxRemoteConnectionData))] 32 | [JsonSerializable(typeof(DevBoxStorageProfile))] 33 | [JsonSerializable(typeof(DevBoxCreationParameters))] 34 | [JsonSerializable(typeof(DevCenterOperationBase))] 35 | [JsonSerializable(typeof(DevBoxCreationPoolName))] 36 | public partial class JsonSourceGenerationContext : JsonSerializerContext 37 | { 38 | } 39 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Exceptions/DevBoxCreationException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.Exceptions; 5 | 6 | public class DevBoxCreationException : Exception 7 | { 8 | public DevBoxCreationException(string message) 9 | : base(message) 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Exceptions/DevBoxNameInvalidException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.Exceptions; 5 | 6 | public class DevBoxNameInvalidException : Exception 7 | { 8 | public DevBoxNameInvalidException(string message) 9 | : base(message) 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Exceptions/DevBoxOperationMonitorException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.Exceptions; 5 | 6 | public class DevBoxOperationMonitorException : Exception 7 | { 8 | public DevBoxOperationMonitorException(string message) 9 | : base(message) 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Exceptions/DevBoxProjectNameInvalidException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.Exceptions; 5 | 6 | public class DevBoxProjectNameInvalidException : Exception 7 | { 8 | public DevBoxProjectNameInvalidException(string message) 9 | : base(message) 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Exceptions/WingetConfigurationException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.Exceptions; 5 | 6 | public class WingetConfigurationException : Exception 7 | { 8 | public WingetConfigurationException(string message) 9 | : base(message) 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Helpers/AbilitiesJSONToCSClasses.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.Helpers; 5 | 6 | // Example of a task JSON response that will be deserialized into the BaseClass class 7 | // { 8 | // "abilitiesAsAdmin": [], 9 | // "abilitiesAsDeveloper": [ 10 | // "ReadDevBoxes", 11 | // "WriteDevBoxes", 12 | // ... 13 | // ] 14 | // } 15 | // 16 | 17 | /// 18 | /// Represents the class for the abilities JSON response. 19 | /// 20 | public class AbilitiesJSONToCSClasses 21 | { 22 | public class BaseClass 23 | { 24 | public List AbilitiesAsAdmin { get; set; } = new(); 25 | 26 | public List AbilitiesAsDeveloper { get; set; } = new(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Helpers/AdaptiveCardJSONToCSClass.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DevBox.Helpers; 5 | 6 | public class AdaptiveCardJSONToCSClass 7 | { 8 | public string? Data 9 | { 10 | get; set; 11 | } 12 | 13 | public string? Id 14 | { 15 | get; set; 16 | } 17 | 18 | public string? Title 19 | { 20 | get; set; 21 | } 22 | 23 | public string? Type 24 | { 25 | get; set; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Helpers/DevCenterOperationStatusConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json; 5 | using System.Text.Json.Serialization; 6 | using DevHomeAzureExtension.DevBox.Models; 7 | 8 | namespace DevHomeAzureExtension.DevBox.Helpers; 9 | 10 | /// 11 | /// Custom JSON converter for . 12 | /// This is added directly to the to handle the conversion of the enum to and from JSON. 13 | /// 14 | /// 15 | public class DevCenterOperationStatusConverter : JsonConverter 16 | { 17 | public override DevCenterOperationStatus Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 18 | { 19 | if (Enum.TryParse(reader.GetString(), out DevCenterOperationStatus status)) 20 | { 21 | return status; 22 | } 23 | 24 | return DevCenterOperationStatus.Failed; // Set a default value if parsing fails 25 | } 26 | 27 | public override void Write(Utf8JsonWriter writer, DevCenterOperationStatus value, JsonSerializerOptions options) 28 | { 29 | writer.WriteStringValue(value.ToString()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Models/DevBoxCreationParameters.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Globalization; 5 | using System.Text; 6 | 7 | namespace DevHomeAzureExtension.DevBox.Models; 8 | 9 | /// 10 | /// These parameters are the parameters we'll expect to be passed in from Dev Home to create a Dev Box. 11 | /// 12 | public class DevBoxCreationParameters 13 | { 14 | public string ProjectName { get; set; } = string.Empty; 15 | 16 | public string PoolName { get; set; } = string.Empty; 17 | 18 | public string NewEnvironmentName { get; set; } = string.Empty; 19 | 20 | public string DevCenterUri { get; set; } = string.Empty; 21 | 22 | public DevBoxCreationParameters(string projectName, string poolName, string newEnvironmentName, string devCenterUri) 23 | { 24 | ProjectName = projectName; 25 | PoolName = poolName; 26 | NewEnvironmentName = newEnvironmentName; 27 | DevCenterUri = devCenterUri; 28 | } 29 | 30 | public override string ToString() 31 | { 32 | var builder = new StringBuilder(); 33 | builder.AppendLine(CultureInfo.InvariantCulture, $"Project Name: {ProjectName} "); 34 | builder.AppendLine(CultureInfo.InvariantCulture, $"Pool Name: {PoolName} "); 35 | builder.AppendLine(CultureInfo.InvariantCulture, $"DevBox Name: {NewEnvironmentName} "); 36 | builder.AppendLine(CultureInfo.InvariantCulture, $"DevCenter Uri: {DevCenterUri} "); 37 | return builder.ToString(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Models/DevBoxHttpsRequestResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json; 5 | 6 | namespace DevHomeAzureExtension.DevBox.Models; 7 | 8 | /// 9 | /// Represents the result of an HTTPS request result from the Dev Center. For Dev Box operations 10 | /// the only things we care about is the JSON response and the response header. 11 | /// 12 | public class DevBoxHttpsRequestResult 13 | { 14 | public JsonElement JsonResponseRoot { get; set; } 15 | 16 | public DevBoxOperationResponseHeader ResponseHeader { get; set; } 17 | 18 | public DevBoxHttpsRequestResult(JsonElement jsonResponseRoot, DevBoxOperationResponseHeader responseHeader) 19 | { 20 | JsonResponseRoot = jsonResponseRoot; 21 | ResponseHeader = responseHeader; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Models/DevBoxOperationResponseHeader.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Net.Http.Headers; 5 | 6 | namespace DevHomeAzureExtension.DevBox.Models; 7 | 8 | /// 9 | /// Represents the header for a Dev Box long running operation. The Dev Box APIs run a Location and an Operation-Location 10 | /// value in the header. These can be used to poll the progress of the operation. 11 | /// See API documentation 12 | /// 13 | public class DevBoxOperationResponseHeader 14 | { 15 | private const string OperationLocationStr = "Operation-Location"; 16 | 17 | public Uri? Location { get; set; } 18 | 19 | public Uri? OperationLocation { get; set; } 20 | 21 | /// 22 | /// gets the Id for the operation. This is used by the when checking how long the operation has been running. 23 | /// 24 | public string Id { get; private set; } = Guid.NewGuid().ToString(); 25 | 26 | /// 27 | /// Initializes a new instance of the class. 28 | /// 29 | /// Header returned from a Dev Center rest Api that expect the operation to be long running 30 | public DevBoxOperationResponseHeader(HttpResponseHeaders headers) 31 | { 32 | Location = headers.Location; 33 | 34 | if (headers.TryGetValues(OperationLocationStr, out var operationLocationValues)) 35 | { 36 | OperationLocation = new Uri(operationLocationValues.First()); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Models/DevBoxOperationWatcherTimer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.Services.DevBox; 5 | using Windows.System.Threading; 6 | 7 | namespace DevHomeAzureExtension.DevBox.Models; 8 | 9 | /// 10 | /// Used to store information about a timer that is being stored by the . 11 | /// 12 | public class DevBoxOperationWatcherTimer 13 | { 14 | /// 15 | /// Gets or sets the thread pool timer associated with the object. 16 | /// 17 | public ThreadPoolTimer? Timer { get; set; } 18 | 19 | /// 20 | /// Gets the start time of the operation 21 | /// 22 | public DateTime StartTime { get; private set; } = DateTime.Now; 23 | } 24 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Models/DevBoxProjectAndPoolContainer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.DevBox.DevBoxJsonToCsClasses; 5 | 6 | namespace DevHomeAzureExtension.DevBox.Models; 7 | 8 | /// 9 | /// Represents an object that contains both a DevBoxProject and a DevBoxPoolRoot. 10 | /// There is no API that combines these two objects, so this is a custom object. 11 | /// 12 | public class DevBoxProjectAndPoolContainer 13 | { 14 | public DevBoxProject? Project { get; set; } 15 | 16 | public DevBoxPoolRoot? Pools { get; set; } 17 | } 18 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Models/DevCenterOperationBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json.Serialization; 5 | 6 | namespace DevHomeAzureExtension.DevBox.Models; 7 | 8 | /// 9 | /// The status of a DevCenter operation. 10 | /// See API documentation for more information. 11 | /// 12 | public enum DevCenterOperationStatus 13 | { 14 | NotStarted, 15 | Running, 16 | Succeeded, 17 | Canceled, 18 | Failed, 19 | } 20 | 21 | /// 22 | /// For all DevCenter operations, this class is used to store the common properties. 23 | /// It is used when querying the status of an operation. 24 | /// 25 | public class DevCenterOperationBase 26 | { 27 | public DevCenterOperationStatus? Status { get; set; } 28 | 29 | public DateTime StartTime { get; set; } 30 | 31 | [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] 32 | public DateTime? EndTime { get; set; } 33 | 34 | public override string ToString() 35 | { 36 | return $"Status: {Status}, StartTime: {StartTime}, EndTime: {EndTime}"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/AzureExtension/DevBox/Templates/Caution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/DevBox/Templates/Caution.png -------------------------------------------------------------------------------- /src/AzureExtension/DeveloperId/IAuthenticationHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Identity.Client; 5 | using Microsoft.UI; 6 | 7 | namespace DevHomeAzureExtension.DeveloperId; 8 | 9 | public interface IAuthenticationHelper 10 | { 11 | public AuthenticationSettings MicrosoftEntraIdSettings 12 | { 13 | get; set; 14 | } 15 | 16 | public void InitializePublicClientApplicationBuilder(); 17 | 18 | public void InitializePublicClientAppForWAMBrokerAsync(); 19 | 20 | public Task> GetAllStoredLoginIdsAsync(); 21 | 22 | public Task InitializePublicClientAppForWAMBrokerAsyncWithParentWindow(WindowId? windowPtr); 23 | 24 | public Task LoginDeveloperAccount(string[] scopes); 25 | 26 | public Task SignOutDeveloperIdAsync(string username); 27 | 28 | public Task AcquireWindowsAccountTokenSilently(string[] scopes); 29 | 30 | public Task> AcquireAllDeveloperAccountTokens(string[] scopes); 31 | 32 | public Task ObtainTokenForLoggedInDeveloperAccount(string[] scopes, string loginId); 33 | } 34 | -------------------------------------------------------------------------------- /src/AzureExtension/DeveloperId/IAuthenticationSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.DeveloperId; 5 | 6 | public interface IAuthenticationSettings 7 | { 8 | public void InitializeSettings(); 9 | } 10 | -------------------------------------------------------------------------------- /src/AzureExtension/DeveloperId/MSALLogger.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.IdentityModel.Abstractions; 5 | using Serilog; 6 | 7 | namespace DevHomeAzureExtension.DeveloperId; 8 | 9 | // The below class is used in MSAL.NET logging for better diagnosability of issues (see more here: https://learn.microsoft.com/en-us/entra/msal/dotnet/advanced/exceptions/msal-logging) 10 | public class MSALLogger(EventLogLevel minLogLevel = EventLogLevel.LogAlways) : IIdentityLogger 11 | { 12 | private readonly EventLogLevel _minLogLevel = minLogLevel; 13 | private readonly ILogger _log = Serilog.Log.ForContext("SourceContext", nameof(MSALLogger)); 14 | 15 | public bool IsEnabled(EventLogLevel eventLogLevel) 16 | { 17 | return eventLogLevel >= _minLogLevel; 18 | } 19 | 20 | public void Log(LogEntry entry) 21 | { 22 | switch (entry.EventLogLevel) 23 | { 24 | case EventLogLevel.Verbose: 25 | _log.Verbose($"{entry.Message}"); 26 | break; 27 | case EventLogLevel.Critical: 28 | _log.Fatal($"{entry.Message}"); 29 | break; 30 | case EventLogLevel.Error: 31 | _log.Error($"{entry.Message}"); 32 | break; 33 | case EventLogLevel.Warning: 34 | // MSAL logging is even spammy with warnings. 35 | _log.Debug($"{entry.Message}"); 36 | break; 37 | case EventLogLevel.Informational: 38 | // The MSAL Logging is very spammy, information is very common. 39 | _log.Verbose($"{entry.Message}"); 40 | break; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/AzureExtension/Exceptions/AzureAuthorizationException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension; 5 | 6 | public class AzureAuthorizationException : Exception 7 | { 8 | public AzureAuthorizationException() 9 | { 10 | } 11 | 12 | public AzureAuthorizationException(string message) 13 | : base(message) 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AzureExtension/Exceptions/AzureClientException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension; 5 | 6 | public class AzureClientException : Exception 7 | { 8 | public AzureClientException() 9 | { 10 | } 11 | 12 | public AzureClientException(string message) 13 | : base(message) 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AzureExtension/Exceptions/DataStoreException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension; 5 | 6 | public class DataStoreException : Exception 7 | { 8 | public DataStoreException() 9 | { 10 | } 11 | 12 | public DataStoreException(string message) 13 | : base(message) 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AzureExtension/Exceptions/DataStoreInaccessibleException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension; 5 | 6 | public class DataStoreInaccessibleException : ApplicationException 7 | { 8 | public DataStoreInaccessibleException() 9 | { 10 | } 11 | 12 | public DataStoreInaccessibleException(string message) 13 | : base(message) 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AzureExtension/Exceptions/InvalidApiException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension; 5 | 6 | public class InvalidApiException : Exception 7 | { 8 | public InvalidApiException() 9 | { 10 | } 11 | 12 | public InvalidApiException(string message) 13 | : base(message) 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AzureExtension/Exceptions/RepositoryNotFoundException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension; 5 | 6 | public class RepositoryNotFoundException : ApplicationException 7 | { 8 | public RepositoryNotFoundException() 9 | { 10 | } 11 | 12 | public RepositoryNotFoundException(string message) 13 | : base(message) 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AzureExtension/Helpers/DateTimeExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Globalization; 5 | 6 | namespace DevHomeAzureExtension.Helpers; 7 | 8 | public static class DateTimeExtensions 9 | { 10 | // Data store stores time as integers, which is just the Ticks so we don't lose precision. 11 | // This extension provides converters for storing the values as either TEXT or INTEGER, 12 | // Although SQLite types are suggestions, it may be internally represented differently. 13 | public static long ToDataStoreInteger(this DateTime value) 14 | { 15 | return value.Ticks; 16 | } 17 | 18 | public static long ToDataStoreInteger(this TimeSpan value) 19 | { 20 | return value.Ticks; 21 | } 22 | 23 | public static DateTime ToDateTime(this long value) 24 | { 25 | return new DateTime(value); 26 | } 27 | 28 | public static TimeSpan ToTimeSpan(this long value) 29 | { 30 | return new TimeSpan(value); 31 | } 32 | 33 | public static string ToDataStoreString(this DateTime value) 34 | { 35 | return value.ToDataStoreInteger().ToStringInvariant(); 36 | } 37 | 38 | public static string ToDataStoreString(this TimeSpan value) 39 | { 40 | return value.ToDataStoreInteger().ToStringInvariant(); 41 | } 42 | 43 | public static DateTime ToDateTime(this string value) 44 | { 45 | return long.Parse(value, CultureInfo.InvariantCulture).ToDateTime(); 46 | } 47 | 48 | public static TimeSpan ToTimeSpan(this string value) 49 | { 50 | return long.Parse(value, CultureInfo.InvariantCulture).ToTimeSpan(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/AzureExtension/Helpers/FileHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Diagnostics; 5 | using System.Text; 6 | using Newtonsoft.Json; 7 | using Serilog; 8 | 9 | namespace DevHomeAzureExtension.Helpers; 10 | 11 | public static class FileHelper 12 | { 13 | #pragma warning disable CS8603 // Possible null reference return. 14 | public static T Read(string folderPath, string fileName) 15 | { 16 | var path = Path.Combine(folderPath, fileName); 17 | if (File.Exists(path)) 18 | { 19 | var json = File.ReadAllText(path); 20 | return JsonConvert.DeserializeObject(json); 21 | } 22 | 23 | return default; 24 | } 25 | #pragma warning restore CS8603 // Possible null reference return. 26 | 27 | public static void Save(string folderPath, string fileName, T content) 28 | { 29 | if (!Directory.Exists(folderPath)) 30 | { 31 | Directory.CreateDirectory(folderPath); 32 | } 33 | 34 | var fileContent = JsonConvert.SerializeObject(content); 35 | File.WriteAllText(Path.Combine(folderPath, fileName), fileContent, Encoding.UTF8); 36 | } 37 | 38 | public static void Delete(string folderPath, string fileName) 39 | { 40 | if (!string.IsNullOrEmpty(fileName) && File.Exists(Path.Combine(folderPath, fileName))) 41 | { 42 | File.Delete(Path.Combine(folderPath, fileName)); 43 | } 44 | } 45 | 46 | public static void OpenLogsLocation() 47 | { 48 | var log = Log.ForContext("SourceContext", "OpenLogs"); 49 | try 50 | { 51 | var logLocation = Environment.GetEnvironmentVariable("DEVHOME_LOGS_ROOT"); 52 | log.Information($"Opening logs at: {logLocation}"); 53 | Process.Start("explorer.exe", $"{logLocation}"); 54 | } 55 | catch (Exception e) 56 | { 57 | log.Error(e, $"Error opening log location"); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/AzureExtension/Helpers/IconLoader.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Serilog; 5 | 6 | namespace DevHomeAzureExtension.Helpers; 7 | 8 | public class IconLoader 9 | { 10 | private static readonly Dictionary _base64ImageRegistry = new(); 11 | 12 | public static string GetIconAsBase64(string filename) 13 | { 14 | var log = Log.ForContext("SourceContext", nameof(IconLoader)); 15 | log.Debug($"Asking for icon: {filename}"); 16 | if (_base64ImageRegistry.TryAdd(filename, ConvertIconToDataString(filename))) 17 | { 18 | log.Debug($"The icon {filename} was converted and is now stored."); 19 | } 20 | 21 | return _base64ImageRegistry[filename]; 22 | } 23 | 24 | private static string ConvertIconToDataString(string fileName) 25 | { 26 | var path = Path.Combine(AppContext.BaseDirectory, @"Widgets/Assets/", fileName); 27 | var imageData = Convert.ToBase64String(File.ReadAllBytes(path.ToString())); 28 | return imageData; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/AzureExtension/Helpers/Links.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.VisualStudio.Services.WebApi; 5 | 6 | namespace DevHomeAzureExtension.Helpers; 7 | 8 | public class Links 9 | { 10 | public static string GetLinkHref(ReferenceLinks links, string linkName) 11 | { 12 | if (links == null || links.Links == null 13 | || !links.Links.ContainsKey(linkName) 14 | || links.Links[linkName] == null) 15 | { 16 | return string.Empty; 17 | } 18 | 19 | if (links.Links[linkName] is not ReferenceLink linkRef) 20 | { 21 | return string.Empty; 22 | } 23 | 24 | return linkRef.Href; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/AzureExtension/Helpers/RuntimeHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Windows.Win32; 5 | using Windows.Win32.Foundation; 6 | 7 | namespace DevHomeAzureExtension.Helpers; 8 | 9 | public static class RuntimeHelper 10 | { 11 | public static bool IsMSIX 12 | { 13 | get 14 | { 15 | uint length = 0; 16 | return PInvoke.GetCurrentPackageFullName(ref length, null) != WIN32_ERROR.APPMODEL_ERROR_NO_PACKAGE; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AzureExtension/Helpers/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Globalization; 5 | 6 | namespace DevHomeAzureExtension.Helpers; 7 | 8 | public static class StringExtensions 9 | { 10 | public static string ToStringInvariant(this T value) => Convert.ToString(value, CultureInfo.InvariantCulture)!; 11 | 12 | public static string FormatInvariant(this string value, params object[] arguments) 13 | { 14 | return string.Format(CultureInfo.InvariantCulture, value, arguments); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AzureExtension/Helpers/TimeSpanHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Jeffijoe.MessageFormat; 5 | using Serilog; 6 | 7 | namespace DevHomeAzureExtension.Helpers; 8 | 9 | internal sealed class TimeSpanHelper 10 | { 11 | public static string TimeSpanToDisplayString(TimeSpan timeSpan, ILogger? log = null) 12 | { 13 | if (timeSpan.TotalSeconds < 1) 14 | { 15 | return Resources.GetResource("Widget_Template_Now", log); 16 | } 17 | 18 | if (timeSpan.TotalMinutes < 1) 19 | { 20 | return MessageFormatter.Format(Resources.GetResource("Widget_Template_SecondsAgo", log), new { seconds = timeSpan.Seconds }); 21 | } 22 | 23 | if (timeSpan.TotalHours < 1) 24 | { 25 | return MessageFormatter.Format(Resources.GetResource("Widget_Template_MinutesAgo", log), new { minutes = timeSpan.Minutes }); 26 | } 27 | 28 | if (timeSpan.TotalDays < 1) 29 | { 30 | return MessageFormatter.Format(Resources.GetResource("Widget_Template_HoursAgo", log), new { hours = timeSpan.Hours }); 31 | } 32 | 33 | return MessageFormatter.Format(Resources.GetResource("Widget_Template_DaysAgo", log), new { days = timeSpan.Days }); 34 | } 35 | 36 | internal static string DateTimeOffsetToDisplayString(DateTimeOffset? dateTime, ILogger log) 37 | { 38 | if (dateTime == null) 39 | { 40 | return Resources.GetResource("Widget_Template_UnknownTime", log); 41 | } 42 | 43 | return TimeSpanToDisplayString(DateTime.UtcNow - dateTime.Value.DateTime, log); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/AzureExtension/NativeMethods.txt: -------------------------------------------------------------------------------- 1 | GetCurrentPackageFullName 2 | CredWrite 3 | CredRead 4 | CredFree 5 | CredDelete 6 | WIN32_ERROR 7 | SHLoadIndirectString 8 | -------------------------------------------------------------------------------- /src/AzureExtension/Notifications/NotificationManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Windows.AppNotifications; 5 | using Serilog; 6 | 7 | namespace DevHomeAzureExtension.Notifications; 8 | 9 | public class NotificationManager 10 | { 11 | private readonly ILogger _log = Log.ForContext("SourceContext", nameof(NotificationManager)); 12 | 13 | private bool _isRegistered; 14 | 15 | public NotificationManager(Windows.Foundation.TypedEventHandler handler) 16 | { 17 | AppNotificationManager.Default.NotificationInvoked += handler; 18 | AppNotificationManager.Default.Register(); 19 | _isRegistered = true; 20 | _log.Debug($"NotificationManager created and registered."); 21 | } 22 | 23 | ~NotificationManager() 24 | { 25 | Unregister(); 26 | } 27 | 28 | public void Unregister() 29 | { 30 | if (_isRegistered) 31 | { 32 | AppNotificationManager.Default.Unregister(); 33 | _isRegistered = false; 34 | _log.Debug($"NotificationManager unregistered."); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/AzureExtension/Providers/SettingsCardData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Providers; 5 | 6 | internal sealed class SettingsCardData 7 | { 8 | public string NotificationsEnabled { get; set; } = string.Empty; 9 | 10 | public string CacheLastUpdated { get; set; } = string.Empty; 11 | 12 | public string UpdateAzureData { get; set; } = string.Empty; 13 | } 14 | -------------------------------------------------------------------------------- /src/AzureExtension/Providers/SettingsCardSerializerContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Text.Json.Serialization; 5 | 6 | namespace DevHomeAzureExtension.Providers; 7 | 8 | [JsonSourceGenerationOptions(PropertyNameCaseInsensitive = true)] 9 | [JsonSerializable(typeof(SettingsCardData))] 10 | internal sealed partial class SettingsCardSerializerContext : JsonSerializerContext 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /src/AzureExtension/Providers/SettingsCardTemplate.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "AdaptiveCard", 3 | "body": [ 4 | { 5 | "type": "Container", 6 | "items": [ 7 | { 8 | "type": "ActionSet", 9 | "actions": [ 10 | { 11 | "type": "Action.Submit", 12 | "title": "${NotificationsEnabled}", 13 | "verb": "ToggleNotifications", 14 | "associatedInputs": "auto" 15 | } 16 | ] 17 | }, 18 | { 19 | "type": "TextBlock", 20 | "text": "${CacheLastUpdated}", 21 | "size": "medium" 22 | }, 23 | { 24 | "type": "ActionSet", 25 | "actions": [ 26 | { 27 | "type": "Action.Execute", 28 | "title": "${UpdateAzureData}", 29 | "verb": "UpdateData", 30 | "tooltip": "${UpdateAzureData}" 31 | } 32 | ] 33 | }, 34 | { 35 | "type": "ActionSet", 36 | "actions": [ 37 | { 38 | "type": "Action.Execute", 39 | "title": "%Settings_ViewLogs%", 40 | "verb": "OpenLogs", 41 | "tooltip": "%Settings_ViewLogs%" 42 | } 43 | ] 44 | } 45 | ] 46 | } 47 | ], 48 | "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", 49 | "version": "1.5", 50 | "minHeight": "200px" 51 | } 52 | -------------------------------------------------------------------------------- /src/AzureExtension/Providers/SettingsProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.Helpers; 5 | using Microsoft.Windows.DevHome.SDK; 6 | using Serilog; 7 | 8 | namespace DevHomeAzureExtension.Providers; 9 | 10 | public class SettingsProvider() : ISettingsProvider 11 | { 12 | private static readonly Lazy _logger = new(() => Log.ForContext("SourceContext", nameof(SettingsProvider))); 13 | 14 | private static readonly ILogger _log = _logger.Value; 15 | 16 | string ISettingsProvider.DisplayName => Resources.GetResource(@"SettingsProviderDisplayName", _log); 17 | 18 | public AdaptiveCardSessionResult GetSettingsAdaptiveCardSession() 19 | { 20 | _log.Information($"GetSettingsAdaptiveCardSession"); 21 | return new AdaptiveCardSessionResult(new SettingsUIController()); 22 | } 23 | 24 | public void Dispose() 25 | { 26 | GC.SuppressFinalize(this); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/AzureExtension/Services/DevBox/ARMTokenService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.Contracts; 5 | using DevHomeAzureExtension.DeveloperId; 6 | using Microsoft.Windows.DevHome.SDK; 7 | using Serilog; 8 | using DevBoxConstants = DevHomeAzureExtension.DevBox.Constants; 9 | 10 | namespace DevHomeAzureExtension.Services.DevBox; 11 | 12 | /// 13 | /// Implementation of the Azure Resource Manager (ARM) token service. 14 | /// It is a wrapper leveraging Developer ID's silent token acquiring 15 | /// function, with the scope needed for ARM 16 | /// 17 | public class ARMTokenService : IArmTokenService 18 | { 19 | private AuthenticationHelper AuthHelper => new(); 20 | 21 | public async Task GetTokenAsync(IDeveloperId? devId) 22 | { 23 | if (devId == null) 24 | { 25 | Log.Error($"ARMTokenService::GetTokenAsync: No dev id provided"); 26 | return string.Empty; 27 | } 28 | 29 | var result = await AuthHelper.ObtainTokenForLoggedInDeveloperAccount(new string[] { DevBoxConstants.ManagementPlaneScope }, devId.LoginId); 30 | return result?.AccessToken ?? string.Empty; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/AzureExtension/Services/DevBox/DataTokenService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.Contracts; 5 | using DevHomeAzureExtension.DeveloperId; 6 | using Microsoft.Windows.DevHome.SDK; 7 | using Serilog; 8 | using DevBoxConstants = DevHomeAzureExtension.DevBox.Constants; 9 | 10 | namespace DevHomeAzureExtension.Services.DevBox; 11 | 12 | /// 13 | /// Implementation of Dev Box Data Plane token service. 14 | /// It is a wrapper leveraging Developer ID's silent token acquiring 15 | /// function with the scope needed for the plane. 16 | /// 17 | public class DataTokenService : IDataTokenService 18 | { 19 | private AuthenticationHelper AuthHelper => new(); 20 | 21 | public async Task GetTokenAsync(IDeveloperId? devId) 22 | { 23 | if (devId == null) 24 | { 25 | Log.Error($"DataTokenService::GetTokenAsync: No dev id provided"); 26 | return string.Empty; 27 | } 28 | 29 | try 30 | { 31 | var result = await AuthHelper.ObtainTokenForLoggedInDeveloperAccount(new string[] { DevBoxConstants.DataPlaneScope }, devId.LoginId); 32 | return result?.AccessToken ?? string.Empty; 33 | } 34 | catch (Exception e) 35 | { 36 | Log.Error($"DataTokenService::GetTokenAsync: {e.ToString}"); 37 | return string.Empty; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/AzureExtension/Services/DevBox/PackagesService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.Contracts; 5 | using Windows.ApplicationModel; 6 | 7 | namespace DevHomeAzureExtension.Services.DevBox; 8 | 9 | public class PackagesService : IPackagesService 10 | { 11 | private readonly Windows.Management.Deployment.PackageManager _packageManager = new(); 12 | 13 | public bool IsPackageInstalled(string packageName) 14 | { 15 | var currentPackage = _packageManager.FindPackagesForUser(string.Empty, packageName).FirstOrDefault(); 16 | return currentPackage != null; 17 | } 18 | 19 | public PackageVersion GetPackageInstalledVersion(string packageName) 20 | { 21 | var version = new PackageVersion(0, 0, 0, 0); 22 | var currentPackage = _packageManager.FindPackagesForUser(string.Empty, packageName).FirstOrDefault(); 23 | if (currentPackage != null) 24 | { 25 | version = currentPackage.Id.Version; 26 | } 27 | 28 | return version; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/AzureExtension/Services/DevBox/TimeSpanService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.Contracts; 5 | using DevHomeAzureExtension.DevBox; 6 | using DevBoxConstants = DevHomeAzureExtension.DevBox.Constants; 7 | 8 | namespace DevHomeAzureExtension.Services.DevBox; 9 | 10 | /// 11 | /// Service to provide time spans for different operations. 12 | /// 13 | public class TimeSpanService : ITimeSpanService 14 | { 15 | public TimeSpan DevBoxOperationDeadline { get; private set; } = DevBoxConstants.OperationDeadline; 16 | 17 | /// 18 | /// Get the period interval based on the action to perform. 19 | /// 20 | /// 21 | /// The creation operation of a Dev Box takes longer than all other operations and can take between 20 to 65 minutes. Possibly more depending 22 | /// on how the users IT admin has configured their Dev Center subscriptions. All other operations take less than 5 minutes except for the delete 23 | /// operation which can take up to 10 minutes. 24 | /// 25 | /// The Dev Box action that is being performed. E.g Start 26 | /// The TimeSpan value that the can use to its periodic timer intervals 27 | public TimeSpan GetPeriodIntervalBasedOnAction(DevBoxActionToPerform actionToPerform) 28 | { 29 | switch (actionToPerform) 30 | { 31 | case DevBoxActionToPerform.Create: 32 | return DevBoxConstants.ThreeMinutePeriod; 33 | default: 34 | return DevBoxConstants.HalfMinutePeriod; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/ADO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/ADO.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/BlueBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/BlueBackground.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/Bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/Bug.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/ChangeRequest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/ChangeRequest.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/Epic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/Epic.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/Feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/Feature.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/Impediment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/Impediment.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/Issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/Issue.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/ProductBacklogItem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/ProductBacklogItem.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/PullRequest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/PullRequest.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/PullRequestApproved.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/PullRequestApproved.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/PullRequestRejected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/PullRequestRejected.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/PullRequestReviewNotStarted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/PullRequestReviewNotStarted.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/PullRequestWaiting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/PullRequestWaiting.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/PullRequestsScreenshotDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/PullRequestsScreenshotDark.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/PullRequestsScreenshotLight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/PullRequestsScreenshotLight.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/QueryResultScreenshotDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/QueryResultScreenshotDark.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/QueryResultScreenshotLight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/QueryResultScreenshotLight.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/QueryTilesScreenshotDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/QueryTilesScreenshotDark.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/QueryTilesScreenshotLight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/QueryTilesScreenshotLight.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/Requirement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/Requirement.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/Review.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/Review.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/Risk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/Risk.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/StatusBlue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/StatusBlue.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/StatusGray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/StatusGray.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/StatusGreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/StatusGreen.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/StatusOrange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/StatusOrange.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/StatusRed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/StatusRed.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/Task.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/Task.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/TestCase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/TestCase.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/TestPlan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/TestPlan.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/TestSuite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/TestSuite.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/UserStory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/UserStory.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/arrow.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/azureIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/azureIcon.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Assets/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtension/Widgets/Assets/screenshot.png -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Enums/WidgetAction.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Widgets.Enums; 5 | 6 | public enum WidgetAction 7 | { 8 | /// 9 | /// Error condition where the action cannot be determined. 10 | /// 11 | Unknown, 12 | 13 | /// 14 | /// Action to initiate the user Sign-In. 15 | /// 16 | SignIn, 17 | 18 | /// 19 | /// Action to initiate the user Added a tile in the configuration. 20 | /// 21 | AddTile, 22 | 23 | /// 24 | /// Action to initiate the user Removed a tile in the configuration. 25 | /// 26 | RemoveTile, 27 | 28 | /// 29 | /// Action to save the updated configuration. 30 | /// 31 | Save, 32 | 33 | /// 34 | /// Action to exit the configuration flow and discard changes. 35 | /// 36 | Cancel, 37 | } 38 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Enums/WidgetActivityState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Widgets.Enums; 5 | 6 | public enum WidgetActivityState 7 | { 8 | /// 9 | /// Error state and default initialization. This state is a clue something went terribly wrong. 10 | /// 11 | Unknown, 12 | 13 | /// 14 | /// Widget is in this state after it is created and before it has data assigned to it, 15 | /// or when the Configure option has been selected. 16 | /// 17 | Configure, 18 | 19 | /// 20 | /// Widget cannot do more until signed in. 21 | /// 22 | SignIn, 23 | 24 | /// 25 | /// Widget is configured and it is assumed user can interact and see it. 26 | /// 27 | Active, 28 | 29 | /// 30 | /// Widget is in good state, but host is minimized or disables the widget. 31 | /// 32 | Inactive, 33 | 34 | /// 35 | /// Widget has been marked for deletion and should not be used or do anything. 36 | /// 37 | Deleted, 38 | } 39 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Enums/WidgetDataState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Widgets; 5 | 6 | public enum WidgetDataState 7 | { 8 | Unknown, 9 | Requested, // Request is out, waiting on a response. Current data is stale. 10 | Okay, // Received and updated data, stable state. 11 | FailedUpdate, // Failed updating data. 12 | FailedRead, // Failed to read the data. 13 | Disposed, // DataManager has been disposed and should not be used. 14 | } 15 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Enums/WidgetPageState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Widgets; 5 | 6 | public enum WidgetPageState 7 | { 8 | Unknown, 9 | SignIn, 10 | Configure, 11 | Loading, 12 | Content, 13 | } 14 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Guids.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Runtime.InteropServices; 5 | 6 | namespace DevHomeAzureExtension.Widgets.COM; 7 | 8 | public static class Guids 9 | { 10 | public const string IClassFactory = "00000001-0000-0000-C000-000000000046"; 11 | public const string IUnknown = "00000000-0000-0000-C000-000000000046"; 12 | } 13 | 14 | // IClassFactory declaration. 15 | [ComImport] 16 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 17 | [Guid(Guids.IClassFactory)] 18 | internal interface IClassFactory 19 | { 20 | [PreserveSig] 21 | int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject); 22 | 23 | [PreserveSig] 24 | int LockServer(bool fLock); 25 | } 26 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/IWidgetImplFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Windows.Widgets.Providers; 5 | 6 | namespace DevHomeAzureExtension.Widgets; 7 | 8 | internal interface IWidgetImplFactory 9 | { 10 | public WidgetImpl Create(WidgetContext widgetContext, string state); 11 | } 12 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Templates/AzureLoadingTemplate.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "AdaptiveCard", 3 | "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", 4 | "version": "1.5", 5 | "body": [ 6 | { 7 | "type": "Container", 8 | "items": [ 9 | { 10 | "type": "TextBlock", 11 | "text": "${if(loadingMessage, loadingMessage, '%Widget_Template/Loading%')}", 12 | "wrap": true, 13 | "weight": "bolder", 14 | "horizontalAlignment": "Center" 15 | } 16 | ], 17 | "horizontalAlignment": "Center", 18 | "verticalContentAlignment": "Center", 19 | "spacing": "extraLarge", 20 | "height": "stretch", 21 | "separator": true 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Templates/AzureQueryTilesTemplate.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "AdaptiveCard", 3 | "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", 4 | "version": "1.5", 5 | "body": [ 6 | { 7 | "type": "ColumnSet", 8 | "$data": "${lines}", 9 | "spacing": "small", 10 | "columns": [ 11 | { 12 | "type": "Column", 13 | "$data": "${tiles}", 14 | "width": "stretch", 15 | "selectAction": { 16 | "type": "Action.OpenUrl", 17 | "url": "${url}", 18 | "tooltip": "%Widget_Template_Tooltip/ClickTile%" 19 | }, 20 | "items": [ 21 | { 22 | "type": "TextBlock", 23 | "text": "${title}", 24 | "color": "dark", 25 | "size": "Medium" 26 | }, 27 | { 28 | "type": "TextBlock", 29 | "text": "${string(counter)}", 30 | "size": "ExtraLarge", 31 | "color": "dark", 32 | "spacing": "Medium" 33 | }, 34 | { 35 | "type": "TextBlock", 36 | "text": "%Widget_Template/WorkItems%", 37 | "wrap": true, 38 | "size": "Medium", 39 | "color": "dark", 40 | "spacing": "Medium" 41 | } 42 | ], 43 | "backgroundImage": { 44 | "url": "data:image/png;base64,${backgroundImage}" 45 | }, 46 | "verticalContentAlignment": "Center", 47 | "spacing": "small", 48 | "style": "emphasis" 49 | }, 50 | { 51 | "type": "Column", 52 | "width": "stretch", 53 | "spacing": "small", 54 | "$when": "${count(tiles) == 1}" // Trick to prevent tile to expand horizontally 55 | } 56 | ] 57 | } 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/Templates/AzureSignInTemplate.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "AdaptiveCard", 3 | "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", 4 | "version": "1.5", 5 | "body": [ 6 | { 7 | "type": "Container", 8 | "items": [ 9 | { 10 | "type": "TextBlock", 11 | "text": "${message}", 12 | "wrap": true, 13 | "horizontalAlignment": "Center", 14 | "height": "stretch", 15 | "size": "Default", 16 | "weight": "Bolder" 17 | } 18 | ], 19 | "horizontalAlignment": "Center", 20 | "spacing": "None" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/WidgetImpl.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Windows.Widgets.Providers; 5 | using Serilog; 6 | 7 | namespace DevHomeAzureExtension.Widgets; 8 | 9 | public abstract class WidgetImpl 10 | { 11 | private string _state = string.Empty; 12 | 13 | public WidgetImpl() 14 | { 15 | _log = new(() => Serilog.Log.ForContext("SourceContext", SourceName)); 16 | } 17 | 18 | private readonly Lazy _log; 19 | 20 | protected ILogger Log => _log.Value; 21 | 22 | protected bool SupportsCustomization { get; set; } = true; 23 | 24 | protected string Name => GetType().Name; 25 | 26 | protected string Id { get; set; } = string.Empty; 27 | 28 | // This is not a unique identifier, but is easier to read in a log and highly unlikely to 29 | // match another running widget. 30 | protected string ShortId => Id.Length > 6 ? Id[..6] : Id; 31 | 32 | protected string SourceName => string.IsNullOrEmpty(ShortId) ? Name : $"{Name}/{ShortId}"; 33 | 34 | public string State() 35 | { 36 | return _state; 37 | } 38 | 39 | public void SetState(string state) 40 | { 41 | _state = state; 42 | } 43 | 44 | public abstract void CreateWidget(WidgetContext widgetContext, string state); 45 | 46 | public abstract void Activate(WidgetContext widgetContext); 47 | 48 | public abstract void Deactivate(string widgetId); 49 | 50 | public abstract void DeleteWidget(string widgetId, string customState); 51 | 52 | public abstract void OnActionInvoked(WidgetActionInvokedArgs actionInvokedArgs); 53 | 54 | public abstract void OnCustomizationRequested(WidgetCustomizationRequestedArgs customizationRequestedArgs); 55 | 56 | public abstract void OnWidgetContextChanged(WidgetContextChangedArgs contextChangedArgs); 57 | } 58 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/WidgetImplFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Windows.Widgets.Providers; 5 | using Serilog; 6 | 7 | namespace DevHomeAzureExtension.Widgets; 8 | 9 | [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Templated class")] 10 | internal sealed class WidgetImplFactory : IWidgetImplFactory 11 | where T : WidgetImpl, new() 12 | { 13 | public WidgetImpl Create(WidgetContext widgetContext, string state) 14 | { 15 | var log = Log.ForContext("SourceContext", nameof(WidgetImpl)); 16 | log.Debug($"In WidgetImpl Create for Id {widgetContext.Id} Definition: {widgetContext.DefinitionId} and state: '{state}'"); 17 | WidgetImpl widgetImpl = new T(); 18 | widgetImpl.CreateWidget(widgetContext, state); 19 | return widgetImpl; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AzureExtension/Widgets/WidgetProviderFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using System.Runtime.InteropServices; 5 | using DevHomeAzureExtension.Widgets.COM; 6 | using Microsoft.Windows.Widgets.Providers; 7 | using WinRT; 8 | 9 | namespace DevHomeAzureExtension.Widgets; 10 | 11 | [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Templated class")] 12 | public class WidgetProviderFactory : IClassFactory 13 | where T : IWidgetProvider 14 | { 15 | private readonly Func _createWidget; 16 | 17 | public WidgetProviderFactory(Func createWidget) 18 | { 19 | _createWidget = createWidget; 20 | } 21 | 22 | public int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject) 23 | { 24 | ppvObject = IntPtr.Zero; 25 | 26 | if (pUnkOuter != IntPtr.Zero) 27 | { 28 | Marshal.ThrowExceptionForHR(CLASSENOAGGREGATION); 29 | } 30 | 31 | if (riid == typeof(T).GUID || riid == Guid.Parse(Guids.IUnknown)) 32 | { 33 | // Create the instance of the .NET object 34 | ppvObject = MarshalInspectable.FromManaged(_createWidget()); 35 | } 36 | else 37 | { 38 | // The object that ppvObject points to does not support the 39 | // interface identified by riid. 40 | Marshal.ThrowExceptionForHR(ENOINTERFACE); 41 | } 42 | 43 | return 0; 44 | } 45 | 46 | int IClassFactory.LockServer(bool fLock) 47 | { 48 | return 0; 49 | } 50 | 51 | private const int CLASSENOAGGREGATION = unchecked((int)0x80040110); 52 | private const int ENOINTERFACE = unchecked((int)0x80004002); 53 | } 54 | -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.scale-100.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.scale-125.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.scale-150.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.scale-200.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.scale-400.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-16.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-16_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-16_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-16_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-16_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-20.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-20_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-20_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-20_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-20_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-24.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-24_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-24_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-256.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-256_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-256_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-256_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-256_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-30.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-30_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-30_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-30_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-30_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-32.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-32_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-32_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-32_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-32_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-36.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-36_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-36_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-36_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-36_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-40.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-40_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-40_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-40_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-40_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-48.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-48_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-48_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-48_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-48_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-56.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-56_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-56_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-56_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-56_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-60.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-60_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-60_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-60_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-60_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-64.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-64_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-64_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-64_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-64_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-72.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-72_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-72_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-72_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-72_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-80.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-80_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-80_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-80_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-80_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-96.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-96_altform-lightunplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-96_altform-lightunplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/AppList.targetsize-96_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/AppList.targetsize-96_altform-unplated.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/LargeTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/LargeTile.scale-100.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/LargeTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/LargeTile.scale-400.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/MedTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/MedTile.scale-100.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/MedTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/MedTile.scale-400.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/SmallTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/SmallTile.scale-100.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/SmallTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/SmallTile.scale-400.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/SplashScreen.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/SplashScreen.scale-125.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/SplashScreen.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/SplashScreen.scale-150.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/SplashScreen.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/SplashScreen.scale-400.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/StoreDisplay-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/StoreDisplay-150.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/StoreDisplay-300.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/StoreDisplay-300.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/StoreDisplay-71.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/StoreDisplay-71.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/StoreLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/StoreLogo.scale-100.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/StoreLogo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/StoreLogo.scale-125.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/StoreLogo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/StoreLogo.scale-150.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/StoreLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/StoreLogo.scale-200.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/StoreLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/StoreLogo.scale-400.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/WideTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/WideTile.scale-100.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Assets/WideTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/src/AzureExtensionServer/Assets/WideTile.scale-400.png -------------------------------------------------------------------------------- /src/AzureExtensionServer/Properties/PublishProfiles/win10-arm64.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | FileSystem 8 | arm64 9 | win10-arm64 10 | true 11 | False 12 | False 13 | True 14 | True 15 | True 16 | 17 | -------------------------------------------------------------------------------- /src/AzureExtensionServer/Properties/PublishProfiles/win10-x64.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | FileSystem 8 | x64 9 | win10-x64 10 | true 11 | False 12 | False 13 | True 14 | True 15 | True 16 | 17 | -------------------------------------------------------------------------------- /src/AzureExtensionServer/Properties/PublishProfiles/win10-x86.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | FileSystem 8 | x86 9 | win10-x86 10 | true 11 | False 12 | False 13 | True 14 | True 15 | True 16 | 17 | -------------------------------------------------------------------------------- /src/AzureExtensionServer/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Provider on launch": { 4 | "commandName": "MsixPackage", 5 | "commandLineArgs": "-RegisterProcessAsComServer", 6 | "doNotLaunchApp": false, 7 | "alwaysReinstallApp": true 8 | }, 9 | "UI App": { 10 | "commandName": "MsixPackage" 11 | }, 12 | "Provider": { 13 | "commandName": "MsixPackage", 14 | "commandLineArgs": "-RegisterProcessAsComServer" 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/AzureExtensionServer/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/AzureExtensionServer/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.Debug" ], 4 | "MinimumLevel": "Debug", 5 | "WriteTo": [ 6 | { 7 | "Name": "Console", 8 | "Args": { 9 | "outputTemplate": "[{Timestamp:yyyy/MM/dd HH:mm:ss.fff} {Level:u3}] ({SourceContext}) {Message:lj}{NewLine}{Exception}", 10 | "restrictedToMinimumLevel": "Debug" 11 | } 12 | }, 13 | { 14 | "Name": "File", 15 | "Args": { 16 | "path": "%DEVHOME_LOGS_ROOT%\\log.dhlog", 17 | "outputTemplate": "[{Timestamp:yyyy/MM/dd HH:mm:ss.fff} {Level:u3}] ({SourceContext}) {Message:lj}{NewLine}{Exception}", 18 | "restrictedToMinimumLevel": "Information", 19 | "rollingInterval": "Day" 20 | } 21 | }, 22 | { 23 | "Name" : "Debug" 24 | } 25 | ], 26 | "Enrich": [ "FromLogContext" ], 27 | "Properties": { 28 | "SourceContext": "AzureExtension" 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Telemetry/AzureExtension.Telemetry.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | AzureExtension.Telemetry 6 | x86;x64;arm64 7 | win10-x86;win10-x64;win10-arm64 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Telemetry/LogLevel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Telemetry; 5 | 6 | /// 7 | /// Telemetry Levels. 8 | /// These levels are defined by our telemetry system, so it's possible the sampling 9 | /// could change in the future. 10 | /// There aren't any convenient enums we can consume, so create our own. 11 | /// 12 | public enum LogLevel 13 | { 14 | /// 15 | /// Local. 16 | /// Only log telemetry locally on the machine (similar to an ETW event). 17 | /// 18 | Local, 19 | 20 | /// 21 | /// Info. 22 | /// Send telemetry from internal and flighted machines, but no external retail machines. 23 | /// 24 | Info, 25 | 26 | /// 27 | /// Measure. 28 | /// Send telemetry from internal and flighted machines, plus a small, sample % of retail machines. 29 | /// Should only be used for telemetry we use to derive measures from. 30 | /// 31 | Measure, 32 | 33 | /// 34 | /// Critical. 35 | /// Send telemetry from all devices sampled at 100%. 36 | /// Should only be used for approved events. 37 | /// 38 | Critical, 39 | } 40 | -------------------------------------------------------------------------------- /src/Telemetry/LoggerFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Telemetry; 5 | 6 | /// 7 | /// Creates instance of Logger 8 | /// This would be useful for future when we have updated interfaces for logger like ILogger2, ILogger3 and so on 9 | public class LoggerFactory 10 | { 11 | private static readonly object _lockObj = new(); 12 | 13 | private static Logger _loggerInstance; 14 | 15 | private static Logger GetLoggerInstance() 16 | { 17 | if (_loggerInstance == null) 18 | { 19 | lock (_lockObj) 20 | { 21 | _loggerInstance ??= new Logger(); 22 | _loggerInstance.AddWellKnownSensitiveStrings(); 23 | } 24 | } 25 | 26 | return _loggerInstance; 27 | } 28 | 29 | /// 30 | /// Gets a singleton instance of Logger 31 | /// This would be useful for future when we have updated interfaces for logger like ILogger2, ILogger3 and so on 32 | public static T Get() 33 | where T : ILogger 34 | { 35 | return (T)(object)GetLoggerInstance(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/AzureExtension/AzureExtension.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | enable 6 | enable 7 | DevHomeAzureExtension.Test 8 | win10-x86;win10-x64;win10-arm64 9 | true 10 | false 11 | enable 12 | true 13 | resources.pri 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /test/AzureExtension/DataStore/DataStoreTestsSetup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Test; 5 | 6 | [TestClass] 7 | public partial class DataStoreTests 8 | { 9 | public TestContext? TestContext 10 | { 11 | get; 12 | set; 13 | } 14 | 15 | private TestOptions _testOptions = new(); 16 | 17 | private TestOptions TestOptions 18 | { 19 | get => _testOptions; 20 | set => _testOptions = value; 21 | } 22 | 23 | [TestInitialize] 24 | public void TestInitialize() 25 | { 26 | TestOptions = TestHelpers.SetupTempTestOptions(TestContext!); 27 | TestHelpers.ConfigureTestLog(TestOptions, TestContext!); 28 | } 29 | 30 | [TestCleanup] 31 | public void Cleanup() 32 | { 33 | TestHelpers.CloseTestLog(); 34 | TestHelpers.CleanupTempTestOptions(TestOptions, TestContext!); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/AzureExtension/DevBox/ArmTestTokenService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.Contracts; 5 | using Microsoft.Windows.DevHome.SDK; 6 | 7 | namespace DevHomeAzureExtension.Test.DevBox; 8 | 9 | public class ArmTestTokenService : IArmTokenService 10 | { 11 | public async Task GetTokenAsync(IDeveloperId? devId) 12 | { 13 | await Task.Delay(0); 14 | return "Placeholder Test Token"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/AzureExtension/DevBox/DataTestTokenService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.Contracts; 5 | using Microsoft.Windows.DevHome.SDK; 6 | 7 | namespace DevHomeAzureExtension.Test.DevBox; 8 | 9 | public class DataTestTokenService : IDataTokenService 10 | { 11 | public async Task GetTokenAsync(IDeveloperId? devId) 12 | { 13 | await Task.Delay(0); 14 | return "Placeholder Test Token"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/AzureExtension/DevBox/EmptyDeveloperId.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Windows.DevHome.SDK; 5 | 6 | namespace DevHomeAzureExtension.Test.DevBox; 7 | 8 | public class EmptyDeveloperId : IDeveloperId 9 | { 10 | public string LoginId => string.Empty; 11 | 12 | public string Url => string.Empty; 13 | } 14 | -------------------------------------------------------------------------------- /test/AzureExtension/DevBox/TimeSpanServiceMock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.Contracts; 5 | using DevHomeAzureExtension.DevBox; 6 | 7 | namespace DevHomeAzureExtension.Test.DevBox; 8 | 9 | public class TimeSpanServiceMock : ITimeSpanService 10 | { 11 | public TimeSpan DevBoxOperationDeadline => TimeSpan.FromSeconds(3); 12 | 13 | public TimeSpan GetPeriodIntervalBasedOnAction(DevBoxActionToPerform actionToPerform) => TimeSpan.FromSeconds(1); 14 | } 15 | -------------------------------------------------------------------------------- /test/AzureExtension/DeveloperId/DeveloperIdTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.DeveloperId; 5 | 6 | namespace DevHomeAzureExtension.Test; 7 | 8 | public partial class DeveloperIdTests 9 | { 10 | [TestMethod] 11 | [TestCategory("Manual")] 12 | [Ignore("Comment out to run")] 13 | public void DevId_Manual_LoginLogoutEvents() 14 | { 15 | // Getting instance the first time will also do the login. 16 | var authProvider = DeveloperIdProvider.GetInstance(); 17 | 18 | // Register for Login and Logout Events 19 | authProvider.Changed += AuthenticationEvent; 20 | 21 | // Start a new interactive login flow 22 | // var windowHandle = Application.Current.GetService().GetWindowHandle(); 23 | // var windowPtr = Win32Interop.GetWindowIdFromWindow(windowHandle); 24 | // Task.Run(async () => { await authProvider.ShowLogonSession(windowPtr); }); 25 | 26 | // Get the list of DeveloperIds 27 | var devIds = authProvider.GetLoggedInDeveloperIdsInternal(); 28 | Assert.IsNotNull(devIds); 29 | Assert.AreEqual(devIds.Count(), 1); 30 | 31 | // Logout 32 | authProvider.LogoutDeveloperId(devIds.First()); 33 | 34 | // Wait 1 sec for the Logout event. 35 | _authenticationEventTriggered.WaitOne(1000); 36 | 37 | // Get the list of DeveloperIds 38 | devIds = authProvider.GetLoggedInDeveloperIdsInternal(); 39 | Assert.IsNotNull(devIds); 40 | Assert.AreEqual(devIds.Count(), 0); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/AzureExtension/DeveloperId/DeveloperIdTestsSetup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Windows.DevHome.SDK; 5 | 6 | namespace DevHomeAzureExtension.Test; 7 | 8 | [TestClass] 9 | public partial class DeveloperIdTests : IDisposable 10 | { 11 | public TestContext? TestContext 12 | { 13 | get; 14 | set; 15 | } 16 | 17 | private TestOptions _testOptions = new(); 18 | 19 | private TestOptions TestOptions 20 | { 21 | get => _testOptions; 22 | set => _testOptions = value; 23 | } 24 | 25 | [TestInitialize] 26 | public void TestInitialize() 27 | { 28 | TestOptions = TestHelpers.SetupTempTestOptions(TestContext!); 29 | TestHelpers.ConfigureTestLog(TestOptions, TestContext!); 30 | } 31 | 32 | [TestCleanup] 33 | public void Cleanup() 34 | { 35 | TestHelpers.CloseTestLog(); 36 | TestHelpers.CleanupTempTestOptions(TestOptions, TestContext!); 37 | } 38 | 39 | private static readonly Semaphore _authenticationEventTriggered = new(initialCount: 0, maximumCount: 1); 40 | 41 | public void AuthenticationEvent(object? sender, IDeveloperId developerId) 42 | { 43 | if (developerId.LoginId is not null) 44 | { 45 | _authenticationEventTriggered.Release(); 46 | } 47 | } 48 | 49 | public void Dispose() 50 | { 51 | GC.SuppressFinalize(this); 52 | _authenticationEventTriggered.Dispose(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /test/AzureExtension/DeveloperId/Mocks/MockAuthenticationSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHomeAzureExtension.DeveloperId; 5 | 6 | namespace DevHomeAzureExtension.Test.DeveloperId.Mocks; 7 | 8 | public class MockAuthenticationSettings : IAuthenticationSettings 9 | { 10 | public void InitializeSettings() 11 | { 12 | // no settings to initialize for testing 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/AzureExtension/Helpers/FileHelpers.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Test; 5 | 6 | public partial class TestHelpers 7 | { 8 | public static string CreateUniqueFolderName(string prefix) 9 | { 10 | // This could potentially be too long of a path name, 11 | // but should be OK for now. Keep the prefix short. 12 | return $"{prefix}-{Guid.NewGuid()}"; 13 | } 14 | 15 | public static string GetUniqueFolderPath(string prefix) 16 | { 17 | return Path.Combine(Path.GetTempPath(), CreateUniqueFolderName(prefix)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/AzureExtension/Helpers/FileSystem.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHome.Logging.Helpers; 5 | 6 | public class FileSystem 7 | { 8 | public static string BuildOutputFilename(string filename, string outputFolder, bool createPathIfNecessary = true) 9 | { 10 | var outputFilename = SubstituteOutputFilename(filename, outputFolder); 11 | var file = new FileInfo(outputFilename); 12 | if (createPathIfNecessary) 13 | { 14 | file.Directory?.Create(); 15 | } 16 | 17 | return file.FullName; 18 | } 19 | 20 | public static string SubstituteNow(string s) 21 | { 22 | if (s.Contains("{now}", StringComparison.CurrentCulture)) 23 | { 24 | var now = DateTime.Now; 25 | var nowAsString = $"{now:yyyyMMdd-HHmmss}"; 26 | return s.Replace("{now}", nowAsString); 27 | } 28 | 29 | return s; 30 | } 31 | 32 | public static string SubstituteOutputFilename(string filename, string outputDirectory) 33 | { 34 | return Path.Combine(SubstituteNow(outputDirectory), SubstituteNow(filename)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/AzureExtension/Helpers/TestOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using DevHome.Logging; 5 | using DevHomeAzureExtension.DataModel; 6 | 7 | namespace DevHomeAzureExtension.Test; 8 | 9 | public partial class TestOptions 10 | { 11 | public string LogFileFolderRoot { get; set; } = string.Empty; 12 | 13 | public string LogFileFolderName { get; set; } = "{now}"; 14 | 15 | public string LogFileName { get; set; } = string.Empty; 16 | 17 | public string LogFileFolderPath => Path.Combine(LogFileFolderRoot, LogFileFolderName); 18 | 19 | public DataStoreOptions DataStoreOptions { get; set; } 20 | 21 | public TestOptions() 22 | { 23 | DataStoreOptions = new DataStoreOptions(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/AzureExtension/Initialize.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Windows.ApplicationModel.DynamicDependency; 5 | 6 | namespace DevHomeAzureExtension.Test; 7 | 8 | [TestClass] 9 | public class Initialize 10 | { 11 | [AssemblyInitialize] 12 | public static void AssemblyInitialize(TestContext context) 13 | { 14 | // TODO: Initialize the appropriate version of the Windows App SDK. 15 | // This is required when testing MSIX apps that are framework-dependent on the Windows App SDK. 16 | Bootstrap.TryInitialize(0x00010001, out var _); 17 | } 18 | 19 | [AssemblyCleanup] 20 | public static void AssemblyCleanup() 21 | { 22 | Bootstrap.Shutdown(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/AzureExtension/RepositoryProvider/Mocks/MockRepository.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Windows.DevHome.SDK; 5 | using Windows.Foundation; 6 | 7 | namespace DevHomeAzureExtension.Test.Mocks; 8 | 9 | public class MockRepository : IRepository 10 | { 11 | public string DisplayName => "Mock Repository"; 12 | 13 | public bool IsPrivate => false; 14 | 15 | public DateTimeOffset LastUpdated => new DateTime(2023, 04, 11); 16 | 17 | public string OwningAccountName => "Local Microsoft"; 18 | 19 | public Uri RepoUri => new("https://www.microsoft.com"); 20 | 21 | public IAsyncAction CloneRepositoryAsync(string cloneDestination, IDeveloperId developerId) 22 | { 23 | throw new NotImplementedException(); 24 | } 25 | 26 | public IAsyncAction CloneRepositoryAsync(string cloneDestination) 27 | { 28 | throw new NotImplementedException(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/AzureExtension/TestContextSink/TestContextSink.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Serilog.Core; 5 | using Serilog.Events; 6 | using Serilog.Formatting.Display; 7 | 8 | namespace DevHomeAzureExtension.Test; 9 | 10 | public class TestContextSink : ILogEventSink 11 | { 12 | private readonly TestContext? _testContext; 13 | 14 | private readonly MessageTemplateTextFormatter _formatter; 15 | 16 | public TestContextSink(IFormatProvider formatProvider, TestContext testContext, string outputTemplate) 17 | { 18 | _testContext = testContext; 19 | _formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider); 20 | } 21 | 22 | public void Emit(LogEvent logEvent) 23 | { 24 | using var writer = new StringWriter(); 25 | _formatter.Format(logEvent, writer); 26 | _testContext?.Write(writer.ToString()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/AzureExtension/TestContextSink/TestContextSinkExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Serilog; 5 | using Serilog.Configuration; 6 | 7 | namespace DevHomeAzureExtension.Test; 8 | 9 | public static class TestContextSinkExtensions 10 | { 11 | public static LoggerConfiguration TestContextSink( 12 | this LoggerSinkConfiguration loggerConfiguration, 13 | string outputTemplate, 14 | TestContext? context = null, 15 | IFormatProvider? formatProvider = null) 16 | { 17 | return loggerConfiguration.Sink(new TestContextSink(formatProvider!, context!, outputTemplate)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/AzureExtension/Usings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | global using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | global using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; 6 | -------------------------------------------------------------------------------- /test/AzureExtension/Widgets/Icons.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Test; 5 | 6 | public partial class WidgetTests 7 | { 8 | [TestMethod] 9 | [TestCategory("Unit")] 10 | public void IconsTest() 11 | { 12 | var icon = Helpers.IconLoader.GetIconAsBase64("arrow.png"); 13 | 14 | Assert.IsNotNull(icon); 15 | Assert.IsTrue(icon.Length != 0); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/AzureExtension/Widgets/WidgetTestsSetup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | namespace DevHomeAzureExtension.Test; 5 | 6 | [TestClass] 7 | public partial class WidgetTests 8 | { 9 | public TestContext? TestContext 10 | { 11 | get; 12 | set; 13 | } 14 | 15 | private TestOptions _testOptions = new(); 16 | 17 | private TestOptions TestOptions 18 | { 19 | get => _testOptions; 20 | set => _testOptions = value; 21 | } 22 | 23 | [TestInitialize] 24 | public void TestInitialize() 25 | { 26 | TestOptions = TestHelpers.SetupTempTestOptions(TestContext!); 27 | TestHelpers.ConfigureTestLog(TestOptions, TestContext!); 28 | } 29 | 30 | [TestCleanup] 31 | public void Cleanup() 32 | { 33 | TestHelpers.CloseTestLog(); 34 | TestHelpers.CleanupTempTestOptions(TestOptions, TestContext!); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/Console/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/test/Console/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /test/Console/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/test/Console/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /test/Console/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/test/Console/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /test/Console/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/test/Console/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /test/Console/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/test/Console/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /test/Console/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/test/Console/Assets/StoreLogo.png -------------------------------------------------------------------------------- /test/Console/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/DevHomeAzureExtension/878d7e033a1bc04ee5090fe0e7cd88ec978374ae/test/Console/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /test/Console/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.Extensions.Configuration; 5 | using Serilog; 6 | using Windows.Storage; 7 | 8 | internal sealed class Program 9 | { 10 | private static void Main() 11 | { 12 | // Test console is set up with logging to test any component manually. 13 | Environment.SetEnvironmentVariable("DEVHOME_LOGS_ROOT", ApplicationData.Current.TemporaryFolder.Path); 14 | var configuration = new ConfigurationBuilder() 15 | .AddJsonFile("appsettings.json") 16 | .Build(); 17 | 18 | Log.Logger = new LoggerConfiguration() 19 | .ReadFrom.Configuration(configuration) 20 | .CreateLogger(); 21 | 22 | Log.Information("Hello Azure"); 23 | 24 | Log.CloseAndFlush(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/Console/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "MyApp": { 4 | "commandName": "MsixPackage", 5 | "commandLineArgs": "", /* Command line arguments to pass to the app. */ 6 | "alwaysReinstallApp": false, /* Uninstall and then reinstall the app. All information about the app state is deleted. */ 7 | "remoteDebugEnabled": false, /* Indicates that the debugger should attach to a process on a remote machine. */ 8 | "allowLocalNetworkLoopbackProperty": true, /* Allow the app to make network calls to the device it is installed on. */ 9 | "authenticationMode": "Windows", /* The authentication scheme to use when connecting to the remote machine. */ 10 | "doNotLaunchApp": false, /* Do not launch the app, but debug my code when it starts. */ 11 | "remoteDebugMachine": "", /* The name of the remote machine. */ 12 | "nativeDebugging": false /* Enable debugging for managed and native code together, also known as mixed-mode debugging. */ 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /test/Console/README.md: -------------------------------------------------------------------------------- 1 | # AzureExtension Test Console 2 | 3 | This is a console project for interacting with the AzureExtension database and project. -------------------------------------------------------------------------------- /test/Console/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/Console/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.Debug" ], 4 | "MinimumLevel": "Debug", 5 | "WriteTo": [ 6 | { 7 | "Name": "Console", 8 | "Args": { 9 | "outputTemplate": "[{Timestamp:yyyy/MM/dd HH:mm:ss.fff} {Level:u3}] ({SourceContext}) {Message:lj}{NewLine}{Exception}" 10 | } 11 | }, 12 | { 13 | "Name": "File", 14 | "Args": { 15 | "path": "%DEVHOME_LOGS_ROOT%\\log.dhlog", 16 | "outputTemplate": "[{Timestamp:yyyy/MM/dd HH:mm:ss.fff} {Level:u3}] ({SourceContext}) {Message:lj}{NewLine}{Exception}", 17 | "rollingInterval": "Day" 18 | } 19 | }, 20 | { 21 | "Name": "Debug" 22 | } 23 | ], 24 | "Enrich": [ "FromLogContext" ], 25 | "Properties": { 26 | "SourceContext": "AzureExtension" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /test/scripts/CleanDevHome.ps1: -------------------------------------------------------------------------------- 1 | # Completely removes DevHome and cleans state. 2 | 3 | # Clean Widget State and remove extensions. 4 | & "$PSScriptRoot\CleanWidgets.ps1" 5 | 6 | # Remove Devhome. 7 | Write-Host "Removing DevHome..." 8 | Get-Appxpackage *Microsoft.Windows.DevHome* | Remove-AppxPackage 9 | 10 | Write-Host "DevHome and related packages and state has been removed." 11 | -------------------------------------------------------------------------------- /test/scripts/CleanWidgets.ps1: -------------------------------------------------------------------------------- 1 | Write-Host "Removing DevHome Azure Extension..." 2 | Get-Appxpackage *DevHomeAzureExtension* | Remove-AppxPackage 3 | 4 | Write-Host "Terminating Windows Widget Host..." 5 | Get-Process Widgets -ErrorAction Ignore | Stop-Process 6 | 7 | Write-Host "Terminating DevHome..." 8 | Get-Process DevHome -ErrorAction Ignore | Stop-Process 9 | 10 | Write-Host "Terminating WidgetService..." 11 | Get-Process WidgetService -ErrorAction Ignore | Stop-Process 12 | 13 | $widgetSessionsPath = Join-Path -Path $env:localappdata -ChildPath "Packages\MicrosoftWindows.Client.WebExperience_cw5n1h2txyewy\LocalState\WidgetSessions" 14 | Write-Host "Removing WidgetSessions folder: $widgetSessionsPath" 15 | Remove-Item -Path $widgetSessionsPath -Force -Recurse -ErrorAction SilentlyContinue 16 | 17 | Write-Host "Cleaned all Widget State. Redeploy the Azure Extension and relaunch DevHome." --------------------------------------------------------------------------------