Skip to content

Commit

Permalink
recognize privacyidea token
Browse files Browse the repository at this point in the history
  • Loading branch information
frankmer committed Jun 4, 2024
1 parent 12a25a0 commit ce96194
Show file tree
Hide file tree
Showing 7 changed files with 289 additions and 480 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'dart:ui';

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

Expand All @@ -10,8 +8,8 @@ import '../../../../../../utils/customization/action_theme.dart';
import '../../../../../../utils/globals.dart';
import '../../../../../../utils/lock_auth.dart';
import '../../../../../../utils/riverpod_providers.dart';
import '../../../../../../widgets/dialog_widgets/default_dialog.dart';
import '../../../../../../widgets/focused_item_as_overlay.dart';
import '../../default_token_actions/default_edit_action_dialog.dart';
import '../../token_action.dart';

class EditDayPassowrdTokenAction extends TokenAction {
Expand Down Expand Up @@ -52,103 +50,23 @@ class EditDayPassowrdTokenAction extends TokenAction {
),
));

void _showDialog() {
final tokenLabel = TextEditingController(text: token.label);
final imageUrl = TextEditingController(text: token.tokenImage);
final period = token.period;
final algorithm = token.algorithm;

showDialog(
useRootNavigator: false,
context: globalNavigatorKey.currentContext!,
builder: (BuildContext context) => BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
child: DefaultDialog(
scrollable: true,
title: Text(
AppLocalizations.of(context)!.editToken,
overflow: TextOverflow.fade,
softWrap: false,
),
actions: [
TextButton(
child: Text(
AppLocalizations.of(context)!.cancel,
overflow: TextOverflow.fade,
softWrap: false,
),
onPressed: () {
Navigator.of(context).pop();
},
void _showDialog() => showDialog(
useRootNavigator: false,
context: globalNavigatorKey.currentContext!,
builder: (BuildContext context) => DefaultEditActionDialog(
token: token,
additionalChildren: [
TextFormField(
initialValue: token.algorithm.name,
decoration: InputDecoration(labelText: AppLocalizations.of(context)!.algorithm),
enabled: false,
),
TextButton(
child: Text(
AppLocalizations.of(context)!.save,
overflow: TextOverflow.fade,
softWrap: false,
),
onPressed: () async {
globalRef
?.read(tokenProvider.notifier)
.updateToken(token, (p0) => p0.copyWith(label: tokenLabel.text, tokenImage: imageUrl.text, period: period, algorithm: algorithm));
Navigator.of(context).pop();
}),
],
content: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: tokenLabel,
decoration: InputDecoration(labelText: AppLocalizations.of(context)!.name),
validator: (value) {
if (value!.isEmpty) {
return AppLocalizations.of(context)!.name;
}
return null;
},
),
TextFormField(
controller: imageUrl,
decoration: InputDecoration(labelText: AppLocalizations.of(context)!.imageUrl),
validator: (value) {
if (value!.isEmpty) {
return AppLocalizations.of(context)!.imageUrl;
}
return null;
},
),
TextFormField(
initialValue: algorithm.name,
decoration: InputDecoration(labelText: AppLocalizations.of(context)!.algorithm),
enabled: false,
),
TextFormField(
initialValue: period.toString().split('.').first,
decoration: InputDecoration(labelText: AppLocalizations.of(context)!.period),
enabled: false,
),
if (token.origin != null)
TextFormField(
initialValue: token.origin!.appName,
decoration: const InputDecoration(labelText: 'Origin'),
enabled: false,
),
TextFormField(
initialValue: token.isPrivacyIdeaToken == false ? 'Yes' : 'No',
decoration: const InputDecoration(labelText: 'Is exportable?'),
enabled: false,
),
],
),
TextFormField(
initialValue: token.period.toString().split('.').first,
decoration: InputDecoration(labelText: AppLocalizations.of(context)!.period),
enabled: false,
),
),
],
),
),
);
}
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:privacyidea_authenticator/views/main_view/main_view_widgets/token_widgets/default_token_actions/default_edit_action_dialog.dart';

import '../../../../../l10n/app_localizations.dart';
import '../../../../../model/enums/introduction.dart';
Expand All @@ -10,7 +11,6 @@ import '../../../../../utils/globals.dart';
import '../../../../../utils/lock_auth.dart';
import '../../../../../utils/logger.dart';
import '../../../../../utils/riverpod_providers.dart';
import '../../../../../widgets/dialog_widgets/default_dialog.dart';
import '../../../../../widgets/focused_item_as_overlay.dart';
import '../token_action.dart';

Expand All @@ -30,7 +30,7 @@ class DefaultEditAction extends TokenAction {
_showDialog();
},
child: FocusedItemAsOverlay(
tooltipWhenFocused: AppLocalizations.of(context)!.renameToken,
tooltipWhenFocused: AppLocalizations.of(context)!.editToken,
childIsMoving: true,
isFocused: ref.watch(introductionProvider).isConditionFulfilled(ref, Introduction.editToken),
onComplete: () => ref.read(introductionProvider.notifier).complete(Introduction.editToken),
Expand All @@ -40,7 +40,7 @@ class DefaultEditAction extends TokenAction {
children: [
const Icon(Icons.edit),
Text(
AppLocalizations.of(context)!.rename,
AppLocalizations.of(context)!.save,
overflow: TextOverflow.fade,
softWrap: false,
),
Expand All @@ -50,61 +50,27 @@ class DefaultEditAction extends TokenAction {
}

void _showDialog() {
TextEditingController nameInputController = TextEditingController(text: token.label);
showDialog(
useRootNavigator: false,
context: globalNavigatorKey.currentContext!,
builder: (BuildContext context) {
return DefaultDialog(
scrollable: true,
title: Text(
AppLocalizations.of(context)!.renameToken,
overflow: TextOverflow.fade,
softWrap: false,
),
content: TextFormField(
autofocus: true,
controller: nameInputController,
onChanged: (value) {},
decoration: InputDecoration(labelText: AppLocalizations.of(context)!.name),
validator: (value) {
if (value!.isEmpty) {
return AppLocalizations.of(context)!.name;
}
return null;
},
),
actions: <Widget>[
TextButton(
child: Text(
AppLocalizations.of(context)!.cancel,
overflow: TextOverflow.fade,
softWrap: false,
),
onPressed: () => Navigator.of(context).pop(),
),
TextButton(
child: Text(
AppLocalizations.of(context)!.rename,
overflow: TextOverflow.fade,
softWrap: false,
),
onPressed: () {
final newLabel = nameInputController.text.trim();
if (newLabel.isEmpty) return;
globalRef?.read(tokenProvider.notifier).updateToken(token, (p0) => p0.copyWith(label: newLabel));

Logger.info(
'Renamed token:',
name: 'token_widget_base.dart#TextButton#renameClicked',
error: '\'${token.label}\' changed to \'$newLabel\'',
);

Navigator.of(context).pop();
},
),
],
);
});
useRootNavigator: false,
context: globalNavigatorKey.currentContext!,
builder: (BuildContext context) {
return DefaultEditActionDialog(
token: token,
onSaveButtonPressed: ({required newLabel, newImageUrl}) async {
if (newLabel.isEmpty) return;
final edited = await globalRef?.read(tokenProvider.notifier).updateToken(token, (p0) => p0.copyWith(label: newLabel, tokenImage: newImageUrl));
if (edited == null) {
Logger.error('Token editing failed', name: 'DefaultEditAction#_showDialog');
return;
}
Logger.info(
'Token edited: ${token.label} -> ${edited.label}, ${token.tokenImage} -> ${edited.tokenImage}',
name: 'DefaultEditAction#_showDialog',
);
if (context.mounted) Navigator.of(context).pop();
},
);
},
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:privacyidea_authenticator/l10n/app_localizations.dart';

import '../../../../../model/tokens/token.dart';
import '../../../../../utils/logger.dart';
import '../../../../../utils/riverpod_providers.dart';
import '../../../../../widgets/dialog_widgets/default_dialog.dart';

class DefaultEditActionDialog extends ConsumerStatefulWidget {
final Token token;
final List<Widget>? additionalChildren;
final FutureOr<void> Function({required String newLabel, required String? newImageUrl})? onSaveButtonPressed;
const DefaultEditActionDialog({
required this.token,
this.onSaveButtonPressed,
this.additionalChildren,
super.key,
});

@override
ConsumerState<DefaultEditActionDialog> createState() => _DefaultEditActionDialogState();
}

class _DefaultEditActionDialogState extends ConsumerState<DefaultEditActionDialog> {
late TextEditingController nameInputController = TextEditingController(text: widget.token.label);
late TextEditingController imageUrlController = TextEditingController(text: widget.token.tokenImage);
@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context)!;
return DefaultDialog(
scrollable: true,
title: Text(
appLocalizations.renameToken,
overflow: TextOverflow.fade,
softWrap: false,
),
content: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: nameInputController,
onChanged: (value) {},
decoration: InputDecoration(labelText: appLocalizations.name),
validator: (value) {
if (value!.isEmpty) {
return appLocalizations.name;
}
return null;
},
),
TextFormField(
controller: imageUrlController,
decoration: InputDecoration(labelText: appLocalizations.imageUrl),
validator: (value) {
try {
Uri.parse(value!);
} catch (e) {
return 'appLocalizations.invalidUrl';
}
return null;
},
),
if (widget.additionalChildren != null) ...widget.additionalChildren!,
TextFormField(
initialValue: widget.token.origin?.appName ?? 'appLocalizations.unknown',
decoration: const InputDecoration(labelText: 'Origin'),
readOnly: true,
style: Theme.of(context).textTheme.titleMedium?.copyWith(color: Theme.of(context).disabledColor)),
TextFormField(
initialValue: widget.token.isPrivacyIdeaToken == false ? 'Yes' : 'No',
decoration: const InputDecoration(labelText: 'Is exportable?'),
readOnly: true,
style: Theme.of(context).textTheme.titleMedium?.copyWith(color: Theme.of(context).disabledColor),
),
],
),
),
),
actions: <Widget>[
TextButton(
child: Text(
appLocalizations.cancel,
overflow: TextOverflow.fade,
softWrap: false,
),
onPressed: () => Navigator.of(context).pop(),
),
TextButton(
onPressed: widget.onSaveButtonPressed != null
? () {
widget.onSaveButtonPressed!(
newLabel: nameInputController.text,
newImageUrl: imageUrlController.text,
);
}
: () async {
final newLabel = nameInputController.text;
final newImageUrl = imageUrlController.text;
if (newLabel.isEmpty) return;
final edited =
await globalRef?.read(tokenProvider.notifier).updateToken(widget.token, (p0) => p0.copyWith(label: newLabel, tokenImage: newImageUrl));
if (edited == null) {
Logger.error('Token editing failed', name: 'DefaultEditAction#_showDialog');
return;
}
Logger.info(
'Token edited: ${widget.token.label} -> ${edited.label}, ${widget.token.tokenImage} -> ${edited.tokenImage}',
name: 'DefaultEditAction#_showDialog',
);
if (context.mounted) Navigator.of(context).pop();
},
child: Text(
appLocalizations.save,
overflow: TextOverflow.fade,
softWrap: false,
),
),
],
);
}
}
Loading

0 comments on commit ce96194

Please sign in to comment.