Skip to content

Commit

Permalink
feat: Implement required parameter of limited disclosure in presentat…
Browse files Browse the repository at this point in the history
…ion definition #2599
  • Loading branch information
bibash28 committed Apr 18, 2024
1 parent ed5d1a1 commit 471eea4
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 35 deletions.
6 changes: 1 addition & 5 deletions lib/app/shared/helper_functions/helper_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import 'package:altme/app/app.dart';
import 'package:altme/dashboard/dashboard.dart';
import 'package:altme/oidc4vc/oidc4vc.dart';
import 'package:altme/selective_disclosure/selective_disclosure.dart';
import 'package:asn1lib/asn1lib.dart' as asn1lib;
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:convert/convert.dart';
import 'package:credential_manifest/credential_manifest.dart';

import 'package:dartez/dartez.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';

import 'package:fast_base58/fast_base58.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:intl/intl.dart';
Expand All @@ -23,8 +22,6 @@ import 'package:key_generator/key_generator.dart';
import 'package:oidc4vc/oidc4vc.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:secure_storage/secure_storage.dart';
import 'package:pointycastle/pointycastle.dart' as pc;
import 'package:asn1lib/asn1lib.dart' as asn1lib;
import 'package:x509/x509.dart' as x509;

String generateDefaultAccountName(
Expand Down Expand Up @@ -1661,7 +1658,6 @@ List<String> getStringCredentialsForToken({

/// jwt_vc
presentJwtVc = format?.jwtVc != null || format?.jwtVp != null;
;

/// jwt_vc_json
presentJwtVcJson = format?.jwtVcJson != null || format?.jwtVpJson != null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,6 @@ class _CredentialsDetailsViewState extends State<CredentialsDetailsView> {
.customOidc4vcProfile
.credentialManifestSupport;

final isSecure = profileData.profileSetting.selfSovereignIdentityOptions
.customOidc4vcProfile.securityLevel;

final credentialSupported = widget.credentialModel.credentialSupported;

final claims = credentialSupported?['claims'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,13 @@ class CredentialManifestOfferPickView extends StatelessWidget {
.filteredCredentialList[
credentialManifestState
.selected.first],
presentationDefinition:
presentationDefinition,
),
),

/// next button because we will now choose the claims we will present
/// next button because we will now choose
/// the claims we will present
/// from the selected credential
text: l10n.next,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:altme/app/shared/shared.dart';
import 'package:altme/dashboard/home/home.dart';
import 'package:altme/selective_disclosure/selective_disclosure.dart';
import 'package:credential_manifest/credential_manifest.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:json_annotation/json_annotation.dart';
Expand All @@ -16,6 +17,41 @@ class SelectiveDisclosureCubit extends Cubit<SelectiveDisclosureState> {

final OIDC4VC oidc4vc;

void dataFromPresentation({
required CredentialModel credentialModel,
required PresentationDefinition? presentationDefinition,
}) {
String? limitDisclosure;
final json = <String, dynamic>{};

if (presentationDefinition != null) {
final selectiveDisclosure = SelectiveDisclosure(credentialModel);

final credentialData = createJsonByDecryptingSDValues(
encryptedJson: credentialModel.data,
selectiveDisclosure: selectiveDisclosure,
);

for (final inputDescriptor in presentationDefinition.inputDescriptors) {
final filterList = inputDescriptor.constraints?.fields ?? <Field>[];

limitDisclosure = inputDescriptor.constraints?.limitDisclosure;

for (final field in filterList) {
for (final path in field.path) {
final searchList = getTextsFromCredential(path, credentialData);
for (final element in searchList) {
final key = path.split('.').toList().last;
json[key] = element;
}
}
}
}

emit(state.copyWith(limitDisclosure: limitDisclosure, filters: json));
}
}

void toggle(String claimKeyId) {
final List<String> selectedClaimsKeys = List.of(state.selectedClaimsKeyIds);

Expand Down Expand Up @@ -82,4 +118,18 @@ class SelectiveDisclosureCubit extends Cubit<SelectiveDisclosureState> {
}
emit(state.copyWith(selectedSDIndexInJWT: selected));
}

void disclosureAction({
required String claimKeyId,
required CredentialModel credentialModel,
String? threeDotValue,
String? claimsKey,
}) {
toggle(claimKeyId);
saveIndexOfSDJWT(
claimsKey: claimsKey,
credentialModel: credentialModel,
threeDotValue: threeDotValue,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class SelectiveDisclosureState extends Equatable {
this.message,
this.selectedClaimsKeyIds = const [],
this.selectedSDIndexInJWT = const [],
this.limitDisclosure,
this.filters,
});

factory SelectiveDisclosureState.fromJson(Map<String, dynamic> json) =>
Expand All @@ -14,15 +16,21 @@ class SelectiveDisclosureState extends Equatable {
final StateMessage? message;
final List<String> selectedClaimsKeyIds;
final List<int> selectedSDIndexInJWT;
final String? limitDisclosure;
final Map<String, dynamic>? filters;

SelectiveDisclosureState copyWith({
List<String>? selectedClaimsKeyIds,
List<int>? selectedSDIndexInJWT,
StateMessage? message,
String? limitDisclosure,
Map<String, dynamic>? filters,
}) {
return SelectiveDisclosureState(
selectedClaimsKeyIds: selectedClaimsKeyIds ?? this.selectedClaimsKeyIds,
selectedSDIndexInJWT: selectedSDIndexInJWT ?? this.selectedSDIndexInJWT,
limitDisclosure: limitDisclosure ?? this.limitDisclosure,
filters: filters ?? this.filters,
message: message,
);
}
Expand All @@ -34,5 +42,7 @@ class SelectiveDisclosureState extends Equatable {
selectedClaimsKeyIds,
selectedSDIndexInJWT,
message,
limitDisclosure,
filters,
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:altme/l10n/l10n.dart';
import 'package:altme/scan/cubit/scan_cubit.dart';
import 'package:altme/selective_disclosure/selective_disclosure.dart';
import 'package:altme/selective_disclosure/widget/display_selective_disclosure.dart';
import 'package:credential_manifest/credential_manifest.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:oidc4vc/oidc4vc.dart';
Expand All @@ -17,25 +18,29 @@ class SelectiveDisclosurePickPage extends StatelessWidget {
required this.credential,
required this.issuer,
required this.credentialToBePresented,
required this.presentationDefinition,
});

final Uri uri;
final CredentialModel credential;
final Issuer issuer;
final CredentialModel credentialToBePresented;
final PresentationDefinition? presentationDefinition;

static Route<dynamic> route({
required Uri uri,
required CredentialModel credential,
required Issuer issuer,
required CredentialModel credentialToBePresented,
required PresentationDefinition? presentationDefinition,
}) {
return MaterialPageRoute<void>(
builder: (context) => SelectiveDisclosurePickPage(
uri: uri,
credential: credential,
issuer: issuer,
credentialToBePresented: credentialToBePresented,
presentationDefinition: presentationDefinition,
),
settings: const RouteSettings(name: '/SelectiveDisclosurePickPage'),
);
Expand All @@ -52,24 +57,45 @@ class SelectiveDisclosurePickPage extends StatelessWidget {
credential: credential,
issuer: issuer,
credentialToBePresented: credentialToBePresented,
presentationDefinition: presentationDefinition,
),
);
}
}

class SelectiveDisclosurePickView extends StatelessWidget {
class SelectiveDisclosurePickView extends StatefulWidget {
const SelectiveDisclosurePickView({
super.key,
required this.uri,
required this.credential,
required this.issuer,
required this.credentialToBePresented,
required this.presentationDefinition,
});

final Uri uri;
final CredentialModel credential;
final Issuer issuer;
final CredentialModel credentialToBePresented;
final PresentationDefinition? presentationDefinition;

@override
State<SelectiveDisclosurePickView> createState() =>
_SelectiveDisclosurePickViewState();
}

class _SelectiveDisclosurePickViewState
extends State<SelectiveDisclosurePickView> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
context.read<SelectiveDisclosureCubit>().dataFromPresentation(
credentialModel: widget.credentialToBePresented,
presentationDefinition: widget.presentationDefinition,
);
});
}

@override
Widget build(BuildContext context) {
Expand All @@ -95,7 +121,7 @@ class SelectiveDisclosurePickView extends StatelessWidget {
context.read<ProfileCubit>().state.model.profileSetting;

final credentialImage =
SelectiveDisclosure(credentialToBePresented).getPicture;
SelectiveDisclosure(widget.credentialToBePresented).getPicture;

return BasePage(
title: l10n.thisOrganisationRequestsThisInformation,
Expand All @@ -111,22 +137,22 @@ class SelectiveDisclosurePickView extends StatelessWidget {
PictureDisplay(credentialImage: credentialImage)
else
CredentialDisplay(
credentialModel: credentialToBePresented,
credentialModel: widget.credentialToBePresented,
credDisplayType: CredDisplayType.List,
profileSetting: profileSetting,
isDiscover: false,
),
const SizedBox(height: 20),
DisplaySelectiveDisclosure(
credentialModel: credentialToBePresented,
credentialModel: widget.credentialToBePresented,
claims: null,
selectedClaimsKeyIds: state.selectedClaimsKeyIds,
selectiveDisclosureState: state,
onPressed: (claimKey, claimKeyId, threeDotValue) {
context.read<SelectiveDisclosureCubit>().toggle(claimKeyId);
context.read<SelectiveDisclosureCubit>().saveIndexOfSDJWT(
context.read<SelectiveDisclosureCubit>().disclosureAction(
claimsKey: claimKey,
credentialModel: credentialToBePresented,
credentialModel: widget.credentialToBePresented,
threeDotValue: threeDotValue,
claimKeyId: claimKeyId,
);
},
showVertically: true,
Expand All @@ -142,7 +168,7 @@ class SelectiveDisclosurePickView extends StatelessWidget {
onPressed: () => present(
context: context,
selectedSDIndexInJWT: state.selectedSDIndexInJWT,
uri: uri,
uri: widget.uri,
),
text: l10n.credentialPickPresent,
),
Expand Down Expand Up @@ -184,7 +210,7 @@ class SelectiveDisclosurePickView extends StatelessWidget {
}
}

final encryptedValues = credentialToBePresented.jwt
final encryptedValues = widget.credentialToBePresented.jwt
?.split('~')
.where((element) => element.isNotEmpty)
.toList();
Expand Down Expand Up @@ -244,17 +270,17 @@ class SelectiveDisclosurePickView extends StatelessWidget {

newJwt = '$newJwt$jwtToken';

final CredentialModel newModel =
credentialToBePresented.copyWith(selectiveDisclosureJwt: newJwt);
final CredentialModel newModel = widget.credentialToBePresented
.copyWith(selectiveDisclosureJwt: newJwt);

final credToBePresented = [newModel];

await context.read<ScanCubit>().credentialOfferOrPresent(
uri: uri,
credentialModel: credential,
credentialModel: widget.credential,
keyId: SecureStorageKeys.ssiKey,
credentialsToBePresented: credToBePresented,
issuer: issuer,
issuer: widget.issuer,
qrCodeScanCubit: context.read<QRCodeScanCubit>(),
);
} else {
Expand Down
4 changes: 1 addition & 3 deletions lib/selective_disclosure/selective_disclosure.dart
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,7 @@ class SelectiveDisclosure {
}
}

List<ClaimsData> getClaimsData({
required String key,
}) {
List<ClaimsData> getClaimsData({required String key}) {
dynamic data;
final value = <ClaimsData>[];
final JsonPath dataPath = JsonPath(
Expand Down
Loading

0 comments on commit 471eea4

Please sign in to comment.