src/client/GraphContext.ps1
# Copyright 2018, Adam Edwards # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. . (import-script ../metadata/GraphCache) . (import-script ../metadata/GraphSegment) . (import-script ../metadata/UriCache) . (import-script ../Client/GraphConnection) . (import-script ../Client/LogicalGraphManager) ScriptClass GraphContext { $connection = $null $version = $null $name = $null $location = $null $uriCache = $null function __initialize($connection, $apiversion, $name) { if ( ! $name ) { throw "Graph name must be specified" } $graphConnection = $this.scriptclass |=> GetConnection $connection $null $graphVersion = if ( $apiVersion ) { $apiVersion } else { $this.scriptclass |=> GetDefaultVersion } $this.uriCache = new-so UriCache 1000 $this.connection = $graphConnection $this.version = $graphVersion $this.name = $name $this.location = $::.GraphSegment.RootSegment } function UpdateGraph($metadata = $null, $wait = $false, $force = $false) { $this.scriptclass |=> __GetGraph (GetEndpoint) $this.version $metadata $wait $force $true | out-null $this.uriCache.Clear() # Need to change this to handle async retrieval of new graph } function GetGraph($metadata = $null, $force = $false) { $this.scriptclass |=> __GetGraph (GetEndpoint) $this.version $metadata $true $force } function GetEndpoint { $this.connection.GraphEndpoint.Graph } function Update($identity, $scope) { if ($identity) { $newConnection = new-so GraphConnection $this.Connection.GraphEndpoint $identity $scope $this.connection = $newConnection } } function SetLocation([PSCustomObject] $location) { $this.location = $location } static { $current = $null $cache = $null $defaultContextName = 'v1.0' function __initialize { $::.LogicalGraphManager |=> __initialize $currentContext = $::.LogicalGraphManager |=> Get |=> NewContext $null (__GetSimpleConnection ([GraphType]::MSGraph)) (GetDefaultVersion) $this.defaultContextName $this.current = $currentContext.Name $this.cache = new-so GraphCache # Start an asynchronous load of the metadata unless this is disabled # This is only meant for user interactive sessions and should be # disabled if this module is used in background jobs if ( ! (get-variable -scope script -name '__poshgraph_no_auto_metadata' -erroraction silentlycontinue) ) { write-verbose "Asynchronously updating Graph metadata" $currentContext |=> UpdateGraph } else { write-verbose "Found __poshgraph_no_auto_metadata variable, skipping Graph metadata update" } } function FindContext($endpoint, $apiVersion) { $::.LogicalGraphManager |=> Get |=> FindContext $endpoint $apiVersion } function GetCurrent { if ( $this.current ) { write-verbose "Attempt to get current context -- current context is set to '$($this.current)'" $::.LogicalGraphManager |=> Get |=> GetContext $this.current } else { write-verbose "Attempt to get current context -- no context is currently set" } } function SetCurrentByName($name) { if ( ! ($::.LogicalGraphManager |=> Get |=> GetContext $name) ) { throw "No such context: '$name'" } write-verbose "Setting current context to '$name'" $this.current = $name } function GetCurrentConnection { $context = GetCurrent if ( $context ) { $context.connection } } function DisconnectCurrentConnection { $context = GetCurrent if ( $context ) { $context.connection |=> Disconnect } else { throw "Cannot disconnect the current context from Graph because there is no current context." } } function GetDefaultVersion { 'v1.0' } function __IsContextConnected($context) { $context -and ($context.connection |=> IsConnected) } function __GetSimpleConnection([GraphCloud] $graphType, [GraphCloud] $cloud = 'Public', [String[]] $ScopeNames, $anonymous = $false) { write-verbose "Connection request for Graph = '$graphType', Cloud = '$cloud', Anonymous = $($anonymous -eq $true)" $graphScopes = if ( $scopenames ) { write-verbose "Scopes requested:" $scopenames | foreach { write-verbose "`t$($_)" } $scopenames } else { write-verbose "No scopes requested, using User.Read" @('User.Read') } $currentContext = GetCurrent $sessionConnection = GetCurrentConnection if ( $graphType -eq [GraphType]::AADGraph -or ! (__IsContextConnected $currentContext) -or (! $anonymous -and ! $sessionConnection.identity)) { $::.GraphConnection |=> NewSimpleConnection $graphType $cloud $graphScopes $anonymous } else { $sessionConnection } } function GetConnection($connection = $null, $context = $null, $cloud = $null, [String[]] $scopenames = $null, $anonymous = $null) { $currentContext = GetCurrent $existingConnection = if ( $connection ) { write-verbose "Using supplied connection" $connection } elseif ( $context ) { write-verbose "Using connection from supplied context '$($context.name)'" $context.connection } elseif ( $currentContext ) { write-verbose "Found existing connection from current context '$($currentcontext.name)'" if ( ( ! $cloud -or $currentContext.cloud -eq $cloud) -and (!$scopenames -or $scopenames -eq 'User.Read' -or ($scopenames -is [String[]] -and $scopenames.length -eq 1 -and $scopenames[0] -eq 'User.Read' )) -and ! $anonymous ) { write-verbose "Current context is compatible with supplied arguments, will use it" $currentContext } else { write-verbose "Current context is not compatible with supplied arguments, new connection required" } } $connectionScopes = if ( $scopeNames ) { $scopeNames } else { write-verbose "Scopes were not specified, adding default User.Read scope" @('User.Read') } if ( $existingConnection ) { write-verbose "Using an existing connection supplied directly or obtained through a context" $existingConnection } else { write-verbose "No connection supplied and no compatible connection found from a context" $namedArguments=@{Anonymous=($anonymous -eq $true)} if ( $cloud ) { $namedArguments['Cloud'] = $cloud } $namedArguments['ScopeNames'] = $connectionScopes write-verbose "Custom arguments or no current context -- getting a new connection" $newConnection = __GetSimpleConnection ([GraphType]::MSGraph) @namedArguments $newConnection } } function GetMetadataStatus($context) { $this.cache |=> GetMetadataStatus $context.connection.GraphEndpoint.Graph $context.version } function __GetGraph($endpoint, $apiVersion, $metadata, $wait = $false, $force = $false, $forceupdate = $false) { $deferBuild = $apiVersion -ne 'v1.0' if ( $Force ) { $this.cache |=> CancelPendingGraph $endpoint $apiVersion } if ( $wait -and ! $forceupdate ) { $this.cache |=> GetGraph $endpoint $apiVersion $metadata $deferBuild } else { $asyncResult = $this.cache |=> GetGraphAsync $endpoint $apiVersion $metadata $deferBuild if ( $wait ) { $this.cache |=> WaitForGraphAsync $asyncResult } else { $asyncResult } } } } } $::.GraphContext |=> __initialize |