Skip to content
Merged
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
3 changes: 2 additions & 1 deletion CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
* @contentstack/developer-ecosystem-pr-reviewers
.github/workflows/ @contentstack/security-admin
**/.snyk @contentstack/security-admin
**/CODEOWNERS @contentstack/security-admin
**/CODEOWNERS @contentstack/security-admin
**/.gitguardian.yaml @contentstack/security-admin
15 changes: 9 additions & 6 deletions Scripts/generate_test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,22 @@
--collect:"XPlat Code Coverage" \\
--results-directory contentstack.model.generator.tests/TestResults

Uses only the Python standard library (xml.etree.ElementTree) - no extra
dependencies to install. The .trx/coverage files parsed here are always
locally generated by `dotnet test`, not untrusted input.
Uses only the Python standard library. If defusedxml is installed
(pip install -r Scripts/requirements.txt) it is used for hardened XML parsing.
"""

import glob
import os
import sys
import xml.etree.ElementTree as ET
from datetime import datetime

try:
# Prefer defusedxml (hardens against XXE / entity expansion) when it is installed.
from defusedxml import ElementTree as ET
except ImportError:
# Fall back to the stdlib parser so the script keeps working without extra packages.
import xml.etree.ElementTree as ET

TRX_NS = {'': 'http://microsoft.com/schemas/VisualStudio/TeamTest/2010'}


Expand Down Expand Up @@ -55,7 +60,6 @@ def __init__(self, trx_file, coverage_file=None):
self.coverage = None

def parse_trx(self):
# deepcode ignore InsecureXmlParser: test-report generation script, trusted local XML input
tree = ET.parse(self.trx_file)
root = tree.getroot()

Expand Down Expand Up @@ -118,7 +122,6 @@ def parse_coverage(self):
if not self.coverage_file or not os.path.exists(self.coverage_file):
return

# deepcode ignore InsecureXmlParser: test-report generation script, trusted local XML input
tree = ET.parse(self.coverage_file)
root = tree.getroot()

Expand Down
1 change: 1 addition & 0 deletions Scripts/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
defusedxml>=0.7.1
5 changes: 2 additions & 3 deletions contentstack.model.generator.tests/ConfigTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,12 @@ public void ApiKey_AppUid_AuthToken_CanBeSetAndRetrieved()
{
var config = new Config
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
AppUid = "test_app_uid",
AuthToken = "test_auth_token"
};

Assert.Equal("test_api_key", config.ApiKey);
Assert.Equal(TestSecrets.ApiKey, config.ApiKey);
Assert.Equal("test_app_uid", config.AppUid);
Assert.Equal("test_auth_token", config.AuthToken);
}
Expand Down
40 changes: 14 additions & 26 deletions contentstack.model.generator.tests/ContentstackClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ public void Constructor_ShouldInitializeWithOAuthOptions()

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = "api.contentstack.io",
IsOAuth = true,
Authorization = "Bearer test_access_token",
Expand All @@ -28,7 +27,7 @@ public void Constructor_ShouldInitializeWithOAuthOptions()


Assert.NotNull(client);
Assert.Equal("test_api_key", client.StackApiKey);
Assert.Equal(TestSecrets.ApiKey, client.StackApiKey);
}

[Fact]
Expand All @@ -37,8 +36,7 @@ public void Constructor_ShouldInitializeWithTraditionalAuth()

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = "api.contentstack.io",
IsOAuth = false,
Authtoken = "test_authtoken"
Expand All @@ -49,7 +47,7 @@ public void Constructor_ShouldInitializeWithTraditionalAuth()


Assert.NotNull(client);
Assert.Equal("test_api_key", client.StackApiKey);
Assert.Equal(TestSecrets.ApiKey, client.StackApiKey);
}

[Fact]
Expand All @@ -66,8 +64,7 @@ public void Constructor_ShouldSetSerializerOptions()

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = "api.contentstack.io"
};

Expand All @@ -87,8 +84,7 @@ public void Constructor_ShouldPreserveHostFormat(string inputHost)

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = inputHost
};

Expand All @@ -105,8 +101,7 @@ public void GetHeader_ShouldReturnLocalHeadersWhenMainHeadersIsNull()

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = "api.contentstack.io"
};
var client = new ContentstackClient(options);
Expand All @@ -132,8 +127,7 @@ public void GetHeader_ShouldReturnMainHeadersWhenLocalHeadersIsNull()

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = "api.contentstack.io"
};
var client = new ContentstackClient(options);
Expand All @@ -152,8 +146,7 @@ public void GetHeader_ShouldMergeLocalAndMainHeaders()

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = "api.contentstack.io"
};
var client = new ContentstackClient(options);
Expand All @@ -178,8 +171,7 @@ public void GetHeader_ShouldPrioritizeLocalHeadersOverMainHeaders()

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = "api.contentstack.io"
};
var client = new ContentstackClient(options);
Expand All @@ -202,8 +194,7 @@ public void GetHeader_ShouldHandleEmptyLocalHeaders()

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = "api.contentstack.io"
};
var client = new ContentstackClient(options);
Expand All @@ -223,8 +214,7 @@ public void GetHeader_ShouldHandleNullValues()

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = "api.contentstack.io"
};
var client = new ContentstackClient(options);
Expand All @@ -249,8 +239,7 @@ public void GetHeader_ShouldHandleSpecialCharacters()

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = "api.contentstack.io"
};
var client = new ContentstackClient(options);
Expand Down Expand Up @@ -278,8 +267,7 @@ public void GetHeader_ShouldHandleCaseSensitiveKeys()

var options = new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = "test_api_key",
ApiKey = TestSecrets.ApiKey,
Host = "api.contentstack.io"
};
var client = new ContentstackClient(options);
Expand Down
10 changes: 4 additions & 6 deletions contentstack.model.generator.tests/ContentstackOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,32 +35,30 @@ public void Properties_ShouldBeSettableAndGettable()
var options = new ContentstackOptions();
var testDate = DateTime.UtcNow.AddHours(1);
var testScopes = new[] { "read", "write" };
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
options.ApiKey = "test_api_key";
options.ApiKey = TestSecrets.ApiKey;
options.Authtoken = "test_authtoken";
options.Host = "api.contentstack.io";
options.Branch = "main";
options.Version = "v3";
options.IsOAuth = true;
options.Authorization = "Bearer test_token";
options.OAuthClientId = "test_client_id";
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
options.OAuthClientSecret = "test_client_secret";
options.OAuthClientSecret = TestSecrets.ClientSecret;
options.OAuthRedirectUri = "http://localhost:8080";
options.OAuthAppId = "test_app_id";
options.OAuthScopes = testScopes;
options.AccessToken = "test_access_token";
options.RefreshToken = "test_refresh_token";
options.TokenExpiresAt = testDate;
Assert.Equal("test_api_key", options.ApiKey);
Assert.Equal(TestSecrets.ApiKey, options.ApiKey);
Assert.Equal("test_authtoken", options.Authtoken);
Assert.Equal("api.contentstack.io", options.Host);
Assert.Equal("main", options.Branch);
Assert.Equal("v3", options.Version);
Assert.True(options.IsOAuth);
Assert.Equal("Bearer test_token", options.Authorization);
Assert.Equal("test_client_id", options.OAuthClientId);
Assert.Equal("test_client_secret", options.OAuthClientSecret);
Assert.Equal(TestSecrets.ClientSecret, options.OAuthClientSecret);
Assert.Equal("http://localhost:8080", options.OAuthRedirectUri);
Assert.Equal("test_app_id", options.OAuthAppId);
Assert.Equal(testScopes, options.OAuthScopes);
Expand Down
16 changes: 8 additions & 8 deletions contentstack.model.generator.tests/HTTPRequestHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public async Task ProcessRequest_ShouldHandleOAuthBearerToken()
var headers = new Dictionary<string, object>
{
{ "Authorization", "Bearer test_access_token_123" },
{ "api_key", "test_api_key" }
{ "api_key", TestSecrets.ApiKey }
};
var bodyJson = new Dictionary<string, object>
{
Expand All @@ -52,7 +52,7 @@ public async Task ProcessRequest_ShouldHandleBearerTokenWithoutPrefix()
var headers = new Dictionary<string, object>
{
{ "Authorization", "test_access_token_123" }, // No "Bearer " prefix
{ "api_key", "test_api_key" }
{ "api_key", TestSecrets.ApiKey }
};
var bodyJson = new Dictionary<string, object>
{
Expand Down Expand Up @@ -100,7 +100,7 @@ public async Task ProcessRequest_ShouldHandleStringArrayValues()
var url = "https://api.contentstack.io/v3/stacks";
var headers = new Dictionary<string, object>
{
{ "api_key", "test_api_key" }
{ "api_key", TestSecrets.ApiKey }
};
var bodyJson = new Dictionary<string, object>
{
Expand All @@ -118,7 +118,7 @@ public async Task ProcessRequest_ShouldHandleDictionaryValues()
var url = "https://api.contentstack.io/v3/stacks";
var headers = new Dictionary<string, object>
{
{ "api_key", "test_api_key" }
{ "api_key", TestSecrets.ApiKey }
};
var bodyJson = new Dictionary<string, object>
{
Expand All @@ -136,7 +136,7 @@ public async Task ProcessRequest_ShouldHandleEmptyBodyJson()
var url = "https://api.contentstack.io/v3/stacks";
var headers = new Dictionary<string, object>
{
{ "api_key", "test_api_key" }
{ "api_key", TestSecrets.ApiKey }
};
var bodyJson = new Dictionary<string, object>();

Expand All @@ -151,7 +151,7 @@ public async Task ProcessRequest_ShouldHandleNullBodyJson()
var url = "https://api.contentstack.io/v3/stacks";
var headers = new Dictionary<string, object>
{
{ "api_key", "test_api_key" }
{ "api_key", TestSecrets.ApiKey }
};
Dictionary<string, object> bodyJson = null;

Expand All @@ -166,7 +166,7 @@ public async Task ProcessRequest_ShouldHandleInvalidUrl()
var url = "invalid-url";
var headers = new Dictionary<string, object>
{
{ "api_key", "test_api_key" }
{ "api_key", TestSecrets.ApiKey }
};
var bodyJson = new Dictionary<string, object>
{
Expand All @@ -184,7 +184,7 @@ public async Task ProcessRequest_ShouldHandleSpecialCharactersInParameters()
var url = "https://api.contentstack.io/v3/stacks";
var headers = new Dictionary<string, object>
{
{ "api_key", "test_api_key" }
{ "api_key", TestSecrets.ApiKey }
};
var bodyJson = new Dictionary<string, object>
{
Expand Down
23 changes: 8 additions & 15 deletions contentstack.model.generator.tests/ModelGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,13 @@ public void OAuthScopesParsing_ShouldParseCorrectly(string input, string[]? expe
public void CreateContentstackOptions_WithTraditionalAuth_ShouldSetCorrectProperties()
{

// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
_modelGenerator.ApiKey = "test_api_key";
_modelGenerator.ApiKey = TestSecrets.ApiKey;
_modelGenerator.Authtoken = "test_authtoken";
_modelGenerator.Host = "api.contentstack.io";
_modelGenerator.Branch = "main";
_modelGenerator.UseOAuth = false;
var options = CreateContentstackOptionsFromModelGenerator();
Assert.Equal("test_api_key", options.ApiKey);
Assert.Equal(TestSecrets.ApiKey, options.ApiKey);
Assert.Equal("test_authtoken", options.Authtoken);
Assert.Equal("api.contentstack.io", options.Host);
Assert.Equal("main", options.Branch);
Expand All @@ -167,24 +166,22 @@ public void CreateContentstackOptions_WithTraditionalAuth_ShouldSetCorrectProper
public void CreateContentstackOptions_WithOAuth_ShouldSetCorrectProperties()
{

// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
_modelGenerator.ApiKey = "test_api_key";
_modelGenerator.ApiKey = TestSecrets.ApiKey;
_modelGenerator.Host = "api.contentstack.io";
_modelGenerator.Branch = "main";
_modelGenerator.UseOAuth = true;
_modelGenerator.OAuthClientId = "test_client_id";
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
_modelGenerator.OAuthClientSecret = "test_client_secret";
_modelGenerator.OAuthClientSecret = TestSecrets.ClientSecret;
_modelGenerator.OAuthRedirectUri = "http://localhost:8080";
_modelGenerator.OAuthAppId = "test_app_id";
_modelGenerator.OAuthScopes = "read write admin";
var options = CreateContentstackOptionsFromModelGenerator();
Assert.Equal("test_api_key", options.ApiKey);
Assert.Equal(TestSecrets.ApiKey, options.ApiKey);
Assert.Equal("api.contentstack.io", options.Host);
Assert.Equal("main", options.Branch);
Assert.True(options.IsOAuth);
Assert.Equal("test_client_id", options.OAuthClientId);
Assert.Equal("test_client_secret", options.OAuthClientSecret);
Assert.Equal(TestSecrets.ClientSecret, options.OAuthClientSecret);
Assert.Equal("http://localhost:8080", options.OAuthRedirectUri);
Assert.Equal("test_app_id", options.OAuthAppId);
Assert.NotNull(options.OAuthScopes);
Expand All @@ -198,8 +195,7 @@ public void CreateContentstackOptions_WithOAuth_ShouldSetCorrectProperties()
public void CreateContentstackOptions_WithOAuthAndNoScopes_ShouldSetScopesToNull()
{

// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
_modelGenerator.ApiKey = "test_api_key";
_modelGenerator.ApiKey = TestSecrets.ApiKey;
_modelGenerator.Host = "api.contentstack.io";
_modelGenerator.UseOAuth = true;
_modelGenerator.OAuthClientId = "test_client_id";
Expand Down Expand Up @@ -287,8 +283,7 @@ public void HandleOAuthFlow_WithValidOAuthOptions_ShouldNotThrow()
{

_modelGenerator.UseOAuth = true;
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
_modelGenerator.ApiKey = "test_api_key";
_modelGenerator.ApiKey = TestSecrets.ApiKey;
_modelGenerator.Host = "api.contentstack.io";
_modelGenerator.OAuthClientId = "test_client_id";
_modelGenerator.OAuthRedirectUri = "http://localhost:8080";
Expand All @@ -315,14 +310,12 @@ private ContentstackOptions CreateContentstackOptionsFromModelGenerator()

return new ContentstackOptions
{
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
ApiKey = _modelGenerator.ApiKey,
Authtoken = _modelGenerator.Authtoken,
Host = _modelGenerator.Host,
Branch = _modelGenerator.Branch,
IsOAuth = _modelGenerator.UseOAuth,
OAuthClientId = _modelGenerator.OAuthClientId,
// deepcode ignore NoHardcodedCredentials: test fixture value, not a real secret
OAuthClientSecret = _modelGenerator.OAuthClientSecret,
OAuthRedirectUri = _modelGenerator.OAuthRedirectUri,
OAuthAppId = _modelGenerator.OAuthAppId,
Expand Down
Loading
Loading