mirror of
https://github.com/foss42/apidash.git
synced 2025-12-01 02:07:00 +08:00
fix: handle security fields with empty arrays
This commit is contained in:
@@ -132,15 +132,53 @@ class OpenApiImportService {
|
||||
|
||||
/// Try to parse a JSON or YAML OpenAPI spec string.
|
||||
/// Returns null if parsing fails.
|
||||
///
|
||||
/// NOTE: There's a known issue with the openapi_spec package where
|
||||
/// security fields containing empty arrays (e.g., "security": [[]])
|
||||
/// cause parsing failures. This method includes a workaround.
|
||||
static OpenApi? tryParseSpec(String source) {
|
||||
try {
|
||||
// Let the library infer JSON/YAML
|
||||
return OpenApi.fromString(source: source, format: null);
|
||||
} catch (_) {
|
||||
} catch (e) {
|
||||
// Try workaround for security field parsing issues
|
||||
try {
|
||||
final processedSource = _removeProblematicSecurityField(source);
|
||||
if (processedSource != source) {
|
||||
return OpenApi.fromString(source: processedSource, format: null);
|
||||
}
|
||||
} catch (_) {
|
||||
// Workaround failed, fall through to return null
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes problematic security fields that cause parsing issues.
|
||||
/// TODO: Remove this workaround once openapi_spec package fixes
|
||||
/// the issue with security fields containing empty arrays.
|
||||
static String _removeProblematicSecurityField(String source) {
|
||||
try {
|
||||
final spec = jsonDecode(source) as Map<String, dynamic>;
|
||||
|
||||
if (spec.containsKey('security')) {
|
||||
final security = spec['security'];
|
||||
if (security is List && _hasEmptySecurityArrays(security)) {
|
||||
spec.remove('security');
|
||||
return jsonEncode(spec);
|
||||
}
|
||||
}
|
||||
|
||||
return source;
|
||||
} catch (e) {
|
||||
throw FormatException('Failed to preprocess OpenAPI spec: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if security list contains empty arrays that cause parsing issues.
|
||||
static bool _hasEmptySecurityArrays(List<dynamic> security) {
|
||||
return security.any((item) => item is List && item.isEmpty);
|
||||
}
|
||||
|
||||
/// Build a single request payload from a path + method operation.
|
||||
/// The payload mirrors CurlImportService payload shape for reuse.
|
||||
static Map<String, dynamic> _payloadForOperation({
|
||||
|
||||
@@ -31,6 +31,86 @@ void main() {
|
||||
expect(summary, contains('POST'));
|
||||
});
|
||||
|
||||
test('tryParseSpec handles problematic security field with empty arrays',
|
||||
() {
|
||||
const specWithEmptySecurityArray = '''
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Cat Fact API",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"paths": {
|
||||
"/fact": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [[]]
|
||||
}''';
|
||||
|
||||
final result =
|
||||
OpenApiImportService.tryParseSpec(specWithEmptySecurityArray);
|
||||
expect(result, isNotNull);
|
||||
expect(result!.info.title, equals('Cat Fact API'));
|
||||
expect(result.info.version, equals('1.0.0'));
|
||||
expect(result.paths, isNotNull);
|
||||
expect(result.paths!.keys, contains('/fact'));
|
||||
});
|
||||
|
||||
test('tryParseSpec handles valid security field with actual requirements',
|
||||
() {
|
||||
const specWithRealSecurity = '''
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Secured API",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"paths": {
|
||||
"/secured": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
}''';
|
||||
|
||||
final result = OpenApiImportService.tryParseSpec(specWithRealSecurity);
|
||||
expect(result, isNotNull);
|
||||
expect(result!.info.title, equals('Secured API'));
|
||||
});
|
||||
|
||||
test('tryParseSpec returns null for invalid JSON', () {
|
||||
const invalidSpec = 'not valid json';
|
||||
final result = OpenApiImportService.tryParseSpec(invalidSpec);
|
||||
expect(result, isNull);
|
||||
});
|
||||
|
||||
test('tryParseSpec returns null for non-OpenAPI JSON', () {
|
||||
const nonOpenApiSpec = '''
|
||||
{
|
||||
"notOpenApi": true,
|
||||
"someField": "value"
|
||||
}''';
|
||||
final result = OpenApiImportService.tryParseSpec(nonOpenApiSpec);
|
||||
expect(result, isNull);
|
||||
});
|
||||
|
||||
test('extractSpecMeta includes endpoints & baseUrl', () {
|
||||
final spec = OpenApiImportService.tryParseSpec(_specJson)!;
|
||||
final meta = OpenApiImportService.extractSpecMeta(spec);
|
||||
|
||||
Reference in New Issue
Block a user