Skip to content

Commit

Permalink
refactor token folder for new backdound
Browse files Browse the repository at this point in the history
  • Loading branch information
frankmer committed Oct 8, 2024
1 parent 38841f4 commit 6282e22
Show file tree
Hide file tree
Showing 13 changed files with 347 additions and 213 deletions.
1 change: 1 addition & 0 deletions lib/api/token_container_api_endpoint.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:cryptography/cryptography.dart';
import 'package:http/http.dart';
import 'package:privacyidea_authenticator/model/extensions/token_folder_extension.dart';
import 'package:privacyidea_authenticator/processors/scheme_processors/token_import_scheme_processors/otp_auth_processor.dart';
import 'package:privacyidea_authenticator/utils/ecc_utils.dart';
import 'package:privacyidea_authenticator/utils/privacyidea_io_client.dart';
Expand Down
69 changes: 69 additions & 0 deletions lib/model/extensions/token_folder_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* privacyIDEA Authenticator
*
* Author: Frank Merkel <[email protected]>
*
* Copyright (c) 2024 NetKnights GmbH
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import '../../utils/logger.dart';
import '../enums/token_origin_source_type.dart';
import '../token_folder.dart';
import '../token_template.dart';
import '../tokens/token.dart';

extension TokenListExtension on List<Token> {
List<Token> get piTokens {
final piTokens = where((token) => token.isPrivacyIdeaToken == true).toList();
Logger.debug('${piTokens.length}/$length tokens with "isPrivacyIdeaToken == true"');
return piTokens;
}

List<Token> get nonPiTokens {
final nonPiTokens = where((token) => token.isPrivacyIdeaToken == false).toList();
Logger.debug('${nonPiTokens.length}/$length tokens with "isPrivacyIdeaToken == false"');
return nonPiTokens;
}

List<Token> get maybePiTokens {
final maybePiTokens = where((token) => token.isPrivacyIdeaToken == null).toList();
Logger.debug('${maybePiTokens.length}/$length tokens with "isPrivacyIdeaToken == null"');
return maybePiTokens;
}

List<Token> inFolder([TokenFolder? folder]) {
if (folder == null) return where((token) => token.folderId != null).toList();
return where((token) => token.folderId == folder.folderId).toList();
}

List<Token> inNoFolder() => where((token) => token.folderId == null).toList();

List<Token> ofContainer(String containerSerial) {
final filtered = where((token) => token.origin?.source == TokenOriginSourceType.container && token.containerSerial == containerSerial).toList();
Logger.debug('${filtered.length}/$length tokens with containerSerial: $containerSerial');
return filtered;
}

List<Token> whereNotType(List<Type> types) => where((token) => !types.contains(token.runtimeType)).toList();

List<TokenTemplate> toTemplates() {
if (isEmpty) return [];
final templates = <TokenTemplate>[];
for (var token in this) {
final template = token.toTemplate();
if (template != null) templates.add(template);
}
return templates;
}
}
60 changes: 4 additions & 56 deletions lib/model/riverpod_states/token_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@
*/
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:privacyidea_authenticator/model/extensions/token_folder_extension.dart';

import '../../utils/logger.dart';
import '../enums/push_token_rollout_state.dart';
import '../enums/token_origin_source_type.dart';
import '../token_template.dart';
import '../token_folder.dart';
import '../tokens/otp_token.dart';
import '../tokens/push_token.dart';
Expand Down Expand Up @@ -172,66 +171,15 @@ class TokenState {
return (TokenState(tokens: newTokens, lastlyUpdatedTokens: updatedTokens), failedToReplace);
}

List<Token> tokensInFolder(TokenFolder folder, {List<Type> only = const [], List<Type> exclude = const []}) =>
tokens.inFolder(folder, only: only, exclude: exclude);
List<Token> tokensInFolder([TokenFolder? folder]) => tokens.inFolder(folder);

List<Token> tokensWithoutFolder({List<Type> only = const [], List<Type> exclude = const []}) => tokens.withoutFolder(only: only, exclude: exclude);
List<Token> tokensInNoFolder() => tokens.inNoFolder();

List<Token> containerTokens(String containerSerial) {
final piTokens = tokens.piTokens;
Logger.debug('PiTokens: ${piTokens}');
Logger.debug('PiTokens: $piTokens');
final containerTokens = piTokens.ofContainer(containerSerial);
Logger.debug('${containerTokens.length}/${piTokens.length} tokens with containerSerial: $containerSerial');
return containerTokens;
}
}

extension TokenListExtension on List<Token> {
List<Token> get piTokens {
final piTokens = where((token) => token.isPrivacyIdeaToken == true).toList();
Logger.debug('${piTokens.length}/$length tokens with "isPrivacyIdeaToken == true"');
return piTokens;
}

List<Token> get nonPiTokens {
final nonPiTokens = where((token) => token.isPrivacyIdeaToken == false).toList();
Logger.debug('${nonPiTokens.length}/$length tokens with "isPrivacyIdeaToken == false"');
return nonPiTokens;
}

List<Token> get maybePiTokens {
final maybePiTokens = where((token) => token.isPrivacyIdeaToken == null).toList();
Logger.debug('${maybePiTokens.length}/$length tokens with "isPrivacyIdeaToken == null"');
return maybePiTokens;
}

List<Token> inFolder(TokenFolder folder, {List<Type> only = const [], List<Type> exclude = const []}) => where((token) {
if (token.folderId != folder.folderId) return false;
if (exclude.contains(token.runtimeType)) return false;
if (only.isNotEmpty && !only.contains(token.runtimeType)) return false;
return true;
}).toList();

List<Token> withoutFolder({List<Type> only = const [], List<Type> exclude = const []}) => where((token) {
if (token.folderId != null) return false;
if (exclude.contains(token.runtimeType)) return false;
if (only.isNotEmpty && !only.contains(token.runtimeType)) return false;
return true;
}).toList();

List<Token> ofContainer(String containerSerial) {
final filtered = where((token) => token.origin?.source == TokenOriginSourceType.container && token.containerSerial == containerSerial).toList();
Logger.debug('${filtered.length}/$length tokens with containerSerial: $containerSerial');
return filtered;
}

List<TokenTemplate> toTemplates() {
if (isEmpty) return [];
final templates = <TokenTemplate>[];
for (var token in this) {
final template = token.toTemplate();
if (template != null) templates.add(template);
}
return templates;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import '../../../logger.dart';
part 'settings_notifier.g.dart';

final settingsProvider = settingsNotifierProviderOf(repo: PreferenceSettingsRepository());
final hidePushTokensProvider = settingsProvider.select<bool>((asyncValue) => asyncValue.value?.hidePushTokens ?? false);

@Riverpod(keepAlive: true)
class SettingsNotifier extends _$SettingsNotifier {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
*/

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_slidable/flutter_slidable.dart';

import '../../../../l10n/app_localizations.dart';
import '../../../../model/token_container.dart';
import '../../../../utils/customization/theme_extentions/action_theme.dart';
import '../../../../utils/riverpod/riverpod_providers/generated_providers/token_container_notifier.dart';
import '../../../../widgets/dialog_widgets/default_dialog.dart';
import '../../../main_view/main_view_widgets/token_widgets/slideable_action.dart';
import '../../../view_interface.dart';

Expand Down Expand Up @@ -55,3 +57,30 @@ class DeleteContainerAction extends ConsumerSlideableAction {
);
void _showDeleteDialog(BuildContext context, WidgetRef ref) {}
}

class DeleteContainerDialog extends ConsumerWidget {
final TokenContainer container;

const DeleteContainerDialog(this.container);

@override
Widget build(BuildContext context, WidgetRef ref) {
return DefaultDialog(
title: Text('AppLocalizations.of(context)!.deleteContainerDialogTitle'),
content: Text('AppLocalizations.of(context)!.deleteContainerDialogContent'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(AppLocalizations.of(context)!.cancel),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
ref.read(tokenContainerProvider.notifier).deleteContainer(container);
},
child: Text(AppLocalizations.of(context)!.delete),
),
],
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:privacyidea_authenticator/widgets/dialog_widgets/default_dialog.dart';

import '../../../../l10n/app_localizations.dart';
import '../../../../model/token_container.dart';
Expand All @@ -35,6 +36,10 @@ class EditContainerAction extends ConsumerSlideableAction {
super.key,
});

void _showEditContainerDialog(BuildContext context) {
showDialog(useRootNavigator: false, context: context, builder: (_) => EditContainerDialog(context));
}

@override
CustomSlidableAction build(BuildContext context, WidgetRef ref) => CustomSlidableAction(
onPressed: (BuildContext context) {},
Expand All @@ -53,3 +58,32 @@ class EditContainerAction extends ConsumerSlideableAction {
),
);
}

class EditContainerDialog extends StatelessWidget {
final BuildContext context;

const EditContainerDialog(this.context);

@override
Widget build(BuildContext context) {
return DefaultDialog(
title: Text('AppLocalizations.of(context)!.editContainer'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Edit Container'),
],
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(AppLocalizations.of(context)!.cancel),
),
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(AppLocalizations.of(context)!.save),
),
],
);
}
}
36 changes: 27 additions & 9 deletions lib/views/main_view/main_view_widgets/drag_target_divider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,10 @@ class _DragTargetDividerState<T extends SortableMixin> extends ConsumerState<Dra
final dividerHeight = expansionController.value * widget.dividerExpandedHeight + (1 - expansionController.value) * widget.dividerBaseHeight;
return Opacity(
opacity: widget.opacity,
child: Padding(
child: DefaultDivider(
dividerHeight: dividerHeight,
padding: EdgeInsets.only(bottom: widget.isLastDivider ? max(widget.bottomPaddingIfLast - dividerHeight + widget.dividerBaseHeight, 0) : 0),
child: Container(
height: dividerHeight,
decoration: BoxDecoration(
color: Theme.of(context).dividerColor,
borderRadius: BorderRadius.circular(dividerHeight / 4),
),
margin: EdgeInsets.only(left: 8 - expansionController.value * 2, right: 8 - expansionController.value * 2, top: 8, bottom: 8),
),
margin: EdgeInsets.symmetric(horizontal: 8 - expansionController.value * 2, vertical: 8),
),
);
},
Expand All @@ -124,3 +118,27 @@ bool _onWillAccept(SortableMixin? data, WidgetRef ref) {
if (ref.read(dragItemScrollerStateProvider)) return false;
return true;
}

class DefaultDivider extends StatelessWidget {
final double dividerHeight;
final EdgeInsets? padding;
final EdgeInsets? margin;

const DefaultDivider({
this.padding,
this.margin,
this.dividerHeight = 1.5,
super.key,
});

@override
Widget build(BuildContext context) => Container(
height: dividerHeight,
decoration: BoxDecoration(
color: Theme.of(context).dividerColor,
borderRadius: BorderRadius.circular(dividerHeight / 4),
),
padding: padding,
margin: margin,
);
}
Loading

0 comments on commit 6282e22

Please sign in to comment.