Skip to content

Commit

Permalink
refactor: Updated authorisation test flow
Browse files Browse the repository at this point in the history
  • Loading branch information
bibash28 committed Sep 20, 2023
1 parent 0fd399a commit c93ffd9
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@ class Oidc4vcCredentialPickView extends StatelessWidget {
issuer: issuer,
preAuthorizedCode: preAuthorizedCode,
oidc4vcType: oidc4vcType,
selectedCredentialsIndex: state,
credentialOfferJson: credentialOfferJson,
);
},
Expand Down
153 changes: 81 additions & 72 deletions lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -510,86 +510,91 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
required OIDC4VCType currentOIIDC4VCType,
required QRCodeScanCubit qrCodeScanCubit,
}) async {
emit(
state.copyWith(
uri: Uri.parse(scannedResponse),
qrScanStatus: QrScanStatus.loading,
),
);
try {
emit(
state.copyWith(
uri: Uri.parse(scannedResponse),
qrScanStatus: QrScanStatus.loading,
),
);

dynamic credentialOfferJson;
switch (currentOIIDC4VCType) {
case OIDC4VCType.DEFAULT:
case OIDC4VCType.GREENCYPHER:
case OIDC4VCType.EBSIV3:
credentialOfferJson = await getCredentialOfferJson(
scannedResponse: scannedResponse,
dioClient: client,
);
if (credentialOfferJson == null) break;
dynamic credentialOfferJson;
switch (currentOIIDC4VCType) {
case OIDC4VCType.DEFAULT:
case OIDC4VCType.GREENCYPHER:
case OIDC4VCType.EBSIV3:
credentialOfferJson = await getCredentialOfferJson(
scannedResponse: scannedResponse,
dioClient: client,
);
if (credentialOfferJson == null) break;

final dynamic preAuthorizedCodeGrant = credentialOfferJson['grants']
['urn:ietf:params:oauth:grant-type:pre-authorized_code'];
final dynamic preAuthorizedCodeGrant = credentialOfferJson['grants']
['urn:ietf:params:oauth:grant-type:pre-authorized_code'];

bool? userPinRequired;
bool? userPinRequired;

if (preAuthorizedCodeGrant != null &&
preAuthorizedCodeGrant is Map &&
preAuthorizedCodeGrant.containsKey('user_pin_required')) {
userPinRequired = preAuthorizedCodeGrant['user_pin_required'] as bool;
}
if (preAuthorizedCodeGrant != null &&
preAuthorizedCodeGrant is Map &&
preAuthorizedCodeGrant.containsKey('user_pin_required')) {
userPinRequired =
preAuthorizedCodeGrant['user_pin_required'] as bool;
}

if (userPinRequired == null) break;
if (userPinRequired == null) break;

if (userPinRequired) {
emit(
state.copyWith(
qrScanStatus: QrScanStatus.success,
route: UserPinPage.route(
onCancel: () {
goBack();
},
onProceed: (String userPin) async {
await initiateOIDC4VCCredentialIssuance(
scannedResponse: scannedResponse,
credentialsCubit: credentialsCubit,
oidc4vcType: currentOIIDC4VCType,
didKitProvider: didKitProvider,
qrCodeScanCubit: qrCodeScanCubit,
secureStorageProvider: getSecureStorage,
dioClient: client,
userPin: userPin,
credentialOfferJson: credentialOfferJson,
);
},
if (userPinRequired) {
emit(
state.copyWith(
qrScanStatus: QrScanStatus.success,
route: UserPinPage.route(
onCancel: () {
goBack();
},
onProceed: (String userPin) async {
await initiateOIDC4VCCredentialIssuance(
scannedResponse: scannedResponse,
credentialsCubit: credentialsCubit,
oidc4vcType: currentOIIDC4VCType,
didKitProvider: didKitProvider,
qrCodeScanCubit: qrCodeScanCubit,
secureStorageProvider: getSecureStorage,
dioClient: client,
userPin: userPin,
credentialOfferJson: credentialOfferJson,
);
},
),
),
),
);
} else {
break;
}
);
} else {
break;
}

return;
return;

case OIDC4VCType.GAIAX:
case OIDC4VCType.EBSIV2:
break;
case OIDC4VCType.GAIAX:
case OIDC4VCType.EBSIV2:
break;

case OIDC4VCType.JWTVC:
throw Exception();
}
case OIDC4VCType.JWTVC:
throw Exception();
}

await initiateOIDC4VCCredentialIssuance(
scannedResponse: scannedResponse,
credentialsCubit: credentialsCubit,
oidc4vcType: currentOIIDC4VCType,
didKitProvider: didKitProvider,
qrCodeScanCubit: qrCodeScanCubit,
secureStorageProvider: getSecureStorage,
dioClient: client,
userPin: null,
credentialOfferJson: credentialOfferJson,
);
await initiateOIDC4VCCredentialIssuance(
scannedResponse: scannedResponse,
credentialsCubit: credentialsCubit,
oidc4vcType: currentOIIDC4VCType,
didKitProvider: didKitProvider,
qrCodeScanCubit: qrCodeScanCubit,
secureStorageProvider: getSecureStorage,
dioClient: client,
userPin: null,
credentialOfferJson: credentialOfferJson,
);
} catch (e) {
log.e(e);
}
}

Future<void> startOIDC4VCDeferedCredentialIssuance({
Expand Down Expand Up @@ -937,7 +942,6 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {

Future<void> processSelectedCredentials({
required List<dynamic> selectedCredentials,
required List<int> selectedCredentialsIndex,
required OIDC4VCType oidc4vcType,
required String? userPin,
required String? preAuthorizedCode,
Expand All @@ -954,6 +958,8 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
userPin: userPin,
preAuthorizedCode: preAuthorizedCode,
issuer: issuer,
codeForAuthorisedFlow: null,
codeVerifier: null,
);
} else {
emit(state.loading());
Expand All @@ -966,7 +972,6 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
secureStorageProvider: secureStorageProvider,
credentialOfferJson: credentialOfferJson,
issuer: issuer,
selectedCredentialsIndex: selectedCredentialsIndex,
);
goBack();
}
Expand All @@ -990,6 +995,8 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
required String? userPin,
required String? preAuthorizedCode,
required String issuer,
required String? codeForAuthorisedFlow,
required String? codeVerifier,
}) async {
try {
final OIDC4VC oidc4vc = oidc4vcType.getOIDC4VC;
Expand All @@ -1006,10 +1013,12 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
secureStorageProvider: getSecureStorage,
credential: selectedCredentials[i],
isLastCall: i + 1 == selectedCredentials.length,
dioClient: DioClient('', Dio()),
dioClient: client,
userPin: userPin,
issuer: issuer,
preAuthorizedCode: preAuthorizedCode,
codeForAuthorisedFlow: codeForAuthorisedFlow,
codeVerifier: codeVerifier,
);
}

Expand Down
7 changes: 2 additions & 5 deletions lib/oidc4vc/get_and_add_credential.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Future<void> getAndAddCredential({
required String? userPin,
required String? preAuthorizedCode,
required String issuer,
required String? codeForAuthorisedFlow,
required String? codeVerifier,
}) async {
final mnemonic =
await secureStorageProvider.get(SecureStorageKeys.ssiMnemonic);
Expand All @@ -36,11 +38,6 @@ Future<void> getAndAddCredential({
didKitProvider: didKitProvider,
);

final codeForAuthorisedFlow =
Uri.parse(scannedResponse).queryParameters['code'];
final codeVerifier =
Uri.parse(scannedResponse).queryParameters['code_verifier'];

if (preAuthorizedCode != null ||
(codeForAuthorisedFlow != null && codeVerifier != null)) {
/// codeForAuthorisedFlow != null
Expand Down
19 changes: 13 additions & 6 deletions lib/oidc4vc/get_authorization_uri_for_issuer.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:altme/app/app.dart';
import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';

import 'package:altme/oidc4vc/oidc4vc.dart';
import 'package:did_kit/did_kit.dart';
import 'package:oidc4vc/oidc4vc.dart';
import 'package:secure_storage/secure_storage.dart';
Expand All @@ -12,7 +12,6 @@ Future<void> getAuthorizationUriForIssuer({
required OIDC4VCType oidc4vcType,
required DIDKitProvider didKitProvider,
required List<dynamic> selectedCredentials,
required List<int> selectedCredentialsIndex,
required SecureStorageProvider secureStorageProvider,
required String issuer,
required dynamic credentialOfferJson,
Expand All @@ -37,18 +36,26 @@ Future<void> getAuthorizationUriForIssuer({
['issuer_state'] as String;

final String nonce = const Uuid().v4();
final PkcePair pkcePair = PkcePair.generate();

final jwt = JWT({
'codeVerifier': pkcePair.codeVerifier,
'credentials': selectedCredentials,
'issuer': issuer,
'type': oidc4vcType.name,
});

final jwtToken = jwt.sign(SecretKey('0123456789'));

final Uri ebsiAuthenticationUri = await oidc4vc.getAuthorizationUriForIssuer(
selectedCredentials: selectedCredentials,
clientId: did,
webLink: Parameters.oidc4vcUniversalLink,
schema: scannedResponse,
redirectUri: Parameters.oidc4vcUniversalLink,
issuer: issuer,
issuerState: issuerState,
nonce: nonce,
options: selectedCredentialsIndex.toString(),
state: const Uuid().v4(),
pkcePair: PkcePair.generate(),
state: jwtToken,
);
await LaunchUrl.launchUri(ebsiAuthenticationUri);
}
29 changes: 16 additions & 13 deletions lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:altme/dashboard/dashboard.dart';
import 'package:altme/oidc4vc/oidc4vc.dart';

import 'package:did_kit/did_kit.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'package:oidc4vc/oidc4vc.dart';
import 'package:secure_storage/secure_storage.dart';

Expand Down Expand Up @@ -47,8 +48,7 @@ Future<void> initiateOIDC4VCCredentialIssuance({
if (credentials is List<dynamic>) {
final codeForAuthorisedFlow =
Uri.parse(scannedResponse).queryParameters['code'];
final stateOfCredentialsSelected =
Uri.parse(scannedResponse).queryParameters['options'];
final state = Uri.parse(scannedResponse).queryParameters['state'];

if (preAuthorizedCode != null) {
/// full phase flow of preAuthorized
Expand All @@ -61,7 +61,7 @@ Future<void> initiateOIDC4VCCredentialIssuance({
credentialOfferJson: credentialOfferJson,
);
} else {
if (codeForAuthorisedFlow == null || stateOfCredentialsSelected == null) {
if (codeForAuthorisedFlow == null || state == null) {
/// first phase flow of authorised
qrCodeScanCubit.navigateToOidc4vcCredentialPickPage(
credentials: credentials,
Expand All @@ -74,25 +74,26 @@ Future<void> initiateOIDC4VCCredentialIssuance({
} else {
/// second phase flow of authorised
/// remove empty fields
stateOfCredentialsSelected.replaceAll(' ', '');
final jwt = decodePayload(
jwtDecode: JWTDecode(),
token: state,
);

/// Remove the brackets and split the string into a list of substrings
final List<String> stringList = stateOfCredentialsSelected
.substring(1, stateOfCredentialsSelected.length - 1)
.split(',');
final stateOfCredentialsSelected = jwt['options'] as List<dynamic>;
final String codeVerifier = jwt['codeVerifier'].toString();

// Convert the list of strings to a list of integers
final List<int> intList = stringList.map(int.parse).toList();
final selectedCredentials = stateOfCredentialsSelected
.map((index) => credentials[index])
.toList();

final selectedCredentials =
intList.map((index) => credentials[index]).toList();
await qrCodeScanCubit.addCredentialsInLoop(
selectedCredentials: selectedCredentials,
userPin: userPin,
issuer: issuer,
preAuthorizedCode: null,
oidc4vcType: oidc4vcType,
codeForAuthorisedFlow: codeForAuthorisedFlow,
codeVerifier: codeVerifier,
);
}
}
Expand All @@ -111,6 +112,8 @@ Future<void> initiateOIDC4VCCredentialIssuance({
userPin: userPin,
issuer: issuer,
preAuthorizedCode: preAuthorizedCode,
codeForAuthorisedFlow: null,
codeVerifier: null,
);
oidc4vc.resetNonceAndAccessTokenAndAuthorizationDetails();
qrCodeScanCubit.goBack();
Expand Down
Loading

0 comments on commit c93ffd9

Please sign in to comment.