]>
Commit | Line | Data |
---|---|---|
0e468546 TM |
1 | import 'package:built_collection/built_collection.dart'; |
2 | import 'package:built_value/built_value.dart'; | |
3 | import 'package:built_value/serializer.dart'; | |
4 | import 'package:proxmox_login_manager/proxmox_general_settings_model.dart'; | |
5 | import 'package:proxmox_login_manager/serializers.dart'; | |
6 | import 'package:shared_preferences/shared_preferences.dart'; | |
7 | import 'dart:convert'; | |
8 | import 'package:proxmox_dart_api_client/proxmox_dart_api_client.dart' | |
9 | as proxclient; | |
10 | part 'proxmox_login_model.g.dart'; | |
11 | ||
12 | abstract 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 | ||
61 | abstract 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 | ||
134 | class 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 | } |