mc5-api-client 1.0.15__py3-none-any.whl → 1.0.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mc5_api_client/__init__.py +107 -2
- mc5_api_client/account.py +352 -0
- mc5_api_client/account_quick.py +246 -0
- mc5_api_client/alerts.py +336 -0
- mc5_api_client/alerts_quick.py +210 -0
- mc5_api_client/cli.py +1 -1
- mc5_api_client/client.py +875 -34
- mc5_api_client/debug.py +259 -0
- mc5_api_client/federation.py +257 -0
- mc5_api_client/federation_quick.py +198 -0
- mc5_api_client/platform.py +109 -0
- mc5_api_client/simple_client.py +563 -19
- mc5_api_client/squad_battle.py +439 -0
- mc5_api_client/squad_battle_quick.py +223 -0
- mc5_api_client/telemetry.py +344 -0
- mc5_api_client/transfer.py +348 -0
- mc5_api_client/transfer_quick.py +280 -0
- {mc5_api_client-1.0.15.dist-info → mc5_api_client-1.0.17.dist-info}/METADATA +581 -7
- mc5_api_client-1.0.17.dist-info/RECORD +28 -0
- mc5_api_client-1.0.15.dist-info/RECORD +0 -15
- {mc5_api_client-1.0.15.dist-info → mc5_api_client-1.0.17.dist-info}/WHEEL +0 -0
- {mc5_api_client-1.0.15.dist-info → mc5_api_client-1.0.17.dist-info}/entry_points.txt +0 -0
- {mc5_api_client-1.0.15.dist-info → mc5_api_client-1.0.17.dist-info}/licenses/LICENSE +0 -0
- {mc5_api_client-1.0.15.dist-info → mc5_api_client-1.0.17.dist-info}/top_level.txt +0 -0
mc5_api_client/__init__.py
CHANGED
|
@@ -15,18 +15,73 @@ messaging, and more.
|
|
|
15
15
|
|
|
16
16
|
from typing import Optional, Dict, Any
|
|
17
17
|
|
|
18
|
-
__version__ = "1.0.
|
|
18
|
+
__version__ = "1.0.16"
|
|
19
19
|
__author__ = "Chizoba"
|
|
20
20
|
__email__ = "chizoba2026@hotmail.com"
|
|
21
21
|
__license__ = "MIT"
|
|
22
22
|
|
|
23
|
+
from .telemetry import telemetry, report_error, report_usage, is_telemetry_enabled
|
|
24
|
+
from .debug import debug_mode, debug_print, debug_function, analyze_error, print_error_analysis
|
|
25
|
+
from .platform import Platform, get_platform_config, get_android_anonymous_credential, get_pc_anonymous_credential
|
|
26
|
+
from .squad_battle import SquadBattleMixin
|
|
27
|
+
from .transfer_quick import (
|
|
28
|
+
quick_generate_transfer_code,
|
|
29
|
+
quick_check_transfer_status,
|
|
30
|
+
quick_get_device_linking_guide,
|
|
31
|
+
quick_link_device_workflow,
|
|
32
|
+
quick_validate_transfer_code,
|
|
33
|
+
quick_force_new_code,
|
|
34
|
+
quick_transfer_status_summary
|
|
35
|
+
)
|
|
36
|
+
from .account_quick import (
|
|
37
|
+
quick_get_account_info,
|
|
38
|
+
quick_get_device_history,
|
|
39
|
+
quick_get_credential_summary,
|
|
40
|
+
quick_analyze_account_security,
|
|
41
|
+
quick_get_account_overview,
|
|
42
|
+
quick_export_account_data
|
|
43
|
+
)
|
|
44
|
+
from .alerts_quick import (
|
|
45
|
+
quick_start_alert_stream,
|
|
46
|
+
quick_test_alert_connection,
|
|
47
|
+
quick_start_alerts_with_discord,
|
|
48
|
+
quick_monitor_alerts,
|
|
49
|
+
create_alert_callback
|
|
50
|
+
)
|
|
51
|
+
from .federation_quick import (
|
|
52
|
+
quick_get_active_sessions,
|
|
53
|
+
quick_get_my_sessions,
|
|
54
|
+
quick_get_session_statistics,
|
|
55
|
+
quick_check_session_status,
|
|
56
|
+
quick_get_server_type_sessions,
|
|
57
|
+
quick_analyze_session_activity
|
|
58
|
+
)
|
|
59
|
+
from .squad_battle_quick import (
|
|
60
|
+
quick_create_squad_battle_room,
|
|
61
|
+
quick_post_squad_battle_result,
|
|
62
|
+
quick_get_squad_battle_history,
|
|
63
|
+
quick_analyze_squad_performance,
|
|
64
|
+
quick_get_squad_wall_messages,
|
|
65
|
+
quick_send_squad_battle_notification,
|
|
66
|
+
quick_post_squad_wall_message
|
|
67
|
+
)
|
|
23
68
|
from .simple_client import (
|
|
24
69
|
SimpleMC5Client,
|
|
25
70
|
batch_search_players,
|
|
26
71
|
clan_cleanup,
|
|
27
72
|
monitor_clan_activity,
|
|
28
73
|
quick_search,
|
|
29
|
-
quick_kick
|
|
74
|
+
quick_kick,
|
|
75
|
+
quick_remove_friend,
|
|
76
|
+
quick_send_friend_request,
|
|
77
|
+
quick_check_friend_status,
|
|
78
|
+
quick_accept_friend_request,
|
|
79
|
+
quick_sign_up_for_event,
|
|
80
|
+
quick_get_event_leaderboard,
|
|
81
|
+
quick_get_my_event_rank,
|
|
82
|
+
quick_get_squad_invitations,
|
|
83
|
+
quick_accept_squad_invitation,
|
|
84
|
+
quick_decline_squad_invitation
|
|
30
85
|
)
|
|
31
86
|
from .client import MC5Client
|
|
32
87
|
from .auth import TokenGenerator
|
|
@@ -100,6 +155,56 @@ __all__ = [
|
|
|
100
155
|
"monitor_clan_activity",
|
|
101
156
|
"quick_search",
|
|
102
157
|
"quick_kick",
|
|
158
|
+
"quick_remove_friend",
|
|
159
|
+
"quick_send_friend_request",
|
|
160
|
+
"quick_check_friend_status",
|
|
161
|
+
"quick_accept_friend_request",
|
|
162
|
+
"quick_sign_up_for_event",
|
|
163
|
+
"quick_get_event_leaderboard",
|
|
164
|
+
"quick_get_my_event_rank",
|
|
165
|
+
"quick_get_squad_invitations",
|
|
166
|
+
"quick_accept_squad_invitation",
|
|
167
|
+
"quick_decline_squad_invitation",
|
|
168
|
+
"quick_create_squad_battle_room",
|
|
169
|
+
"quick_post_squad_battle_result",
|
|
170
|
+
"quick_get_squad_battle_history",
|
|
171
|
+
"quick_analyze_squad_performance",
|
|
172
|
+
"quick_get_squad_wall_messages",
|
|
173
|
+
"quick_send_squad_battle_notification",
|
|
174
|
+
"quick_post_squad_wall_message",
|
|
175
|
+
"quick_get_active_sessions",
|
|
176
|
+
"quick_get_my_sessions",
|
|
177
|
+
"quick_get_session_statistics",
|
|
178
|
+
"quick_check_session_status",
|
|
179
|
+
"quick_get_server_type_sessions",
|
|
180
|
+
"quick_analyze_session_activity",
|
|
181
|
+
"quick_start_alert_stream",
|
|
182
|
+
"quick_test_alert_connection",
|
|
183
|
+
"quick_start_alerts_with_discord",
|
|
184
|
+
"quick_monitor_alerts",
|
|
185
|
+
"create_alert_callback",
|
|
186
|
+
"quick_get_account_info",
|
|
187
|
+
"quick_get_device_history",
|
|
188
|
+
"quick_get_credential_summary",
|
|
189
|
+
"quick_analyze_account_security",
|
|
190
|
+
"quick_get_account_overview",
|
|
191
|
+
"quick_export_account_data",
|
|
192
|
+
"quick_generate_transfer_code",
|
|
193
|
+
"quick_check_transfer_status",
|
|
194
|
+
"quick_get_device_linking_guide",
|
|
195
|
+
"quick_link_device_workflow",
|
|
196
|
+
"quick_validate_transfer_code",
|
|
197
|
+
"quick_force_new_code",
|
|
198
|
+
"quick_transfer_status_summary",
|
|
199
|
+
"telemetry",
|
|
200
|
+
"report_error",
|
|
201
|
+
"report_usage",
|
|
202
|
+
"is_telemetry_enabled",
|
|
203
|
+
"debug_mode",
|
|
204
|
+
"debug_print",
|
|
205
|
+
"debug_function",
|
|
206
|
+
"analyze_error",
|
|
207
|
+
"print_error_analysis",
|
|
103
208
|
"create_admin_client",
|
|
104
209
|
"create_user_client",
|
|
105
210
|
"quick_add_squad_rating",
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# ────────────[ CHIZOBA ]────────────────────────────
|
|
3
|
+
# | Email : chizoba2026@hotmail.com
|
|
4
|
+
# | File : account.py
|
|
5
|
+
# | License | MIT License © 2026 Chizoba
|
|
6
|
+
# | Brief | User account management and analytics
|
|
7
|
+
# ────────────────★─────────────────────────────────
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from typing import Optional, Dict, Any, List
|
|
11
|
+
from .telemetry import report_error, report_usage
|
|
12
|
+
from .debug import debug_function, debug_print
|
|
13
|
+
|
|
14
|
+
class AccountMixin:
|
|
15
|
+
"""Mixin class for user account management and analytics."""
|
|
16
|
+
|
|
17
|
+
@debug_function
|
|
18
|
+
def get_account_info(self) -> Dict[str, Any]:
|
|
19
|
+
"""
|
|
20
|
+
Get comprehensive user account information.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
Complete account data including credentials, installations, and device history
|
|
24
|
+
"""
|
|
25
|
+
try:
|
|
26
|
+
url = f"{self.BASE_URLS['janus']}/users/me"
|
|
27
|
+
|
|
28
|
+
params = {
|
|
29
|
+
"access_token": self._token_data["access_token"]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
debug_print("👤 Getting comprehensive account information", "info")
|
|
33
|
+
result = self._make_request("GET", url, params=params)
|
|
34
|
+
|
|
35
|
+
if result:
|
|
36
|
+
# Analyze account data
|
|
37
|
+
account_analysis = self._analyze_account_data(result)
|
|
38
|
+
|
|
39
|
+
debug_print(f"✅ Account info retrieved: {len(result.get('credentials', []))} credentials, {len(result.get('installations', []))} installations", "success")
|
|
40
|
+
|
|
41
|
+
report_usage("get_account_info", True, 0, {
|
|
42
|
+
"credentials_count": len(result.get('credentials', [])),
|
|
43
|
+
"installations_count": len(result.get('installations', [])),
|
|
44
|
+
"has_alias": bool(result.get('alias')),
|
|
45
|
+
"is_ghost": result.get('is_ghost', False)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
"account_data": result,
|
|
50
|
+
"analysis": account_analysis
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return {"account_data": {}, "analysis": {}}
|
|
54
|
+
|
|
55
|
+
except Exception as e:
|
|
56
|
+
debug_print(f"❌ Failed to get account info: {e}", "error")
|
|
57
|
+
report_error(e, "get_account_info", {})
|
|
58
|
+
raise
|
|
59
|
+
|
|
60
|
+
def _analyze_account_data(self, account_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
61
|
+
"""
|
|
62
|
+
Analyze account data for insights.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
account_data: Raw account data from API
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Analysis results and statistics
|
|
69
|
+
"""
|
|
70
|
+
try:
|
|
71
|
+
credentials = account_data.get("credentials", [])
|
|
72
|
+
installations = account_data.get("installations", [])
|
|
73
|
+
alias = account_data.get("alias", [])
|
|
74
|
+
|
|
75
|
+
# Analyze credentials
|
|
76
|
+
credential_analysis = self._analyze_credentials(credentials)
|
|
77
|
+
|
|
78
|
+
# Analyze installations
|
|
79
|
+
installation_analysis = self._analyze_installations(installations)
|
|
80
|
+
|
|
81
|
+
# Analyze account security
|
|
82
|
+
security_analysis = self._analyze_security(account_data)
|
|
83
|
+
|
|
84
|
+
analysis = {
|
|
85
|
+
"credentials": credential_analysis,
|
|
86
|
+
"installations": installation_analysis,
|
|
87
|
+
"security": security_analysis,
|
|
88
|
+
"account_summary": {
|
|
89
|
+
"account_id": account_data.get("account"),
|
|
90
|
+
"total_credentials": len(credentials),
|
|
91
|
+
"total_installations": len(installations),
|
|
92
|
+
"has_alias": bool(alias),
|
|
93
|
+
"alias_count": len(alias),
|
|
94
|
+
"is_ghost": account_data.get("is_ghost", False),
|
|
95
|
+
"last_login": account_data.get("last_login")
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return analysis
|
|
100
|
+
|
|
101
|
+
except Exception as e:
|
|
102
|
+
debug_print(f"❌ Failed to analyze account data: {e}", "error")
|
|
103
|
+
return {}
|
|
104
|
+
|
|
105
|
+
def _analyze_credentials(self, credentials: List[str]) -> Dict[str, Any]:
|
|
106
|
+
"""
|
|
107
|
+
Analyze user credentials.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
credentials: List of credential strings
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
Credential analysis
|
|
114
|
+
"""
|
|
115
|
+
try:
|
|
116
|
+
# Count credential types
|
|
117
|
+
credential_types = {}
|
|
118
|
+
microsoft_count = 0
|
|
119
|
+
anonymous_count = 0
|
|
120
|
+
|
|
121
|
+
for cred in credentials:
|
|
122
|
+
if ":" in cred:
|
|
123
|
+
cred_type = cred.split(":")[0]
|
|
124
|
+
credential_types[cred_type] = credential_types.get(cred_type, 0) + 1
|
|
125
|
+
|
|
126
|
+
if cred_type == "microsoftgraph":
|
|
127
|
+
microsoft_count += 1
|
|
128
|
+
elif cred_type == "anonymous":
|
|
129
|
+
anonymous_count += 1
|
|
130
|
+
|
|
131
|
+
# Extract unique anonymous IDs
|
|
132
|
+
anonymous_ids = []
|
|
133
|
+
for cred in credentials:
|
|
134
|
+
if cred.startswith("anonymous:"):
|
|
135
|
+
anon_id = cred.split(":")[1]
|
|
136
|
+
if anon_id not in anonymous_ids:
|
|
137
|
+
anonymous_ids.append(anon_id)
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
"total_credentials": len(credentials),
|
|
141
|
+
"credential_types": credential_types,
|
|
142
|
+
"microsoft_credentials": microsoft_count,
|
|
143
|
+
"anonymous_credentials": anonymous_count,
|
|
144
|
+
"unique_anonymous_ids": len(anonymous_ids),
|
|
145
|
+
"latest_anonymous_id": anonymous_ids[-1] if anonymous_ids else None
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
except Exception as e:
|
|
149
|
+
debug_print(f"❌ Failed to analyze credentials: {e}", "error")
|
|
150
|
+
return {"total_credentials": len(credentials)}
|
|
151
|
+
|
|
152
|
+
def _analyze_installations(self, installations: List[Dict[str, Any]]) -> Dict[str, Any]:
|
|
153
|
+
"""
|
|
154
|
+
Analyze device installations.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
installations: List of installation data
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
Installation analysis
|
|
161
|
+
"""
|
|
162
|
+
try:
|
|
163
|
+
# Count by model
|
|
164
|
+
models = {}
|
|
165
|
+
countries = {}
|
|
166
|
+
languages = {}
|
|
167
|
+
resolutions = {}
|
|
168
|
+
firmware_versions = {}
|
|
169
|
+
|
|
170
|
+
valid_installations = 0
|
|
171
|
+
|
|
172
|
+
for install in installations:
|
|
173
|
+
if install.get("model"): # Only count valid installations
|
|
174
|
+
valid_installations += 1
|
|
175
|
+
|
|
176
|
+
model = install.get("model", "Unknown")
|
|
177
|
+
models[model] = models.get(model, 0) + 1
|
|
178
|
+
|
|
179
|
+
country = install.get("country", "Unknown")
|
|
180
|
+
countries[country] = countries.get(country, 0) + 1
|
|
181
|
+
|
|
182
|
+
language = install.get("language", "Unknown")
|
|
183
|
+
languages[language] = languages.get(language, 0) + 1
|
|
184
|
+
|
|
185
|
+
resolution = install.get("resolution", "Unknown")
|
|
186
|
+
resolutions[resolution] = resolutions.get(resolution, 0) + 1
|
|
187
|
+
|
|
188
|
+
firmware = install.get("firmware", "Unknown")
|
|
189
|
+
firmware_versions[firmware] = firmware_versions.get(firmware, 0) + 1
|
|
190
|
+
|
|
191
|
+
# Find most common values
|
|
192
|
+
most_common_model = max(models.items(), key=lambda x: x[1]) if models else ("Unknown", 0)
|
|
193
|
+
most_common_country = max(countries.items(), key=lambda x: x[1]) if countries else ("Unknown", 0)
|
|
194
|
+
most_common_language = max(languages.items(), key=lambda x: x[1]) if languages else ("Unknown", 0)
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
"total_installations": len(installations),
|
|
198
|
+
"valid_installations": valid_installations,
|
|
199
|
+
"device_models": models,
|
|
200
|
+
"countries": countries,
|
|
201
|
+
"languages": languages,
|
|
202
|
+
"resolutions": resolutions,
|
|
203
|
+
"firmware_versions": firmware_versions,
|
|
204
|
+
"most_common_model": most_common_model[0],
|
|
205
|
+
"most_common_model_count": most_common_model[1],
|
|
206
|
+
"most_common_country": most_common_country[0],
|
|
207
|
+
"most_common_language": most_common_language[0]
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
except Exception as e:
|
|
211
|
+
debug_print(f"❌ Failed to analyze installations: {e}", "error")
|
|
212
|
+
return {"total_installations": len(installations)}
|
|
213
|
+
|
|
214
|
+
def _analyze_security(self, account_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
215
|
+
"""
|
|
216
|
+
Analyze account security.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
account_data: Account data
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
Security analysis
|
|
223
|
+
"""
|
|
224
|
+
try:
|
|
225
|
+
credentials = account_data.get("credentials", [])
|
|
226
|
+
installations = account_data.get("installations", [])
|
|
227
|
+
|
|
228
|
+
# Security metrics
|
|
229
|
+
security_score = 100
|
|
230
|
+
security_issues = []
|
|
231
|
+
|
|
232
|
+
# Check for multiple anonymous credentials
|
|
233
|
+
anonymous_count = sum(1 for cred in credentials if cred.startswith("anonymous:"))
|
|
234
|
+
if anonymous_count > 10:
|
|
235
|
+
security_score -= 10
|
|
236
|
+
security_issues.append(f"High number of anonymous credentials: {anonymous_count}")
|
|
237
|
+
|
|
238
|
+
# Check for installations from many countries
|
|
239
|
+
countries = set()
|
|
240
|
+
for install in installations:
|
|
241
|
+
if install.get("country"):
|
|
242
|
+
countries.add(install["country"])
|
|
243
|
+
|
|
244
|
+
if len(countries) > 5:
|
|
245
|
+
security_score -= 15
|
|
246
|
+
security_issues.append(f"Installations from many countries: {len(countries)}")
|
|
247
|
+
|
|
248
|
+
# Check for ghost account
|
|
249
|
+
if account_data.get("is_ghost", False):
|
|
250
|
+
security_score -= 20
|
|
251
|
+
security_issues.append("Account is marked as ghost")
|
|
252
|
+
|
|
253
|
+
# Check for no recent login
|
|
254
|
+
last_login = account_data.get("last_login")
|
|
255
|
+
if not last_login:
|
|
256
|
+
security_score -= 5
|
|
257
|
+
security_issues.append("No recent login recorded")
|
|
258
|
+
|
|
259
|
+
return {
|
|
260
|
+
"security_score": max(0, security_score),
|
|
261
|
+
"security_issues": security_issues,
|
|
262
|
+
"risk_level": "Low" if security_score >= 80 else "Medium" if security_score >= 60 else "High",
|
|
263
|
+
"unique_countries": len(countries),
|
|
264
|
+
"anonymous_credential_count": anonymous_count
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
except Exception as e:
|
|
268
|
+
debug_print(f"❌ Failed to analyze security: {e}", "error")
|
|
269
|
+
return {"security_score": 0, "risk_level": "Unknown"}
|
|
270
|
+
|
|
271
|
+
@debug_function
|
|
272
|
+
def get_device_history(self) -> Dict[str, Any]:
|
|
273
|
+
"""
|
|
274
|
+
Get device installation history.
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
Device history with timeline analysis
|
|
278
|
+
"""
|
|
279
|
+
try:
|
|
280
|
+
account_data = self.get_account_info()
|
|
281
|
+
installations = account_data.get("account_data", {}).get("installations", [])
|
|
282
|
+
|
|
283
|
+
# Sort by device_id to create timeline
|
|
284
|
+
device_timeline = []
|
|
285
|
+
seen_devices = set()
|
|
286
|
+
|
|
287
|
+
for install in installations:
|
|
288
|
+
device_id = install.get("device_id")
|
|
289
|
+
if device_id and device_id not in seen_devices:
|
|
290
|
+
seen_devices.add(device_id)
|
|
291
|
+
device_timeline.append({
|
|
292
|
+
"device_id": device_id,
|
|
293
|
+
"model": install.get("model"),
|
|
294
|
+
"country": install.get("country"),
|
|
295
|
+
"language": install.get("language"),
|
|
296
|
+
"resolution": install.get("resolution"),
|
|
297
|
+
"firmware": install.get("firmware")
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
debug_print(f"📱 Device history: {len(device_timeline)} unique devices", "success")
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
"device_timeline": device_timeline,
|
|
304
|
+
"total_unique_devices": len(device_timeline),
|
|
305
|
+
"device_summary": {
|
|
306
|
+
"most_recent_device": device_timeline[-1] if device_timeline else None,
|
|
307
|
+
"device_countries": list(set(d.get("country", "Unknown") for d in device_timeline if d.get("country")))
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
except Exception as e:
|
|
312
|
+
debug_print(f"❌ Failed to get device history: {e}", "error")
|
|
313
|
+
report_error(e, "get_device_history", {})
|
|
314
|
+
raise
|
|
315
|
+
|
|
316
|
+
@debug_function
|
|
317
|
+
def get_credential_summary(self) -> Dict[str, Any]:
|
|
318
|
+
"""
|
|
319
|
+
Get credential summary and analysis.
|
|
320
|
+
|
|
321
|
+
Returns:
|
|
322
|
+
Credential summary with security analysis
|
|
323
|
+
"""
|
|
324
|
+
try:
|
|
325
|
+
account_data = self.get_account_info()
|
|
326
|
+
credentials = account_data.get("account_data", {}).get("credentials", [])
|
|
327
|
+
|
|
328
|
+
# Extract credential details
|
|
329
|
+
credential_details = []
|
|
330
|
+
for i, cred in enumerate(credentials):
|
|
331
|
+
if ":" in cred:
|
|
332
|
+
cred_type, cred_value = cred.split(":", 1)
|
|
333
|
+
credential_details.append({
|
|
334
|
+
"index": i,
|
|
335
|
+
"type": cred_type,
|
|
336
|
+
"value": cred_value[:20] + "..." if len(cred_value) > 20 else cred_value,
|
|
337
|
+
"full_value": cred
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
debug_print(f"🔐 Credential summary: {len(credentials)} credentials analyzed", "success")
|
|
341
|
+
|
|
342
|
+
return {
|
|
343
|
+
"credential_count": len(credentials),
|
|
344
|
+
"credential_details": credential_details,
|
|
345
|
+
"credential_types": list(set(d["type"] for d in credential_details)),
|
|
346
|
+
"latest_credential": credential_details[-1] if credential_details else None
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
except Exception as e:
|
|
350
|
+
debug_print(f"❌ Failed to get credential summary: {e}", "error")
|
|
351
|
+
report_error(e, "get_credential_summary", {})
|
|
352
|
+
raise
|