diff --git a/lib/core/database/tables/local_user_account.dart b/lib/core/database/tables/local_user_account.dart index a8bed4e..c2228ce 100644 --- a/lib/core/database/tables/local_user_account.dart +++ b/lib/core/database/tables/local_user_account.dart @@ -1,6 +1,7 @@ import 'package:hive_flutter/adapters.dart'; import 'package:paperless_mobile/core/config/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/local_user_settings.dart'; +import 'package:paperless_api/paperless_api.dart'; part 'local_user_account.g.dart'; @@ -9,23 +10,19 @@ class LocalUserAccount extends HiveObject { @HiveField(0) final String serverUrl; - @HiveField(1) - final String username; - - @HiveField(2) - final String? fullName; - @HiveField(3) final String id; @HiveField(4) LocalUserSettings settings; + @HiveField(5) + UserModel paperlessUser; + LocalUserAccount({ required this.id, required this.serverUrl, - required this.username, required this.settings, - this.fullName, + required this.paperlessUser, }); } diff --git a/lib/features/login/cubit/authentication_cubit.dart b/lib/features/login/cubit/authentication_cubit.dart index 1ead7c1..fcd10a6 100644 --- a/lib/features/login/cubit/authentication_cubit.dart +++ b/lib/features/login/cubit/authentication_cubit.dart @@ -8,7 +8,6 @@ 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/interceptor/dio_http_error_interceptor.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'; @@ -29,6 +28,8 @@ class AuthenticationCubit extends Cubit { final LabelRepository _labelRepository; final SavedViewRepository _savedViewRepository; final PaperlessServerStatsApi _serverStatsApi; + final PaperlessUserApi _userApi; + final PaperlessUserApiV3? _userApiV3; AuthenticationCubit( this._localAuthService, @@ -37,7 +38,10 @@ class AuthenticationCubit extends Cubit { this._labelRepository, this._savedViewRepository, this._serverStatsApi, - ) : super(const AuthenticationState()); + this._userApi, { + PaperlessUserApiV3? userApiV3, + }) : _userApiV3 = userApiV3, + super(const AuthenticationState()); Future login({ required LoginFormCredentials credentials, @@ -45,89 +49,49 @@ class AuthenticationCubit extends Cubit { ClientCertificate? clientCertificate, }) async { assert(credentials.username != null && credentials.password != null); + final localUserId = "${credentials.username}@$serverUrl"; - _sessionManager.updateSettings( - baseUrl: serverUrl, - clientCertificate: clientCertificate, - ); - final token = await _authApi.login( - username: credentials.username!, - password: credentials.password!, - ); - _sessionManager.updateSettings( - baseUrl: serverUrl, - clientCertificate: clientCertificate, - authToken: token, + final serverUser = await _addUser( + localUserId, + serverUrl, + credentials, + clientCertificate, + _sessionManager, ); - final userAccountBox = Hive.box(HiveBoxes.localUserAccount); - final userStateBox = Hive.box(HiveBoxes.localUserAppState); - - final userId = "${credentials.username}@$serverUrl"; - - if (userAccountBox.containsKey(userId)) { - throw Exception("User with id $userId already exists!"); - } - - final fullName = await _fetchFullName(); - // Create user account - await userAccountBox.put( - userId, - LocalUserAccount( - id: userId, - settings: LocalUserSettings(), - serverUrl: serverUrl, - username: credentials.username!, - fullName: fullName, - ), - ); - - // Create user state - await userStateBox.put( - userId, - LocalUserAppState(userId: userId), - ); - - // Save credentials in encrypted box - final userCredentialsBox = await _getUserCredentialsBox(); - await userCredentialsBox.put( - userId, - UserCredentials( - token: token, - clientCertificate: clientCertificate, - ), - ); - userCredentialsBox.close(); + final response = await _sessionManager.client.get("/api/"); + final apiVersion = response.headers["x-api-version"] as int; // Mark logged in user as currently active user. final globalSettings = Hive.box(HiveBoxes.globalSettings).getValue()!; - globalSettings.currentLoggedInUser = userId; + globalSettings.currentLoggedInUser = localUserId; await globalSettings.save(); emit( AuthenticationState( isAuthenticated: true, username: credentials.username, - userId: userId, - fullName: fullName, + localUserId: localUserId, + fullName: serverUser.fullName, + apiVersion: apiVersion, ), ); } /// Switches to another account if it exists. - Future switchAccount(String userId) async { + Future switchAccount(String localUserId) async { final globalSettings = Hive.box(HiveBoxes.globalSettings).getValue()!; - if (globalSettings.currentLoggedInUser == userId) { + if (globalSettings.currentLoggedInUser == localUserId) { return; } final userAccountBox = Hive.box(HiveBoxes.localUserAccount); - if (!userAccountBox.containsKey(userId)) { - debugPrint("User $userId not yet registered."); + if (!userAccountBox.containsKey(localUserId)) { + debugPrint("User $localUserId not yet registered."); return; } - final account = userAccountBox.get(userId)!; + final account = userAccountBox.get(localUserId)!; if (account.settings.isBiometricAuthenticationEnabled) { final authenticated = @@ -139,12 +103,12 @@ class AuthenticationCubit extends Cubit { } final credentialsBox = await _getUserCredentialsBox(); - if (!credentialsBox.containsKey(userId)) { + if (!credentialsBox.containsKey(localUserId)) { await credentialsBox.close(); - debugPrint("Invalid authentication for $userId"); + debugPrint("Invalid authentication for $localUserId"); return; } - final credentials = credentialsBox.get(userId); + final credentials = credentialsBox.get(localUserId); await credentialsBox.close(); await _resetExternalState(); @@ -157,15 +121,19 @@ class AuthenticationCubit extends Cubit { ); await _reloadRepositories(); - globalSettings.currentLoggedInUser = userId; + 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.username, - fullName: account.fullName, - userId: userId, + username: account.paperlessUser.username, + fullName: account.paperlessUser.fullName, + localUserId: localUserId, + apiVersion: apiVersion, ), ); } @@ -177,62 +145,16 @@ class AuthenticationCubit extends Cubit { required bool enableBiometricAuthentication, }) async { assert(credentials.password != null && credentials.username != null); - final userId = "${credentials.username}@$serverUrl"; - - final userAccountsBox = Hive.box(HiveBoxes.localUserAccount); - final userStateBox = Hive.box(HiveBoxes.localUserAppState); - - if (userAccountsBox.containsKey(userId)) { - throw Exception("User already exists"); - } - // Creates a parallel session to get token and disposes of resources after. - final sessionManager = SessionManager([ - DioHttpErrorInterceptor(), - ]); - sessionManager.updateSettings( - clientCertificate: clientCertificate, - baseUrl: serverUrl, - ); - final authApi = PaperlessAuthenticationApiImpl(sessionManager.client); - - final token = await authApi.login( - username: credentials.username!, - password: credentials.password!, - ); - sessionManager.resetSettings(); - - final fullName = await _fetchFullName(); - - await userAccountsBox.put( - userId, - LocalUserAccount( - id: userId, - serverUrl: serverUrl, - username: credentials.username!, - settings: LocalUserSettings( - isBiometricAuthenticationEnabled: enableBiometricAuthentication, - ), - fullName: fullName, - ), + final localUserId = "${credentials.username}@$serverUrl"; + await _addUser( + localUserId, + serverUrl, + credentials, + clientCertificate, + _sessionManager, ); - await userStateBox.put( - userId, - LocalUserAppState( - userId: userId, - ), - ); - - final userCredentialsBox = await _getUserCredentialsBox(); - await userCredentialsBox.put( - userId, - UserCredentials( - token: token, - clientCertificate: clientCertificate, - ), - ); - await userCredentialsBox.close(); - return userId; + return localUserId; } Future removeAccount(String userId) async { @@ -287,11 +209,16 @@ class AuthenticationCubit extends Cubit { 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.username, + username: userAccount.paperlessUser.username, + apiVersion: apiVersion, + fullName: userAccount.paperlessUser.fullName, ), ); } @@ -343,12 +270,68 @@ class AuthenticationCubit extends Cubit { ]); } - Future _fetchFullName() async { - try { - final uiSettings = await _serverStatsApi.getUiSettings(); - return uiSettings.displayName; - } catch (error) { - return null; + Future _addUser( + String localUserId, + String serverUrl, + LoginFormCredentials credentials, + ClientCertificate? clientCert, + SessionManager sessionManager, + ) async { + assert(credentials.username != null && credentials.password != null); + + sessionManager.updateSettings( + baseUrl: serverUrl, + clientCertificate: clientCert, + ); + final authApi = PaperlessAuthenticationApiImpl(sessionManager.client); + + final token = await authApi.login( + username: credentials.username!, + password: credentials.password!, + ); + sessionManager.updateSettings( + baseUrl: serverUrl, + clientCertificate: clientCert, + authToken: token, + ); + + final userAccountBox = Hive.box(HiveBoxes.localUserAccount); + final userStateBox = Hive.box(HiveBoxes.localUserAppState); + + if (userAccountBox.containsKey(localUserId)) { + throw Exception("User with id $localUserId already exists!"); } + + final serverUserId = await _userApi.findCurrentUserId(); + final serverUser = await _userApi.find(serverUserId); + + // Create user account + await userAccountBox.put( + localUserId, + LocalUserAccount( + id: localUserId, + settings: LocalUserSettings(), + serverUrl: serverUrl, + paperlessUser: serverUser, + ), + ); + + // Create user state + await userStateBox.put( + localUserId, + LocalUserAppState(userId: localUserId), + ); + + // Save credentials in encrypted box + final userCredentialsBox = await _getUserCredentialsBox(); + await userCredentialsBox.put( + localUserId, + UserCredentials( + token: token, + clientCertificate: clientCert, + ), + ); + userCredentialsBox.close(); + return serverUser; } } diff --git a/lib/features/login/cubit/authentication_state.dart b/lib/features/login/cubit/authentication_state.dart index cced26f..8b76cd6 100644 --- a/lib/features/login/cubit/authentication_state.dart +++ b/lib/features/login/cubit/authentication_state.dart @@ -5,14 +5,16 @@ class AuthenticationState with EquatableMixin { final bool isAuthenticated; final String? username; final String? fullName; - final String? userId; + final String? localUserId; + final int? apiVersion; const AuthenticationState({ this.isAuthenticated = false, this.showBiometricAuthenticationScreen = false, this.username, this.fullName, - this.userId, + this.localUserId, + this.apiVersion, }); AuthenticationState copyWith({ @@ -20,7 +22,8 @@ class AuthenticationState with EquatableMixin { bool? showBiometricAuthenticationScreen, String? username, String? fullName, - String? userId, + String? localUserId, + int? apiVersion, }) { return AuthenticationState( isAuthenticated: isAuthenticated ?? this.isAuthenticated, @@ -28,16 +31,18 @@ class AuthenticationState with EquatableMixin { showBiometricAuthenticationScreen ?? this.showBiometricAuthenticationScreen, username: username ?? this.username, fullName: fullName ?? this.fullName, - userId: userId ?? this.userId, + localUserId: localUserId ?? this.localUserId, + apiVersion: apiVersion ?? this.apiVersion, ); } @override List get props => [ - userId, + localUserId, username, fullName, isAuthenticated, showBiometricAuthenticationScreen, + apiVersion, ]; } diff --git a/lib/features/settings/view/manage_accounts_page.dart b/lib/features/settings/view/manage_accounts_page.dart index 1337487..9165ed0 100644 --- a/lib/features/settings/view/manage_accounts_page.dart +++ b/lib/features/settings/view/manage_accounts_page.dart @@ -1,17 +1,13 @@ -import 'dart:ui'; - import 'package:collection/collection.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hive_flutter/adapters.dart'; import 'package:paperless_mobile/core/config/hive/hive_config.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/database/tables/global_settings.dart'; +import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart'; import 'package:paperless_mobile/features/login/model/login_form_credentials.dart'; -import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/features/login/view/login_page.dart'; -import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/features/settings/view/dialogs/switch_account_dialog.dart'; import 'package:paperless_mobile/features/settings/view/pages/switching_accounts_page.dart'; import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart'; @@ -33,18 +29,18 @@ class ManageAccountsPage extends StatelessWidget { .whereNot((element) => element == globalSettings.currentLoggedInUser) .toList(); return SimpleDialog( - insetPadding: EdgeInsets.all(24), - contentPadding: EdgeInsets.all(8), + insetPadding: const EdgeInsets.all(24), + contentPadding: const EdgeInsets.all(8), title: Stack( alignment: Alignment.center, children: [ - Align( + const Align( alignment: Alignment.centerLeft, child: CloseButton(), ), Center(child: Text(S.of(context)!.accounts)), ], - ), //TODO: INTL + ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), ), @@ -103,7 +99,7 @@ class ManageAccountsPage extends StatelessWidget { ), ], ), - isThreeLine: true, + isThreeLine: account.fullName != null, leading: UserAvatar( account: account, userId: userId, @@ -116,7 +112,7 @@ class ManageAccountsPage extends StatelessWidget { PopupMenuItem( child: ListTile( title: Text(S.of(context)!.switchAccount), - leading: Icon(Icons.switch_account_rounded), + leading: const Icon(Icons.switch_account_rounded), ), value: 0, ), @@ -124,7 +120,7 @@ class ManageAccountsPage extends StatelessWidget { PopupMenuItem( child: ListTile( title: Text(S.of(context)!.remove), - leading: Icon( + leading: const Icon( Icons.person_remove, color: Colors.red, ), @@ -135,7 +131,7 @@ class ManageAccountsPage extends StatelessWidget { PopupMenuItem( child: ListTile( title: Text(S.of(context)!.logout), - leading: Icon( + leading: const Icon( Icons.person_remove, color: Colors.red, ), diff --git a/lib/main.dart b/lib/main.dart index 78efaec..f8f9e1d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -297,7 +297,7 @@ class _AuthenticationWrapperState extends State { builder: (context, authentication) { if (authentication.isAuthenticated) { return HomeRoute( - key: ValueKey(authentication.userId), + key: ValueKey(authentication.localUserId), ); } else if (authentication.showBiometricAuthenticationScreen) { return const VerifyIdentityPage(); diff --git a/packages/paperless_api/lib/config/hive/hive_type_ids.dart b/packages/paperless_api/lib/config/hive/hive_type_ids.dart index 254ac8b..c2a3887 100644 --- a/packages/paperless_api/lib/config/hive/hive_type_ids.dart +++ b/packages/paperless_api/lib/config/hive/hive_type_ids.dart @@ -1,5 +1,6 @@ import 'package:hive/hive.dart'; import 'package:paperless_api/paperless_api.dart'; +import 'package:paperless_api/src/models/user_model.dart'; class PaperlessApiHiveTypeIds { PaperlessApiHiveTypeIds._(); @@ -24,6 +25,12 @@ class PaperlessApiHiveTypeIds { static const int anyAssignedIdQueryParameter = 118; static const int setIdQueryParameter = 119; static const int notAssignedTagsQuery = 120; + static const int userModelv3 = 121; + static const int userPermissions = 122; + static const int inheritedPermissions = 123; + static const int groupModel = 124; + static const int permissions = 125; + static const int userModelv2 = 126; } void registerPaperlessApiHiveTypeAdapters() { @@ -46,4 +53,11 @@ void registerPaperlessApiHiveTypeAdapters() { Hive.registerAdapter(UnsetIdQueryParameterAdapter()); Hive.registerAdapter(AnyAssignedIdQueryParameterAdapter()); Hive.registerAdapter(NotAssignedIdQueryParameterAdapter()); + // Users and permissions + Hive.registerAdapter(UserModelV3Adapter()); + Hive.registerAdapter(UserModelV2Adapter()); + Hive.registerAdapter(UserPermissionsAdapter()); + Hive.registerAdapter(InheritedPermissionsAdapter()); + Hive.registerAdapter(GroupModelAdapter()); + Hive.registerAdapter(PermissionsAdapter()); } diff --git a/packages/paperless_api/lib/src/models/document_model.dart b/packages/paperless_api/lib/src/models/document_model.dart index 838a93c..f53bd5b 100644 --- a/packages/paperless_api/lib/src/models/document_model.dart +++ b/packages/paperless_api/lib/src/models/document_model.dart @@ -2,6 +2,7 @@ import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_api/src/converters/local_date_time_json_converter.dart'; import 'package:paperless_api/src/models/search_hit.dart'; @@ -44,6 +45,12 @@ class DocumentModel extends Equatable { ) final SearchHit? searchHit; + final int? owner; + final bool? userCanChange; + + // Only present if full_perms=true + final Permissions? permissions; + const DocumentModel({ required this.id, required this.title, @@ -59,6 +66,9 @@ class DocumentModel extends Equatable { this.archivedFileName, this.storagePath, this.searchHit, + this.owner, + this.userCanChange, + this.permissions, }); factory DocumentModel.fromJson(Map json) => _$DocumentModelFromJson(json); diff --git a/packages/paperless_api/lib/src/models/group_model.dart b/packages/paperless_api/lib/src/models/group_model.dart new file mode 100644 index 0000000..f932e4a --- /dev/null +++ b/packages/paperless_api/lib/src/models/group_model.dart @@ -0,0 +1,18 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:hive/hive.dart'; +import 'package:paperless_api/paperless_api.dart'; + +part 'group_model.freezed.dart'; +part 'group_model.g.dart'; + +@freezed +@HiveType(typeId: PaperlessApiHiveTypeIds.groupModel) +class GroupModel with _$GroupModel { + const factory GroupModel({ + @HiveField(0) required int id, + @HiveField(1) required String name, + @HiveField(2) required List permissions, + }) = _GroupModel; + + factory GroupModel.fromJson(Map json) => _$GroupModelFromJson(json); +} diff --git a/packages/paperless_api/lib/src/models/group_model.freezed.dart b/packages/paperless_api/lib/src/models/group_model.freezed.dart new file mode 100644 index 0000000..d91b6bc --- /dev/null +++ b/packages/paperless_api/lib/src/models/group_model.freezed.dart @@ -0,0 +1,213 @@ +// 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 'group_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(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'); + +GroupModel _$GroupModelFromJson(Map json) { + return _GroupModel.fromJson(json); +} + +/// @nodoc +mixin _$GroupModel { + @HiveField(0) + int get id => throw _privateConstructorUsedError; + @HiveField(1) + String get name => throw _privateConstructorUsedError; + @HiveField(2) + List get permissions => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $GroupModelCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $GroupModelCopyWith<$Res> { + factory $GroupModelCopyWith( + GroupModel value, $Res Function(GroupModel) then) = + _$GroupModelCopyWithImpl<$Res, GroupModel>; + @useResult + $Res call( + {@HiveField(0) int id, + @HiveField(1) String name, + @HiveField(2) List permissions}); +} + +/// @nodoc +class _$GroupModelCopyWithImpl<$Res, $Val extends GroupModel> + implements $GroupModelCopyWith<$Res> { + _$GroupModelCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? name = null, + Object? permissions = null, + }) { + return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + permissions: null == permissions + ? _value.permissions + : permissions // ignore: cast_nullable_to_non_nullable + as List, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$_GroupModelCopyWith<$Res> + implements $GroupModelCopyWith<$Res> { + factory _$$_GroupModelCopyWith( + _$_GroupModel value, $Res Function(_$_GroupModel) then) = + __$$_GroupModelCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@HiveField(0) int id, + @HiveField(1) String name, + @HiveField(2) List permissions}); +} + +/// @nodoc +class __$$_GroupModelCopyWithImpl<$Res> + extends _$GroupModelCopyWithImpl<$Res, _$_GroupModel> + implements _$$_GroupModelCopyWith<$Res> { + __$$_GroupModelCopyWithImpl( + _$_GroupModel _value, $Res Function(_$_GroupModel) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? name = null, + Object? permissions = null, + }) { + return _then(_$_GroupModel( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + permissions: null == permissions + ? _value._permissions + : permissions // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$_GroupModel implements _GroupModel { + const _$_GroupModel( + {@HiveField(0) required this.id, + @HiveField(1) required this.name, + @HiveField(2) required final List permissions}) + : _permissions = permissions; + + factory _$_GroupModel.fromJson(Map json) => + _$$_GroupModelFromJson(json); + + @override + @HiveField(0) + final int id; + @override + @HiveField(1) + final String name; + final List _permissions; + @override + @HiveField(2) + List get permissions { + if (_permissions is EqualUnmodifiableListView) return _permissions; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_permissions); + } + + @override + String toString() { + return 'GroupModel(id: $id, name: $name, permissions: $permissions)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_GroupModel && + (identical(other.id, id) || other.id == id) && + (identical(other.name, name) || other.name == name) && + const DeepCollectionEquality() + .equals(other._permissions, _permissions)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash( + runtimeType, id, name, const DeepCollectionEquality().hash(_permissions)); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_GroupModelCopyWith<_$_GroupModel> get copyWith => + __$$_GroupModelCopyWithImpl<_$_GroupModel>(this, _$identity); + + @override + Map toJson() { + return _$$_GroupModelToJson( + this, + ); + } +} + +abstract class _GroupModel implements GroupModel { + const factory _GroupModel( + {@HiveField(0) required final int id, + @HiveField(1) required final String name, + @HiveField(2) required final List permissions}) = + _$_GroupModel; + + factory _GroupModel.fromJson(Map json) = + _$_GroupModel.fromJson; + + @override + @HiveField(0) + int get id; + @override + @HiveField(1) + String get name; + @override + @HiveField(2) + List get permissions; + @override + @JsonKey(ignore: true) + _$$_GroupModelCopyWith<_$_GroupModel> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/packages/paperless_api/lib/src/models/models.dart b/packages/paperless_api/lib/src/models/models.dart index c1dd7f9..7421f2d 100644 --- a/packages/paperless_api/lib/src/models/models.dart +++ b/packages/paperless_api/lib/src/models/models.dart @@ -24,3 +24,8 @@ export 'saved_view_model.dart'; export 'task/task.dart'; export 'task/task_status.dart'; export 'field_suggestions.dart'; +export 'permissions/permissions.dart'; +export 'permissions/user_permissions.dart'; +export 'permissions/inherited_permissions.dart'; +export 'group_model.dart'; +export 'user_model.dart'; diff --git a/packages/paperless_api/lib/src/models/permissions/inherited_permissions.dart b/packages/paperless_api/lib/src/models/permissions/inherited_permissions.dart new file mode 100644 index 0000000..9336562 --- /dev/null +++ b/packages/paperless_api/lib/src/models/permissions/inherited_permissions.dart @@ -0,0 +1,235 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:hive/hive.dart'; +import 'package:paperless_api/config/hive/hive_type_ids.dart'; + +part 'inherited_permissions.g.dart'; + +@HiveType(typeId: PaperlessApiHiveTypeIds.inheritedPermissions) +@JsonEnum(valueField: "value") +enum InheritedPermissions { + @HiveField(0) + adminAddLogentry("admin.add_logentry"), + @HiveField(1) + adminChangeLogentry("admin.change_logentry"), + @HiveField(2) + adminDeleteLogentry("admin.delete_logentry"), + @HiveField(3) + adminViewLogentry("admin.view_logentry"), + @HiveField(4) + authAddGroup("auth.add_group"), + @HiveField(5) + authAddPermission("auth.add_permission"), + @HiveField(6) + authAddUser("auth.add_user"), + @HiveField(7) + authChangeGroup("auth.change_group"), + @HiveField(8) + authChangePermission("auth.change_permission"), + @HiveField(9) + authChangeUser("auth.change_user"), + @HiveField(10) + authDeleteGroup("auth.delete_group"), + @HiveField(11) + authDeletePermission("auth.delete_permission"), + @HiveField(12) + authDeleteUser("auth.delete_user"), + @HiveField(13) + authViewGroup("auth.view_group"), + @HiveField(14) + authViewPermission("auth.view_permission"), + @HiveField(15) + authViewUser("auth.view_user"), + @HiveField(16) + authtokenAddToken("authtoken.add_token"), + @HiveField(17) + authtokenAddTokenproxy("authtoken.add_tokenproxy"), + @HiveField(18) + authtokenChangeToken("authtoken.change_token"), + @HiveField(19) + authtokenChangeTokenproxy("authtoken.change_tokenproxy"), + @HiveField(20) + authtokenDeleteToken("authtoken.delete_token"), + @HiveField(21) + authtokenDeleteTokenproxy("authtoken.delete_tokenproxy"), + @HiveField(22) + authtokenViewToken("authtoken.view_token"), + @HiveField(23) + authtokenViewTokenproxy("authtoken.view_tokenproxy"), + @HiveField(24) + contenttypesAddContenttype("contenttypes.add_contenttype"), + @HiveField(25) + contenttypesChangeContenttype("contenttypes.change_contenttype"), + @HiveField(26) + contenttypesDeleteContenttype("contenttypes.delete_contenttype"), + @HiveField(27) + contenttypesViewContenttype("contenttypes.view_contenttype"), + @HiveField(28) + djangoCeleryResultsAddChordcounter("django_celery_results.add_chordcounter"), + @HiveField(29) + djangoCeleryResultsAddGroupresult("django_celery_results.add_groupresult"), + @HiveField(30) + djangoCeleryResultsAddTaskresult("django_celery_results.add_taskresult"), + @HiveField(31) + djangoCeleryResultsChangeChordcounter("django_celery_results.change_chordcounter"), + @HiveField(32) + djangoCeleryResultsChangeGroupresult("django_celery_results.change_groupresult"), + @HiveField(33) + djangoCeleryResultsChangeTaskresult("django_celery_results.change_taskresult"), + @HiveField(34) + djangoCeleryResultsDeleteChordcounter("django_celery_results.delete_chordcounter"), + @HiveField(35) + djangoCeleryResultsDeleteGroupresult("django_celery_results.delete_groupresult"), + @HiveField(36) + djangoCeleryResultsDeleteTaskresult("django_celery_results.delete_taskresult"), + @HiveField(37) + djangoCeleryResultsViewChordcounter("django_celery_results.view_chordcounter"), + @HiveField(38) + djangoCeleryResultsViewGroupresult("django_celery_results.view_groupresult"), + @HiveField(39) + djangoCeleryResultsViewTaskresult("django_celery_results.view_taskresult"), + @HiveField(40) + documentsAddComment("documents.add_comment"), + @HiveField(41) + documentsAddCorrespondent("documents.add_correspondent"), + @HiveField(42) + documentsAddDocument("documents.add_document"), + @HiveField(43) + documentsAddDocumenttype("documents.add_documenttype"), + @HiveField(44) + documentsAddLog("documents.add_log"), + @HiveField(45) + documentsAddNote("documents.add_note"), + @HiveField(46) + documentsAddPaperlesstask("documents.add_paperlesstask"), + @HiveField(47) + documentsAddSavedview("documents.add_savedview"), + @HiveField(48) + documentsAddSavedviewfilterrule("documents.add_savedviewfilterrule"), + @HiveField(49) + documentsAddStoragepath("documents.add_storagepath"), + @HiveField(50) + documentsAddTag("documents.add_tag"), + @HiveField(51) + documentsAddUisettings("documents.add_uisettings"), + @HiveField(52) + documentsChangeComment("documents.change_comment"), + @HiveField(53) + documentsChangeCorrespondent("documents.change_correspondent"), + @HiveField(54) + documentsChangeDocument("documents.change_document"), + @HiveField(55) + documentsChangeDocumenttype("documents.change_documenttype"), + @HiveField(56) + documentsChangeLog("documents.change_log"), + @HiveField(57) + documentsChangeNote("documents.change_note"), + @HiveField(58) + documentsChangePaperlesstask("documents.change_paperlesstask"), + @HiveField(59) + documentsChangeSavedview("documents.change_savedview"), + @HiveField(60) + documentsChangeSavedviewfilterrule("documents.change_savedviewfilterrule"), + @HiveField(61) + documentsChangeStoragepathdocuments("documents.change_storagepathdocuments.change_tag"), + @HiveField(62) + documentsChangeUisettings("documents.change_uisettings"), + @HiveField(63) + documentsDeleteComment("documents.delete_comment"), + @HiveField(64) + documentsDeleteCorrespondent("documents.delete_correspondent"), + @HiveField(65) + documentsDeleteDocument("documents.delete_document"), + @HiveField(66) + documentsDeleteDocumenttype("documents.delete_documenttype"), + @HiveField(67) + documentsDeleteLog("documents.delete_log"), + @HiveField(68) + documentsDeleteNote("documents.delete_note"), + @HiveField(69) + documentsDeletePaperlesstask("documents.delete_paperlesstask"), + @HiveField(70) + documentsDeleteSavedview("documents.delete_savedview"), + @HiveField(71) + documentsDeleteSavedviewfilterrule("documents.delete_savedviewfilterrule"), + @HiveField(72) + documentsDeleteStoragepath("documents.delete_storagepath"), + @HiveField(73) + documentsDeleteTag("documents.delete_tag"), + @HiveField(74) + documentsDeleteUisettings("documents.delete_uisettings"), + @HiveField(75) + documentsViewComment("documents.view_comment"), + @HiveField(76) + documentsViewCorrespondent("documents.view_correspondent"), + @HiveField(77) + documentsViewDocument("documents.view_document"), + @HiveField(78) + documentsViewDocumenttype("documents.view_documenttype"), + @HiveField(79) + documentsViewLog("documents.view_log"), + @HiveField(80) + documentsViewNote("documents.view_note"), + @HiveField(81) + documentsViewPaperlesstask("documents.view_paperlesstask"), + @HiveField(82) + documentsViewSavedview("documents.view_savedview"), + @HiveField(83) + documentsViewSavedviewfilterrule("documents.view_savedviewfilterrule"), + @HiveField(84) + documentsViewStoragepath("documents.view_storagepath"), + @HiveField(85) + documentsViewTag("documents.view_tag"), + @HiveField(86) + documentsViewUisettings("documents.view_uisettings"), + @HiveField(87) + guardianAddGroupobjectpermission("guardian.add_groupobjectpermission"), + @HiveField(88) + guardianAddUserobjectpermission("guardian.add_userobjectpermission"), + @HiveField(89) + guardianChangeGroupobjectpermission("guardian.change_groupobjectpermission"), + @HiveField(90) + guardianChangeUserobjectpermission("guardian.change_userobjectpermission"), + @HiveField(91) + guardianDeleteGroupobjectpermission("guardian.delete_groupobjectpermission"), + @HiveField(92) + guardianDeleteUserobjectpermission("guardian.delete_userobjectpermission"), + @HiveField(93) + guardianViewGroupobjectpermission("guardian.view_groupobjectpermission"), + @HiveField(94) + guardianViewUserobjectpermission("guardian.view_userobjectpermission"), + @HiveField(95) + paperlessMailAddMailaccount("paperless_mail.add_mailaccount"), + @HiveField(96) + paperlessMailAddMailrule("paperless_mail.add_mailrule"), + @HiveField(97) + paperlessMailAddProcessedmail("paperless_mail.add_processedmail"), + @HiveField(98) + paperlessMailChangeMailaccount("paperless_mail.change_mailaccount"), + @HiveField(99) + paperlessMailChangeMailrule("paperless_mail.change_mailrule"), + @HiveField(100) + paperlessMailChangeProcessedmail("paperless_mail.change_processedmail"), + @HiveField(101) + paperlessMailDeleteMailaccount("paperless_mail.delete_mailaccount"), + @HiveField(102) + paperlessMailDeleteMailrule("paperless_mail.delete_mailrule"), + @HiveField(103) + paperlessMailDeleteProcessedmail("paperless_mail.delete_processedmail"), + @HiveField(104) + paperlessMailViewMailaccount("paperless_mail.view_mailaccount"), + @HiveField(105) + paperlessMailViewMailrule("paperless_mail.view_mailrule"), + @HiveField(106) + paperlessMailViewProcessedmail("paperless_mail.view_processedmail"), + @HiveField(107) + sessionsAddSession("sessions.add_session"), + @HiveField(108) + sessionsChangeSession("sessions.change_session"), + @HiveField(109) + sessionsDeleteSession("sessions.delete_session"), + @HiveField(110) + sessionsViewSession("sessions.view_session"); + + const InheritedPermissions(this.value); + final String value; +} diff --git a/packages/paperless_api/lib/src/models/permissions/permissions.dart b/packages/paperless_api/lib/src/models/permissions/permissions.dart new file mode 100644 index 0000000..ea0d489 --- /dev/null +++ b/packages/paperless_api/lib/src/models/permissions/permissions.dart @@ -0,0 +1,17 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:hive/hive.dart'; +import 'package:paperless_api/paperless_api.dart'; + +part 'permissions.freezed.dart'; +part 'permissions.g.dart'; + +@HiveType(typeId: PaperlessApiHiveTypeIds.permissions) +@freezed +class Permissions with _$Permissions { + const factory Permissions({ + @HiveField(0) @Default([]) List view, + @HiveField(1) @Default([]) List change, + }) = _Permissions; + + factory Permissions.fromJson(Map json) => _$PermissionsFromJson(json); +} diff --git a/packages/paperless_api/lib/src/models/permissions/permissions.freezed.dart b/packages/paperless_api/lib/src/models/permissions/permissions.freezed.dart new file mode 100644 index 0000000..6b324a5 --- /dev/null +++ b/packages/paperless_api/lib/src/models/permissions/permissions.freezed.dart @@ -0,0 +1,195 @@ +// 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 'permissions.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(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'); + +Permissions _$PermissionsFromJson(Map json) { + return _Permissions.fromJson(json); +} + +/// @nodoc +mixin _$Permissions { + @HiveField(0) + List get view => throw _privateConstructorUsedError; + @HiveField(1) + List get change => throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $PermissionsCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $PermissionsCopyWith<$Res> { + factory $PermissionsCopyWith( + Permissions value, $Res Function(Permissions) then) = + _$PermissionsCopyWithImpl<$Res, Permissions>; + @useResult + $Res call({@HiveField(0) List view, @HiveField(1) List change}); +} + +/// @nodoc +class _$PermissionsCopyWithImpl<$Res, $Val extends Permissions> + implements $PermissionsCopyWith<$Res> { + _$PermissionsCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? view = null, + Object? change = null, + }) { + return _then(_value.copyWith( + view: null == view + ? _value.view + : view // ignore: cast_nullable_to_non_nullable + as List, + change: null == change + ? _value.change + : change // ignore: cast_nullable_to_non_nullable + as List, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$_PermissionsCopyWith<$Res> + implements $PermissionsCopyWith<$Res> { + factory _$$_PermissionsCopyWith( + _$_Permissions value, $Res Function(_$_Permissions) then) = + __$$_PermissionsCopyWithImpl<$Res>; + @override + @useResult + $Res call({@HiveField(0) List view, @HiveField(1) List change}); +} + +/// @nodoc +class __$$_PermissionsCopyWithImpl<$Res> + extends _$PermissionsCopyWithImpl<$Res, _$_Permissions> + implements _$$_PermissionsCopyWith<$Res> { + __$$_PermissionsCopyWithImpl( + _$_Permissions _value, $Res Function(_$_Permissions) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? view = null, + Object? change = null, + }) { + return _then(_$_Permissions( + view: null == view + ? _value._view + : view // ignore: cast_nullable_to_non_nullable + as List, + change: null == change + ? _value._change + : change // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$_Permissions implements _Permissions { + const _$_Permissions( + {@HiveField(0) final List view = const [], + @HiveField(1) final List change = const []}) + : _view = view, + _change = change; + + factory _$_Permissions.fromJson(Map json) => + _$$_PermissionsFromJson(json); + + final List _view; + @override + @JsonKey() + @HiveField(0) + List get view { + if (_view is EqualUnmodifiableListView) return _view; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_view); + } + + final List _change; + @override + @JsonKey() + @HiveField(1) + List get change { + if (_change is EqualUnmodifiableListView) return _change; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_change); + } + + @override + String toString() { + return 'Permissions(view: $view, change: $change)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_Permissions && + const DeepCollectionEquality().equals(other._view, _view) && + const DeepCollectionEquality().equals(other._change, _change)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash( + runtimeType, + const DeepCollectionEquality().hash(_view), + const DeepCollectionEquality().hash(_change)); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_PermissionsCopyWith<_$_Permissions> get copyWith => + __$$_PermissionsCopyWithImpl<_$_Permissions>(this, _$identity); + + @override + Map toJson() { + return _$$_PermissionsToJson( + this, + ); + } +} + +abstract class _Permissions implements Permissions { + const factory _Permissions( + {@HiveField(0) final List view, + @HiveField(1) final List change}) = _$_Permissions; + + factory _Permissions.fromJson(Map json) = + _$_Permissions.fromJson; + + @override + @HiveField(0) + List get view; + @override + @HiveField(1) + List get change; + @override + @JsonKey(ignore: true) + _$$_PermissionsCopyWith<_$_Permissions> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/packages/paperless_api/lib/src/models/permissions/user_permissions.dart b/packages/paperless_api/lib/src/models/permissions/user_permissions.dart new file mode 100644 index 0000000..14d0a54 --- /dev/null +++ b/packages/paperless_api/lib/src/models/permissions/user_permissions.dart @@ -0,0 +1,117 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:hive/hive.dart'; +import 'package:paperless_api/config/hive/hive_type_ids.dart'; +part 'user_permissions.g.dart'; + +@HiveType(typeId: PaperlessApiHiveTypeIds.userPermissions) +@JsonEnum(valueField: "value") +enum UserPermissions { + @HiveField(0) + addCorrespondent("add_correspondent"), + @HiveField(1) + addDocument("add_document"), + @HiveField(2) + addDocumenttype("add_documenttype"), + @HiveField(3) + addGroup("add_group"), + @HiveField(4) + addMailaccount("add_mailaccount"), + @HiveField(5) + addMailrule("add_mailrule"), + @HiveField(6) + addNote("add_note"), + @HiveField(7) + addPaperlesstask("add_paperlesstask"), + @HiveField(8) + addSavedview("add_savedview"), + @HiveField(9) + addStoragepath("add_storagepath"), + @HiveField(10) + addTag("add_tag"), + @HiveField(11) + addUisettings("add_uisettings"), + @HiveField(12) + addUser("add_user"), + @HiveField(13) + changeCorrespondent("change_correspondent"), + @HiveField(14) + changeDocument("change_document"), + @HiveField(15) + changeDocumenttype("change_documenttype"), + @HiveField(16) + changeGroup("change_group"), + @HiveField(17) + changeMailaccount("change_mailaccount"), + @HiveField(18) + changeMailrule("change_mailrule"), + @HiveField(19) + changeNote("change_note"), + @HiveField(20) + changePaperlesstask("change_paperlesstask"), + @HiveField(21) + changeSavedview("change_savedview"), + @HiveField(22) + changeStoragepath("change_storagepath"), + @HiveField(23) + changeTag("change_tag"), + @HiveField(24) + changeUisettings("change_uisettings"), + @HiveField(25) + changeUser("change_user"), + @HiveField(26) + deleteCorrespondent("delete_correspondent"), + @HiveField(27) + deleteDocument("delete_document"), + @HiveField(28) + deleteDocumenttype("delete_documenttype"), + @HiveField(29) + deleteGroup("delete_group"), + @HiveField(30) + deleteMailaccount("delete_mailaccount"), + @HiveField(31) + deleteMailrule("delete_mailrule"), + @HiveField(32) + deleteNote("delete_note"), + @HiveField(33) + deletePaperlesstask("delete_paperlesstask"), + @HiveField(34) + deleteSavedview("delete_savedview"), + @HiveField(35) + deleteStoragepath("delete_storagepath"), + @HiveField(36) + deleteTag("delete_tag"), + @HiveField(37) + deleteUisettings("delete_uisettings"), + @HiveField(38) + deleteUser("delete_user"), + @HiveField(39) + viewCorrespondent("view_correspondent"), + @HiveField(40) + viewDocument("view_document"), + @HiveField(41) + viewDocumenttype("view_documenttype"), + @HiveField(42) + viewGroup("view_group"), + @HiveField(43) + viewMailaccount("view_mailaccount"), + @HiveField(44) + viewMailrule("view_mailrule"), + @HiveField(45) + viewNote("view_note"), + @HiveField(46) + viewPaperlesstask("view_paperlesstask"), + @HiveField(47) + viewSavedview("view_savedview"), + @HiveField(48) + viewStoragepath("view_storagepath"), + @HiveField(49) + viewTag("view_tag"), + @HiveField(50) + viewUisettings("view_uisettings"), + @HiveField(51) + viewUser("view_user"); + + const UserPermissions(this.value); + + final String value; +} diff --git a/packages/paperless_api/lib/src/models/user_model.dart b/packages/paperless_api/lib/src/models/user_model.dart new file mode 100644 index 0000000..b02a377 --- /dev/null +++ b/packages/paperless_api/lib/src/models/user_model.dart @@ -0,0 +1,72 @@ +// ignore_for_file: invalid_annotation_target + +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:hive/hive.dart'; +import 'package:paperless_api/config/hive/hive_type_ids.dart'; +import 'package:paperless_api/src/models/permissions/inherited_permissions.dart'; +import 'package:paperless_api/src/models/permissions/user_permissions.dart'; + +part 'user_model.freezed.dart'; +part 'user_model.g.dart'; + +@freezed +class UserModel with _$UserModel { + const UserModel._(); + + @JsonSerializable(fieldRename: FieldRename.snake) + @HiveType(typeId: PaperlessApiHiveTypeIds.userModelv3) + const factory UserModel.v3({ + @HiveField(0) required int id, + @HiveField(1) required String username, + @HiveField(2) required String email, + @HiveField(3) String? firstName, + @HiveField(4) String? lastName, + @HiveField(5) DateTime? dateJoined, + @HiveField(6) @Default(true) bool isStaff, + @HiveField(7) @Default(true) bool isActive, + @HiveField(8) @Default(true) bool isSuperuser, + @HiveField(9) @Default([]) List groups, + @HiveField(10) @Default(UserPermissions.values) List userPermissions, + @HiveField(11) + @Default(InheritedPermissions.values) + List inheritedPermissions, + }) = UserModelV3; + + @JsonSerializable(fieldRename: FieldRename.snake) + @HiveType(typeId: PaperlessApiHiveTypeIds.userModelv2) + const factory UserModel.v2({ + @HiveField(0) @JsonKey(name: "user_id") required int id, + @HiveField(1) required String username, + @HiveField(2) String? displayName, + }) = UserModelV2; + + factory UserModel.fromJson(Map json) => _$UserModelFromJson(json); + + String? get fullName => map( + v2: (value) => value.displayName, + v3: (value) { + if (value.firstName == null && value.lastName == null) { + return null; + } + if (value.firstName == null) { + return value.lastName; + } + return value.firstName! + (value.lastName ?? ''); + }, + ); + + bool hasPermission(UserPermissions permission) { + return map( + v3: (value) { + if (value.isSuperuser) { + return true; + } + return value.userPermissions.contains(permission); + }, + v2: (value) { + // In previous versions, all users have access to all + return true; + }, + ); + } +} diff --git a/packages/paperless_api/lib/src/models/user_model.freezed.dart b/packages/paperless_api/lib/src/models/user_model.freezed.dart new file mode 100644 index 0000000..c675095 --- /dev/null +++ b/packages/paperless_api/lib/src/models/user_model.freezed.dart @@ -0,0 +1,845 @@ +// 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 'user_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(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'); + +UserModel _$UserModelFromJson(Map json) { + switch (json['runtimeType']) { + case 'v3': + return UserModelV3.fromJson(json); + case 'v2': + return UserModelV2.fromJson(json); + + default: + throw CheckedFromJsonException(json, 'runtimeType', 'UserModel', + 'Invalid union type "${json['runtimeType']}"!'); + } +} + +/// @nodoc +mixin _$UserModel { + @HiveField(0) + int get id => throw _privateConstructorUsedError; + @HiveField(1) + String get username => throw _privateConstructorUsedError; + @optionalTypeArgs + TResult when({ + required TResult Function( + @HiveField(0) int id, + @HiveField(1) String username, + @HiveField(2) String email, + @HiveField(3) String? firstName, + @HiveField(4) String? lastName, + @HiveField(5) DateTime? dateJoined, + @HiveField(6) bool isStaff, + @HiveField(7) bool isActive, + @HiveField(8) bool isSuperuser, + @HiveField(9) List groups, + @HiveField(10) List userPermissions, + @HiveField(11) List inheritedPermissions) + v3, + required TResult Function(@HiveField(0) @JsonKey(name: "user_id") int id, + @HiveField(1) String username, @HiveField(2) String? displayName) + v2, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function( + @HiveField(0) int id, + @HiveField(1) String username, + @HiveField(2) String email, + @HiveField(3) String? firstName, + @HiveField(4) String? lastName, + @HiveField(5) DateTime? dateJoined, + @HiveField(6) bool isStaff, + @HiveField(7) bool isActive, + @HiveField(8) bool isSuperuser, + @HiveField(9) List groups, + @HiveField(10) List userPermissions, + @HiveField(11) List inheritedPermissions)? + v3, + TResult? Function(@HiveField(0) @JsonKey(name: "user_id") int id, + @HiveField(1) String username, @HiveField(2) String? displayName)? + v2, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeWhen({ + TResult Function( + @HiveField(0) int id, + @HiveField(1) String username, + @HiveField(2) String email, + @HiveField(3) String? firstName, + @HiveField(4) String? lastName, + @HiveField(5) DateTime? dateJoined, + @HiveField(6) bool isStaff, + @HiveField(7) bool isActive, + @HiveField(8) bool isSuperuser, + @HiveField(9) List groups, + @HiveField(10) List userPermissions, + @HiveField(11) List inheritedPermissions)? + v3, + TResult Function(@HiveField(0) @JsonKey(name: "user_id") int id, + @HiveField(1) String username, @HiveField(2) String? displayName)? + v2, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult map({ + required TResult Function(UserModelV3 value) v3, + required TResult Function(UserModelV2 value) v2, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(UserModelV3 value)? v3, + TResult? Function(UserModelV2 value)? v2, + }) => + throw _privateConstructorUsedError; + @optionalTypeArgs + TResult maybeMap({ + TResult Function(UserModelV3 value)? v3, + TResult Function(UserModelV2 value)? v2, + required TResult orElse(), + }) => + throw _privateConstructorUsedError; + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $UserModelCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $UserModelCopyWith<$Res> { + factory $UserModelCopyWith(UserModel value, $Res Function(UserModel) then) = + _$UserModelCopyWithImpl<$Res, UserModel>; + @useResult + $Res call({@HiveField(0) int id, @HiveField(1) String username}); +} + +/// @nodoc +class _$UserModelCopyWithImpl<$Res, $Val extends UserModel> + implements $UserModelCopyWith<$Res> { + _$UserModelCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? username = null, + }) { + return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + username: null == username + ? _value.username + : username // ignore: cast_nullable_to_non_nullable + as String, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$UserModelV3CopyWith<$Res> + implements $UserModelCopyWith<$Res> { + factory _$$UserModelV3CopyWith( + _$UserModelV3 value, $Res Function(_$UserModelV3) then) = + __$$UserModelV3CopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@HiveField(0) int id, + @HiveField(1) String username, + @HiveField(2) String email, + @HiveField(3) String? firstName, + @HiveField(4) String? lastName, + @HiveField(5) DateTime? dateJoined, + @HiveField(6) bool isStaff, + @HiveField(7) bool isActive, + @HiveField(8) bool isSuperuser, + @HiveField(9) List groups, + @HiveField(10) List userPermissions, + @HiveField(11) List inheritedPermissions}); +} + +/// @nodoc +class __$$UserModelV3CopyWithImpl<$Res> + extends _$UserModelCopyWithImpl<$Res, _$UserModelV3> + implements _$$UserModelV3CopyWith<$Res> { + __$$UserModelV3CopyWithImpl( + _$UserModelV3 _value, $Res Function(_$UserModelV3) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? username = null, + Object? email = null, + Object? firstName = freezed, + Object? lastName = freezed, + Object? dateJoined = freezed, + Object? isStaff = null, + Object? isActive = null, + Object? isSuperuser = null, + Object? groups = null, + Object? userPermissions = null, + Object? inheritedPermissions = null, + }) { + return _then(_$UserModelV3( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + username: null == username + ? _value.username + : username // ignore: cast_nullable_to_non_nullable + as String, + email: null == email + ? _value.email + : email // ignore: cast_nullable_to_non_nullable + as String, + firstName: freezed == firstName + ? _value.firstName + : firstName // ignore: cast_nullable_to_non_nullable + as String?, + lastName: freezed == lastName + ? _value.lastName + : lastName // ignore: cast_nullable_to_non_nullable + as String?, + dateJoined: freezed == dateJoined + ? _value.dateJoined + : dateJoined // ignore: cast_nullable_to_non_nullable + as DateTime?, + isStaff: null == isStaff + ? _value.isStaff + : isStaff // ignore: cast_nullable_to_non_nullable + as bool, + isActive: null == isActive + ? _value.isActive + : isActive // ignore: cast_nullable_to_non_nullable + as bool, + isSuperuser: null == isSuperuser + ? _value.isSuperuser + : isSuperuser // ignore: cast_nullable_to_non_nullable + as bool, + groups: null == groups + ? _value._groups + : groups // ignore: cast_nullable_to_non_nullable + as List, + userPermissions: null == userPermissions + ? _value._userPermissions + : userPermissions // ignore: cast_nullable_to_non_nullable + as List, + inheritedPermissions: null == inheritedPermissions + ? _value._inheritedPermissions + : inheritedPermissions // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc + +@JsonSerializable(fieldRename: FieldRename.snake) +@HiveType(typeId: PaperlessApiHiveTypeIds.userModelv3) +class _$UserModelV3 extends UserModelV3 { + const _$UserModelV3( + {@HiveField(0) required this.id, + @HiveField(1) required this.username, + @HiveField(2) required this.email, + @HiveField(3) this.firstName, + @HiveField(4) this.lastName, + @HiveField(5) this.dateJoined, + @HiveField(6) this.isStaff = true, + @HiveField(7) this.isActive = true, + @HiveField(8) this.isSuperuser = true, + @HiveField(9) final List groups = const [], + @HiveField(10) final List userPermissions = + UserPermissions.values, + @HiveField(11) final List inheritedPermissions = + InheritedPermissions.values, + final String? $type}) + : _groups = groups, + _userPermissions = userPermissions, + _inheritedPermissions = inheritedPermissions, + $type = $type ?? 'v3', + super._(); + + factory _$UserModelV3.fromJson(Map json) => + _$$UserModelV3FromJson(json); + + @override + @HiveField(0) + final int id; + @override + @HiveField(1) + final String username; + @override + @HiveField(2) + final String email; + @override + @HiveField(3) + final String? firstName; + @override + @HiveField(4) + final String? lastName; + @override + @HiveField(5) + final DateTime? dateJoined; + @override + @JsonKey() + @HiveField(6) + final bool isStaff; + @override + @JsonKey() + @HiveField(7) + final bool isActive; + @override + @JsonKey() + @HiveField(8) + final bool isSuperuser; + final List _groups; + @override + @JsonKey() + @HiveField(9) + List get groups { + if (_groups is EqualUnmodifiableListView) return _groups; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_groups); + } + + final List _userPermissions; + @override + @JsonKey() + @HiveField(10) + List get userPermissions { + if (_userPermissions is EqualUnmodifiableListView) return _userPermissions; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_userPermissions); + } + + final List _inheritedPermissions; + @override + @JsonKey() + @HiveField(11) + List get inheritedPermissions { + if (_inheritedPermissions is EqualUnmodifiableListView) + return _inheritedPermissions; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_inheritedPermissions); + } + + @JsonKey(name: 'runtimeType') + final String $type; + + @override + String toString() { + return 'UserModel.v3(id: $id, username: $username, email: $email, firstName: $firstName, lastName: $lastName, dateJoined: $dateJoined, isStaff: $isStaff, isActive: $isActive, isSuperuser: $isSuperuser, groups: $groups, userPermissions: $userPermissions, inheritedPermissions: $inheritedPermissions)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$UserModelV3 && + (identical(other.id, id) || other.id == id) && + (identical(other.username, username) || + other.username == username) && + (identical(other.email, email) || other.email == email) && + (identical(other.firstName, firstName) || + other.firstName == firstName) && + (identical(other.lastName, lastName) || + other.lastName == lastName) && + (identical(other.dateJoined, dateJoined) || + other.dateJoined == dateJoined) && + (identical(other.isStaff, isStaff) || other.isStaff == isStaff) && + (identical(other.isActive, isActive) || + other.isActive == isActive) && + (identical(other.isSuperuser, isSuperuser) || + other.isSuperuser == isSuperuser) && + const DeepCollectionEquality().equals(other._groups, _groups) && + const DeepCollectionEquality() + .equals(other._userPermissions, _userPermissions) && + const DeepCollectionEquality() + .equals(other._inheritedPermissions, _inheritedPermissions)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash( + runtimeType, + id, + username, + email, + firstName, + lastName, + dateJoined, + isStaff, + isActive, + isSuperuser, + const DeepCollectionEquality().hash(_groups), + const DeepCollectionEquality().hash(_userPermissions), + const DeepCollectionEquality().hash(_inheritedPermissions)); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$UserModelV3CopyWith<_$UserModelV3> get copyWith => + __$$UserModelV3CopyWithImpl<_$UserModelV3>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function( + @HiveField(0) int id, + @HiveField(1) String username, + @HiveField(2) String email, + @HiveField(3) String? firstName, + @HiveField(4) String? lastName, + @HiveField(5) DateTime? dateJoined, + @HiveField(6) bool isStaff, + @HiveField(7) bool isActive, + @HiveField(8) bool isSuperuser, + @HiveField(9) List groups, + @HiveField(10) List userPermissions, + @HiveField(11) List inheritedPermissions) + v3, + required TResult Function(@HiveField(0) @JsonKey(name: "user_id") int id, + @HiveField(1) String username, @HiveField(2) String? displayName) + v2, + }) { + return v3(id, username, email, firstName, lastName, dateJoined, isStaff, + isActive, isSuperuser, groups, userPermissions, inheritedPermissions); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function( + @HiveField(0) int id, + @HiveField(1) String username, + @HiveField(2) String email, + @HiveField(3) String? firstName, + @HiveField(4) String? lastName, + @HiveField(5) DateTime? dateJoined, + @HiveField(6) bool isStaff, + @HiveField(7) bool isActive, + @HiveField(8) bool isSuperuser, + @HiveField(9) List groups, + @HiveField(10) List userPermissions, + @HiveField(11) List inheritedPermissions)? + v3, + TResult? Function(@HiveField(0) @JsonKey(name: "user_id") int id, + @HiveField(1) String username, @HiveField(2) String? displayName)? + v2, + }) { + return v3?.call( + id, + username, + email, + firstName, + lastName, + dateJoined, + isStaff, + isActive, + isSuperuser, + groups, + userPermissions, + inheritedPermissions); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function( + @HiveField(0) int id, + @HiveField(1) String username, + @HiveField(2) String email, + @HiveField(3) String? firstName, + @HiveField(4) String? lastName, + @HiveField(5) DateTime? dateJoined, + @HiveField(6) bool isStaff, + @HiveField(7) bool isActive, + @HiveField(8) bool isSuperuser, + @HiveField(9) List groups, + @HiveField(10) List userPermissions, + @HiveField(11) List inheritedPermissions)? + v3, + TResult Function(@HiveField(0) @JsonKey(name: "user_id") int id, + @HiveField(1) String username, @HiveField(2) String? displayName)? + v2, + required TResult orElse(), + }) { + if (v3 != null) { + return v3(id, username, email, firstName, lastName, dateJoined, isStaff, + isActive, isSuperuser, groups, userPermissions, inheritedPermissions); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(UserModelV3 value) v3, + required TResult Function(UserModelV2 value) v2, + }) { + return v3(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(UserModelV3 value)? v3, + TResult? Function(UserModelV2 value)? v2, + }) { + return v3?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(UserModelV3 value)? v3, + TResult Function(UserModelV2 value)? v2, + required TResult orElse(), + }) { + if (v3 != null) { + return v3(this); + } + return orElse(); + } + + @override + Map toJson() { + return _$$UserModelV3ToJson( + this, + ); + } +} + +abstract class UserModelV3 extends UserModel { + const factory UserModelV3( + {@HiveField(0) + required final int id, + @HiveField(1) + required final String username, + @HiveField(2) + required final String email, + @HiveField(3) + final String? firstName, + @HiveField(4) + final String? lastName, + @HiveField(5) + final DateTime? dateJoined, + @HiveField(6) + final bool isStaff, + @HiveField(7) + final bool isActive, + @HiveField(8) + final bool isSuperuser, + @HiveField(9) + final List groups, + @HiveField(10) + final List userPermissions, + @HiveField(11) + final List inheritedPermissions}) = + _$UserModelV3; + const UserModelV3._() : super._(); + + factory UserModelV3.fromJson(Map json) = + _$UserModelV3.fromJson; + + @override + @HiveField(0) + int get id; + @override + @HiveField(1) + String get username; + @HiveField(2) + String get email; + @HiveField(3) + String? get firstName; + @HiveField(4) + String? get lastName; + @HiveField(5) + DateTime? get dateJoined; + @HiveField(6) + bool get isStaff; + @HiveField(7) + bool get isActive; + @HiveField(8) + bool get isSuperuser; + @HiveField(9) + List get groups; + @HiveField(10) + List get userPermissions; + @HiveField(11) + List get inheritedPermissions; + @override + @JsonKey(ignore: true) + _$$UserModelV3CopyWith<_$UserModelV3> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$UserModelV2CopyWith<$Res> + implements $UserModelCopyWith<$Res> { + factory _$$UserModelV2CopyWith( + _$UserModelV2 value, $Res Function(_$UserModelV2) then) = + __$$UserModelV2CopyWithImpl<$Res>; + @override + @useResult + $Res call( + {@HiveField(0) @JsonKey(name: "user_id") int id, + @HiveField(1) String username, + @HiveField(2) String? displayName}); +} + +/// @nodoc +class __$$UserModelV2CopyWithImpl<$Res> + extends _$UserModelCopyWithImpl<$Res, _$UserModelV2> + implements _$$UserModelV2CopyWith<$Res> { + __$$UserModelV2CopyWithImpl( + _$UserModelV2 _value, $Res Function(_$UserModelV2) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? username = null, + Object? displayName = freezed, + }) { + return _then(_$UserModelV2( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + username: null == username + ? _value.username + : username // ignore: cast_nullable_to_non_nullable + as String, + displayName: freezed == displayName + ? _value.displayName + : displayName // ignore: cast_nullable_to_non_nullable + as String?, + )); + } +} + +/// @nodoc + +@JsonSerializable(fieldRename: FieldRename.snake) +@HiveType(typeId: PaperlessApiHiveTypeIds.userModelv2) +class _$UserModelV2 extends UserModelV2 { + const _$UserModelV2( + {@HiveField(0) @JsonKey(name: "user_id") required this.id, + @HiveField(1) required this.username, + @HiveField(2) this.displayName, + final String? $type}) + : $type = $type ?? 'v2', + super._(); + + factory _$UserModelV2.fromJson(Map json) => + _$$UserModelV2FromJson(json); + + @override + @HiveField(0) + @JsonKey(name: "user_id") + final int id; + @override + @HiveField(1) + final String username; + @override + @HiveField(2) + final String? displayName; + + @JsonKey(name: 'runtimeType') + final String $type; + + @override + String toString() { + return 'UserModel.v2(id: $id, username: $username, displayName: $displayName)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$UserModelV2 && + (identical(other.id, id) || other.id == id) && + (identical(other.username, username) || + other.username == username) && + (identical(other.displayName, displayName) || + other.displayName == displayName)); + } + + @JsonKey(ignore: true) + @override + int get hashCode => Object.hash(runtimeType, id, username, displayName); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$UserModelV2CopyWith<_$UserModelV2> get copyWith => + __$$UserModelV2CopyWithImpl<_$UserModelV2>(this, _$identity); + + @override + @optionalTypeArgs + TResult when({ + required TResult Function( + @HiveField(0) int id, + @HiveField(1) String username, + @HiveField(2) String email, + @HiveField(3) String? firstName, + @HiveField(4) String? lastName, + @HiveField(5) DateTime? dateJoined, + @HiveField(6) bool isStaff, + @HiveField(7) bool isActive, + @HiveField(8) bool isSuperuser, + @HiveField(9) List groups, + @HiveField(10) List userPermissions, + @HiveField(11) List inheritedPermissions) + v3, + required TResult Function(@HiveField(0) @JsonKey(name: "user_id") int id, + @HiveField(1) String username, @HiveField(2) String? displayName) + v2, + }) { + return v2(id, username, displayName); + } + + @override + @optionalTypeArgs + TResult? whenOrNull({ + TResult? Function( + @HiveField(0) int id, + @HiveField(1) String username, + @HiveField(2) String email, + @HiveField(3) String? firstName, + @HiveField(4) String? lastName, + @HiveField(5) DateTime? dateJoined, + @HiveField(6) bool isStaff, + @HiveField(7) bool isActive, + @HiveField(8) bool isSuperuser, + @HiveField(9) List groups, + @HiveField(10) List userPermissions, + @HiveField(11) List inheritedPermissions)? + v3, + TResult? Function(@HiveField(0) @JsonKey(name: "user_id") int id, + @HiveField(1) String username, @HiveField(2) String? displayName)? + v2, + }) { + return v2?.call(id, username, displayName); + } + + @override + @optionalTypeArgs + TResult maybeWhen({ + TResult Function( + @HiveField(0) int id, + @HiveField(1) String username, + @HiveField(2) String email, + @HiveField(3) String? firstName, + @HiveField(4) String? lastName, + @HiveField(5) DateTime? dateJoined, + @HiveField(6) bool isStaff, + @HiveField(7) bool isActive, + @HiveField(8) bool isSuperuser, + @HiveField(9) List groups, + @HiveField(10) List userPermissions, + @HiveField(11) List inheritedPermissions)? + v3, + TResult Function(@HiveField(0) @JsonKey(name: "user_id") int id, + @HiveField(1) String username, @HiveField(2) String? displayName)? + v2, + required TResult orElse(), + }) { + if (v2 != null) { + return v2(id, username, displayName); + } + return orElse(); + } + + @override + @optionalTypeArgs + TResult map({ + required TResult Function(UserModelV3 value) v3, + required TResult Function(UserModelV2 value) v2, + }) { + return v2(this); + } + + @override + @optionalTypeArgs + TResult? mapOrNull({ + TResult? Function(UserModelV3 value)? v3, + TResult? Function(UserModelV2 value)? v2, + }) { + return v2?.call(this); + } + + @override + @optionalTypeArgs + TResult maybeMap({ + TResult Function(UserModelV3 value)? v3, + TResult Function(UserModelV2 value)? v2, + required TResult orElse(), + }) { + if (v2 != null) { + return v2(this); + } + return orElse(); + } + + @override + Map toJson() { + return _$$UserModelV2ToJson( + this, + ); + } +} + +abstract class UserModelV2 extends UserModel { + const factory UserModelV2( + {@HiveField(0) @JsonKey(name: "user_id") required final int id, + @HiveField(1) required final String username, + @HiveField(2) final String? displayName}) = _$UserModelV2; + const UserModelV2._() : super._(); + + factory UserModelV2.fromJson(Map json) = + _$UserModelV2.fromJson; + + @override + @HiveField(0) + @JsonKey(name: "user_id") + int get id; + @override + @HiveField(1) + String get username; + @HiveField(2) + String? get displayName; + @override + @JsonKey(ignore: true) + _$$UserModelV2CopyWith<_$UserModelV2> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/packages/paperless_api/lib/src/modules/modules.dart b/packages/paperless_api/lib/src/modules/modules.dart index 8f98dd6..18ac2e2 100644 --- a/packages/paperless_api/lib/src/modules/modules.dart +++ b/packages/paperless_api/lib/src/modules/modules.dart @@ -11,3 +11,7 @@ export 'server_stats_api/paperless_server_stats_api.dart'; export 'server_stats_api/paperless_server_stats_api_impl.dart'; export 'tasks_api/paperless_tasks_api.dart'; export 'tasks_api/paperless_tasks_api_impl.dart'; +export 'user_api/paperless_user_api.dart'; +export 'user_api/paperless_user_api_v2_impl.dart'; +export 'user_api/paperless_user_api_v3.dart'; +export 'user_api/paperless_user_api_v3_impl.dart'; diff --git a/packages/paperless_api/lib/src/modules/user_api/paperless_user_api.dart b/packages/paperless_api/lib/src/modules/user_api/paperless_user_api.dart new file mode 100644 index 0000000..d6cbae2 --- /dev/null +++ b/packages/paperless_api/lib/src/modules/user_api/paperless_user_api.dart @@ -0,0 +1,6 @@ +import 'package:paperless_api/paperless_api.dart'; + +abstract class PaperlessUserApi { + Future findCurrentUserId(); + Future find(int id); +} diff --git a/packages/paperless_api/lib/src/modules/user_api/paperless_user_api_v2_impl.dart b/packages/paperless_api/lib/src/modules/user_api/paperless_user_api_v2_impl.dart new file mode 100644 index 0000000..2e63ba5 --- /dev/null +++ b/packages/paperless_api/lib/src/modules/user_api/paperless_user_api_v2_impl.dart @@ -0,0 +1,27 @@ +import 'package:dio/dio.dart'; +import 'package:paperless_api/paperless_api.dart'; +import 'package:paperless_api/src/modules/user_api/paperless_user_api.dart'; + +class PaperlessUserApiV2Impl implements PaperlessUserApi { + final Dio client; + + PaperlessUserApiV2Impl(this.client); + + @override + Future findCurrentUserId() async { + final response = await client.get("/api/ui_settings/"); + if (response.statusCode == 200) { + return response.data['user']['id']; + } + throw const PaperlessServerException.unknown(); + } + + @override + Future find(int id) async { + final response = await client.get("/api/ui_settings/"); + if (response.statusCode == 200) { + return UserModelV2.fromJson(response.data); + } + throw const PaperlessServerException.unknown(); + } +} diff --git a/packages/paperless_api/lib/src/modules/user_api/paperless_user_api_v3.dart b/packages/paperless_api/lib/src/modules/user_api/paperless_user_api_v3.dart new file mode 100644 index 0000000..3f8447f --- /dev/null +++ b/packages/paperless_api/lib/src/modules/user_api/paperless_user_api_v3.dart @@ -0,0 +1,10 @@ +import 'package:paperless_api/src/models/user_model.dart'; + +abstract class PaperlessUserApiV3 { + Future> findWhere({ + String startsWith, + String endsWith, + String contains, + String username, + }); +} diff --git a/packages/paperless_api/lib/src/modules/user_api/paperless_user_api_v3_impl.dart b/packages/paperless_api/lib/src/modules/user_api/paperless_user_api_v3_impl.dart new file mode 100644 index 0000000..a3ce6ff --- /dev/null +++ b/packages/paperless_api/lib/src/modules/user_api/paperless_user_api_v3_impl.dart @@ -0,0 +1,50 @@ +import 'package:dio/dio.dart'; +import 'package:paperless_api/paperless_api.dart'; +import 'package:paperless_api/src/modules/user_api/paperless_user_api.dart'; +import 'package:paperless_api/src/modules/user_api/paperless_user_api_v3.dart'; + +class PaperlessUserApiV3Impl implements PaperlessUserApi, PaperlessUserApiV3 { + final Dio dio; + + PaperlessUserApiV3Impl(this.dio); + + @override + Future find(int id) async { + final response = await dio.get("/api/users/$id/"); + if (response.statusCode == 200) { + return UserModelV3.fromJson(response.data); + } + throw const PaperlessServerException.unknown(); + } + + @override + Future> findWhere({ + String startsWith = '', + String endsWith = '', + String contains = '', + String username = '', + }) async { + final response = await dio.get("/api/users/", queryParameters: { + "username__istartswith": startsWith, + "username__iendswith": endsWith, + "username__icontains": contains, + "username__iexact": username, + }); + if (response.statusCode == 200) { + return PagedSearchResult.fromJson( + response.data, + UserModelV3.fromJson as UserModel Function(Object?), + ).results; + } + throw const PaperlessServerException.unknown(); + } + + @override + Future findCurrentUserId() async { + final response = await dio.get("/api/ui_settings/"); + if (response.statusCode == 200) { + return response.data['user_id']; + } + throw const PaperlessServerException.unknown(); + } +}