Skip to content

Commit

Permalink
refactor!: rework deserialization of security schemes
Browse files Browse the repository at this point in the history
  • Loading branch information
JKRhb committed May 13, 2023
1 parent a817508 commit 617e064
Show file tree
Hide file tree
Showing 12 changed files with 219 additions and 210 deletions.
46 changes: 44 additions & 2 deletions lib/src/definitions/extensions/json_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ import '../interaction_affordances/event.dart';
import '../interaction_affordances/interaction_affordance.dart';
import '../interaction_affordances/property.dart';
import '../link.dart';
import '../security/ace_security_scheme.dart';
import '../security/apikey_security_scheme.dart';
import '../security/auto_security_scheme.dart';
import '../security/basic_security_scheme.dart';
import '../security/bearer_security_scheme.dart';
import '../security/combo_security_scheme.dart';
import '../security/digest_security_scheme.dart';
import '../security/no_security_scheme.dart';
import '../security/oauth2_security_scheme.dart';
import '../security/psk_security_scheme.dart';
import '../security/security_scheme.dart';
import '../thing_description.dart';
import '../validation/validation_exception.dart';
Expand Down Expand Up @@ -312,7 +322,7 @@ extension ParseField on Map<String, dynamic> {
/// defined.
Map<String, SecurityScheme>? parseSecurityDefinitions(
PrefixMapping prefixMapping,
Set<String>? parsedFields,
Set<String> parsedFields,
) {
final fieldValue =
parseMapField<dynamic>('securityDefinitions', parsedFields);
Expand All @@ -326,7 +336,7 @@ extension ParseField on Map<String, dynamic> {
for (final securityDefinition in fieldValue.entries) {
final dynamic value = securityDefinition.value;
if (value is Map<String, dynamic>) {
final securityScheme = SecurityScheme.fromJson(value, prefixMapping);
final securityScheme = value._parseSecurityScheme(prefixMapping, {});
if (securityScheme != null) {
result[securityDefinition.key] = securityScheme;
}
Expand All @@ -336,6 +346,38 @@ extension ParseField on Map<String, dynamic> {
return result;
}

SecurityScheme? _parseSecurityScheme(
PrefixMapping prefixMapping,
Set<String> parsedFields,
) {
final scheme = parseRequiredField('scheme', parsedFields);

switch (scheme) {
case 'auto':
return AutoSecurityScheme.fromJson(this, prefixMapping, parsedFields);
case 'basic':
return BasicSecurityScheme.fromJson(this, prefixMapping, parsedFields);
case 'bearer':
return BearerSecurityScheme.fromJson(this, prefixMapping, parsedFields);
case 'combo':
return ComboSecurityScheme.fromJson(this, prefixMapping, parsedFields);
case 'nosec':
return NoSecurityScheme.fromJson(this, prefixMapping, parsedFields);
case 'psk':
return PskSecurityScheme.fromJson(this, prefixMapping, parsedFields);
case 'digest':
return DigestSecurityScheme.fromJson(this, prefixMapping, parsedFields);
case 'apikey':
return ApiKeySecurityScheme.fromJson(this, prefixMapping, parsedFields);
case 'oauth2':
return OAuth2SecurityScheme.fromJson(this, prefixMapping, parsedFields);
case 'ace:ACESecurityScheme':
return AceSecurityScheme.fromJson(this, prefixMapping, parsedFields);
}

return null;
}

/// Parses [Property]s contained in this JSON object.
///
/// Adds the key `properties` to the set of [parsedFields], if defined.
Expand Down
43 changes: 23 additions & 20 deletions lib/src/definitions/security/ace_security_scheme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,53 @@ import '../extensions/json_parser.dart';

import 'security_scheme.dart';

const _schemeName = 'ace:ACESecurityScheme';

/// Experimental ACE Security Scheme.
class AceSecurityScheme extends SecurityScheme {
/// Constructor.
AceSecurityScheme({
String? description,
this.as,
this.audience,
this.scopes,
this.cnonce,
Map<String, String>? descriptions,
}) : super('ace:ACESecurityScheme') {
this.description = description;
this.descriptions.addAll(descriptions ?? {});
}
super.description,
super.descriptions,
super.proxy,
super.jsonLdType,
super.additionalFields,
}) : super(_schemeName);

Check warning on line 28 in lib/src/definitions/security/ace_security_scheme.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/definitions/security/ace_security_scheme.dart#L28

Added line #L28 was not covered by tests

/// Creates an [AceSecurityScheme] from a [json] object.
AceSecurityScheme.fromJson(
Map<String, dynamic> json,
PrefixMapping prefixMapping,
) : super('ace:ACESecurityScheme') {
final Set<String> parsedFields = {};

as = json.parseField<String>('ace:as', parsedFields);
cnonce = json.parseField<bool>('ace:cnonce', parsedFields);
audience = json.parseField<String>('ace:audience', parsedFields);
scopes = json.parseArrayField<String>('ace:scopes', parsedFields);

parseSecurityJson(json, parsedFields, prefixMapping);
}
Set<String> parsedFields,
) : as = json.parseField<String>('ace:as', parsedFields),
cnonce = json.parseField<bool>('ace:cnonce', parsedFields),
audience = json.parseField<String>('ace:audience', parsedFields),
scopes = json.parseArrayField<String>('ace:scopes', parsedFields),
super.fromJson(
_schemeName,
json,
prefixMapping,
parsedFields,
);

/// URI of the authorization server.
String? as;
final String? as;

/// The intended audience for this [AceSecurityScheme].
String? audience;
final String? audience;

/// Set of authorization scope identifiers provided as an array.
///
/// These are provided in tokens returned by an authorization server and
/// associated with forms in order to identify what resources a client may
/// access and how. The values associated with a form should be chosen from
/// those defined in an [AceSecurityScheme] active on that form.
List<String>? scopes;
final List<String>? scopes;

/// Indicates whether a [cnonce] is required by the Resource Server.
bool? cnonce;
final bool? cnonce;
}
32 changes: 18 additions & 14 deletions lib/src/definitions/security/apikey_security_scheme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,40 @@ import '../extensions/json_parser.dart';
import 'security_scheme.dart';

const _defaultInValue = 'query';
const _schemeName = 'apikey';

/// API key authentication security configuration identified by the Vocabulary
/// Term `apikey`.
class ApiKeySecurityScheme extends SecurityScheme {
/// Constructor.
ApiKeySecurityScheme({
super.description,
super.proxy,
this.name,
String? in_,
this.in_ = _defaultInValue,
super.description,
super.descriptions,
}) : in_ = in_ ?? _defaultInValue,
super('apikey');
super.proxy,
super.jsonLdType,
super.additionalFields,
}) : super(_schemeName);

Check warning on line 27 in lib/src/definitions/security/apikey_security_scheme.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/definitions/security/apikey_security_scheme.dart#L27

Added line #L27 was not covered by tests

/// Creates a [ApiKeySecurityScheme] from a [json] object.
ApiKeySecurityScheme.fromJson(
Map<String, dynamic> json,
PrefixMapping prefixMapping,
) : super('apikey') {
final Set<String> parsedFields = {};

name = json.parseField<String>('name', parsedFields);
in_ = json.parseField<String>('in', parsedFields) ?? _defaultInValue;

parseSecurityJson(json, parsedFields, prefixMapping);
}
Set<String> parsedFields,
) : name = json.parseField<String>('name', parsedFields),
in_ = json.parseField<String>('in', parsedFields) ?? _defaultInValue,
super.fromJson(
_schemeName,
json,
prefixMapping,
parsedFields,
);

/// Name for query, header, cookie, or uri parameters.
String? name;

/// Specifies the location of security authentication information.
late String in_;
final String in_;
}
16 changes: 13 additions & 3 deletions lib/src/definitions/security/auto_security_scheme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,24 @@ import 'package:curie/curie.dart';

import 'security_scheme.dart';

const _schemeName = 'auto';

/// An automatic security configuration identified by the
/// vocabulary term `auto`.
class AutoSecurityScheme extends SecurityScheme {
/// Constructor.
AutoSecurityScheme({

Check warning on line 17 in lib/src/definitions/security/auto_security_scheme.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/definitions/security/auto_security_scheme.dart#L17

Added line #L17 was not covered by tests
super.description,
super.descriptions,
super.proxy,
super.jsonLdType,
super.additionalFields,
}) : super(_schemeName);

Check warning on line 23 in lib/src/definitions/security/auto_security_scheme.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/definitions/security/auto_security_scheme.dart#L23

Added line #L23 was not covered by tests

/// Creates an [AutoSecurityScheme] from a [json] object.
AutoSecurityScheme.fromJson(
Map<String, dynamic> json,
PrefixMapping prefixMapping,
) : super('auto') {
parseSecurityJson(json, {}, prefixMapping);
}
Set<String> parsedFields,
) : super.fromJson(_schemeName, json, prefixMapping, parsedFields);
}
29 changes: 14 additions & 15 deletions lib/src/definitions/security/basic_security_scheme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,34 @@ import 'security_scheme.dart';

const _defaultInValue = 'header';

const _schemeName = 'basic';

/// Basic Authentication security configuration identified by the Vocabulary
/// Term `basic`.
class BasicSecurityScheme extends SecurityScheme {
/// Constructor.
BasicSecurityScheme({
super.description,
super.proxy,
this.name,
String? in_,
this.in_ = _defaultInValue,
super.description,
super.descriptions,
}) : in_ = in_ ?? _defaultInValue,
super('basic');
super.proxy,
super.jsonLdType,
super.additionalFields,
}) : super(_schemeName);

Check warning on line 28 in lib/src/definitions/security/basic_security_scheme.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/definitions/security/basic_security_scheme.dart#L28

Added line #L28 was not covered by tests

/// Creates a [BasicSecurityScheme] from a [json] object.
BasicSecurityScheme.fromJson(
Map<String, dynamic> json,
PrefixMapping prefixMapping,
) : super('basic') {
final Set<String> parsedFields = {};

name = json.parseField<String>('name', parsedFields);
in_ = json.parseField<String>('in', parsedFields) ?? _defaultInValue;

parseSecurityJson(json, parsedFields, prefixMapping);
}
Set<String> parsedFields,
) : name = json.parseField<String>('name', parsedFields),
in_ = json.parseField<String>('in', parsedFields) ?? _defaultInValue,
super.fromJson(_schemeName, json, prefixMapping, parsedFields);

/// Name for query, header, cookie, or uri parameters.
late final String? name;
final String? name;

/// Specifies the location of security authentication information.
late String in_ = 'header';
final String in_;
}
47 changes: 22 additions & 25 deletions lib/src/definitions/security/bearer_security_scheme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,53 +13,50 @@ const _defaultInValue = 'header';
const _defaultAlgValue = 'ES256';
const _defaultFormatValue = 'jwt';

const _schemeName = 'bearer';

/// Bearer Token security configuration identified by the Vocabulary Term
/// `bearer`.
class BearerSecurityScheme extends SecurityScheme {
/// Constructor.
BearerSecurityScheme({
this.name,
String? alg,
String? format,
this.alg = _defaultAlgValue,
this.format = _defaultFormatValue,
this.authorization,
String? in_,
super.proxy,
this.in_ = _defaultInValue,
super.description,
super.descriptions,
}) : in_ = in_ ?? _defaultInValue,
alg = alg ?? _defaultAlgValue,
format = format ?? _defaultFormatValue,
super('bearer');
super.proxy,
super.jsonLdType,
super.additionalFields,
}) : super(_schemeName);

Check warning on line 33 in lib/src/definitions/security/bearer_security_scheme.dart

View check run for this annotation

Codecov / codecov/patch

lib/src/definitions/security/bearer_security_scheme.dart#L33

Added line #L33 was not covered by tests

/// Creates a [BearerSecurityScheme] from a [json] object.
BearerSecurityScheme.fromJson(
Map<String, dynamic> json,
PrefixMapping prefixMapping,
) : super('bearer') {
final Set<String> parsedFields = {};

name = json.parseField<String>('name', parsedFields);
in_ = json.parseField<String>('in', parsedFields) ?? _defaultInValue;
format =
json.parseField<String>('format', parsedFields) ?? _defaultFormatValue;
alg = json.parseField<String>('alg', parsedFields) ?? _defaultAlgValue;
authorization = json.parseField<String>('authorization', parsedFields);

parseSecurityJson(json, parsedFields, prefixMapping);
}
Set<String> parsedFields,
) : name = json.parseField<String>('name', parsedFields),
in_ = json.parseField<String>('in', parsedFields) ?? _defaultInValue,
format = json.parseField<String>('format', parsedFields) ??
_defaultFormatValue,
alg = json.parseField<String>('alg', parsedFields) ?? _defaultAlgValue,
authorization = json.parseField<String>('authorization', parsedFields),
super.fromJson(_schemeName, json, prefixMapping, parsedFields);

/// URI of the authorization server.
late final String? authorization;
final String? authorization;

/// Name for query, header, cookie, or uri parameters.
late final String? name;
final String? name;

/// Encoding, encryption, or digest algorithm.
late final String alg;
final String alg;

/// Specifies format of security authentication information.
late final String format;
final String format;

/// Specifies the location of security authentication information.
late final String in_;
final String in_;
}
6 changes: 3 additions & 3 deletions lib/src/definitions/security/combo_security_scheme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class ComboSecurityScheme extends SecurityScheme {
super.description,
super.descriptions,
super.proxy,
super.jsonLdType,
super.additionalFields,
}) : super(_schemeName);

/// Creates a [ComboSecurityScheme] from a [json] object.
Expand All @@ -30,9 +32,7 @@ class ComboSecurityScheme extends SecurityScheme {
Set<String> parsedFields,
) : oneOf = json.parseArrayField<String>('oneOf', parsedFields),
allOf = json.parseArrayField<String>('allOf', parsedFields),
super(_schemeName) {
parseSecurityJson(json, parsedFields, prefixMapping);
}
super.fromJson(_schemeName, json, prefixMapping, parsedFields);

/// Array of two or more strings identifying other named security scheme
/// definitions, any one of which, when satisfied, will allow access.
Expand Down
Loading

0 comments on commit 617e064

Please sign in to comment.