]> git.proxmox.com Git - flutter/proxmox_login_manager.git/blame - lib/proxmox_login_model.dart
migrate to sound null safety
[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
a9d1ee22 69 ProxmoxProductType? get productType;
0e468546 70
a9d1ee22 71 String? get ticket;
0e468546
TM
72
73 /// The username with the corresponding realm e.g. root@pam
74 String get fullUsername => '$username@$realm';
75
79ed04db 76 bool get activeSession =>
a9d1ee22 77 ticket != null && ticket!.isNotEmpty && !ticketExpired();
1dfe0c76 78
a9d1ee22 79 String? get hostname;
1dfe0c76
TM
80
81 String get fullHostname {
a9d1ee22
TL
82 var location = origin;
83 if (location == null) {
84 return 'Unknown';
1dfe0c76 85 }
a9d1ee22
TL
86 var name = hostname;
87 if (name == null || name.isEmpty) {
88 return location.host;
1dfe0c76 89 }
a9d1ee22
TL
90 if (location.host == name) {
91 return name;
92 }
93 return '${location.host} - $hostname';
1dfe0c76
TM
94 }
95
0e468546
TM
96 ProxmoxLoginModel._();
97
a9d1ee22
TL
98 factory ProxmoxLoginModel(
99 [void Function(ProxmoxLoginModelBuilder)? updates]) = _$ProxmoxLoginModel;
0e468546 100
a9d1ee22
TL
101 Map<String, dynamic>? toJson() {
102 return serializers.serializeWith(ProxmoxLoginModel.serializer, this)
103 as Map<String, dynamic>?;
0e468546
TM
104 }
105
a9d1ee22 106 static ProxmoxLoginModel? fromJson(Map<String, dynamic> json) {
0e468546
TM
107 return serializers.deserializeWith(ProxmoxLoginModel.serializer, json);
108 }
109
110 static Serializer<ProxmoxLoginModel> get serializer =>
111 _$proxmoxLoginModelSerializer;
79ed04db
TM
112
113 bool ticketExpired() {
114 final ticketRegex = RegExp(r'(PVE|PMG)(?:QUAR)?:(?:(\S+):)?([A-Z0-9]{8})::')
a9d1ee22 115 .firstMatch(ticket!)!;
79ed04db 116 final time = DateTime.fromMillisecondsSinceEpoch(
a9d1ee22 117 int.parse(ticketRegex.group(3)!, radix: 16) * 1000);
79ed04db
TM
118 return DateTime.now().isAfter(time.add(Duration(hours: 1)));
119 }
0e468546
TM
120}
121
122class ProxmoxProductType extends EnumClass {
123 static const ProxmoxProductType pve = _$pve;
124 static const ProxmoxProductType pmg = _$pmg;
125 static const ProxmoxProductType pbs = _$pbs;
126
127 const ProxmoxProductType._(String name) : super(name);
128
129 static BuiltSet<ProxmoxProductType> get values => _$ProxmoxProductTypeValues;
130 static ProxmoxProductType valueOf(String name) =>
131 _$ProxmoxProductTypeValueOf(name);
132
133 static Serializer<ProxmoxProductType> get serializer =>
134 _$proxmoxProductTypeSerializer;
135}