]>
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 | |
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 | ||
122 | class 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 | } |