]> git.proxmox.com Git - flutter/proxmox_login_manager.git/blame - lib/proxmox_login_model.dart
tree-wide: use super-initializer parameters where possible
[flutter/proxmox_login_manager.git] / lib / proxmox_login_model.dart
CommitLineData
0e468546
TM
1import 'package:built_collection/built_collection.dart';
2import 'package:built_value/built_value.dart';
3import 'package:built_value/serializer.dart';
4import 'package:proxmox_login_manager/proxmox_general_settings_model.dart';
5import 'package:proxmox_login_manager/serializers.dart';
6import 'package:shared_preferences/shared_preferences.dart';
7import 'dart:convert';
8import 'package:proxmox_dart_api_client/proxmox_dart_api_client.dart'
9 as proxclient;
10part 'proxmox_login_model.g.dart';
11
12abstract class ProxmoxLoginStorage
13 implements Built<ProxmoxLoginStorage, ProxmoxLoginStorageBuilder> {
a9d1ee22 14 BuiltList<ProxmoxLoginModel>? get logins;
0e468546
TM
15
16 ProxmoxLoginStorage._();
17 factory ProxmoxLoginStorage(
a9d1ee22 18 [void Function(ProxmoxLoginStorageBuilder)? updates]) =
0e468546
TM
19 _$ProxmoxLoginStorage;
20
a9d1ee22 21 Object? toJson() {
0e468546
TM
22 return serializers.serializeWith(ProxmoxLoginStorage.serializer, this);
23 }
24
a9d1ee22 25 static ProxmoxLoginStorage? fromJson(Object? json) {
0e468546
TM
26 return serializers.deserializeWith(ProxmoxLoginStorage.serializer, json);
27 }
28
29 static Serializer<ProxmoxLoginStorage> get serializer =>
30 _$proxmoxLoginStorageSerializer;
31
a9d1ee22 32 static Future<ProxmoxLoginStorage?> fromLocalStorage() async {
0e468546
TM
33 final SharedPreferences prefs = await SharedPreferences.getInstance();
34 if (prefs.containsKey('ProxmoxLoginList')) {
a9d1ee22 35 final decodedJson = json.decode(prefs.getString('ProxmoxLoginList')!);
0e468546
TM
36 return fromJson(decodedJson);
37 }
38 return ProxmoxLoginStorage();
39 }
40
41 Future<void> saveToDisk() async {
42 final SharedPreferences prefs = await SharedPreferences.getInstance();
43 prefs.setString('ProxmoxLoginList', json.encode(toJson()));
44 }
45
46 Future<proxclient.ProxmoxApiClient> recoverLatestSession() async {
a9d1ee22 47 final latestSession = logins!.singleWhere((e) => e.ticket!.isNotEmpty);
0e468546
TM
48 final settings = await ProxmoxGeneralSettingsModel.fromLocalStorage();
49 final apiClient = await proxclient.authenticate(latestSession.fullUsername,
a9d1ee22 50 latestSession.ticket!, latestSession.origin!, settings.sslValidation!);
0e468546
TM
51 return apiClient;
52 }
53
54 Future<void> invalidateAllSessions() async {
55 final invalidatedList =
a9d1ee22 56 logins!.map((e) => e.rebuild((login) => login..ticket = ''));
0e468546
TM
57 await rebuild((e) => e.logins.replace(invalidatedList)).saveToDisk();
58 }
59}
60
61abstract class ProxmoxLoginModel
62 implements Built<ProxmoxLoginModel, ProxmoxLoginModelBuilder> {
a9d1ee22 63 Uri? get origin;
0e468546 64
a9d1ee22 65 String? get username;
0e468546 66
a9d1ee22 67 String? get realm;
0e468546 68
62145778
DC
69 bool? get passwordSaved;
70
a9d1ee22 71 ProxmoxProductType? get productType;
0e468546 72
a9d1ee22 73 String? get ticket;
0e468546
TM
74
75 /// The username with the corresponding realm e.g. root@pam
76 String get fullUsername => '$username@$realm';
77
79ed04db 78 bool get activeSession =>
a9d1ee22 79 ticket != null && ticket!.isNotEmpty && !ticketExpired();
1dfe0c76 80
a9d1ee22 81 String? get hostname;
1dfe0c76
TM
82
83 String get fullHostname {
a9d1ee22
TL
84 var location = origin;
85 if (location == null) {
86 return 'Unknown';
1dfe0c76 87 }
a9d1ee22
TL
88 var name = hostname;
89 if (name == null || name.isEmpty) {
90 return location.host;
1dfe0c76 91 }
a9d1ee22
TL
92 if (location.host == name) {
93 return name;
94 }
95 return '${location.host} - $hostname';
1dfe0c76
TM
96 }
97
62145778
DC
98 String? get identifier {
99 if (origin == null) {
100 return null;
101 }
102
103 var host = origin!.host;
104 var port = origin!.port;
105 return '$username@$realm@$host:$port';
106 }
107
0e468546
TM
108 ProxmoxLoginModel._();
109
a9d1ee22
TL
110 factory ProxmoxLoginModel(
111 [void Function(ProxmoxLoginModelBuilder)? updates]) = _$ProxmoxLoginModel;
0e468546 112
a9d1ee22
TL
113 Map<String, dynamic>? toJson() {
114 return serializers.serializeWith(ProxmoxLoginModel.serializer, this)
115 as Map<String, dynamic>?;
0e468546
TM
116 }
117
a9d1ee22 118 static ProxmoxLoginModel? fromJson(Map<String, dynamic> json) {
0e468546
TM
119 return serializers.deserializeWith(ProxmoxLoginModel.serializer, json);
120 }
121
122 static Serializer<ProxmoxLoginModel> get serializer =>
123 _$proxmoxLoginModelSerializer;
79ed04db
TM
124
125 bool ticketExpired() {
126 final ticketRegex = RegExp(r'(PVE|PMG)(?:QUAR)?:(?:(\S+):)?([A-Z0-9]{8})::')
a9d1ee22 127 .firstMatch(ticket!)!;
79ed04db 128 final time = DateTime.fromMillisecondsSinceEpoch(
a9d1ee22 129 int.parse(ticketRegex.group(3)!, radix: 16) * 1000);
7c043135 130 return DateTime.now().isAfter(time.add(const Duration(hours: 1)));
79ed04db 131 }
0e468546
TM
132}
133
134class ProxmoxProductType extends EnumClass {
135 static const ProxmoxProductType pve = _$pve;
136 static const ProxmoxProductType pmg = _$pmg;
137 static const ProxmoxProductType pbs = _$pbs;
138
39597066 139 const ProxmoxProductType._(super.name);
0e468546
TM
140
141 static BuiltSet<ProxmoxProductType> get values => _$ProxmoxProductTypeValues;
142 static ProxmoxProductType valueOf(String name) =>
143 _$ProxmoxProductTypeValueOf(name);
144
145 static Serializer<ProxmoxProductType> get serializer =>
146 _$proxmoxProductTypeSerializer;
147}