feat: Restructure providers and repositories (WIP, not compiling)

This commit is contained in:
Anton Stubenbord
2023-04-30 20:49:36 +02:00
parent 4e87a196f9
commit 88085b5662
14 changed files with 776 additions and 269 deletions

View File

@@ -3,13 +3,12 @@ import 'dart:typed_data';
import 'package:equatable/equatable.dart';
import 'package:flutter/widgets.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hive_flutter/adapters.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
import 'package:paperless_mobile/core/repository/label_repository.dart';
import 'package:paperless_mobile/core/repository/saved_view_repository.dart';
import 'package:paperless_mobile/core/security/session_manager.dart';
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
@@ -19,29 +18,22 @@ import 'package:paperless_mobile/features/login/services/authentication_service.
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
import 'package:paperless_mobile/core/database/tables/local_user_settings.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
part 'authentication_state.dart';
part 'authentication_cubit.freezed.dart';
class AuthenticationCubit extends Cubit<AuthenticationState> {
final PaperlessUserApi _userApi;
final LocalAuthenticationService _localAuthService;
final PaperlessAuthenticationApi _authApi;
final SessionManager _sessionManager;
final LabelRepository _labelRepository;
final SavedViewRepository _savedViewRepository;
final PaperlessServerStatsApi _serverStatsApi;
final PaperlessUserApi _userApi;
final PaperlessUserApiV3? _userApiV3;
AuthenticationCubit(
this._localAuthService,
this._authApi,
this._sessionManager,
this._labelRepository,
this._savedViewRepository,
this._serverStatsApi,
this._userApi, {
PaperlessUserApiV3? userApiV3,
}) : _userApiV3 = userApiV3,
super(const AuthenticationState());
this._userApi,
) : super(const AuthenticationState.unauthenticated());
Future<void> login({
required LoginFormCredentials credentials,
@@ -66,14 +58,10 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
globalSettings.currentLoggedInUser = localUserId;
await globalSettings.save();
emit(
AuthenticationState(
isAuthenticated: true,
username: credentials.username,
localUserId: localUserId,
fullName: serverUser.fullName,
AuthenticationState.authenticated(
apiVersion: apiVersion,
localUserId: localUserId,
),
);
}
@@ -116,26 +104,18 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
_sessionManager.updateSettings(
authToken: credentials!.token,
clientCertificate: credentials.clientCertificate,
serverInformation: PaperlessServerInformationModel(),
baseUrl: account.serverUrl,
);
await _reloadRepositories();
globalSettings.currentLoggedInUser = localUserId;
await globalSettings.save();
final response = await _sessionManager.client.get("/api/");
final apiVersion = response.headers["x-api-version"] as int;
emit(
AuthenticationState(
isAuthenticated: true,
username: account.paperlessUser.username,
fullName: account.paperlessUser.fullName,
localUserId: localUserId,
apiVersion: apiVersion,
),
);
emit(AuthenticationState.authenticated(
localUserId: localUserId,
apiVersion: apiVersion,
));
}
Future<String> addAccount({
@@ -179,19 +159,19 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
///
Future<void> restoreSessionState() async {
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
final userId = globalSettings.currentLoggedInUser;
if (userId == null) {
final localUserId = globalSettings.currentLoggedInUser;
if (localUserId == null) {
// If there is nothing to restore, we can quit here.
return;
}
final userAccount = Hive.box<LocalUserAccount>(HiveBoxes.localUserAccount).get(userId)!;
final userAccount = Hive.box<LocalUserAccount>(HiveBoxes.localUserAccount).get(localUserId)!;
if (userAccount.settings.isBiometricAuthenticationEnabled) {
final localAuthSuccess =
await _localAuthService.authenticateLocalUser("Authenticate to log back in"); //TODO: INTL
if (!localAuthSuccess) {
emit(const AuthenticationState(showBiometricAuthenticationScreen: true));
emit(const AuthenticationState.requriresLocalAuthentication());
return;
}
}
@@ -207,18 +187,13 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
clientCertificate: authentication.clientCertificate,
authToken: authentication.token,
baseUrl: userAccount.serverUrl,
serverInformation: PaperlessServerInformationModel(),
);
final response = await _sessionManager.client.get("/api/");
final apiVersion = response.headers["x-api-version"] as int;
emit(
AuthenticationState(
isAuthenticated: true,
showBiometricAuthenticationScreen: false,
username: userAccount.paperlessUser.username,
AuthenticationState.authenticated(
apiVersion: apiVersion,
fullName: userAccount.paperlessUser.fullName,
localUserId: localUserId,
),
);
}
@@ -229,7 +204,7 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
globalSettings
..currentLoggedInUser = null
..save();
emit(const AuthenticationState());
emit(const AuthenticationState.unauthenticated());
}
Future<Uint8List> _getEncryptedBoxKey() async {
@@ -254,23 +229,12 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
);
}
Future<void> _resetExternalState() {
Future<void> _resetExternalState() async {
_sessionManager.resetSettings();
return Future.wait([
HydratedBloc.storage.clear(),
_labelRepository.clear(),
_savedViewRepository.clear(),
]);
await HydratedBloc.storage.clear();
}
Future<void> _reloadRepositories() {
return Future.wait([
_labelRepository.initialize(),
_savedViewRepository.findAll(),
]);
}
Future<UserModel> _addUser(
Future<int> _addUser(
String localUserId,
String serverUrl,
LoginFormCredentials credentials,
@@ -303,7 +267,6 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
}
final serverUserId = await _userApi.findCurrentUserId();
final serverUser = await _userApi.find(serverUserId);
// Create user account
await userAccountBox.put(
@@ -312,7 +275,7 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
id: localUserId,
settings: LocalUserSettings(),
serverUrl: serverUrl,
paperlessUser: serverUser,
paperlessUserId: 1,
),
);
@@ -332,6 +295,6 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
),
);
userCredentialsBox.close();
return serverUser;
return serverUserId;
}
}

View File

@@ -0,0 +1,465 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'authentication_cubit.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
/// @nodoc
mixin _$AuthenticationState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() unauthenticated,
required TResult Function() requriresLocalAuthentication,
required TResult Function(String localUserId, int apiVersion) authenticated,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? unauthenticated,
TResult? Function()? requriresLocalAuthentication,
TResult? Function(String localUserId, int apiVersion)? authenticated,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? unauthenticated,
TResult Function()? requriresLocalAuthentication,
TResult Function(String localUserId, int apiVersion)? authenticated,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Unauthenticated value) unauthenticated,
required TResult Function(_RequiresLocalAuthentication value)
requriresLocalAuthentication,
required TResult Function(_Authenticated value) authenticated,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Unauthenticated value)? unauthenticated,
TResult? Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication,
TResult? Function(_Authenticated value)? authenticated,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Unauthenticated value)? unauthenticated,
TResult Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication,
TResult Function(_Authenticated value)? authenticated,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $AuthenticationStateCopyWith<$Res> {
factory $AuthenticationStateCopyWith(
AuthenticationState value, $Res Function(AuthenticationState) then) =
_$AuthenticationStateCopyWithImpl<$Res, AuthenticationState>;
}
/// @nodoc
class _$AuthenticationStateCopyWithImpl<$Res, $Val extends AuthenticationState>
implements $AuthenticationStateCopyWith<$Res> {
_$AuthenticationStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
}
/// @nodoc
abstract class _$$_UnauthenticatedCopyWith<$Res> {
factory _$$_UnauthenticatedCopyWith(
_$_Unauthenticated value, $Res Function(_$_Unauthenticated) then) =
__$$_UnauthenticatedCopyWithImpl<$Res>;
}
/// @nodoc
class __$$_UnauthenticatedCopyWithImpl<$Res>
extends _$AuthenticationStateCopyWithImpl<$Res, _$_Unauthenticated>
implements _$$_UnauthenticatedCopyWith<$Res> {
__$$_UnauthenticatedCopyWithImpl(
_$_Unauthenticated _value, $Res Function(_$_Unauthenticated) _then)
: super(_value, _then);
}
/// @nodoc
class _$_Unauthenticated implements _Unauthenticated {
const _$_Unauthenticated();
@override
String toString() {
return 'AuthenticationState.unauthenticated()';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$_Unauthenticated);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() unauthenticated,
required TResult Function() requriresLocalAuthentication,
required TResult Function(String localUserId, int apiVersion) authenticated,
}) {
return unauthenticated();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? unauthenticated,
TResult? Function()? requriresLocalAuthentication,
TResult? Function(String localUserId, int apiVersion)? authenticated,
}) {
return unauthenticated?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? unauthenticated,
TResult Function()? requriresLocalAuthentication,
TResult Function(String localUserId, int apiVersion)? authenticated,
required TResult orElse(),
}) {
if (unauthenticated != null) {
return unauthenticated();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Unauthenticated value) unauthenticated,
required TResult Function(_RequiresLocalAuthentication value)
requriresLocalAuthentication,
required TResult Function(_Authenticated value) authenticated,
}) {
return unauthenticated(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Unauthenticated value)? unauthenticated,
TResult? Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication,
TResult? Function(_Authenticated value)? authenticated,
}) {
return unauthenticated?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Unauthenticated value)? unauthenticated,
TResult Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication,
TResult Function(_Authenticated value)? authenticated,
required TResult orElse(),
}) {
if (unauthenticated != null) {
return unauthenticated(this);
}
return orElse();
}
}
abstract class _Unauthenticated implements AuthenticationState {
const factory _Unauthenticated() = _$_Unauthenticated;
}
/// @nodoc
abstract class _$$_RequiresLocalAuthenticationCopyWith<$Res> {
factory _$$_RequiresLocalAuthenticationCopyWith(
_$_RequiresLocalAuthentication value,
$Res Function(_$_RequiresLocalAuthentication) then) =
__$$_RequiresLocalAuthenticationCopyWithImpl<$Res>;
}
/// @nodoc
class __$$_RequiresLocalAuthenticationCopyWithImpl<$Res>
extends _$AuthenticationStateCopyWithImpl<$Res,
_$_RequiresLocalAuthentication>
implements _$$_RequiresLocalAuthenticationCopyWith<$Res> {
__$$_RequiresLocalAuthenticationCopyWithImpl(
_$_RequiresLocalAuthentication _value,
$Res Function(_$_RequiresLocalAuthentication) _then)
: super(_value, _then);
}
/// @nodoc
class _$_RequiresLocalAuthentication implements _RequiresLocalAuthentication {
const _$_RequiresLocalAuthentication();
@override
String toString() {
return 'AuthenticationState.requriresLocalAuthentication()';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$_RequiresLocalAuthentication);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() unauthenticated,
required TResult Function() requriresLocalAuthentication,
required TResult Function(String localUserId, int apiVersion) authenticated,
}) {
return requriresLocalAuthentication();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? unauthenticated,
TResult? Function()? requriresLocalAuthentication,
TResult? Function(String localUserId, int apiVersion)? authenticated,
}) {
return requriresLocalAuthentication?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? unauthenticated,
TResult Function()? requriresLocalAuthentication,
TResult Function(String localUserId, int apiVersion)? authenticated,
required TResult orElse(),
}) {
if (requriresLocalAuthentication != null) {
return requriresLocalAuthentication();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Unauthenticated value) unauthenticated,
required TResult Function(_RequiresLocalAuthentication value)
requriresLocalAuthentication,
required TResult Function(_Authenticated value) authenticated,
}) {
return requriresLocalAuthentication(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Unauthenticated value)? unauthenticated,
TResult? Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication,
TResult? Function(_Authenticated value)? authenticated,
}) {
return requriresLocalAuthentication?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Unauthenticated value)? unauthenticated,
TResult Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication,
TResult Function(_Authenticated value)? authenticated,
required TResult orElse(),
}) {
if (requriresLocalAuthentication != null) {
return requriresLocalAuthentication(this);
}
return orElse();
}
}
abstract class _RequiresLocalAuthentication implements AuthenticationState {
const factory _RequiresLocalAuthentication() = _$_RequiresLocalAuthentication;
}
/// @nodoc
abstract class _$$_AuthenticatedCopyWith<$Res> {
factory _$$_AuthenticatedCopyWith(
_$_Authenticated value, $Res Function(_$_Authenticated) then) =
__$$_AuthenticatedCopyWithImpl<$Res>;
@useResult
$Res call({String localUserId, int apiVersion});
}
/// @nodoc
class __$$_AuthenticatedCopyWithImpl<$Res>
extends _$AuthenticationStateCopyWithImpl<$Res, _$_Authenticated>
implements _$$_AuthenticatedCopyWith<$Res> {
__$$_AuthenticatedCopyWithImpl(
_$_Authenticated _value, $Res Function(_$_Authenticated) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? localUserId = null,
Object? apiVersion = null,
}) {
return _then(_$_Authenticated(
localUserId: null == localUserId
? _value.localUserId
: localUserId // ignore: cast_nullable_to_non_nullable
as String,
apiVersion: null == apiVersion
? _value.apiVersion
: apiVersion // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
/// @nodoc
class _$_Authenticated implements _Authenticated {
const _$_Authenticated({required this.localUserId, required this.apiVersion});
@override
final String localUserId;
@override
final int apiVersion;
@override
String toString() {
return 'AuthenticationState.authenticated(localUserId: $localUserId, apiVersion: $apiVersion)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$_Authenticated &&
(identical(other.localUserId, localUserId) ||
other.localUserId == localUserId) &&
(identical(other.apiVersion, apiVersion) ||
other.apiVersion == apiVersion));
}
@override
int get hashCode => Object.hash(runtimeType, localUserId, apiVersion);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$_AuthenticatedCopyWith<_$_Authenticated> get copyWith =>
__$$_AuthenticatedCopyWithImpl<_$_Authenticated>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() unauthenticated,
required TResult Function() requriresLocalAuthentication,
required TResult Function(String localUserId, int apiVersion) authenticated,
}) {
return authenticated(localUserId, apiVersion);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? unauthenticated,
TResult? Function()? requriresLocalAuthentication,
TResult? Function(String localUserId, int apiVersion)? authenticated,
}) {
return authenticated?.call(localUserId, apiVersion);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? unauthenticated,
TResult Function()? requriresLocalAuthentication,
TResult Function(String localUserId, int apiVersion)? authenticated,
required TResult orElse(),
}) {
if (authenticated != null) {
return authenticated(localUserId, apiVersion);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Unauthenticated value) unauthenticated,
required TResult Function(_RequiresLocalAuthentication value)
requriresLocalAuthentication,
required TResult Function(_Authenticated value) authenticated,
}) {
return authenticated(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Unauthenticated value)? unauthenticated,
TResult? Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication,
TResult? Function(_Authenticated value)? authenticated,
}) {
return authenticated?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Unauthenticated value)? unauthenticated,
TResult Function(_RequiresLocalAuthentication value)?
requriresLocalAuthentication,
TResult Function(_Authenticated value)? authenticated,
required TResult orElse(),
}) {
if (authenticated != null) {
return authenticated(this);
}
return orElse();
}
}
abstract class _Authenticated implements AuthenticationState {
const factory _Authenticated(
{required final String localUserId,
required final int apiVersion}) = _$_Authenticated;
String get localUserId;
int get apiVersion;
@JsonKey(ignore: true)
_$$_AuthenticatedCopyWith<_$_Authenticated> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -1,48 +1,11 @@
part of 'authentication_cubit.dart';
class AuthenticationState with EquatableMixin {
final bool showBiometricAuthenticationScreen;
final bool isAuthenticated;
final String? username;
final String? fullName;
final String? localUserId;
final int? apiVersion;
const AuthenticationState({
this.isAuthenticated = false,
this.showBiometricAuthenticationScreen = false,
this.username,
this.fullName,
this.localUserId,
this.apiVersion,
});
AuthenticationState copyWith({
bool? isAuthenticated,
bool? showBiometricAuthenticationScreen,
String? username,
String? fullName,
String? localUserId,
int? apiVersion,
}) {
return AuthenticationState(
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
showBiometricAuthenticationScreen:
showBiometricAuthenticationScreen ?? this.showBiometricAuthenticationScreen,
username: username ?? this.username,
fullName: fullName ?? this.fullName,
localUserId: localUserId ?? this.localUserId,
apiVersion: apiVersion ?? this.apiVersion,
);
}
@override
List<Object?> get props => [
localUserId,
username,
fullName,
isAuthenticated,
showBiometricAuthenticationScreen,
apiVersion,
];
@freezed
class AuthenticationState with _$AuthenticationState {
const factory AuthenticationState.unauthenticated() = _Unauthenticated;
const factory AuthenticationState.requriresLocalAuthentication() = _RequiresLocalAuthentication;
const factory AuthenticationState.authenticated({
required String localUserId,
required int apiVersion,
}) = _Authenticated;
}

View File

@@ -0,0 +1,48 @@
import 'package:equatable/equatable.dart';
class OldAuthenticationState with EquatableMixin {
final bool showBiometricAuthenticationScreen;
final bool isAuthenticated;
final String? username;
final String? fullName;
final String? localUserId;
final int? apiVersion;
const OldAuthenticationState({
this.isAuthenticated = false,
this.showBiometricAuthenticationScreen = false,
this.username,
this.fullName,
this.localUserId,
this.apiVersion,
});
OldAuthenticationState copyWith({
bool? isAuthenticated,
bool? showBiometricAuthenticationScreen,
String? username,
String? fullName,
String? localUserId,
int? apiVersion,
}) {
return OldAuthenticationState(
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
showBiometricAuthenticationScreen:
showBiometricAuthenticationScreen ?? this.showBiometricAuthenticationScreen,
username: username ?? this.username,
fullName: fullName ?? this.fullName,
localUserId: localUserId ?? this.localUserId,
apiVersion: apiVersion ?? this.apiVersion,
);
}
@override
List<Object?> get props => [
localUserId,
username,
fullName,
isAuthenticated,
showBiometricAuthenticationScreen,
apiVersion,
];
}