@@ -30,7 +30,7 @@ Function Get-DocumentsUrl([string]$Container, [string]$Collection, [string]$Reco
30
30
$encodedRecordId = [uri ]::EscapeDataString($RecordId )
31
31
32
32
return @ {
33
- ApiUrl = " $collectionsUrl /$DOCS_TYPE /$encodedRecordId " ;
33
+ ApiUrl = " $collectionsUrl /$DOCS_TYPE /$encodedRecordId " ;
34
34
ResourceUrl = " $collectionsUrl /$DOCS_TYPE /$RecordId " ;
35
35
}
36
36
}
@@ -61,20 +61,36 @@ Function Set-CacheValue([string]$key, $value, [hashtable]$cache, [int]$expiratio
61
61
}
62
62
63
63
Function Get-Base64Masterkey ([string ]$ResourceGroup , [string ]$Database , [string ]$SubscriptionId ) {
64
- $cacheKey = " $SubscriptionId /$ResourceGroup /$Database "
64
+ $readonly = $env: COSMOS_DB_FLAG_ENABLE_READONLY_KEYS -eq 1
65
+
66
+ $cacheKey = " $SubscriptionId /$ResourceGroup /$Database /$readonly "
65
67
$cacheResult = Get-CacheValue - Key $cacheKey - Cache $MASTER_KEY_CACHE
66
68
if ($cacheResult ) {
67
69
return $cacheResult
68
70
}
69
71
70
- if ($SubscriptionId ) {
71
- $masterKey = az cosmosdb keys list -- name $Database -- query primaryMasterKey -- output tsv -- resource- group $ResourceGroup -- subscription $SubscriptionId
72
+ $masterKey = Get-Base64MasterkeyWithoutCaching - ResourceGroup $ResourceGroup - Database $Database - SubscriptionId $SubscriptionId - Readonly $readonly
73
+
74
+ Set-CacheValue - Key $cacheKey - Value $masterKey - Cache $MASTER_KEY_CACHE - ExpirationHours 6
75
+
76
+ $masterKey
77
+ }
78
+
79
+ # This is just to support testing caching with Get-Base64Masterkey and isn't meant to be used directly
80
+ Function Get-Base64MasterkeyWithoutCaching ([string ]$ResourceGroup , [string ]$Database , [string ]$SubscriptionId , [bool ]$Readonly ) {
81
+ $query = if ($readonly ) {
82
+ " primaryReadonlyMasterKey"
72
83
}
73
84
else {
74
- $masterKey = az cosmosdb keys list -- name $Database -- query primaryMasterKey -- output tsv -- resource - group $ResourceGroup
85
+ " primaryMasterKey"
75
86
}
76
87
77
- Set-CacheValue - Key $cacheKey - Value $masterKey - Cache $MASTER_KEY_CACHE - ExpirationHours 6
88
+ if ($SubscriptionId ) {
89
+ $masterKey = az cosmosdb keys list -- name $Database -- query $query -- output tsv -- resource- group $ResourceGroup -- subscription $SubscriptionId
90
+ }
91
+ else {
92
+ $masterKey = az cosmosdb keys list -- name $Database -- query $query -- output tsv -- resource- group $ResourceGroup
93
+ }
78
94
79
95
$masterKey
80
96
}
@@ -140,9 +156,9 @@ Function Get-CommonHeaders([string]$now, [string]$encodedAuthString, [string]$co
140
156
$headers [" x-ms-documentdb-partitionkey" ] = " [`" $PartitionKey `" ]"
141
157
}
142
158
143
- if ($Etag ) {
144
- $headers [" If-Match" ] = $Etag
145
- }
159
+ if ($Etag ) {
160
+ $headers [" If-Match" ] = $Etag
161
+ }
146
162
147
163
$headers
148
164
}
@@ -172,15 +188,16 @@ Function Get-ExceptionResponseOrThrow($err) {
172
188
173
189
if ($err.Exception.Response ) {
174
190
$msg = @ {
175
- StatusCode = $err.Exception.Response.StatusCode ;
191
+ StatusCode = $err.Exception.Response.StatusCode ;
176
192
RawResponse = $err.Exception.Response ;
177
193
}
178
194
179
195
if ($PSVersionTable.PSEdition -eq " Core" ) {
180
196
# In PS Core, the body is eaten and put into this message
181
197
# See: https://stackoverflow.com/questions/18771424/how-to-get-powershell-invoke-restmethod-to-return-body-of-http-500-code-response
182
198
$msg.Content = $err.ErrorDetails.Message
183
- } else {
199
+ }
200
+ else {
184
201
# In Desktop we can re-read the content stream
185
202
$result = $err.Exception.Response.GetResponseStream ()
186
203
$reader = New-Object System.IO.StreamReader($result )
@@ -191,7 +208,8 @@ Function Get-ExceptionResponseOrThrow($err) {
191
208
}
192
209
193
210
return [PSCustomObject ]$msg
194
- } else {
211
+ }
212
+ else {
195
213
throw $err.Exception
196
214
}
197
215
}
@@ -802,7 +820,8 @@ Function Update-CosmosDbRecord {
802
820
803
821
if ($EnforceOptimisticConcurrency ) {
804
822
$headers = Get-CommonHeaders - now $now - encodedAuthString $encodedAuthString - PartitionKey $requestPartitionKey - Etag $Object._etag
805
- } else {
823
+ }
824
+ else {
806
825
$headers = Get-CommonHeaders - now $now - encodedAuthString $encodedAuthString - PartitionKey $requestPartitionKey
807
826
}
808
827
@@ -911,11 +930,12 @@ Function Get-CosmosDbRecordContent([parameter(ValueFromPipeline)]$RecordResponse
911
930
process {
912
931
$code = [int ]$RecordResponse.StatusCode
913
932
$content =
914
- if ($RecordResponse.Content ) {
915
- $RecordResponse.Content | ConvertFrom-Json
916
- } else {
917
- $null
918
- }
933
+ if ($RecordResponse.Content ) {
934
+ $RecordResponse.Content | ConvertFrom-Json
935
+ }
936
+ else {
937
+ $null
938
+ }
919
939
920
940
if ($code -lt 300 ) {
921
941
if ($RecordResponse.Content ) {
@@ -925,6 +945,12 @@ Function Get-CosmosDbRecordContent([parameter(ValueFromPipeline)]$RecordResponse
925
945
$null
926
946
}
927
947
}
948
+ elseif ($code -eq 401 ) {
949
+ if ($env: COSMOS_DB_FLAG_ENABLE_READONLY_KEYS -eq 1 ) {
950
+ throw " Unauthorized (used a readonly key)"
951
+ }
952
+ throw " Unauthorized"
953
+ }
928
954
elseif ($code -eq 404 ) {
929
955
if ($content.Message -like " *Owner resource does not exist*" ) {
930
956
throw " Database does not exist"
@@ -935,6 +961,7 @@ Function Get-CosmosDbRecordContent([parameter(ValueFromPipeline)]$RecordResponse
935
961
elseif ($code -eq 429 ) {
936
962
throw " Request rate limited"
937
963
}
964
+
938
965
else {
939
966
$message = $content.Message
940
967
throw " Request failed with status code $code with message`n`n $message "
@@ -961,6 +988,14 @@ Function Use-CosmosDbInternalFlag
961
988
}
962
989
}
963
990
991
+ Function Use-CosmosDbReadonlyKeys
992
+ (
993
+ [switch ]$Disable
994
+ ) {
995
+ $env: COSMOS_DB_FLAG_ENABLE_READONLY_KEYS = if ($Disable ) { 0 } else { 1 }
996
+ }
997
+
998
+
964
999
Export-ModuleMember - Function " Get-CosmosDbRecord"
965
1000
Export-ModuleMember - Function " Get-AllCosmosDbRecords"
966
1001
@@ -974,4 +1009,6 @@ Export-ModuleMember -Function "Remove-CosmosDbRecord"
974
1009
975
1010
Export-ModuleMember - Function " Get-CosmosDbRecordContent"
976
1011
977
- Export-ModuleMember - Function " Use-CosmosDbInternalFlag"
1012
+ Export-ModuleMember - Function " Use-CosmosDbReadonlyKeys"
1013
+
1014
+ Export-ModuleMember - Function " Use-CosmosDbInternalFlag"
0 commit comments