diff --git a/.azure-pipelines/generate-auth-module-template.yml b/.azure-pipelines/generate-auth-module-template.yml
index 0b92300335c..0600456da0a 100644
--- a/.azure-pipelines/generate-auth-module-template.yml
+++ b/.azure-pipelines/generate-auth-module-template.yml
@@ -10,10 +10,6 @@ parameters:
displayName: 'Authentication Module Name'
type: string
default: 'Authentication'
- - name: AUTH_MODULE_DLL_PATTERN
- displayName: 'Authentication Module DLL Pattern'
- type: string
- default: 'Microsoft.Graph.Authentication.dll'
- name: Api_Key
displayName: 'Api Key'
type: string
@@ -78,7 +74,8 @@ jobs:
inputs:
ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet (AKV)'
FolderPath: $(AUTH_MODULE_PATH)
- Pattern: $(AUTH_MODULE_DLL_PATTERN)
+ # Recursively finds files matching these patterns:
+ Pattern: 'Microsoft.Graph.Authentication.dll, Microsoft.Graph.Authentication.Core.dll'
signConfigType: inlineSignParams
inlineOperation: |
[
@@ -105,7 +102,8 @@ jobs:
inputs:
ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet (AKV)'
FolderPath: $(AUTH_MODULE_PATH)
- Pattern: $(AUTH_MODULE_DLL_PATTERN)
+ # Recursively finds files matching these patterns:
+ Pattern: 'Microsoft.Graph.Authentication.dll, Microsoft.Graph.Authentication.Core.dll, InitializeAssemblyResolver.ps1'
signConfigType: inlineSignParams
inlineOperation: |
[
diff --git a/.azure-pipelines/generate-auth-module.yml b/.azure-pipelines/generate-auth-module.yml
deleted file mode 100644
index 3d74a18f287..00000000000
--- a/.azure-pipelines/generate-auth-module.yml
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-# Generates a release build artifact (nuget) from HEAD of master for auth module.
-name: $(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
-trigger:
- branches:
- include:
- - master
- paths:
- include:
- - src/Authentication/*
-pr: none
-variables:
- MODULE_NAME: 'Authentication'
- MODULE_PATH: 'src\Authentication\Authentication\'
- MODULE_DLL_PATTERN: 'Microsoft.Graph.Authentication.dll'
-
-jobs:
-- job: MSGraphPSSDKGeneration
- displayName: MS Graph PS SDK Auth Generation
- timeoutInMinutes: 300
- pool:
- vmImage: 'windows-latest'
-
- steps:
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2
- displayName: 'Run CredScan'
- inputs:
- debugMode: false
-
- - task: NuGetToolInstaller@1
- displayName: 'Install Nuget'
-
- - task: PowerShell@2
- displayName: 'Generate and Build Auth Module'
- inputs:
- filePath: '$(System.DefaultWorkingDirectory)/tools/GenerateAuthenticationModule.ps1'
- arguments: '-ArtifactsLocation $(Build.ArtifactStagingDirectory) -Build -EnableSigning'
- pwsh: true
-
- - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
- displayName: 'ESRP DLL Strong Name (Graph Auth Module)'
- inputs:
- ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet (AKV)'
- FolderPath: $(MODULE_PATH)
- Pattern: $(MODULE_DLL_PATTERN)
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "keyCode": "CP-233863-SN",
- "operationSetCode": "StrongNameSign",
- "parameters": [],
- "toolName": "sign",
- "toolVersion": "1.0"
- },
- {
- "keyCode": "CP-233863-SN",
- "operationSetCode": "StrongNameVerify",
- "parameters": [],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
- SessionTimeout: 20
-
- - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
- displayName: 'ESRP DLL CodeSigning (Graph Auth Module)'
- inputs:
- ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet (AKV)'
- FolderPath: $(MODULE_PATH)
- Pattern: $(MODULE_DLL_PATTERN)
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "keyCode": "CP-230012",
- "operationSetCode": "SigntoolSign",
- "parameters": [
- {
- "parameterName": "OpusName",
- "parameterValue": "Microsoft"
- },
- {
- "parameterName": "OpusInfo",
- "parameterValue": "http://www.microsoft.com"
- },
- {
- "parameterName": "FileDigest",
- "parameterValue": "/fd \"SHA256\""
- },
- {
- "parameterName": "PageHash",
- "parameterValue": "/NPH"
- },
- {
- "parameterName": "TimeStamp",
- "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
- }
- ],
- "toolName": "sign",
- "toolVersion": "1.0"
- },
- {
- "keyCode": "CP-230012",
- "operationSetCode": "SigntoolVerify",
- "parameters": [],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
- SessionTimeout: 20
-
- - task: PowerShell@2
- displayName: 'Pack Auth Module'
- inputs:
- targetType: 'inline'
- script: |
- & $(System.DefaultWorkingDirectory)/tools/PackModule.ps1 -Module $(MODULE_NAME) -ArtifactsLocation $(Build.ArtifactStagingDirectory)
- pwsh: true
-
- - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
- displayName: 'ESRP NuGet CodeSigning'
- inputs:
- ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet (AKV)'
- FolderPath: '$(Build.ArtifactStagingDirectory)\$(MODULE_NAME)'
- Pattern: 'Microsoft.Graph.$(MODULE_NAME)*.nupkg'
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "keyCode": "CP-401405",
- "operationSetCode": "NuGetSign",
- "parameters": [ ],
- "toolName": "sign",
- "toolVersion": "1.0"
- },
- {
- "keyCode": "CP-401405",
- "operationSetCode": "NuGetVerify",
- "parameters": [ ],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
- SessionTimeout: 20
-
- - task: PublishBuildArtifacts@1
- displayName: Publish Artifact Microsoft.Graph.Authentication.nupkg'
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)/$(MODULE_NAME)'
- ArtifactName: 'drop'
- publishLocation: 'Container'
-
- - task: YodLabs.O365PostMessage.O365PostMessageBuild.O365PostMessageBuild@0
- displayName: 'Graph Client Tooling pipeline fail notification'
- inputs:
- addressType: serviceEndpoint
- serviceEndpointName: 'microsoftgraph pipeline status'
- title: '$(Build.DefinitionName) failure notification'
- text: 'This pipeline has failed. View the build details for further information. This is a blocking failure. '
- condition: and(failed(), ne(variables['Build.Reason'], 'Manual'))
- enabled: true
diff --git a/.azure-pipelines/generate-beta-modules.yml b/.azure-pipelines/generate-beta-modules.yml
deleted file mode 100644
index f41459c1093..00000000000
--- a/.azure-pipelines/generate-beta-modules.yml
+++ /dev/null
@@ -1,267 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-# Generates a release build artifact (nuget) from HEAD of master for beta Graph workload modules.
-name: $(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
-trigger:
- branches:
- include:
- - master
- paths:
- include:
- - src/*
- - config/ModulesMapping.jsonc
- exclude:
- - src/Authentication/*
-pr: none
-variables:
- MODULE_PREFIX: 'Microsoft.Graph'
- WORKLOAD_MODULE_PATH: 'src\'
- AUTH_MODULE_PATH: 'src\Authentication\Authentication\bin\'
- AUTH_MODULE_DLL_PATTERN: 'Microsoft.Graph.Authentication.dll'
-
-jobs:
-- job: MSGraphPSSDKGeneration
- displayName: MS Graph PS SDK Beta Generation
- timeoutInMinutes: 800
- pool:
- name: Microsoft Graph
- demands: 'Agent.Name -equals PS-Build-Agent'
-
- steps:
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2
- displayName: 'Run CredScan'
- inputs:
- debugMode: false
-
- # Install Node
- - task: NodeTool@0
- displayName: Node install
- inputs:
- versionSpec: '13.14.0'
-
- - task: Npm@1
- displayName: 'Install AutoRest'
- inputs:
- command: 'custom'
- customCommand: 'install -g autorest'
-
- - task: NuGetToolInstaller@1
- displayName: 'Install Nuget'
-
- - task: PowerShell@2
- displayName: 'Build Auth Modules'
- inputs:
- filePath: '$(System.DefaultWorkingDirectory)/tools/GenerateAuthenticationModule.ps1'
- arguments: '-ArtifactsLocation $(Build.ArtifactStagingDirectory) -Build -BuildWhenEqual -EnableSigning'
- pwsh: true
-
- - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
- displayName: 'ESRP DLL Strong Name (Graph Auth Module)'
- inputs:
- ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet'
- FolderPath: $(AUTH_MODULE_PATH)
- Pattern: '$(AUTH_MODULE_DLL_PATTERN)'
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "keyCode": "CP-233863-SN",
- "operationSetCode": "StrongNameSign",
- "parameters": [],
- "toolName": "sign",
- "toolVersion": "1.0"
- },
- {
- "keyCode": "CP-233863-SN",
- "operationSetCode": "StrongNameVerify",
- "parameters": [],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
- SessionTimeout: 20
-
- - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
- displayName: 'ESRP DLL CodeSigning (Graph Auth Module)'
- inputs:
- ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet'
- FolderPath: $(AUTH_MODULE_PATH)
- Pattern: $(AUTH_MODULE_DLL_PATTERN)
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "keyCode": "CP-230012",
- "operationSetCode": "SigntoolSign",
- "parameters": [
- {
- "parameterName": "OpusName",
- "parameterValue": "Microsoft"
- },
- {
- "parameterName": "OpusInfo",
- "parameterValue": "http://www.microsoft.com"
- },
- {
- "parameterName": "FileDigest",
- "parameterValue": "/fd \"SHA256\""
- },
- {
- "parameterName": "PageHash",
- "parameterValue": "/NPH"
- },
- {
- "parameterName": "TimeStamp",
- "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
- }
- ],
- "toolName": "sign",
- "toolVersion": "1.0"
- },
- {
- "keyCode": "CP-230012",
- "operationSetCode": "SigntoolVerify",
- "parameters": [],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
- SessionTimeout: 20
-
- - task: PowerShell@2
- displayName: 'Generate and Build Graph Resource Modules'
- inputs:
- filePath: '$(System.DefaultWorkingDirectory)/tools/GenerateModules.ps1'
- arguments: '-ArtifactsLocation $(Build.ArtifactStagingDirectory)\ -Build -Test -EnableSigning'
- pwsh: true
-
- - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
- displayName: 'ESRP DLL Strong Name (Graph Resource Modules)'
- inputs:
- ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet'
- FolderPath: $(WORKLOAD_MODULE_PATH)
- Pattern: '$(MODULE_PREFIX).*.private.dll'
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "keyCode": "CP-233863-SN",
- "operationSetCode": "StrongNameSign",
- "parameters": [],
- "toolName": "sign",
- "toolVersion": "1.0"
- },
- {
- "keyCode": "CP-233863-SN",
- "operationSetCode": "StrongNameVerify",
- "parameters": [],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
- SessionTimeout: 20
-
- - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
- displayName: 'ESRP DLL CodeSigning (Graph Resource Module)'
- inputs:
- ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet'
- FolderPath: $(WORKLOAD_MODULE_PATH)
- Pattern: '$(MODULE_PREFIX).*.private.dll, $(MODULE_PREFIX).*.psm1, $(MODULE_PREFIX).*.format.ps1xml, ProxyCmdletDefinitions.ps1, load-dependency.ps1'
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "keyCode": "CP-230012",
- "operationSetCode": "SigntoolSign",
- "parameters": [
- {
- "parameterName": "OpusName",
- "parameterValue": "Microsoft"
- },
- {
- "parameterName": "OpusInfo",
- "parameterValue": "http://www.microsoft.com"
- },
- {
- "parameterName": "FileDigest",
- "parameterValue": "/fd \"SHA256\""
- },
- {
- "parameterName": "PageHash",
- "parameterValue": "/NPH"
- },
- {
- "parameterName": "TimeStamp",
- "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
- }
- ],
- "toolName": "sign",
- "toolVersion": "1.0"
- },
- {
- "keyCode": "CP-230012",
- "operationSetCode": "SigntoolVerify",
- "parameters": [],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
- SessionTimeout: 160
-
- - task: PowerShell@2
- displayName: 'Pack Modules'
- inputs:
- targetType: 'inline'
- script: |
- $ModuleMappingConfigPath = "$(System.DefaultWorkingDirectory)/config/ModulesMapping.jsonc"
- [HashTable] $ModuleMapping = Get-Content $ModuleMappingConfigPath | ConvertFrom-Json -AsHashTable
- $ModuleMapping.Keys | ForEach-Object {
- $ModuleName = $_
- $ModuleProjectDir = "$(System.DefaultWorkingDirectory)/src/$ModuleName/$ModuleName"
- & $(System.DefaultWorkingDirectory)/tools/PackModule.ps1 -Module $ModuleName -ArtifactsLocation $(Build.ArtifactStagingDirectory)\
- }
- pwsh: true
-
- - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
- displayName: 'ESRP NuGet CodeSigning'
- inputs:
- ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet'
- FolderPath: '$(Build.ArtifactStagingDirectory)\'
- Pattern: '*.nupkg'
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "keyCode": "CP-401405",
- "operationSetCode": "NuGetSign",
- "parameters": [ ],
- "toolName": "sign",
- "toolVersion": "1.0"
- },
- {
- "keyCode": "CP-401405",
- "operationSetCode": "NuGetVerify",
- "parameters": [ ],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
- SessionTimeout: 20
-
- - task: PublishBuildArtifacts@1
- displayName: Publish Artifact Beta Modules
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)/'
- ArtifactName: 'drop'
- publishLocation: 'Container'
-
- - task: YodLabs.O365PostMessage.O365PostMessageBuild.O365PostMessageBuild@0
- displayName: 'Graph Client Tooling pipeline fail notification'
- inputs:
- addressType: serviceEndpoint
- serviceEndpointName: 'microsoftgraph pipeline status'
- title: '$(Build.DefinitionName) failure notification'
- text: 'This pipeline has failed. View the build details for further information. This is a blocking failure. '
- condition: and(failed(), ne(variables['Build.Reason'], 'Manual'))
- enabled: true
\ No newline at end of file
diff --git a/.azure-pipelines/generate-beta-rollup-module.yml b/.azure-pipelines/generate-beta-rollup-module.yml
deleted file mode 100644
index a2179ae12a8..00000000000
--- a/.azure-pipelines/generate-beta-rollup-module.yml
+++ /dev/null
@@ -1,132 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-# Generates a release build artifact (nuget) for beta roll-up module.
-name: $(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
-trigger: none
-pr: none
-variables:
- MODULE_PREFIX: 'Microsoft.Graph'
- MODULE_NAME: 'Graph'
- MODULE_PATH: 'src/Graph/Graph'
-
-jobs:
-- job: MSGraphPSSDKGeneration
- displayName: MS Graph PS SDK Roll-Up Generation
- timeoutInMinutes: 300
- pool:
- vmImage: 'windows-latest'
-
- steps:
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2
- displayName: 'Run CredScan'
- inputs:
- debugMode: false
-
- - task: NuGetToolInstaller@1
- displayName: 'Install Nuget'
-
- - task: PowerShell@2
- displayName: 'Generate and Build Roll-Up Module'
- inputs:
- filePath: '$(System.DefaultWorkingDirectory)/tools/GenerateRollUpModule.ps1'
- pwsh: true
-
- - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
- displayName: 'ESRP CodeSigning (Graph Roll-Up Module)'
- inputs:
- ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet'
- FolderPath: $(MODULE_PATH)
- Pattern: '$(MODULE_PREFIX).psm1, $(MODULE_PREFIX).*.format.ps1xml, *.ps1'
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "keyCode": "CP-230012",
- "operationSetCode": "SigntoolSign",
- "parameters": [
- {
- "parameterName": "OpusName",
- "parameterValue": "Microsoft"
- },
- {
- "parameterName": "OpusInfo",
- "parameterValue": "http://www.microsoft.com"
- },
- {
- "parameterName": "FileDigest",
- "parameterValue": "/fd \"SHA256\""
- },
- {
- "parameterName": "PageHash",
- "parameterValue": "/NPH"
- },
- {
- "parameterName": "TimeStamp",
- "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
- }
- ],
- "toolName": "sign",
- "toolVersion": "1.0"
- },
- {
- "keyCode": "CP-230012",
- "operationSetCode": "SigntoolVerify",
- "parameters": [],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
- SessionTimeout: 20
-
- - task: NuGetCommand@2
- displayName: 'Pack Roll-Up Module'
- inputs:
- command: 'pack'
- Configuration: Release
- packagesToPack: '$(System.DefaultWorkingDirectory)/$(MODULE_PATH)/$(MODULE_PREFIX).nuspec'
- packDestination: '$(Build.ArtifactStagingDirectory)/'
- versioningScheme: 'off'
-
- - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
- displayName: 'ESRP NuGet CodeSigning'
- inputs:
- ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet'
- FolderPath: '$(Build.ArtifactStagingDirectory)/'
- Pattern: 'Microsoft.Graph*.nupkg'
- signConfigType: inlineSignParams
- inlineOperation: |
- [
- {
- "keyCode": "CP-401405",
- "operationSetCode": "NuGetSign",
- "parameters": [ ],
- "toolName": "sign",
- "toolVersion": "1.0"
- },
- {
- "keyCode": "CP-401405",
- "operationSetCode": "NuGetVerify",
- "parameters": [ ],
- "toolName": "sign",
- "toolVersion": "1.0"
- }
- ]
- SessionTimeout: 20
-
- - task: PublishBuildArtifacts@1
- displayName: Publish Artifact Microsoft.Graph.nupkg'
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)/'
- ArtifactName: 'drop'
- publishLocation: 'Container'
-
- - task: YodLabs.O365PostMessage.O365PostMessageBuild.O365PostMessageBuild@0
- displayName: 'Graph Client Tooling pipeline fail notification'
- inputs:
- addressType: serviceEndpoint
- serviceEndpointName: 'microsoftgraph pipeline status'
- title: '$(Build.DefinitionName) failure notification'
- text: 'This pipeline has failed. View the build details for further information. This is a blocking failure. '
- condition: and(failed(), ne(variables['Build.Reason'], 'Manual'))
- enabled: true
\ No newline at end of file
diff --git a/.azure-pipelines/generate-modules-template.yml b/.azure-pipelines/generate-modules-template.yml
index de39096de2c..40a844f8a05 100644
--- a/.azure-pipelines/generate-modules-template.yml
+++ b/.azure-pipelines/generate-modules-template.yml
@@ -6,10 +6,6 @@ parameters:
displayName: 'Module Path'
type: string
default: 'src\Authentication\Authentication\bin\'
- - name: AUTH_MODULE_DLL_PATTERN
- displayName: 'Module Pattern'
- type: string
- default: 'Microsoft.Graph.Authentication.dll'
- name: Api_Key
displayName: 'Api Key'
type: string
@@ -66,7 +62,7 @@ jobs:
inputs:
ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet (AKV)'
FolderPath: $(AUTH_MODULE_PATH)
- Pattern: '$(AUTH_MODULE_DLL_PATTERN)'
+ Pattern: 'Microsoft.Graph.Authentication.dll, Microsoft.Graph.Authentication.Core.dll'
signConfigType: inlineSignParams
inlineOperation: |
[
@@ -93,7 +89,7 @@ jobs:
inputs:
ConnectedServiceName: 'microsoftgraph ESRP CodeSign DLL and NuGet (AKV)'
FolderPath: $(AUTH_MODULE_PATH)
- Pattern: $(AUTH_MODULE_DLL_PATTERN)
+ Pattern: 'Microsoft.Graph.Authentication.dll, Microsoft.Graph.Authentication.Core.dll'
signConfigType: inlineSignParams
inlineOperation: |
[
diff --git a/.azure-pipelines/generation-templates/generate-service-modules.yml b/.azure-pipelines/generation-templates/generate-service-modules.yml
index 599dd804e30..dd2c922ff8a 100644
--- a/.azure-pipelines/generation-templates/generate-service-modules.yml
+++ b/.azure-pipelines/generation-templates/generate-service-modules.yml
@@ -6,8 +6,6 @@ parameters:
type: string
- name: AuthModulePath
type: string
- - name: AuthModuleDllPattern
- type: string
- name: ServiceModulePath
type: string
- name: ModulePrefix
@@ -30,7 +28,6 @@ jobs:
Branch: ${{ parameters.Branch }}
ModulesToGenerate: ${{ parameters.ModulesToGenerate }}
AuthModulePath: ${{ parameters.AuthModulePath }}
- AuthModuleDllPattern: ${{ parameters.AuthModuleDllPattern }}
ServiceModulePath: ${{ parameters.ServiceModulePath }}
ModulePrefix: ${{ parameters.ModulePrefix }}
EnableSigning: ${{ parameters.EnableSigning }}
@@ -64,7 +61,7 @@ jobs:
inputs:
ConnectedServiceName: "microsoftgraph ESRP CodeSign DLL and NuGet (AKV)"
FolderPath: $(AuthModulePath)
- Pattern: $(AuthModuleDllPattern)
+ Pattern: 'Microsoft.Graph.Authentication.dll, Microsoft.Graph.Authentication.Core.dll'
signConfigType: inlineSignParams
inlineOperation: |
[
@@ -91,7 +88,7 @@ jobs:
inputs:
ConnectedServiceName: "microsoftgraph ESRP CodeSign DLL and NuGet (AKV)"
FolderPath: $(AuthModulePath)
- Pattern: $(AuthModuleDllPattern)
+ Pattern: 'Microsoft.Graph.Authentication.dll, Microsoft.Graph.Authentication.Core.dll'
signConfigType: inlineSignParams
inlineOperation: |
[
diff --git a/.azure-pipelines/integrated-pipeline.yml b/.azure-pipelines/integrated-pipeline.yml
index 93fcf8488af..dc2af0bc751 100644
--- a/.azure-pipelines/integrated-pipeline.yml
+++ b/.azure-pipelines/integrated-pipeline.yml
@@ -17,8 +17,6 @@ parameters:
variables:
AUTH_MODULE_NAME: 'Authentication'
AUTH_MODULE_PATH: 'src\Authentication\Authentication'
- AUTH_MODULE_DLL_PATTERN: 'Microsoft.Graph.Authentication.dll'
- MODULE_DLL_PATTERN: 'Microsoft.Graph.Authentication.dll'
MODULE_PREFIX: 'Microsoft.Graph'
ROLLUP_MODULE_NAME: 'Graph'
ROLLUP_MODULE_PATH: 'src/Graph/Graph'
@@ -101,7 +99,6 @@ stages:
Api_Key: $(Api_Key)
AUTH_MODULE_NAME: $(AUTH_MODULE)
AUTH_MODULE_PATH: $(AUTH_MODULE_PATH)
- AUTH_MODULE_DLL_PATTERN: $(AUTH_MODULE_DLL_PATTERN)
EnableSigning: true
BUILDNUMBER: $(BUILDNUMBER)
@@ -115,7 +112,6 @@ stages:
WORKLOAD_MODULE_PATH: $(WORKLOAD_MODULE_PATH)
GRAPH_VERSION: $(GRAPH_VERSION)
AUTH_MODULE_PATH: $(AUTH_MODULE_PATH)
- AUTH_MODULE_DLL_PATTERN: $(AUTH_MODULE_DLL_PATTERN)
EnableSigning: true
BUILDNUMBER: $(BUILDNUMBER)
diff --git a/.azure-pipelines/validate-pr-auth-module.yml b/.azure-pipelines/validate-pr-auth-module.yml
deleted file mode 100644
index 1dd1b386db7..00000000000
--- a/.azure-pipelines/validate-pr-auth-module.yml
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-# Validate pull requests to master and dev branches for auth module.
-name: $(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
-pr:
- branches:
- include:
- - dev
- - master
- - milestone/*
- paths:
- include:
- - src/Authentication/*
-trigger: none
-
-jobs:
-- job: MSGraphPSSDKValidation_Windows
- displayName: MS Graph PS SDK Auth Validation - Windows
- timeoutInMinutes: 300
- pool:
- vmImage: 'windows-latest'
-
- steps:
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2
- displayName: 'Run CredScan'
- inputs:
- debugMode: false
-
- - task: PowerShell@2
- displayName: 'Generate and Build Auth Module'
- inputs:
- filePath: '$(System.DefaultWorkingDirectory)/tools/GenerateAuthenticationModule.ps1'
- arguments: '-RepositoryApiKey $(Api_Key) -ArtifactsLocation $(Build.ArtifactStagingDirectory) -Build'
- pwsh: true
-
- - task: DotNetCoreCLI@2
- displayName: 'Run Enabled Tests'
- inputs:
- command: 'test'
- projects: '$(System.DefaultWorkingDirectory)/src/Authentication/Authentication.Test/*.csproj'
- testRunTitle: 'Run Enabled Tests'
-
- - task: YodLabs.O365PostMessage.O365PostMessageBuild.O365PostMessageBuild@0
- displayName: 'Graph Client Tooling pipeline fail notification'
- inputs:
- addressType: serviceEndpoint
- serviceEndpointName: 'microsoftgraph pipeline status'
- title: '$(Build.DefinitionName) failure notification'
- text: 'This pipeline has failed. View the build details for further information. This is a blocking failure. '
- condition: and(failed(), ne(variables['Build.Reason'], 'Manual'))
- enabled: true
-
-- job: MSGraphPSSDKValidation_Linux
- displayName: MS Graph PS SDK Auth Validation - Linux
- pool:
- vmImage: 'ubuntu-latest'
- steps:
- - task: DotNetCoreCLI@2
- displayName: 'Run Enabled Tests'
- inputs:
- command: 'test'
- projects: '$(System.DefaultWorkingDirectory)/src/Authentication/Authentication.Test/*.csproj'
- testRunTitle: 'Run Enabled Tests'
-
- - task: YodLabs.O365PostMessage.O365PostMessageBuild.O365PostMessageBuild@0
- displayName: 'Graph Client Tooling pipeline fail notification'
- inputs:
- addressType: serviceEndpoint
- serviceEndpointName: 'microsoftgraph pipeline status'
- title: '$(Build.DefinitionName) failure notification'
- text: 'This pipeline has failed. View the build details for further information. This is a blocking failure. '
- condition: and(failed(), ne(variables['Build.Reason'], 'Manual'))
- enabled: true
-
-- job: MSGraphPSSDKValidation_MacOS
- displayName: MS Graph PS SDK Auth Validation - MacOS
- pool:
- vmImage: 'macOS-latest'
- steps:
- - task: DotNetCoreCLI@2
- displayName: 'Run Enabled Tests'
- inputs:
- command: 'test'
- projects: '$(System.DefaultWorkingDirectory)/src/Authentication/Authentication.Test/*.csproj'
- testRunTitle: 'Run Enabled Tests'
-
- - task: YodLabs.O365PostMessage.O365PostMessageBuild.O365PostMessageBuild@0
- displayName: 'Graph Client Tooling pipeline fail notification'
- inputs:
- addressType: serviceEndpoint
- serviceEndpointName: 'microsoftgraph pipeline status'
- title: '$(Build.DefinitionName) failure notification'
- text: 'This pipeline has failed. View the build details for further information. This is a blocking failure. '
- condition: and(failed(), ne(variables['Build.Reason'], 'Manual'))
- enabled: true
\ No newline at end of file
diff --git a/.azure-pipelines/validate-pr-beta-modules.yml b/.azure-pipelines/validate-pr-beta-modules.yml
deleted file mode 100644
index c89258b16e5..00000000000
--- a/.azure-pipelines/validate-pr-beta-modules.yml
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-# Validate pull requests to master and dev branches for Graph workload modules.
-name: $(BuildDefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
-pr:
- branches:
- include:
- - master
- - dev
- - milestone/*
- paths:
- include:
- - src/Beta/*
- - config/ModulesMapping.jsonc
-trigger: none
-
-variables:
- GRAPH_VERSION: 'beta'
-
-jobs:
-- job: MSGraphPSSDKValidation
- displayName: MS Graph PS SDK Beta Validation
- timeoutInMinutes: 600
- pool:
- name: Microsoft Graph
- demands: 'Agent.Name -equals PS-Build-Agent'
-
- steps:
- - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2
- displayName: 'Run CredScan'
- inputs:
- debugMode: false
-
- # Install Node
- - task: NodeTool@0
- displayName: Node install
- inputs:
- versionSpec: '13.14.0'
-
- - task: Npm@1
- displayName: 'Install AutoRest'
- inputs:
- command: 'custom'
- customCommand: 'install -g autorest'
-
- - task: PowerShell@2
- displayName: 'Generate and Build Graph Resource Modules'
- inputs:
- filePath: '$(System.DefaultWorkingDirectory)/tools/GenerateModules.ps1'
- arguments: '-RepositoryApiKey $(Api_Key) -Build -Test'
- pwsh: true
-
- - task: YodLabs.O365PostMessage.O365PostMessageBuild.O365PostMessageBuild@0
- displayName: 'Graph Client Tooling pipeline fail notification'
- inputs:
- addressType: serviceEndpoint
- serviceEndpointName: 'microsoftgraph pipeline status'
- title: '$(Build.DefinitionName) failure notification'
- text: 'This pipeline has failed. View the build details for further information. This is a blocking failure. '
- condition: and(failed(), ne(variables['Build.Reason'], 'Manual'))
- enabled: true
\ No newline at end of file
diff --git a/.azure-pipelines/weekly-generation.yml b/.azure-pipelines/weekly-generation.yml
index f6ef8293ca7..48a7331a877 100644
--- a/.azure-pipelines/weekly-generation.yml
+++ b/.azure-pipelines/weekly-generation.yml
@@ -42,8 +42,7 @@ stages:
parameters:
ModulesToGenerate: $[ stageDependencies.DownloadOpenAPIDocs.GetLatestDocs.outputs['OpenAPIDocDiff.ModulesWithChanges'] ]
Branch: $[ stageDependencies.DownloadOpenAPIDocs.GetLatestDocs.outputs['ComputeBranch.WeeklyBranch'] ]
- AuthModulePath: "src/Authentication/Authentication/bin/"
- AuthModuleDllPattern: "Microsoft.Graph.Authentication.dll"
+ AuthModulePath: "src/Authentication/Authentication"
ServiceModulePath: "src/"
ModulePrefix: "Microsoft.Graph"
EnableSigning: false
diff --git a/src/Authentication/Authentication.Core/Authenticator.cs b/src/Authentication/Authentication.Core/Authenticator.cs
new file mode 100644
index 00000000000..fe23f3a1a1c
--- /dev/null
+++ b/src/Authentication/Authentication.Core/Authenticator.cs
@@ -0,0 +1,112 @@
+// ------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
+// ------------------------------------------------------------------------------
+
+namespace Microsoft.Graph.Authentication.Core
+{
+ using Microsoft.Graph.Auth;
+ using Microsoft.Graph.PowerShell.Authentication;
+ using Microsoft.Graph.PowerShell.Authentication.Core;
+ using Microsoft.Graph.PowerShell.Authentication.Helpers;
+ using Microsoft.Identity.Client;
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Linq;
+ using System.Net.Http;
+ using System.Threading;
+ using System.Threading.Tasks;
+
+ ///
+ /// Authenticator class for handling sign-ins and sign-outs.
+ ///
+ public static class Authenticator
+ {
+ ///
+ /// Authenticates the client using the provided .
+ ///
+ /// The to authenticate.
+ /// Whether or not to force refresh a token if one exists.
+ /// The cancellation token.
+ ///
+ public static async Task AuthenticateAsync(IAuthContext authContext, bool forceRefresh, CancellationToken cancellationToken)
+ {
+ try
+ {
+ // Gets a static instance of IAuthenticationProvider when the client app hasn't changed.
+ IAuthenticationProvider authProvider = AuthenticationHelpers.GetAuthProvider(authContext);
+ IClientApplicationBase clientApplication = null;
+ if (authContext.AuthType == AuthenticationType.Delegated)
+ {
+ clientApplication = (authProvider as DeviceCodeProvider).ClientApplication;
+ }
+ if (authContext.AuthType == AuthenticationType.AppOnly)
+ {
+ clientApplication = (authProvider as ClientCredentialProvider).ClientApplication;
+ }
+
+ // Incremental scope consent without re-instantiating the auth provider. We will use a static instance.
+ GraphRequestContext graphRequestContext = new GraphRequestContext();
+ graphRequestContext.CancellationToken = cancellationToken;
+ graphRequestContext.MiddlewareOptions = new Dictionary
+ {
+ {
+ typeof(AuthenticationHandlerOption).ToString(),
+ new AuthenticationHandlerOption
+ {
+ AuthenticationProviderOption = new AuthenticationProviderOption
+ {
+ Scopes = authContext.Scopes,
+ ForceRefresh = forceRefresh
+ }
+ }
+ }
+ };
+
+ // Trigger consent.
+ HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me");
+ httpRequestMessage.Properties.Add(typeof(GraphRequestContext).ToString(), graphRequestContext);
+ await authProvider.AuthenticateRequestAsync(httpRequestMessage);
+
+ IAccount account = null;
+ if (clientApplication != null)
+ {
+ // Only get accounts when we are using MSAL to get an access token.
+ IEnumerable accounts = clientApplication.GetAccountsAsync().GetAwaiter().GetResult();
+ account = accounts.FirstOrDefault();
+ }
+
+ JwtHelpers.DecodeJWT(httpRequestMessage.Headers.Authorization?.Parameter, account, ref authContext);
+ return authContext;
+ }
+ catch (AuthenticationException authEx)
+ {
+ if ((authEx.InnerException is TaskCanceledException) && cancellationToken.IsCancellationRequested)
+ {
+ // DeviceCodeTimeout
+ throw new Exception(string.Format(
+ CultureInfo.CurrentCulture,
+ ErrorConstants.Message.DeviceCodeTimeout,
+ Constants.MaxDeviceCodeTimeOut));
+ }
+ else
+ {
+ throw authEx.InnerException ?? authEx;
+ }
+ }
+ catch (Exception ex)
+ {
+ throw ex.InnerException ?? ex;
+ }
+ }
+
+ ///
+ /// Signs out of the provided .
+ ///
+ /// The to sign-out from.
+ public static void LogOut(IAuthContext authContext)
+ {
+ AuthenticationHelpers.Logout(authContext);
+ }
+ }
+}
diff --git a/src/Authentication/Authentication/Common/GraphSession.cs b/src/Authentication/Authentication.Core/Common/GraphSession.cs
similarity index 98%
rename from src/Authentication/Authentication/Common/GraphSession.cs
rename to src/Authentication/Authentication.Core/Common/GraphSession.cs
index 275b4a190b0..9de7e41c12d 100644
--- a/src/Authentication/Authentication/Common/GraphSession.cs
+++ b/src/Authentication/Authentication.Core/Common/GraphSession.cs
@@ -4,6 +4,7 @@
namespace Microsoft.Graph.PowerShell.Authentication
{
+ using Microsoft.Graph.PowerShell.Authentication.Core;
using Microsoft.Graph.PowerShell.Authentication.Interfaces;
using System;
using System.Security;
@@ -175,7 +176,7 @@ public static void Modify(Action modifier)
///
/// Resets the current instance of to initial state.
///
- internal static void Reset()
+ public static void Reset()
{
try
{
diff --git a/src/Authentication/Authentication.Core/Constants.cs b/src/Authentication/Authentication.Core/Constants.cs
new file mode 100644
index 00000000000..2b7675a6089
--- /dev/null
+++ b/src/Authentication/Authentication.Core/Constants.cs
@@ -0,0 +1,18 @@
+// ------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
+// ------------------------------------------------------------------------------
+
+namespace Microsoft.Graph.PowerShell.Authentication.Core
+{
+ using System.IO;
+ public static class Constants
+ {
+ public const int MaxDeviceCodeTimeOut = 120; // 2 mins timeout.
+ public static readonly string GraphDirectoryPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile), ".graph");
+ internal const string TokenCacheServiceName = "com.microsoft.graph.powershell.sdkcache";
+ internal const string DefaultProfile = "v1.0";
+ internal const int TokenExpirationBufferInMinutes = 5;
+ internal const string DefaulAdTenant = "common";
+ internal const string DefaultAzureADEndpoint = "https://login.microsoftonline.com";
+ }
+}
diff --git a/src/Authentication/Authentication.Core/ErrorConstants.cs b/src/Authentication/Authentication.Core/ErrorConstants.cs
new file mode 100644
index 00000000000..3ee456579e6
--- /dev/null
+++ b/src/Authentication/Authentication.Core/ErrorConstants.cs
@@ -0,0 +1,31 @@
+// ------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
+// ------------------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Graph.PowerShell.Authentication.Core
+{
+ public static class ErrorConstants
+ {
+ internal static class Codes
+ {
+ internal const string SessionNotInitialized = "sessionNotInitialized";
+ internal const string SessionLockReadRecursion = "sessionLockReadRecursion";
+ internal const string SessionLockReadDisposed = "sessionLockReadDisposed";
+ internal const string SessionLockWriteDisposed = "sessionLockWriteDisposed";
+ internal const string SessionLockWriteRecursion = "sessionLockWriteRecursion";
+ internal const string InvalidJWT = "invalidJWT";
+ }
+
+ public static class Message
+ {
+ public const string MissingAuthContext = "Authentication needed, call Connect-MgGraph.";
+ internal const string InvalidJWT = "Invalid JWT access token.";
+ internal const string NullOrEmptyParameter = "Parameter '{0}' cannot be null or empty.";
+ internal const string MacKeyChainFailed = "{0} failed with result code {1}.";
+ internal const string DeviceCodeTimeout = "Device code terminal timed-out after {0} seconds. Please try again.";
+ internal const string InvalidUserProvidedToken = "The provided access token is invalid. Set a valid access token to `-{0}` parameter and try again.";
+ internal const string ExpiredUserProvidedToken = "The provided access token has expired. Set a valid access token to `-{0}` parameter and try again.";
+ }
+ }
+}
diff --git a/src/Authentication/Authentication/Interfaces/IAuthContext.cs b/src/Authentication/Authentication.Core/Interfaces/IAuthContext.cs
similarity index 100%
rename from src/Authentication/Authentication/Interfaces/IAuthContext.cs
rename to src/Authentication/Authentication.Core/Interfaces/IAuthContext.cs
diff --git a/src/Authentication/Authentication/Interfaces/IDataStore.cs b/src/Authentication/Authentication.Core/Interfaces/IDataStore.cs
similarity index 100%
rename from src/Authentication/Authentication/Interfaces/IDataStore.cs
rename to src/Authentication/Authentication.Core/Interfaces/IDataStore.cs
diff --git a/src/Authentication/Authentication/Interfaces/IGraphEnvironment.cs b/src/Authentication/Authentication.Core/Interfaces/IGraphEnvironment.cs
similarity index 100%
rename from src/Authentication/Authentication/Interfaces/IGraphEnvironment.cs
rename to src/Authentication/Authentication.Core/Interfaces/IGraphEnvironment.cs
diff --git a/src/Authentication/Authentication/Interfaces/IGraphSession.cs b/src/Authentication/Authentication.Core/Interfaces/IGraphSession.cs
similarity index 100%
rename from src/Authentication/Authentication/Interfaces/IGraphSession.cs
rename to src/Authentication/Authentication.Core/Interfaces/IGraphSession.cs
diff --git a/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj b/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj
new file mode 100644
index 00000000000..9832da8843a
--- /dev/null
+++ b/src/Authentication/Authentication.Core/Microsoft.Graph.Authentication.Core.csproj
@@ -0,0 +1,26 @@
+
+
+
+ netstandard2.0;netcoreapp2.1;net461
+ Microsoft.Graph.PowerShell.Authentication.Core
+ 1.4.2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Authentication/Authentication/Models/JwtPayload.cs b/src/Authentication/Authentication.Core/Models/JwtPayload.cs
similarity index 100%
rename from src/Authentication/Authentication/Models/JwtPayload.cs
rename to src/Authentication/Authentication.Core/Models/JwtPayload.cs
diff --git a/src/Authentication/Authentication.Core/Properties/AssemblyInfo.cs b/src/Authentication/Authentication.Core/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000000..47dc954fb32
--- /dev/null
+++ b/src/Authentication/Authentication.Core/Properties/AssemblyInfo.cs
@@ -0,0 +1,5 @@
+using System.Runtime.CompilerServices;
+
+#if DEBUG
+[assembly: InternalsVisibleTo("Microsoft.Graph.Authentication.Test")]
+#endif
diff --git a/src/Authentication/Authentication/TokenCache/LinuxTokenCache.cs b/src/Authentication/Authentication.Core/TokenCache/LinuxTokenCache.cs
similarity index 98%
rename from src/Authentication/Authentication/TokenCache/LinuxTokenCache.cs
rename to src/Authentication/Authentication.Core/TokenCache/LinuxTokenCache.cs
index f195708c02b..1c73c082c29 100644
--- a/src/Authentication/Authentication/TokenCache/LinuxTokenCache.cs
+++ b/src/Authentication/Authentication.Core/TokenCache/LinuxTokenCache.cs
@@ -4,6 +4,7 @@
namespace Microsoft.Graph.PowerShell.Authentication.TokenCache
{
+ using Microsoft.Graph.PowerShell.Authentication.Core;
using Microsoft.Graph.PowerShell.Authentication.TokenCache.NativePlatformLibs;
using System;
using System.Globalization;
diff --git a/src/Authentication/Authentication/TokenCache/MacTokenCache.cs b/src/Authentication/Authentication.Core/TokenCache/MacTokenCache.cs
similarity index 99%
rename from src/Authentication/Authentication/TokenCache/MacTokenCache.cs
rename to src/Authentication/Authentication.Core/TokenCache/MacTokenCache.cs
index 3ac7a642300..b06a641dac4 100644
--- a/src/Authentication/Authentication/TokenCache/MacTokenCache.cs
+++ b/src/Authentication/Authentication.Core/TokenCache/MacTokenCache.cs
@@ -4,6 +4,7 @@
namespace Microsoft.Graph.PowerShell.Authentication.TokenCache
{
+ using Microsoft.Graph.PowerShell.Authentication.Core;
using Microsoft.Graph.PowerShell.Authentication.TokenCache.NativePlatformLibs;
using System;
using System.Globalization;
diff --git a/src/Authentication/Authentication/TokenCache/NativePlatformLibs/LinuxNativeKeyUtils.cs b/src/Authentication/Authentication.Core/TokenCache/NativePlatformLibs/LinuxNativeKeyUtils.cs
similarity index 100%
rename from src/Authentication/Authentication/TokenCache/NativePlatformLibs/LinuxNativeKeyUtils.cs
rename to src/Authentication/Authentication.Core/TokenCache/NativePlatformLibs/LinuxNativeKeyUtils.cs
diff --git a/src/Authentication/Authentication/TokenCache/NativePlatformLibs/MacNativeKeyChain.cs b/src/Authentication/Authentication.Core/TokenCache/NativePlatformLibs/MacNativeKeyChain.cs
similarity index 100%
rename from src/Authentication/Authentication/TokenCache/NativePlatformLibs/MacNativeKeyChain.cs
rename to src/Authentication/Authentication.Core/TokenCache/NativePlatformLibs/MacNativeKeyChain.cs
diff --git a/src/Authentication/Authentication/TokenCache/TokenCacheStorage.cs b/src/Authentication/Authentication.Core/TokenCache/TokenCacheStorage.cs
similarity index 98%
rename from src/Authentication/Authentication/TokenCache/TokenCacheStorage.cs
rename to src/Authentication/Authentication.Core/TokenCache/TokenCacheStorage.cs
index b1796dc5e73..dce951e1800 100644
--- a/src/Authentication/Authentication/TokenCache/TokenCacheStorage.cs
+++ b/src/Authentication/Authentication.Core/TokenCache/TokenCacheStorage.cs
@@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------
+using Microsoft.Graph.PowerShell.Authentication.Core;
using System;
using System.Globalization;
using System.Security;
diff --git a/src/Authentication/Authentication/TokenCache/WindowsTokenCache.cs b/src/Authentication/Authentication.Core/TokenCache/WindowsTokenCache.cs
similarity index 98%
rename from src/Authentication/Authentication/TokenCache/WindowsTokenCache.cs
rename to src/Authentication/Authentication.Core/TokenCache/WindowsTokenCache.cs
index fa2612ab814..335c87bb632 100644
--- a/src/Authentication/Authentication/TokenCache/WindowsTokenCache.cs
+++ b/src/Authentication/Authentication.Core/TokenCache/WindowsTokenCache.cs
@@ -4,6 +4,7 @@
namespace Microsoft.Graph.PowerShell.Authentication.TokenCache
{
+ using Microsoft.Graph.PowerShell.Authentication.Core;
using System;
using System.Globalization;
using System.IO;
diff --git a/src/Authentication/Authentication/Helpers/AuthenticationHelpers.cs b/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs
similarity index 82%
rename from src/Authentication/Authentication/Helpers/AuthenticationHelpers.cs
rename to src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs
index 93631d0a257..0d3eb662b18 100644
--- a/src/Authentication/Authentication/Helpers/AuthenticationHelpers.cs
+++ b/src/Authentication/Authentication.Core/Utilities/AuthenticationHelpers.cs
@@ -4,7 +4,7 @@
namespace Microsoft.Graph.PowerShell.Authentication.Helpers
{
using Microsoft.Graph.Auth;
- using Microsoft.Graph.PowerShell.Authentication.Models;
+ using Microsoft.Graph.PowerShell.Authentication.Core;
using Microsoft.Graph.PowerShell.Authentication.TokenCache;
using Microsoft.Identity.Client;
@@ -18,11 +18,43 @@ namespace Microsoft.Graph.PowerShell.Authentication.Helpers
using AuthenticationException = System.Security.Authentication.AuthenticationException;
- internal static class AuthenticationHelpers
+ ///
+ /// Helper class for authentication.
+ ///
+ public static class AuthenticationHelpers
{
static ReaderWriterLockSlim _cacheLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
- internal static IAuthenticationProvider GetAuthProvider(IAuthContext authContext)
+ ///
+ /// Signs out of the current session using the provided .
+ ///
+ /// The to sign-out from.
+ internal static void Logout(IAuthContext authContext)
+ {
+ try
+ {
+ _cacheLock.EnterWriteLock();
+ if (authContext.AuthType == AuthenticationType.UserProvidedAccessToken)
+ {
+ GraphSession.Instance.UserProvidedToken = null;
+ }
+ else
+ {
+ TokenCacheStorage.DeleteToken(authContext);
+ }
+ }
+ finally
+ {
+ _cacheLock.ExitWriteLock();
+ }
+ }
+
+ ///
+ /// Gets an using the provide .
+ ///
+ /// The to get an auth provider for.
+ /// A based on provided .
+ public static IAuthenticationProvider GetAuthProvider(IAuthContext authContext)
{
if (authContext is null)
{
@@ -75,70 +107,12 @@ internal static IAuthenticationProvider GetAuthProvider(IAuthContext authContext
}
return authProvider;
}
+
///
- /// Gets a certificate based on the current context.
- /// Priority is Name, ThumbPrint, then In-Memory Cert
+ /// Configures a token cache using the provide .
///
- /// Current context
- /// A based on provided context
- private static X509Certificate2 GetCertificate(IAuthContext context)
- {
- X509Certificate2 certificate;
- if (!string.IsNullOrWhiteSpace(context.CertificateName))
- {
- certificate = GetCertificateByName(context.CertificateName);
- }
- else if (!string.IsNullOrWhiteSpace(context.CertificateThumbprint))
- {
- certificate = GetCertificateByThumbprint(context.CertificateThumbprint);
- }
- else
- {
- certificate = context.Certificate;
- }
-
- if (certificate == null)
- {
- throw new ArgumentNullException(nameof(certificate), $"Certificate with the Specified ThumbPrint {context.CertificateThumbprint}, Name {context.CertificateName} or In-Memory could not be found");
- }
-
- return certificate;
- }
-
- private static string GetAuthorityUrl(IAuthContext authContext)
- {
- string audience = authContext.TenantId ?? GraphEnvironmentConstants.CommonAdTenant;
- string defaultInstance = GraphEnvironment.BuiltInEnvironments[GraphEnvironmentConstants.EnvironmentName.Global].AzureADEndpoint;
- string authorityUrl = $"{defaultInstance}/{audience}";
-
- if (GraphSession.Instance.Environment != null)
- {
- authorityUrl = $"{GraphSession.Instance.Environment.AzureADEndpoint}/{audience}";
- }
-
- return authorityUrl;
- }
-
- internal static void Logout(IAuthContext authConfig)
- {
- try
- {
- _cacheLock.EnterWriteLock();
- if (authConfig.AuthType == AuthenticationType.UserProvidedAccessToken)
- {
- GraphSession.Instance.UserProvidedToken = null;
- }
- else
- {
- TokenCacheStorage.DeleteToken(authConfig);
- }
- }
- finally
- {
- _cacheLock.ExitWriteLock();
- }
- }
-
+ /// MSAL's token cache to configure.
+ /// The to get configure an token cache for.
private static void ConfigureTokenCache(ITokenCache tokenCache, IAuthContext authContext)
{
tokenCache.SetBeforeAccess((TokenCacheNotificationArgs args) =>
@@ -171,6 +145,55 @@ private static void ConfigureTokenCache(ITokenCache tokenCache, IAuthContext aut
});
}
+ ///
+ /// Gets an authority URL from the provided .
+ ///
+ /// The to get an authority URL for.
+ ///
+ private static string GetAuthorityUrl(IAuthContext authContext)
+ {
+ string audience = authContext.TenantId ?? Constants.DefaulAdTenant;
+ string defaultInstance = Constants.DefaultAzureADEndpoint;
+ string authorityUrl = $"{defaultInstance}/{audience}";
+
+ if (GraphSession.Instance.Environment != null)
+ {
+ authorityUrl = $"{GraphSession.Instance.Environment.AzureADEndpoint}/{audience}";
+ }
+
+ return authorityUrl;
+ }
+
+ ///
+ /// Gets a certificate based on the current context.
+ /// Priority is Name, ThumbPrint, then In-Memory Cert
+ ///
+ /// Current context
+ /// A based on provided context
+ private static X509Certificate2 GetCertificate(IAuthContext context)
+ {
+ X509Certificate2 certificate;
+ if (!string.IsNullOrWhiteSpace(context.CertificateName))
+ {
+ certificate = GetCertificateByName(context.CertificateName);
+ }
+ else if (!string.IsNullOrWhiteSpace(context.CertificateThumbprint))
+ {
+ certificate = GetCertificateByThumbprint(context.CertificateThumbprint);
+ }
+ else
+ {
+ certificate = context.Certificate;
+ }
+
+ if (certificate == null)
+ {
+ throw new ArgumentNullException(nameof(certificate), $"Certificate with the Specified ThumbPrint {context.CertificateThumbprint}, Name {context.CertificateName} or In-Memory could not be found");
+ }
+
+ return certificate;
+ }
+
///
/// Gets unexpired certificate of the specified certificate thumbprint for the current user in My store.
///
diff --git a/src/Authentication/Authentication/Helpers/JwtHelpers.cs b/src/Authentication/Authentication.Core/Utilities/JwtHelpers.cs
similarity index 57%
rename from src/Authentication/Authentication/Helpers/JwtHelpers.cs
rename to src/Authentication/Authentication.Core/Utilities/JwtHelpers.cs
index a8e45b9165c..c877d2785c5 100644
--- a/src/Authentication/Authentication/Helpers/JwtHelpers.cs
+++ b/src/Authentication/Authentication.Core/Utilities/JwtHelpers.cs
@@ -5,20 +5,53 @@
namespace Microsoft.Graph.PowerShell.Authentication.Helpers
{
using Microsoft.Graph.Auth;
- using Microsoft.IdentityModel.Tokens;
+ using Microsoft.Graph.PowerShell.Authentication.Core;
+ using Microsoft.Identity.Client;
using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
using System;
- using System.Collections.Generic;
+ using System.Globalization;
using System.IdentityModel.Tokens.Jwt;
- using System.Security.Claims;
- using System.Text;
///
/// A JwtHelpers class.
///
internal static class JwtHelpers
{
+ ///
+ /// Decodes a JWT token and store claims in the provided by ref.
+ ///
+ /// A JWT string.
+ /// MSAL's .
+ /// An to store JWT claims in.
+ internal static void DecodeJWT(string jwToken, IAccount account, ref IAuthContext authContext)
+ {
+ var jwtPayload = JwtHelpers.DecodeToObject(jwToken);
+ if (authContext.AuthType == AuthenticationType.UserProvidedAccessToken)
+ {
+ if (jwtPayload == null)
+ {
+ throw new Exception(string.Format(
+ CultureInfo.CurrentCulture,
+ ErrorConstants.Message.InvalidUserProvidedToken,
+ "AccessToken"));
+ }
+
+ if (jwtPayload.Exp <= JwtHelpers.ConvertToUnixTimestamp(DateTime.UtcNow + TimeSpan.FromMinutes(Constants.TokenExpirationBufferInMinutes)))
+ {
+ throw new Exception(string.Format(
+ CultureInfo.CurrentCulture,
+ ErrorConstants.Message.ExpiredUserProvidedToken,
+ "AccessToken"));
+ }
+ }
+
+ authContext.ClientId = jwtPayload?.Appid ?? authContext.ClientId;
+ authContext.Scopes = jwtPayload?.Scp?.Split(' ') ?? jwtPayload?.Roles;
+ authContext.TenantId = jwtPayload?.Tid ?? account?.HomeAccountId?.TenantId;
+ authContext.AppName = jwtPayload?.AppDisplayname;
+ authContext.Account = jwtPayload?.Upn ?? account?.Username;
+ }
+
///
/// Decodes a JWT token by extracting claims from the payload.
///
diff --git a/src/Authentication/Authentication/Helpers/PlatformHelpers.cs b/src/Authentication/Authentication.Core/Utilities/PlatformHelpers.cs
similarity index 96%
rename from src/Authentication/Authentication/Helpers/PlatformHelpers.cs
rename to src/Authentication/Authentication.Core/Utilities/PlatformHelpers.cs
index cbb9e60ba16..0c4c98234fc 100644
--- a/src/Authentication/Authentication/Helpers/PlatformHelpers.cs
+++ b/src/Authentication/Authentication.Core/Utilities/PlatformHelpers.cs
@@ -6,7 +6,7 @@ namespace Microsoft.Graph.PowerShell.Authentication.Helpers
{
using System.Runtime.InteropServices;
- internal static class OperatingSystem
+ public static class OperatingSystem
{
///
/// Detects if the platform we are running on is Windows.
diff --git a/src/Authentication/Authentication.Test/Helpers/GraphSessionTests.cs b/src/Authentication/Authentication.Test/Helpers/GraphSessionTests.cs
index 2bb665e8ee8..cbc0ae6456e 100644
--- a/src/Authentication/Authentication.Test/Helpers/GraphSessionTests.cs
+++ b/src/Authentication/Authentication.Test/Helpers/GraphSessionTests.cs
@@ -52,7 +52,7 @@ public void ShouldThrowExceptionWhenSessionIsNotInitialized()
{
InvalidOperationException exception = Assert.Throws(() => GraphSession.Instance);
- Assert.Equal(ErrorConstants.Codes.SessionNotInitialized, exception.Message);
+ Assert.Equal(PowerShell.Authentication.Core.ErrorConstants.Codes.SessionNotInitialized, exception.Message);
// reset static instance.
GraphSession.Reset();
diff --git a/src/Authentication/Authentication.sln b/src/Authentication/Authentication.sln
index fd8252ae061..c24efddc101 100644
--- a/src/Authentication/Authentication.sln
+++ b/src/Authentication/Authentication.sln
@@ -5,7 +5,9 @@ VisualStudioVersion = 16.0.29201.188
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Graph.Authentication", "Authentication\Microsoft.Graph.Authentication.csproj", "{44FF315A-27B2-4401-81A9-1912E6511EE6}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Graph.Authentication.Test", "Authentication.Test\Microsoft.Graph.Authentication.Test.csproj", "{416590B4-3A91-4B0D-9B40-3F69438B6D85}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Graph.Authentication.Test", "Authentication.Test\Microsoft.Graph.Authentication.Test.csproj", "{416590B4-3A91-4B0D-9B40-3F69438B6D85}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Graph.Authentication.Core", "Authentication.Core\Microsoft.Graph.Authentication.Core.csproj", "{50050576-74B8-4507-B1FE-C47740BB3B71}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,6 +23,10 @@ Global
{416590B4-3A91-4B0D-9B40-3F69438B6D85}.Debug|Any CPU.Build.0 = Debug|Any CPU
{416590B4-3A91-4B0D-9B40-3F69438B6D85}.Release|Any CPU.ActiveCfg = Release|Any CPU
{416590B4-3A91-4B0D-9B40-3F69438B6D85}.Release|Any CPU.Build.0 = Release|Any CPU
+ {50050576-74B8-4507-B1FE-C47740BB3B71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {50050576-74B8-4507-B1FE-C47740BB3B71}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {50050576-74B8-4507-B1FE-C47740BB3B71}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {50050576-74B8-4507-B1FE-C47740BB3B71}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/Authentication/Authentication/Cmdlets/ConnectMgGraph.cs b/src/Authentication/Authentication/Cmdlets/ConnectMgGraph.cs
index 4bd14d38df0..4de46081237 100644
--- a/src/Authentication/Authentication/Cmdlets/ConnectMgGraph.cs
+++ b/src/Authentication/Authentication/Cmdlets/ConnectMgGraph.cs
@@ -7,17 +7,12 @@ namespace Microsoft.Graph.PowerShell.Authentication.Cmdlets
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
- using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
- using System.Globalization;
using System.Collections;
using System.Security.Cryptography.X509Certificates;
- using Identity.Client;
-
- using Microsoft.Graph.Auth;
using Microsoft.Graph.PowerShell.Authentication.Helpers;
using Microsoft.Graph.PowerShell.Authentication.Models;
@@ -25,6 +20,8 @@ namespace Microsoft.Graph.PowerShell.Authentication.Cmdlets
using Common;
using static Helpers.AsyncHelpers;
+ using Microsoft.Graph.Authentication.Core;
+ using Microsoft.Graph.PowerShell.Authentication.Utilities;
[Cmdlet(VerbsCommunications.Connect, "MgGraph", DefaultParameterSetName = Constants.UserParameterSet)]
[Alias("Connect-Graph")]
@@ -168,7 +165,7 @@ private async Task ProcessRecordAsync()
case Constants.UserParameterSet:
{
// 2 mins timeout. 1 min < HTTP timeout.
- TimeSpan authTimeout = new TimeSpan(0, 0, Constants.MaxDeviceCodeTimeOut);
+ TimeSpan authTimeout = new TimeSpan(0, 0, Core.Constants.MaxDeviceCodeTimeOut);
// To avoid re-initializing the tokenSource, use CancelAfter
_cancellationTokenSource.CancelAfter(authTimeout);
authContext.AuthType = AuthenticationType.Delegated;
@@ -201,71 +198,12 @@ private async Task ProcessRecordAsync()
try
{
- // Gets a static instance of IAuthenticationProvider when the client app hasn't changed.
- IAuthenticationProvider authProvider = AuthenticationHelpers.GetAuthProvider(authContext);
- IClientApplicationBase clientApplication = null;
- if (ParameterSetName == Constants.UserParameterSet)
- {
- clientApplication = (authProvider as DeviceCodeProvider).ClientApplication;
- }
- else if (ParameterSetName == Constants.AppParameterSet)
- {
- clientApplication = (authProvider as ClientCredentialProvider).ClientApplication;
- }
-
- // Incremental scope consent without re-instantiating the auth provider. We will use a static instance.
- GraphRequestContext graphRequestContext = new GraphRequestContext();
- graphRequestContext.CancellationToken = _cancellationTokenSource.Token;
- graphRequestContext.MiddlewareOptions = new Dictionary
- {
- {
- typeof(AuthenticationHandlerOption).ToString(),
- new AuthenticationHandlerOption
- {
- AuthenticationProviderOption = new AuthenticationProviderOption
- {
- Scopes = authContext.Scopes,
- ForceRefresh = ForceRefresh
- }
- }
- }
- };
-
- // Trigger consent.
- HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me");
- httpRequestMessage.Properties.Add(typeof(GraphRequestContext).ToString(), graphRequestContext);
- await authProvider.AuthenticateRequestAsync(httpRequestMessage);
-
- IAccount account = null;
- if (clientApplication != null)
- {
- // Only get accounts when we are using MSAL to get an access token.
- IEnumerable accounts = clientApplication.GetAccountsAsync().GetAwaiter().GetResult();
- account = accounts.FirstOrDefault();
- }
- DecodeJWT(httpRequestMessage.Headers.Authorization?.Parameter, account, ref authContext);
-
// Save auth context to session state.
- GraphSession.Instance.AuthContext = authContext;
- }
- catch (AuthenticationException authEx)
- {
- if ((authEx.InnerException is TaskCanceledException) && _cancellationTokenSource.Token.IsCancellationRequested)
- {
- // DeviceCodeTimeout
- throw new Exception(string.Format(
- CultureInfo.CurrentCulture,
- ErrorConstants.Message.DeviceCodeTimeout,
- Constants.MaxDeviceCodeTimeOut));
- }
- else
- {
- throw authEx.InnerException ?? authEx;
- }
+ GraphSession.Instance.AuthContext = await Authenticator.AuthenticateAsync(authContext, ForceRefresh, _cancellationTokenSource.Token);
}
- catch (Exception ex)
+ catch(Exception ex)
{
- throw ex.InnerException ?? ex;
+ throw ex;
}
WriteObject("Welcome To Microsoft Graph!");
@@ -348,35 +286,6 @@ private void ValidateParameters()
}
}
- private void DecodeJWT(string token, IAccount account, ref IAuthContext authContext)
- {
- JwtPayload jwtPayload = JwtHelpers.DecodeToObject(token);
- if (authContext.AuthType == AuthenticationType.UserProvidedAccessToken)
- {
- if (jwtPayload == null)
- {
- throw new Exception(string.Format(
- CultureInfo.CurrentCulture,
- ErrorConstants.Message.InvalidUserProvidedToken,
- nameof(AccessToken)));
- }
-
- if (jwtPayload.Exp <= JwtHelpers.ConvertToUnixTimestamp(DateTime.UtcNow + TimeSpan.FromMinutes(Constants.TokenExpirationBufferInMinutes)))
- {
- throw new Exception(string.Format(
- CultureInfo.CurrentCulture,
- ErrorConstants.Message.ExpiredUserProvidedToken,
- nameof(AccessToken)));
- }
- }
-
- authContext.ClientId = jwtPayload?.Appid ?? authContext.ClientId;
- authContext.Scopes = jwtPayload?.Scp?.Split(' ') ?? jwtPayload?.Roles;
- authContext.TenantId = jwtPayload?.Tid ?? account?.HomeAccountId?.TenantId;
- authContext.AppName = jwtPayload?.AppDisplayname;
- authContext.Account = jwtPayload?.Upn ?? account?.Username;
- }
-
///
/// Globally initializes GraphSession.
///
@@ -393,6 +302,7 @@ public void OnImport()
public void OnRemove(PSModuleInfo psModuleInfo)
{
GraphSession.Reset();
+ DependencyAssemblyResolver.Reset();
}
}
}
diff --git a/src/Authentication/Authentication/Cmdlets/DisconnectMgGraph.cs b/src/Authentication/Authentication/Cmdlets/DisconnectMgGraph.cs
index 8e38062da9b..a059cc595aa 100644
--- a/src/Authentication/Authentication/Cmdlets/DisconnectMgGraph.cs
+++ b/src/Authentication/Authentication/Cmdlets/DisconnectMgGraph.cs
@@ -3,6 +3,7 @@
// ------------------------------------------------------------------------------
namespace Microsoft.Graph.PowerShell.Authentication.Cmdlets
{
+ using Microsoft.Graph.Authentication.Core;
using Microsoft.Graph.PowerShell.Authentication.Helpers;
using System;
using System.Management.Automation;
@@ -24,13 +25,13 @@ protected override void ProcessRecord()
{
base.ProcessRecord();
- IAuthContext authConfig = GraphSession.Instance.AuthContext;
+ IAuthContext authContext = GraphSession.Instance.AuthContext;
- if (authConfig == null)
+ if (authContext == null)
ThrowTerminatingError(
- new ErrorRecord(new System.Exception("No application to sign out from."), Guid.NewGuid().ToString(), ErrorCategory.InvalidArgument, null));
+ new ErrorRecord(new Exception("No application to sign out from."), Guid.NewGuid().ToString(), ErrorCategory.InvalidArgument, null));
- AuthenticationHelpers.Logout(authConfig);
+ Authenticator.LogOut(authContext);
GraphSession.Instance.AuthContext = null;
}
diff --git a/src/Authentication/Authentication/Constants.cs b/src/Authentication/Authentication/Constants.cs
index 8a4cac07642..62ba55bc18b 100644
--- a/src/Authentication/Authentication/Constants.cs
+++ b/src/Authentication/Authentication/Constants.cs
@@ -7,17 +7,11 @@ namespace Microsoft.Graph.PowerShell.Authentication
using System.IO;
public static class Constants
{
- public const string GraphAuthConfigId = "GraphAuthConfigId";
public const string SDKHeaderValue = "Graph-powershell-{0}-{1}.{2}.{3}";
internal const string UserParameterSet = "UserParameterSet";
internal const string AppParameterSet = "AppParameterSet";
internal const string AccessTokenParameterSet = "AccessTokenParameterSet";
- internal const int MaxDeviceCodeTimeOut = 120; // 2 mins timeout.
- internal static readonly string GraphDirectoryPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile), ".graph");
- internal static readonly string SettingFilePath = Path.Combine(GraphDirectoryPath, "GraphContext.json");
+ internal static readonly string SettingFilePath = Path.Combine(Core.Constants.GraphDirectoryPath, "GraphContext.json");
internal const string ProfileDescription = "A snapshot of the Microsoft Graph {0} API for {1} cloud.";
- internal const string TokenCacheServiceName = "com.microsoft.graph.powershell.sdkcache";
- internal const string DefaultProfile = "v1.0";
- internal const int TokenExpirationBufferInMinutes = 5;
}
}
diff --git a/src/Authentication/Authentication/ErrorConstants.cs b/src/Authentication/Authentication/ErrorConstants.cs
index f9f6cf2fa7d..4f76a504412 100644
--- a/src/Authentication/Authentication/ErrorConstants.cs
+++ b/src/Authentication/Authentication/ErrorConstants.cs
@@ -9,12 +9,6 @@ public static class ErrorConstants
{
internal static class Codes
{
- internal const string SessionNotInitialized = "sessionNotInitialized";
- internal const string SessionLockReadRecursion = "sessionLockReadRecursion";
- internal const string SessionLockReadDisposed = "sessionLockReadDisposed";
- internal const string SessionLockWriteDisposed = "sessionLockWriteDisposed";
- internal const string SessionLockWriteRecursion = "sessionLockWriteRecursion";
- internal const string InvalidJWT = "invalidJWT";
internal const string InvokeGraphHttpResponseException = nameof(InvokeGraphHttpResponseException);
internal const string InvokeGraphContentTypeException = nameof(InvokeGraphContentTypeException);
internal const string InvokeGraphRequestInvalidHost = nameof(InvokeGraphRequestInvalidHost);
@@ -37,18 +31,10 @@ internal static class Codes
internal static class Message
{
- internal const string InvalidJWT = "Invalid JWT access token.";
- internal const string MissingAuthContext = "Authentication needed, call Connect-MgGraph.";
- internal const string NullOrEmptyParameter = "Parameter '{0}' cannot be null or empty.";
- internal const string MacKeyChainFailed = "{0} failed with result code {1}.";
- internal const string DeviceCodeTimeout = "Device code terminal timed-out after {0} seconds. Please try again.";
- internal const string InvalidUserProvidedToken = "The provided access token is invalid. Set a valid access token to `-{0}` parameter and try again.";
- internal const string ExpiredUserProvidedToken = "The provided access token has expired. Set a valid access token to `-{0}` parameter and try again.";
+ internal const string CannotModifyBuiltInEnvironment = "Cannot {0} built-in environment {1}.";
internal const string InvalidUrlParameter = "Parameter '{0}' has an invalid endpoint URL. Please use a valid URL with a network protocol i.e. [protocol]://[resource-name].";
- internal const string InvalidNationalCloud = "Parameter `{0}` has an invalid national cloud. Use Get-MgEnvironment to get a list of valid national clouds.";
internal const string InvalidEnvironment = "Unable to find environment with name '{0}'. Use Get-MgEnvironment to list available environments.";
internal const string CannotAccessFile = "Could not {0} file at '{1}'. Please ensure you have access to this file and try again in a few minutes..";
- internal const string CannotModifyBuiltInEnvironment = "Cannot {0} built-in environment {1}.";
internal const string InvalidCertificateThumbprint = "'{0}' must have a length of 40. Ensure you have the right certificate thumbprint then try again.";
}
}
diff --git a/src/Authentication/Authentication/Helpers/HttpHelpers.cs b/src/Authentication/Authentication/Helpers/HttpHelpers.cs
index 7732252c06f..1eab2b43dd6 100644
--- a/src/Authentication/Authentication/Helpers/HttpHelpers.cs
+++ b/src/Authentication/Authentication/Helpers/HttpHelpers.cs
@@ -37,7 +37,7 @@ public static HttpClient GetGraphHttpClient(IAuthContext authContext = null)
authContext = authContext ?? GraphSession.Instance.AuthContext;
if (authContext is null)
{
- throw new AuthenticationException(ErrorConstants.Message.MissingAuthContext);
+ throw new AuthenticationException(Core.ErrorConstants.Message.MissingAuthContext);
}
IAuthenticationProvider authProvider = AuthenticationHelpers.GetAuthProvider(authContext);
diff --git a/src/Authentication/Authentication/Microsoft.Graph.Authentication.csproj b/src/Authentication/Authentication/Microsoft.Graph.Authentication.csproj
index a100cca9335..17acca82e6a 100644
--- a/src/Authentication/Authentication/Microsoft.Graph.Authentication.csproj
+++ b/src/Authentication/Authentication/Microsoft.Graph.Authentication.csproj
@@ -1,38 +1,23 @@
- 1.4.0
+ 1.4.2
7.1
netstandard2.0
Library
Microsoft.Graph.Authentication
Microsoft.Graph.PowerShell.Authentication
- true
- false
- ./bin
- $(OutputPath)
true
true
Microsoft.Graph.Authentication.nuspec
© Microsoft Corporation. All rights reserved.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -47,7 +32,4 @@
Resources.Designer.cs
-
-
-
\ No newline at end of file
diff --git a/src/Authentication/Authentication/Microsoft.Graph.Authentication.nuspec b/src/Authentication/Authentication/Microsoft.Graph.Authentication.nuspec
index 3d8d9b10de7..01fe73c6929 100644
--- a/src/Authentication/Authentication/Microsoft.Graph.Authentication.nuspec
+++ b/src/Authentication/Authentication/Microsoft.Graph.Authentication.nuspec
@@ -1,7 +1,7 @@
- 1.3.1
+ 1.4.2
Microsoft.Graph.Authentication
Microsoft Graph PowerShell authentication module
Microsoft
@@ -16,20 +16,24 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Authentication/Authentication/Microsoft.Graph.Authentication.psd1 b/src/Authentication/Authentication/Microsoft.Graph.Authentication.psd1
index be0fad82789..b080bc96751 100644
--- a/src/Authentication/Authentication/Microsoft.Graph.Authentication.psd1
+++ b/src/Authentication/Authentication/Microsoft.Graph.Authentication.psd1
@@ -3,7 +3,7 @@
#
# Generated by: Microsoft
#
-# Generated on: 1/29/2021
+# Generated on: 3/12/2021
#
@{
diff --git a/src/Authentication/Authentication/Microsoft.Graph.Authentication.psm1 b/src/Authentication/Authentication/Microsoft.Graph.Authentication.psm1
index ea6bf11ddb6..2dd0e3787f2 100644
--- a/src/Authentication/Authentication/Microsoft.Graph.Authentication.psm1
+++ b/src/Authentication/Authentication/Microsoft.Graph.Authentication.psm1
@@ -1,13 +1,10 @@
-# Load dependencies
-$preloadPath = (Join-Path $PSScriptRoot -ChildPath ".\bin\PreloadAssemblies")
-if ($PSEdition -eq 'Desktop' -and (Test-Path $preloadPath -ErrorAction Ignore)) {
- try {
- Get-ChildItem -ErrorAction Stop -Path $preloadPath -Filter "*.dll" | ForEach-Object {
- Add-Type -Path $_.FullName -ErrorAction Ignore | Out-Null
- }
- }
- catch { }
-}
# Load the module dll
-$null = Import-Module -Name (Join-Path $PSScriptRoot '.\bin\Microsoft.Graph.Authentication.dll')
\ No newline at end of file
+$null = Import-Module -Name (Join-Path $PSScriptRoot 'Microsoft.Graph.Authentication.dll')
+
+if (Test-Path -Path "$PSScriptRoot\StartupScripts" -ErrorAction Ignore)
+{
+ Get-ChildItem "$PSScriptRoot\StartupScripts" -ErrorAction Stop | ForEach-Object {
+ . $_.FullName
+ }
+}
\ No newline at end of file
diff --git a/src/Authentication/Authentication/StartupScripts/InitializeAssemblyResolver.ps1 b/src/Authentication/Authentication/StartupScripts/InitializeAssemblyResolver.ps1
new file mode 100644
index 00000000000..4926d2271d4
--- /dev/null
+++ b/src/Authentication/Authentication/StartupScripts/InitializeAssemblyResolver.ps1
@@ -0,0 +1,11 @@
+try {
+ if ($PSEdition -eq 'Core') {
+ [Microsoft.Graph.PowerShell.Authentication.Utilities.DependencyAssemblyResolver]::Initialize()
+ }
+ else {
+ [Microsoft.Graph.PowerShell.Authentication.Utilities.DependencyAssemblyResolver]::Initialize($true)
+ }
+}
+catch {
+ Write-Warning $_
+}
\ No newline at end of file
diff --git a/src/Authentication/Authentication/Utilities/DependencyAssemblyResolver.cs b/src/Authentication/Authentication/Utilities/DependencyAssemblyResolver.cs
new file mode 100644
index 00000000000..82fe833d2dc
--- /dev/null
+++ b/src/Authentication/Authentication/Utilities/DependencyAssemblyResolver.cs
@@ -0,0 +1,101 @@
+// ------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
+// ------------------------------------------------------------------------------
+
+namespace Microsoft.Graph.PowerShell.Authentication.Utilities
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Reflection;
+ public static class DependencyAssemblyResolver
+ {
+ // Catalog our dependencies here to ensure we don't load anything else.
+ private static IReadOnlyDictionary Dependencies = new Dictionary
+ {
+ { "Microsoft.Identity.Client", new Version("4.23.0.0") },
+ { "Microsoft.Graph.Auth", new Version("1.0.0.0") },
+ { "Microsoft.IdentityModel.Tokens", new Version("5.6.0.61018") },
+ { "Microsoft.IdentityModel.Logging", new Version("5.6.0.61018") },
+ { "Microsoft.IdentityModel.JsonWebTokens", new Version("5.6.0.61018") },
+ { "System.IdentityModel.Tokens.Jwt", new Version("5.6.0.61018") },
+ { "System.Security.Cryptography.ProtectedData", new Version("4.3.0.0") },
+ { "Newtonsoft.Json", new Version("10.0.3.21018") },
+ };
+
+ ///
+ /// Dependencies that need to be loaded per framework.
+ ///
+ private static IList MultiFrameworkDependencies = new List {
+ "Microsoft.Identity.Client",
+ "System.Security.Cryptography.ProtectedData"
+ };
+
+ // Set up the path to our dependency directory within the module.
+ private static string DependenciesDirPath = Path.GetFullPath(Path.Combine(
+ Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Dependencies"));
+
+ ///
+ /// Framework dependency path. /Desktop for PS 5.1, and /Core for PS 6+.
+ ///
+ private static string FrameworkDependenciesDirPath;
+
+ ///
+ /// Initializes our custom assembly resolve event handler. This should be called on module import.
+ ///
+ ///
+ public static void Initialize(bool isDesktopEdition = false)
+ {
+ if (isDesktopEdition)
+ {
+ FrameworkDependenciesDirPath = "Desktop";
+ }
+ else
+ {
+ FrameworkDependenciesDirPath = "Core";
+ }
+ // Set up our event handler when the module is loaded.
+ AppDomain.CurrentDomain.AssemblyResolve += HandleResolveEvent;
+ }
+
+ ///
+ /// Remove our custom assembly resolve event handler from the current app domain.
+ /// This should be called when our module is removed.
+ ///
+ internal static void Reset()
+ {
+ // Remove our event hander when the module is unloaded.
+ AppDomain.CurrentDomain.AssemblyResolve -= HandleResolveEvent;
+ }
+
+
+ private static Assembly HandleResolveEvent(object sender, ResolveEventArgs args)
+ {
+ try
+ {
+ AssemblyName assemblymName = new AssemblyName(args.Name);
+ // We try to resolve our dependencies on our own.
+ if (Dependencies.TryGetValue(assemblymName.Name, out Version requiredVersion)
+ && requiredVersion >= assemblymName.Version
+ && (requiredVersion.Major == assemblymName.Version.Major || string.Equals(assemblymName.Name, "Newtonsoft.Json", StringComparison.OrdinalIgnoreCase)))
+ {
+ string requiredAssemblyPath = string.Empty;
+ if (MultiFrameworkDependencies.Contains(assemblymName.Name))
+ {
+ requiredAssemblyPath = Path.Combine(DependenciesDirPath, FrameworkDependenciesDirPath, $"{assemblymName.Name}.dll");
+ }
+ else
+ {
+ requiredAssemblyPath = Path.Combine(DependenciesDirPath, $"{assemblymName.Name}.dll");
+ }
+ return Assembly.LoadFile(requiredAssemblyPath);
+ }
+ }
+ catch
+ {
+ // If an error is encountered, we fall back to PowerShell's default dependency resolution.
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/Authentication/Authentication/build-module.ps1 b/src/Authentication/Authentication/build-module.ps1
index e75aa4200cb..c6403a143b7 100644
--- a/src/Authentication/Authentication/build-module.ps1
+++ b/src/Authentication/Authentication/build-module.ps1
@@ -1,51 +1,117 @@
-param([switch]$Isolated, [switch]$Pack, [switch]$Release)
+param(
+ [switch]$Isolated,
+ [switch]$Pack,
+ [switch]$Release
+)
+
$ErrorActionPreference = 'Stop'
+$ModuleName = "Authentication"
+$ModulePrefix = "Microsoft.Graph"
+$netStandard = "netstandard2.0"
+$netCoreApp = "netcoreapp2.1"
+$netFx = "net461"
+$copyExtensions = @('.dll', '.pdb')
+
+# Source code locations
+$coreSrc = Join-Path $PSScriptRoot "../$ModuleName.Core"
+$cmdletsSrc = Join-Path $PSScriptRoot "../$ModuleName"
-if($PSEdition -ne 'Core') {
+# Generated output locations
+$outDir = "$PSScriptRoot/artifacts"
+$outDeps = "$outDir/Dependencies"
+$outCore = "$outDeps/Core"
+$outDesktop = "$outDeps/Desktop"
+
+if ($PSEdition -ne 'Core') {
Write-Error 'This script requires PowerShell Core to execute. [Note] Generated cmdlets will work in both PowerShell Core or Windows PowerShell.'
}
-if(-not $Isolated) {
+$Configuration = 'Debug'
+if ($Release) {
+ $Configuration = 'Release'
+}
+
+if (-not $Isolated) {
Write-Host -ForegroundColor Green 'Creating isolated process...'
$pwsh = [System.Diagnostics.Process]::GetCurrentProcess().Path
& "$pwsh" -NonInteractive -NoLogo -NoProfile -File $MyInvocation.MyCommand.Path @PSBoundParameters -Isolated
- if($LastExitCode -ne 0) {
+ if ($LastExitCode -ne 0) {
# Build failed. Don't attempt to run the module.
return
}
- if($Pack) {
+ if ($Pack) {
. (Join-Path $PSScriptRoot 'pack-module.ps1')
- if($LastExitCode -ne 0) {
+ if ($LastExitCode -ne 0) {
# Packing failed. Don't attempt to run the module.
return
}
}
-
return
}
+# Clean build folders.
Write-Host -ForegroundColor Green 'Cleaning build folders...'
-$binFolder = Join-Path $PSScriptRoot 'bin'
-$objFolder = Join-Path $PSScriptRoot 'obj'
-$null = Remove-Item -Recurse -ErrorAction SilentlyContinue -Path $binFolder, $objFolder
+$null = Remove-Item -Path "$coreSrc/bin", "$coreSrc/obj" -Recurse -ErrorAction Ignore
+$null = Remove-Item -Path "$cmdletsSrc/bin", "$cmdletsSrc/obj" -Recurse -ErrorAction Ignore
-if((Test-Path $binFolder) -or (Test-Path $objFolder)) {
+if ((Test-Path "$cmdletsSrc/bin") -or (Test-Path "$cmdletsSrc/obj")) {
Write-Host -ForegroundColor Cyan 'Did you forget to exit your isolated module session before rebuilding?'
Write-Error 'Unable to clean ''bin'' or ''obj'' folder. A process may have an open handle.'
}
Write-Host -ForegroundColor Green 'Compiling module...'
-$buildConfig = 'Debug'
-if($Release) {
- $buildConfig = 'Release'
-}
-dotnet publish $PSScriptRoot --verbosity quiet --configuration $buildConfig /nologo
+# Build authentication.core for each framework.
+Push-Location $coreSrc
+dotnet publish -c $Configuration -f $netStandard --verbosity quiet /nologo
+dotnet publish -c $Configuration -f $netCoreApp --verbosity quiet /nologo
+dotnet publish -c $Configuration -f $netFx --verbosity quiet /nologo
+Pop-Location
+
+# Build authentication.
+Push-Location $cmdletsSrc
+dotnet publish -c $Configuration --verbosity quiet /nologo
+Pop-Location
-if($LastExitCode -ne 0) {
+if ($LastExitCode -ne 0) {
Write-Error 'Compilation failed.'
}
-$null = Remove-Item -Recurse -ErrorAction SilentlyContinue -Path (Join-Path $binFolder 'Debug'), (Join-Path $binFolder 'Release')
+# Ensure out directory exists and is clean.
+Remove-Item -Path $outDir -Recurse -ErrorAction Ignore
+New-Item -Path $outDir -ItemType Directory
+New-Item -Path $outDeps -ItemType Directory
+New-Item -Path $outCore -ItemType Directory
+New-Item -Path $outDesktop -ItemType Directory
+
+# Copy manifest.
+Copy-Item -Path "$cmdletsSrc/$ModulePrefix.$ModuleName.format.ps1xml" -Destination $outDir
+Copy-Item -Path "$cmdletsSrc/$ModulePrefix.$ModuleName.psm1" -Destination $outDir
+Copy-Item -Path "$cmdletsSrc/$ModulePrefix.$ModuleName.psd1" -Destination $outDir
+Copy-Item -Path "$cmdletsSrc/StartupScripts" -Recurse -Destination $outDir
+
+# Core assemblies to include with cmdlets (Let PowerShell load them).
+$CoreAssemblies = @('Microsoft.Graph.Authentication.Core', 'Microsoft.Graph.Core')
+
+# Copy each authentication.core asset to out directory and remember it.
+$Deps = [System.Collections.Generic.HashSet[string]]::new()
+Get-ChildItem -Path "$coreSrc/bin/$Configuration/$netStandard/publish/" |
+Where-Object { $_.Extension -in $copyExtensions } |
+Where-Object { -not $CoreAssemblies.Contains($_.BaseName) } |
+ForEach-Object { [void]$Deps.Add($_.Name); Copy-Item -Path $_.FullName -Destination $outDeps }
+
+Get-ChildItem -Path "$coreSrc/bin/$Configuration/$netCoreApp/publish/" |
+Where-Object { -not $CoreAssemblies.Contains($_.BaseName) } |
+ForEach-Object { [void]$Deps.Add($_.Name); Copy-Item -Path $_.FullName -Destination $outCore }
+
+Get-ChildItem -Path "$coreSrc/bin/$Configuration/$netFx/publish/" |
+Where-Object { -not $CoreAssemblies.Contains($_.BaseName) } |
+ForEach-Object { [void]$Deps.Add($_.Name); Copy-Item -Path $_.FullName -Destination $outDesktop }
+
+# Now copy each authentication asset, not taking any found in authentication.core.
+Get-ChildItem -Path "$cmdletsSrc/bin/$Configuration/$netStandard/publish/" |
+Where-Object { -not $Deps.Contains($_.Name) -and $_.Extension -in $copyExtensions } |
+ForEach-Object { Copy-Item -Path $_.FullName -Destination $outDir }
+
Write-Host -ForegroundColor Green '-------------Done-------------'
\ No newline at end of file
diff --git a/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1 b/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1
index 762045ba529..76845efcd07 100644
--- a/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1
+++ b/src/Authentication/Authentication/test/Connect-MgGraph.Tests.ps1
@@ -1,6 +1,6 @@
BeforeAll {
$ModuleName = "Microsoft.Graph.Authentication"
- $ModulePath = Join-Path $PSScriptRoot "..\$ModuleName.psd1"
+ $ModulePath = Join-Path $PSScriptRoot "..\artifacts\$ModuleName.psd1"
Import-Module $ModulePath -Force
$RandomClientId = (New-Guid).Guid
}
@@ -22,4 +22,15 @@ Describe 'Connect-MgGraph In App Mode' {
It 'ShouldThrowExceptionWhenCertificateThumbprintLengthIs < 40' {
{ Connect-MgGraph -ClientId $RandomClientId -CertificateThumbprint '123456789012345678901234567890123456789' -ErrorAction Stop } | Should -Throw -ExpectedMessage "*'CertificateThumbprint' must have a length of 40.*"
}
+
+}
+Describe 'Connect-MgGraph Depencency Resolution' {
+ BeforeAll {
+ Install-Module Az.Accounts -Repository PSGallery -Force
+ }
+
+ It 'ShouldLoadMgModuleSideBySideWithAzModule.' {
+ { Connect-AzAccount -ApplicationId $RandomClientId -CertificateThumbprint "Invalid" -Tenant "Invalid" -ErrorAction Stop } | Should -Throw -ExpectedMessage "*Could not find tenant id*"
+ { Connect-MgGraph -Scopes "inavid.scope" -ErrorAction Stop } | Should -Throw -ExpectedMessage "*AADSTS70011:*"
+ }
}
\ No newline at end of file
diff --git a/src/Authentication/Authentication/test/Invoke-MgGraphRequest.Tests.ps1 b/src/Authentication/Authentication/test/Invoke-MgGraphRequest.Tests.ps1
index 0d643681ea9..b3a90dcd091 100644
--- a/src/Authentication/Authentication/test/Invoke-MgGraphRequest.Tests.ps1
+++ b/src/Authentication/Authentication/test/Invoke-MgGraphRequest.Tests.ps1
@@ -5,8 +5,9 @@
}
. ($loadEnvPath)
$ModuleName = "Microsoft.Graph.Authentication"
- $ModulePath = Join-Path $PSScriptRoot "..\$ModuleName.psd1"
+ $ModulePath = Join-Path $PSScriptRoot "..\artifacts\$ModuleName.psd1"
Import-Module $ModulePath -Force
+ $PSDefaultParameterValues=@{"Connect-MgGraph:TenantId"=${env:TENANTIDENTIFIER}; "Connect-MgGraph:ClientId"=${env:CLIENTIDENTIFIER}; "Connect-MgGraph:CertificateThumbprint"=${env:CERTIFICATETHUMBPRINT}}
}
Describe 'Invoke-MgGraphRequest Collection Results' {
BeforeAll {
diff --git a/src/Identity.SignIns/Identity.SignIns/test/v1.0-beta/New-MgInvitation.Tests.ps1 b/src/Identity.SignIns/Identity.SignIns/test/v1.0-beta/New-MgInvitation.Tests.ps1
index da32b80221b..8f724ee3f22 100644
--- a/src/Identity.SignIns/Identity.SignIns/test/v1.0-beta/New-MgInvitation.Tests.ps1
+++ b/src/Identity.SignIns/Identity.SignIns/test/v1.0-beta/New-MgInvitation.Tests.ps1
@@ -31,7 +31,7 @@ Describe 'New-MgInvitation' {
InviteRedirectUrl = 'https://myapp.contoso.com'
}
$Invitation = New-MgInvitation @Params
- $Invitation | Should -BeOfType -ExpectedType 'Microsoft.Graph.PowerShell.Models.MicrosoftGraphInvitation1'
+ $Invitation | Should -BeOfType -ExpectedType 'Microsoft.Graph.PowerShell.Models.MicrosoftGraphInvitation'
$Invitation | Should -HaveCount 1
$Invitation.InvitedUserDisplayName | Should -Be $env.Users[0].DisplayName
$Invitation.Status | Should -Be 'PendingAcceptance'
@@ -59,7 +59,7 @@ Describe 'New-MgInvitation' {
InviteRedirectUrl = 'https://myapp.contoso.com'
}
$Invitation = New-MgInvitation -BodyParameter $Params
- $Invitation | Should -BeOfType -ExpectedType 'Microsoft.Graph.PowerShell.Models.MicrosoftGraphInvitation1'
+ $Invitation | Should -BeOfType -ExpectedType 'Microsoft.Graph.PowerShell.Models.MicrosoftGraphInvitation'
$Invitation | Should -HaveCount 1
$Invitation.InvitedUserDisplayName | Should -Be $env.Users[0].DisplayName
$Invitation.Status | Should -Be 'PendingAcceptance'
diff --git a/src/Identity.SignIns/Identity.SignIns/test/v1.0/New-MgInvitation.Tests.ps1 b/src/Identity.SignIns/Identity.SignIns/test/v1.0/New-MgInvitation.Tests.ps1
index c30467a04f2..50a293fe2f3 100644
--- a/src/Identity.SignIns/Identity.SignIns/test/v1.0/New-MgInvitation.Tests.ps1
+++ b/src/Identity.SignIns/Identity.SignIns/test/v1.0/New-MgInvitation.Tests.ps1
@@ -31,7 +31,7 @@ Describe 'New-MgInvitation' {
InviteRedirectUrl = 'https://myapp.contoso.com'
}
$Invitation = New-MgInvitation @Params
- $Invitation | Should -BeOfType -ExpectedType 'Microsoft.Graph.PowerShell.Models.MicrosoftGraphInvitation'
+ $Invitation | Should -BeOfType -ExpectedType 'Microsoft.Graph.PowerShell.Models.MicrosoftGraphInvitation1'
$Invitation | Should -HaveCount 1
$Invitation.InvitedUserDisplayName | Should -Be $env.Users[0].DisplayName
$Invitation.Status | Should -Be 'PendingAcceptance'
@@ -59,7 +59,7 @@ Describe 'New-MgInvitation' {
InviteRedirectUrl = 'https://myapp.contoso.com'
}
$Invitation = New-MgInvitation -BodyParameter $Params
- $Invitation | Should -BeOfType -ExpectedType 'Microsoft.Graph.PowerShell.Models.MicrosoftGraphInvitation'
+ $Invitation | Should -BeOfType -ExpectedType 'Microsoft.Graph.PowerShell.Models.MicrosoftGraphInvitation1'
$Invitation | Should -HaveCount 1
$Invitation.InvitedUserDisplayName | Should -Be $env.Users[0].DisplayName
$Invitation.Status | Should -Be 'PendingAcceptance'
diff --git a/tools/BuildModule.ps1 b/tools/BuildModule.ps1
index 74bd7688034..6a4240fad56 100644
--- a/tools/BuildModule.ps1
+++ b/tools/BuildModule.ps1
@@ -16,6 +16,7 @@ if ($PSEdition -ne "Core") {
}
$NuspecHelperPS1 = Join-Path $PSScriptRoot "./NuspecHelper.ps1"
+$CSProjHelperPS1 = Join-Path $PSScriptRoot "./CSProjHelper.ps1"
$ModuleProjLocation = Join-Path $PSScriptRoot "../src/$Module/$Module"
$BuildModulePS1 = Join-Path $ModuleProjLocation "/build-module.ps1"
$ModuleCsProj = Join-Path $ModuleProjLocation "$ModulePrefix.$Module.csproj"
@@ -25,27 +26,19 @@ $ModuleNuspec = Join-Path $ModuleProjLocation "$ModulePrefix.$Module.nuspec"
# Import scripts
. $NuspecHelperPS1
+. $CSProjHelperPS1
if (-not (Test-Path -Path $BuildModulePS1)) {
Write-Error "Build script file '$BuildModulePS1' not found for '$Module' module."
}
# Set delay sign to true.
-
-$ModuleProjDoc = New-Object System.Xml.XmlDocument
-$ModuleProjDoc.Load($ModuleCsProj)
-$ModuleProjElement = [System.Xml.XmlElement] $ModuleProjDoc.DocumentElement.FirstChild
if ($EnableSigning) {
- Set-ElementValue -XmlDocument $ModuleProjDoc -MetadataElement $ModuleProjElement -ElementName "AssemblyOriginatorKeyFile" -ElementValue (Join-Path $PSScriptRoot $NuspecMetadata["assemblyOriginatorKeyFile"])
- Set-ElementValue -XmlDocument $ModuleProjDoc -MetadataElement $ModuleProjElement -ElementName "DelaySign" -ElementValue "true"
- Set-ElementValue -XmlDocument $ModuleProjDoc -MetadataElement $ModuleProjElement -ElementName "SignAssembly" -ElementValue "true"
+ Set-CSProjValues -ModuleCsProj $ModuleCsProj -ModuleVersion $ModuleVersion -AssemblyOriginatorKeyFile $NuspecMetadata["assemblyOriginatorKeyFile"]
+}
+else {
+ Set-CSProjValues -ModuleCsProj $ModuleCsProj -ModuleVersion $ModuleVersion -Copyright $NuspecMetadata["copyright"]
}
-Set-ElementValue -XmlDocument $ModuleProjDoc -MetadataElement $ModuleProjElement -ElementName "Copyright" -ElementValue $NuspecMetadata["copyright"]
-Set-ElementValue -XmlDocument $ModuleProjDoc -MetadataElement $ModuleProjElement -ElementName "Version" -ElementValue $ModuleVersion
-
-$ModuleProjDoc.Save($ModuleCsProj)
-Write-Host "Updated the .csproj."
-
# Build module
Write-Host -ForegroundColor Green "Building '$Module' module..."
@@ -55,10 +48,10 @@ if ($LASTEXITCODE) {
}
[HashTable]$ModuleManifestSettings = @{
- Path = $ModuleManifest
- ModuleVersion = $ModuleVersion
- IconUri = $NuspecMetadata["iconUri"]
- ReleaseNotes = $ReleaseNotes
+ Path = $ModuleManifest
+ ModuleVersion = $ModuleVersion
+ IconUri = $NuspecMetadata["iconUri"]
+ ReleaseNotes = $ReleaseNotes
}
$FullVersionNumber = $ModuleVersion
diff --git a/tools/CSProjHelper.ps1 b/tools/CSProjHelper.ps1
new file mode 100644
index 00000000000..65150f373a8
--- /dev/null
+++ b/tools/CSProjHelper.ps1
@@ -0,0 +1,35 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+function Set-CSProjValues(
+ [parameter(Mandatory = $true)][string] $ModuleCsProj,
+ [parameter(Mandatory = $true)][string] $ModuleVersion,
+ [string] $Copyright,
+ [string] $AssemblyOriginatorKeyFile) {
+ $NuspecHelperPS1 = Join-Path $PSScriptRoot "./NuspecHelper.ps1"
+
+ # Import scripts
+ . $NuspecHelperPS1
+
+ # Set delay sign to true.
+ $ModuleProjDoc = New-Object System.Xml.XmlDocument
+ $ModuleProjDoc.Load($ModuleCsProj)
+ if ($ModuleProjDoc.DocumentElement.PropertyGroup.Count -gt 1) {
+ $ModuleProjElement = [System.Xml.XmlElement] $ModuleProjDoc.DocumentElement.PropertyGroup[0]
+ } else {
+ $ModuleProjElement = [System.Xml.XmlElement] $ModuleProjDoc.DocumentElement.PropertyGroup
+ }
+
+ if (![string]::IsNullOrWhiteSpace($AssemblyOriginatorKeyFile)) {
+ Set-ElementValue -XmlDocument $ModuleProjDoc -MetadataElement $ModuleProjElement -ElementName "AssemblyOriginatorKeyFile" -ElementValue (Join-Path $PSScriptRoot $AssemblyOriginatorKeyFile)
+ Set-ElementValue -XmlDocument $ModuleProjDoc -MetadataElement $ModuleProjElement -ElementName "DelaySign" -ElementValue "true"
+ Set-ElementValue -XmlDocument $ModuleProjDoc -MetadataElement $ModuleProjElement -ElementName "SignAssembly" -ElementValue "true"
+ }
+ if (![string]::IsNullOrWhiteSpace($Copyright)) {
+ Set-ElementValue -XmlDocument $ModuleProjDoc -MetadataElement $ModuleProjElement -ElementName "Copyright" -ElementValue $Copyright
+ }
+ Set-ElementValue -XmlDocument $ModuleProjDoc -MetadataElement $ModuleProjElement -ElementName "Version" -ElementValue $ModuleVersion
+
+ $ModuleProjDoc.Save($ModuleCsProj)
+ Write-Host "Updated the $ModuleCsProj."
+}
\ No newline at end of file
diff --git a/tools/GenerateAuthenticationModule.ps1 b/tools/GenerateAuthenticationModule.ps1
index abd5de076b8..2d088ec9967 100644
--- a/tools/GenerateAuthenticationModule.ps1
+++ b/tools/GenerateAuthenticationModule.ps1
@@ -27,12 +27,19 @@ if ($PSEdition -ne 'Core') {
$ModulePrefix = "Microsoft.Graph"
$ModuleName = "Authentication"
$AuthModuleManifest = "Microsoft.Graph.Authentication.psd1"
+$SigningKeyFile = "35MSSharedLib1024.snk"
$BuildModulePS1 = Join-Path $PSScriptRoot ".\BuildModule.ps1" -Resolve
$PackModulePS1 = Join-Path $PSScriptRoot ".\PackModule.ps1" -Resolve
$PublishModulePS1 = Join-Path $PSScriptRoot ".\PublishModule.ps1" -Resolve
$ValidateUpdatedModuleVersionPS1 = Join-Path $PSScriptRoot ".\ValidateUpdatedModuleVersion.ps1" -Resolve
-$AuthModulePath = Join-Path $PSScriptRoot "..\src\Authentication\Authentication\" -Resolve
+$AuthSrcPath = Join-Path $PSScriptRoot "..\src\Authentication\"
+$AuthModulePath = Join-Path $AuthSrcPath "Authentication" -Resolve
$TestModulePS1 = Join-Path $PSScriptRoot ".\TestModule.ps1" -Resolve
+$AuthCoreCSProj = Join-Path $AuthSrcPath "$ModuleName.Core" "$ModulePrefix.$ModuleName.Core.csproj"
+$CSProjHelperPS1 = Join-Path $PSScriptRoot "./CSProjHelper.ps1"
+
+# Import scripts
+. $CSProjHelperPS1
# Read ModuleVersion set on local auth module.
$ManifestContent = Import-LocalizedData -BaseDirectory $AuthModulePath -FileName $AuthModuleManifest
@@ -41,8 +48,8 @@ if ($null -eq $ManifestContent.ModuleVersion) {
Write-Error "Version number is not set on $ModulePrefix.$ModuleName module. Please set 'ModuleVersion' in $AuthModulePath\$AuthModuleManifest."
}
$AllowPreRelease = $true
-if($ModulePreviewNumber -eq -1) {
- $AllowPreRelease = $false
+if ($ModulePreviewNumber -eq -1) {
+ $AllowPreRelease = $false
}
# Validate module version with the one on PSGallery.
[VersionState]$VersionState = & $ValidateUpdatedModuleVersionPS1 -ModuleName "$ModulePrefix.$ModuleName" -NextVersion $ManifestContent.ModuleVersion -PSRepository $RepositoryName -ModulePreviewNumber $ModulePreviewNumber
@@ -54,18 +61,20 @@ elseif ($VersionState.Equals([VersionState]::EqualToFeed) -and !$BuildWhenEqual)
Write-Warning "$ModulePrefix.$ModuleName module skipped. Version has not changed and is equal to what's on $RepositoryName."
}
elseif ($VersionState.Equals([VersionState]::Valid) -or $VersionState.Equals([VersionState]::NotOnFeed) -or $BuildWhenEqual) {
- $ModuleVersion = $VersionState.Equals([VersionState]::NotOnFeed) ? "0.1.1" : $ManifestContent.ModuleVersion
+ $ModuleVersion = $VersionState.Equals([VersionState]::NotOnFeed) ? "1.0.0" : $ManifestContent.ModuleVersion
# Build and pack generated module.
if ($Build) {
if ($EnableSigning) {
+ Set-CSProjValues -ModuleCsProj $AuthCoreCSProj -ModuleVersion $ModuleVersion -AssemblyOriginatorKeyFile $SigningKeyFile
& $BuildModulePS1 -Module $ModuleName -ModulePrefix $ModulePrefix -ModuleVersion $ModuleVersion -ModulePreviewNumber $ModulePreviewNumber -ReleaseNotes $ManifestContent.PrivateData.PSData.ReleaseNotes -EnableSigning
}
else {
+ Set-CSProjValues -ModuleCsProj $AuthCoreCSProj -ModuleVersion $ModuleVersion
& $BuildModulePS1 -Module $ModuleName -ModulePrefix $ModulePrefix -ModuleVersion $ModuleVersion -ModulePreviewNumber $ModulePreviewNumber -ReleaseNotes $ManifestContent.PrivateData.PSData.ReleaseNotes
}
}
- if($Test){
- & $TestModulePS1 -ModulePath $AuthModulePath -ModuleName "$ModulePrefix.$ModuleName"
+ if ($Test) {
+ & $TestModulePS1 -ModulePath (Join-Path $AuthModulePath "artifacts" ) -ModuleName "$ModulePrefix.$ModuleName" -ModuleTestsPath (Join-Path $AuthModulePath "test")
}
if ($Pack) {
diff --git a/tools/GenerateModules.ps1 b/tools/GenerateModules.ps1
index f802d563ab1..1ca641ab7cb 100644
--- a/tools/GenerateModules.ps1
+++ b/tools/GenerateModules.ps1
@@ -202,7 +202,7 @@ $ModulesToGenerate | ForEach-Object -ThrottleLimit $ModulesToGenerate.Count -Par
}
if ($Using:Test) {
- & $Using:TestModulePS1 -ModulePath $ModuleProjectDir -ModuleName $FullyQualifiedModuleName
+ & $Using:TestModulePS1 -ModulePath $ModuleProjectDir -ModuleName $FullyQualifiedModuleName -ModuleTestsPath (Join-Path $ModuleProjectDir "test")
}
if ($Using:Pack) {
diff --git a/tools/PackModule.ps1 b/tools/PackModule.ps1
index 820ebc6b899..b29c7c00b44 100644
--- a/tools/PackModule.ps1
+++ b/tools/PackModule.ps1
@@ -3,7 +3,7 @@
Param(
[Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()][string] $Module,
[Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()][string] $ArtifactsLocation,
- [string] $ModulePrefix="Microsoft.Graph",
+ [string] $ModulePrefix = "Microsoft.Graph",
[switch] $ExcludeMarkdownDocsFromNugetPackage
)
$NuspecHelperPS1 = Join-Path $PSScriptRoot "./NuspecHelper.ps1"
@@ -12,8 +12,8 @@ $NuspecHelperPS1 = Join-Path $PSScriptRoot "./NuspecHelper.ps1"
$LASTEXITCODE = $null
$ErrorActionPreference = "Stop"
-if($PSEdition -ne "Core") {
- Write-Error "This script requires PowerShell Core to execute. [Note] Generated cmdlets will work in both PowerShell Core or Windows PowerShell."
+if ($PSEdition -ne "Core") {
+ Write-Error "This script requires PowerShell Core to execute. [Note] Generated cmdlets will work in both PowerShell Core or Windows PowerShell."
}
$ModuleProjLocation = Join-Path $PSScriptRoot "../src/$Module/$Module"
@@ -28,17 +28,18 @@ if (Test-Path $PackModulePS1) {
}
# Pack module
& $PackModulePS1
- if($LASTEXITCODE) {
+ if ($LASTEXITCODE) {
Write-Error "Failed to pack '$Module' module."
}
# Get generated .nupkg
- $NuGetPackage = (Get-ChildItem (Join-Path $ModuleProjLocation "./bin") | Where-Object Name -Match ".nupkg").FullName
+ $NuGetPackage = (Get-ChildItem (Join-Path $ModuleProjLocation "./bin") -Recurse | Where-Object Name -Match ".nupkg").FullName
$ModuleArtifactLocation = "$ArtifactsLocation\$Module"
- if(-not (Test-Path $ModuleArtifactLocation)) {
+ if (-not (Test-Path $ModuleArtifactLocation)) {
New-Item -Path $ModuleArtifactLocation -Type Directory
- } else {
+ }
+ else {
Remove-Item -Path "$ModuleArtifactLocation\*" -Recurse -Force
}
diff --git a/tools/TestModule.ps1 b/tools/TestModule.ps1
index dd01070afbc..30753cd0ce5 100644
--- a/tools/TestModule.ps1
+++ b/tools/TestModule.ps1
@@ -1,6 +1,6 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
-param([string] $ModulePath, [string] $ModuleName, [switch]$Isolated)
+param([string] $ModulePath, [string] $ModuleName, [string] $ModuleTestsPath, [switch]$Isolated)
$ErrorActionPreference = 'Stop'
# Install Pester
@@ -17,20 +17,22 @@ if(-not $Isolated) {
$modulePsd1 = Get-Item -Path (Join-Path $ModulePath "./$ModuleName.psd1")
$LocalLoadEnvPS1 = Join-Path $PSScriptRoot 'Tests/loadEnv.ps1'
+$AuthModulePSd1 = Join-Path $PSScriptRoot "../src/Authentication/Authentication/artifacts/Microsoft.Graph.Authentication.psd1"
+# Import required modules.
Import-Module -Name Pester
+Import-Module $AuthModulePSd1
Import-Module -Name $modulePsd1.FullName
# Replace AutoREST loadEnv.ps1 with our local scipt.
-Copy-Item -Path $LocalLoadEnvPS1 -Destination "$ModulePath/test"
+Copy-Item -Path $LocalLoadEnvPS1 -Destination $ModuleTestsPath
-$testFolder = Join-Path $ModulePath 'test'
$PesterConfiguration = [PesterConfiguration]::Default
-$PesterConfiguration.Run.Path = $testFolder
+$PesterConfiguration.Run.Path = $ModuleTestsPath
$PesterConfiguration.Run.Exit = $true
$PesterConfiguration.CodeCoverage.Enabled = $true
$PesterConfiguration.TestResult.Enabled = $true
-$PesterConfiguration.TestResult.OutputPath = (Join-Path $testFolder "$moduleName-TestResults.xml")
+$PesterConfiguration.TestResult.OutputPath = (Join-Path $ModuleTestsPath "$moduleName-TestResults.xml")
try {
Invoke-Pester -Configuration $PesterConfiguration