Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions config/ModuleMetadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@
],
"versions": {
"authentication": {
"prerelease": "",
"version": "2.26.1"
"prerelease": "preview1",
"version": "2.28.0"
},
"beta": {
"prerelease": "",
"version": "2.26.1"
"prerelease": "preview1",
"version": "2.28.0"
},
"v1.0": {
"prerelease": "",
"version": "2.26.1"
"version": "2.28.0"
}
}
}
37 changes: 36 additions & 1 deletion src/readme.graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,15 @@ directive:
const regexP = /AddIf\(\s*null\s*!=\s*\(\(\(object\)this\._(\w+).*?(\(Microsoft.*.PowerShell\.Runtime\.Json\.JsonNode\)).*?"(\w+)".*?container\.Add\s*\);/gm
$ = $.replace(regexP, (match, p1, p2, p3) => {
let capitalizedP1 = p1.charAt(0).toUpperCase() + p1.slice(1); // Capitalize first letter
return `if(this.IsPropertySet("${p1}"))\n\t\t{\n\t\t\tvar propertyInfo = this.GetType().GetProperty("${capitalizedP1}");\n\t\t\tif (propertyInfo != null)\n\t\t\t{\n\t\t\tSystem.Type propertyType = propertyInfo.PropertyType;\n\t\t\t\t\tAddIf(${p2}PropertyTracker.ConvertToJsonNode(propertyType, this._${p1}),"${p1}",container.Add);\n\t\t\t}\n\t\t}`;
// Check if `capitalizedP1` contains "PasswordSecure" and remove "Secure"
let adjustedP1 = capitalizedP1.includes("PasswordSecure")
? capitalizedP1.replace("Secure", "")
: capitalizedP1;
let lowerCasedP1 = adjustedP1.charAt(0).toLowerCase() + adjustedP1.slice(1);
let jsonNodeFunction = capitalizedP1.includes("PasswordSecure")
? `${p2}PropertyTracker.ConvertToJsonNode(propertyType, SecureStringExtension.ConvertToSecureStringToPlainText(this._${p1}))`
: `${p2}PropertyTracker.ConvertToJsonNode(propertyType, this._${p1})`;
return `if(this.IsPropertySet("${p1}"))\n\t\t{\n\t\t\tvar propertyInfo = this.GetType().GetProperty("${capitalizedP1}");\n\t\t\tif (propertyInfo != null)\n\t\t\t{\n\t\t\tSystem.Type propertyType = propertyInfo.PropertyType;\n\t\t\t\t\tAddIf(${jsonNodeFunction}, "${lowerCasedP1}",container.Add);\n\t\t\t}\n\t\t}`;
});

$ = $.replace(/if\s*\(\s*null\s*!=\s*this\._(\w+)\s*\)/gm, 'if(this.IsPropertySet("$1"))')
Expand Down Expand Up @@ -426,6 +434,9 @@ directive:

$ = $.replace(/\bpublic\s+(Microsoft\.Graph\.[\w.]+\[\])\s+(\w+)\s*{\s*get\s*=>\s*this\.(\w+);\s*set\s*=>\s*this\.\3\s*=\s*value;\s*}/gm,'public $1 $2\n\t{\n\t\tget=>this.$3;\n\t\tset\n\t\t{\n\t\t\tthis.$3=value;\n\t\t\tTrackProperty(nameof($2));\n\t\t}\n\t}')

//Tracker for SecureString properties
$ = $.replace(/\bpublic\s+(System\.Security\.SecureString+)\s+(\w+)\s*{\s*get\s*=>\s*this\.(\w+);\s*set\s*=>\s*this\.\3\s*=\s*value;\s*}/gm,'public $1 $2\n\t{\n\t\tget=>this.$3;\n\t\tset\n\t\t{\n\t\t\tthis.$3=value;\n\t\t\tTrackProperty(nameof($2));\n\t\t}\n\t}')

const match = $documentPath.match(/generated%2Fapi%2FModels%2F([\w]*[\w\d]*)\.cs/gm);
if (match) {
let fileName = match[0];
Expand Down Expand Up @@ -495,6 +506,9 @@ directive:
}
});
}
if($.includes('password') || $.includes('Password')){
$ = $.replace('// work', '// work\n\t\t\t\tConsole.WriteLine("*****************Warning: Plain text passwords will soon be disabled.*****************");\n\t\t\t\tConsole.WriteLine("*****************Please convert your password to a secure string *****************");\n\t\t\t\tConsole.WriteLine("*****************Example: $securePassword = ConvertTo-SecureString -String <Your password> -AsPlainText -Force *****************");')
}

return $;
}
Expand Down Expand Up @@ -963,6 +977,27 @@ directive:
set:
alias: ^(.*)(OnPremises)(.*)$

# Secure password implementation.
- from: openapi-document
where: $.components..properties.currentPassword
transform: >
$["x-ms-client-name"] = "currentPasswordSecure";
$["format"] = "password";
- from: openapi-document
where: $.components..properties.newPassword
transform: >
$["x-ms-client-name"] = "newPasswordSecure";
$["format"] = "password";
- from: openapi-document
where: $.components..properties.password
transform: >
$["x-ms-client-name"] = "passwordSecure";
$["format"] = "password";
- from: openapi-document
where: $.paths..requestBody..properties.password
transform: >
$["x-ms-client-name"] = "passwordSecure";
$["format"] = "password";
# Setting the alias below as per the request on issue [#3241](https://github.com/microsoftgraph/msgraph-sdk-powershell/issues/3241)

- where:
Expand Down
27 changes: 26 additions & 1 deletion tools/Custom/HttpMessageLogFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ private static object SanitizeBody(string body)
{
body = matcher.Replace(body, "$1\"<redacted>\"");
}

// Remove password:* instances in body.
body = AbstractPasswords(body);
return body;
}

Expand Down Expand Up @@ -189,5 +190,29 @@ private static string FormatString(string content)

return content;
}
private static string AbstractPasswords(string content)
{

// Check if the JSON string contains "password" (case-insensitive)
if (content.IndexOf("password", StringComparison.OrdinalIgnoreCase) >= 0)
{
// Deserialize JSON into Dictionary
var obj = JsonConvert.DeserializeObject<Dictionary<string, object>>(content);

// Replace values for properties containing "password" (case-insensitive)
foreach (var key in obj.Keys)
{
if (key.IndexOf("password", StringComparison.OrdinalIgnoreCase) >= 0)
{
obj[key] = "***";
}
}

// Serialize the updated dictionary back to JSON
content = JsonConvert.SerializeObject(obj, Formatting.Indented);

}
return content;
}
}
}
3 changes: 2 additions & 1 deletion tools/Custom/PropertyTracker.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Security;
using System.Collections.Generic;


Expand Down Expand Up @@ -41,7 +42,7 @@ public static NamespacePrefixPlaceholder.PowerShell.Runtime.Json.JsonNode Conver


// Handle different types based on the declared type
if (propertyType == typeof(string))
if (propertyType == typeof(string) || (propertyType == typeof(SecureString)))
{
return new NamespacePrefixPlaceholder.PowerShell.Runtime.Json.JsonString(value.ToString());
}
Expand Down
20 changes: 20 additions & 0 deletions tools/Custom/SecureStringExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Security;
namespace NamespacePrefixPlaceholder.PowerShell.Models
{
public class SecureStringExtension
{
public static string ConvertToSecureStringToPlainText(SecureString secureString)
{
IntPtr unmanagedString = System.Runtime.InteropServices.Marshal.SecureStringToGlobalAllocUnicode(secureString);
try
{
return System.Runtime.InteropServices.Marshal.PtrToStringUni(unmanagedString);
}
finally
{
System.Runtime.InteropServices.Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
}
}
}
}
Loading