Skip to content

Commit

Permalink
feat: Use scope instead of authoriztion_details based on switch #2066
Browse files Browse the repository at this point in the history
  • Loading branch information
bibash28 committed Nov 2, 2023
1 parent e6ad9f9 commit 6ddc494
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 4 deletions.
1 change: 1 addition & 0 deletions lib/app/shared/constants/secure_storage_keys.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class SecureStorageKeys {
static const String enableJWKThumbprint = 'enableJWKThumbprint';
static const String enableCryptographicHolderBinding =
'enableCryptographicHolderBinding';
static const String enableScopeParameter = 'enableScopeParameter';

static const String pinCode = 'pinCode';
static const String data = 'data';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class Oidc4vcSettingMenuView extends StatelessWidget {
const DidKeyTypeWidget(),
const SubjectSyntaxTypeWidget(),
const CryptographicHolderBindingWidget(),
const ScopeParameterWidget(),
DrawerItem(
title: l10n.clientMetadata,
onTap: () {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:altme/app/app.dart';
import 'package:altme/dashboard/profile/profile.dart';
import 'package:altme/l10n/l10n.dart';
import 'package:altme/theme/theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class ScopeParameterWidget extends StatelessWidget {
const ScopeParameterWidget({super.key});

@override
Widget build(BuildContext context) {
final l10n = context.l10n;
return BlocBuilder<ProfileCubit, ProfileState>(
builder: (context, state) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
padding: const EdgeInsets.all(Sizes.spaceSmall),
margin: const EdgeInsets.all(Sizes.spaceXSmall),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.drawerSurface,
borderRadius: const BorderRadius.all(
Radius.circular(Sizes.largeRadius),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 10),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
l10n.scopeParameters,
style: Theme.of(context).textTheme.drawerItemTitle,
),
const SizedBox(height: 10),
Text(
l10n.scopeParametersSubtitle,
style: Theme.of(context).textTheme.drawerItemSubtitle,
),
],
),
),
const SizedBox(height: 10),
Switch(
onChanged: (value) async {
await context
.read<ProfileCubit>()
.updateScopeParameterStatus(
enabled: value,
);
},
value: state.model.enableScopeParameter,
activeColor: Theme.of(context).colorScheme.primary,
),
],
),
),
],
);
},
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export 'cryptograhic_holder_binding.dart';
export 'did_key_type_widget.dart';
export 'scope_parameter.dart';
export 'security_level_widget.dart';
export 'six_or_four_pin_widget.dart';
export 'subject_syntax_type_widget.dart';
17 changes: 17 additions & 0 deletions lib/dashboard/profile/cubit/profile_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ class ProfileCubit extends Cubit<ProfileState> {
enableCryptographicHolderBindingValue == null ||
enableCryptographicHolderBindingValue == 'true';

final enableScopeParameterValue = await secureStorageProvider
.get(SecureStorageKeys.enableScopeParameter);

final enableScopeParameter = enableScopeParameterValue != null &&
enableScopeParameterValue == 'true';

final userPINCodeForAuthenticationValue = await secureStorageProvider
.get(SecureStorageKeys.userPINCodeForAuthentication);
final userPINCodeForAuthentication =
Expand Down Expand Up @@ -161,6 +167,7 @@ class ProfileCubit extends Cubit<ProfileState> {
enable4DigitPINCode: enable4DigitPINCode,
enableJWKThumbprint: enableJWKThumbprint,
enableCryptographicHolderBinding: enableCryptographicHolderBinding,
enableScopeParameter: enableScopeParameter,
);
await update(profileModel);
} catch (e, s) {
Expand Down Expand Up @@ -275,6 +282,11 @@ class ProfileCubit extends Cubit<ProfileState> {
profileModel.enableCryptographicHolderBinding.toString(),
);

await secureStorageProvider.set(
SecureStorageKeys.enableScopeParameter,
profileModel.enableScopeParameter.toString(),
);

emit(
state.copyWith(
model: profileModel,
Expand Down Expand Up @@ -363,6 +375,11 @@ class ProfileCubit extends Cubit<ProfileState> {
await update(profileModel);
}

Future<void> updateScopeParameterStatus({bool enabled = false}) async {
final profileModel = state.model.copyWith(enableScopeParameter: enabled);
await update(profileModel);
}

Future<void> enable4DigitPINCode({bool enabled = false}) async {
final profileModel = state.model.copyWith(enable4DigitPINCode: enabled);
await update(profileModel);
Expand Down
6 changes: 6 additions & 0 deletions lib/dashboard/profile/models/profile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class ProfileModel extends Equatable {
required this.userPINCodeForAuthentication,
required this.enableJWKThumbprint,
required this.enableCryptographicHolderBinding,
required this.enableScopeParameter,
this.companyName = '',
this.companyWebsite = '',
this.jobTitle = '',
Expand Down Expand Up @@ -55,6 +56,7 @@ class ProfileModel extends Equatable {
enable4DigitPINCode: false,
enableJWKThumbprint: false,
enableCryptographicHolderBinding: true,
enableScopeParameter: false,
);

final String firstName;
Expand All @@ -79,6 +81,7 @@ class ProfileModel extends Equatable {
final bool enable4DigitPINCode;
final bool enableJWKThumbprint;
final bool enableCryptographicHolderBinding;
final bool enableScopeParameter;

@override
List<Object> get props => [
Expand All @@ -103,6 +106,7 @@ class ProfileModel extends Equatable {
enable4DigitPINCode,
enableJWKThumbprint,
enableCryptographicHolderBinding,
enableScopeParameter,
];

Map<String, dynamic> toJson() => _$ProfileModelToJson(this);
Expand All @@ -129,6 +133,7 @@ class ProfileModel extends Equatable {
bool? enable4DigitPINCode,
bool? enableJWKThumbprint,
bool? enableCryptographicHolderBinding,
bool? enableScopeParameter,
}) {
return ProfileModel(
firstName: firstName ?? this.firstName,
Expand All @@ -147,6 +152,7 @@ class ProfileModel extends Equatable {
enableJWKThumbprint: enableJWKThumbprint ?? this.enableJWKThumbprint,
enableCryptographicHolderBinding: enableCryptographicHolderBinding ??
this.enableCryptographicHolderBinding,
enableScopeParameter: enableScopeParameter ?? this.enableScopeParameter,
userConsentForIssuerAccess:
userConsentForIssuerAccess ?? this.userConsentForIssuerAccess,
userConsentForVerifierAccess:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,9 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
required dynamic credentialOfferJson,
}) async {
try {
final enableScopeParameterValue =
profileCubit.state.model.enableScopeParameter;
;
if (preAuthorizedCode != null) {
await addCredentialsInLoop(
selectedCredentials: selectedCredentials,
Expand All @@ -1065,6 +1068,7 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
secureStorageProvider: secureStorageProvider,
credentialOfferJson: credentialOfferJson,
issuer: issuer,
credentailsInScopeParameter: enableScopeParameterValue,
);
goBack();
}
Expand Down
2 changes: 2 additions & 0 deletions lib/l10n/arb/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,8 @@
"enableToUseTheJWKThumprintOfTheKey": "Default: DID\nEnable to use the JWK thumprint of the key",
"cryptographicHolderBinding": "Cryptographic holder binding",
"cryptographicHolderBindingSubtitle": "Default : On\nDisable to accept Bearer credentials as tickets with low assurance.",
"scopeParameters": "Scope Parameters",
"scopeParametersSubtitle": "Default : Off\nEnable to force wallet to use scope instead of authorization_details.",
"theServiceIsNotAvailable": "The service is not available",
"download": "Download",
"issuerDID": "Issuer DID",
Expand Down
8 changes: 8 additions & 0 deletions lib/l10n/untranslated.json
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,8 @@
"enableToUseTheJWKThumprintOfTheKey",
"cryptographicHolderBinding",
"cryptographicHolderBindingSubtitle",
"scopeParameters",
"scopeParametersSubtitle",
"theServiceIsNotAvailable",
"download",
"issuerDID",
Expand Down Expand Up @@ -1798,6 +1800,8 @@
"enableToUseTheJWKThumprintOfTheKey",
"cryptographicHolderBinding",
"cryptographicHolderBindingSubtitle",
"scopeParameters",
"scopeParametersSubtitle",
"theServiceIsNotAvailable",
"download",
"issuerDID",
Expand Down Expand Up @@ -2008,6 +2012,8 @@
"enableToUseTheJWKThumprintOfTheKey",
"cryptographicHolderBinding",
"cryptographicHolderBindingSubtitle",
"scopeParameters",
"scopeParametersSubtitle",
"theServiceIsNotAvailable",
"download",
"issuerDID",
Expand Down Expand Up @@ -2915,6 +2921,8 @@
"enableToUseTheJWKThumprintOfTheKey",
"cryptographicHolderBinding",
"cryptographicHolderBindingSubtitle",
"scopeParameters",
"scopeParametersSubtitle",
"theServiceIsNotAvailable",
"download",
"issuerDID",
Expand Down
2 changes: 2 additions & 0 deletions lib/oidc4vc/get_authorization_uri_for_issuer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Future<void> getAuthorizationUriForIssuer({
required SecureStorageProvider secureStorageProvider,
required String issuer,
required dynamic credentialOfferJson,
required bool credentailsInScopeParameter,
}) async {
final privateKey = await fetchPrivateKey(
isEBSIV3: isEBSIV3,
Expand Down Expand Up @@ -62,6 +63,7 @@ Future<void> getAuthorizationUriForIssuer({
pkcePair: pkcePair,
state: jwtToken,
authorizationEndPoint: Parameters.authorizeEndPoint,
credentailsInScopeParameter: credentailsInScopeParameter,
);

await LaunchUrl.launchUri(oidc4vcAuthenticationUri);
Expand Down
13 changes: 13 additions & 0 deletions packages/oidc4vc/lib/src/helper_function.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
String listToString(List<dynamic> inputList) {
final resultList = <dynamic>[];

for (var i = 0; i < inputList.length; i++) {
resultList.add(inputList[i]);

if (i < inputList.length - 1) {
resultList.add(' ');
}
}

return resultList.join();
}
17 changes: 15 additions & 2 deletions packages/oidc4vc/lib/src/oidc4vc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:flutter/foundation.dart';
import 'package:hex/hex.dart';
import 'package:jose/jose.dart';
import 'package:json_path/json_path.dart';
import 'package:oidc4vc/src/helper_function.dart';
import 'package:oidc4vc/src/issuer_token_parameters.dart';
import 'package:oidc4vc/src/pkce_dart.dart';
import 'package:oidc4vc/src/token_parameters.dart';
Expand Down Expand Up @@ -95,6 +96,7 @@ class OIDC4VC {
required PkcePair pkcePair,
required String state,
required String authorizationEndPoint,
required bool credentailsInScopeParameter,
}) async {
try {
final openidConfigurationResponse = await getOpenIdConfig(issuer);
Expand All @@ -113,6 +115,7 @@ class OIDC4VC {
pkcePair: pkcePair,
state: state,
authorizationEndPoint: authorizationEndPoint,
credentailsInScopeParameter: credentailsInScopeParameter,
);

final url = Uri.parse(authorizationEndpoint);
Expand All @@ -136,10 +139,12 @@ class OIDC4VC {
required String authorizationEndPoint,
required PkcePair pkcePair,
required String state,
required bool credentailsInScopeParameter,
}) {
//https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#name-successful-authorization-re

final authorizationDetails = <dynamic>[];
final credentials = <dynamic>[];

for (final credential in selectedCredentials) {
late Map<String, dynamic> data;
Expand Down Expand Up @@ -172,13 +177,16 @@ class OIDC4VC {
'format': credentailData['format'],
'types': credentailData['types'],
};

credentials.addAll(credentailData['types'] as List<dynamic>);
} else if (credential is Map<String, dynamic>) {
data = {
'type': 'openid_credential',
'locations': [issuer],
'format': credential['format'],
'types': credential['types'],
};
credentials.addAll(credential['types'] as List<dynamic>);
} else {
throw Exception();
}
Expand All @@ -192,13 +200,11 @@ class OIDC4VC {
'response_type': 'code',
'client_id': clientId,
'redirect_uri': redirectUri,
'scope': 'openid',
'issuer_state': issuerState,
'state': state,
'nonce': nonce,
'code_challenge': codeChallenge,
'code_challenge_method': 'S256',
'authorization_details': jsonEncode(authorizationDetails),
'client_metadata': jsonEncode({
'authorization_endpoint': authorizationEndPoint,
'scopes_supported': ['openid'],
Expand Down Expand Up @@ -236,6 +242,13 @@ class OIDC4VC {
'id_token_types_supported': ['subject_signed_id_token']
}),
};

if (credentailsInScopeParameter) {
myRequest['scope'] = listToString(credentials);
} else {
myRequest['scope'] = 'openid';
myRequest['authorization_details'] = jsonEncode(authorizationDetails);
}
return myRequest;
}

Expand Down
4 changes: 2 additions & 2 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1421,10 +1421,10 @@ packages:
dependency: transitive
description:
name: local_auth_ios
sha256: "26a8d1ad0b4ef6f861d29921be8383000fda952e323a5b6752cf82ca9cf9a7a9"
sha256: "8293faf72ef0ac4710f209edd03916c2d4c1eeab0483bdcf9b2e659c2f7d737b"
url: "https://pub.dev"
source: hosted
version: "1.1.4"
version: "1.1.5"
local_auth_platform_interface:
dependency: transitive
description:
Expand Down

0 comments on commit 6ddc494

Please sign in to comment.