hiddifypanel 9.0.0.dev24__py3-none-any.whl → 9.0.0.dev25__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.
- hiddifypanel/VERSION +1 -1
- hiddifypanel/VERSION.py +1 -1
- hiddifypanel/drivers/user_driver.py +2 -2
- hiddifypanel/models/admin.py +12 -0
- hiddifypanel/models/user.py +8 -0
- hiddifypanel/panel/admin/AdminstratorAdmin.py +88 -103
- hiddifypanel/panel/admin/Backup.py +2 -0
- hiddifypanel/panel/commercial/restapi/resources.py +26 -17
- hiddifypanel/panel/common.py +8 -5
- hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/en/LC_MESSAGES/messages.po +215 -434
- hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/fa/LC_MESSAGES/messages.po +227 -444
- hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/pt/LC_MESSAGES/messages.po +232 -472
- hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/ru/LC_MESSAGES/messages.po +223 -433
- hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/zh/LC_MESSAGES/messages.po +210 -424
- {hiddifypanel-9.0.0.dev24.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/METADATA +5 -5
- {hiddifypanel-9.0.0.dev24.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/RECORD +25 -25
- {hiddifypanel-9.0.0.dev24.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/LICENSE.md +0 -0
- {hiddifypanel-9.0.0.dev24.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/WHEEL +0 -0
- {hiddifypanel-9.0.0.dev24.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/entry_points.txt +0 -0
- {hiddifypanel-9.0.0.dev24.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/top_level.txt +0 -0
hiddifypanel/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
9.0.0.
|
1
|
+
9.0.0.dev25
|
hiddifypanel/VERSION.py
CHANGED
@@ -41,7 +41,7 @@ def get_enabled_users():
|
|
41
41
|
return res
|
42
42
|
|
43
43
|
|
44
|
-
def add_client(user):
|
44
|
+
def add_client(user: User):
|
45
45
|
for driver in drivers:
|
46
46
|
try:
|
47
47
|
driver.add_client(user)
|
@@ -49,7 +49,7 @@ def add_client(user):
|
|
49
49
|
hiddify.error(f'ERROR! {driver.__class__.__name__} has error {e} in add client for user={user.uuid}')
|
50
50
|
|
51
51
|
|
52
|
-
def remove_client(user):
|
52
|
+
def remove_client(user: User):
|
53
53
|
for driver in drivers:
|
54
54
|
try:
|
55
55
|
driver.remove_client(user)
|
hiddifypanel/models/admin.py
CHANGED
@@ -68,6 +68,18 @@ class AdminUser(db.Model, SerializerMixin):
|
|
68
68
|
sub_admin_ids += sub_admin.recursive_sub_admins_ids(depth-1, seen=seen)
|
69
69
|
return sub_admin_ids
|
70
70
|
|
71
|
+
def remove(model):
|
72
|
+
if model.id == 1 or model.id == g.admin.id:
|
73
|
+
raise ValidationError(_("Owner can not be deleted!"))
|
74
|
+
users=model.recursive_users_query().all()
|
75
|
+
for u in users:
|
76
|
+
u.added_by=g.admin.id
|
77
|
+
|
78
|
+
DailyUsage.query.filter(DailyUsage.admin_id.in_(model.recursive_sub_admins_ids())).update({'admin_id':g.admin.id})
|
79
|
+
AdminUser.query.filter(AdminUser.id.in_(model.recursive_sub_admins_ids())).delete()
|
80
|
+
|
81
|
+
db.session.commit()
|
82
|
+
|
71
83
|
def __str__(self):
|
72
84
|
return str(self.name)
|
73
85
|
|
hiddifypanel/models/user.py
CHANGED
@@ -178,6 +178,14 @@ class User(db.Model, SerializerMixin):
|
|
178
178
|
}
|
179
179
|
|
180
180
|
|
181
|
+
def remove(user: User, commit=True):
|
182
|
+
from hiddifypanel.drivers import user_driver
|
183
|
+
user_driver.remove_client(user)
|
184
|
+
user.delete()
|
185
|
+
if commit:
|
186
|
+
db.session.commit()
|
187
|
+
|
188
|
+
|
181
189
|
def is_user_active(u):
|
182
190
|
"""
|
183
191
|
The "is_user_active" function checks if the input user object "u" is active by verifying if their mode is not
|
@@ -7,9 +7,9 @@ from wtforms.validators import Regexp, ValidationError
|
|
7
7
|
from .adminlte import AdminLTEModelView
|
8
8
|
from flask_babelex import gettext as __
|
9
9
|
from flask_babelex import lazy_gettext as _
|
10
|
-
from hiddifypanel.panel import hiddify,cf_api
|
10
|
+
from hiddifypanel.panel import hiddify, cf_api
|
11
11
|
from flask import Markup
|
12
|
-
from flask import Flask,g,url_for
|
12
|
+
from flask import Flask, g, url_for
|
13
13
|
from flask_sqlalchemy import SQLAlchemy
|
14
14
|
from flask_admin import Admin
|
15
15
|
from flask_admin.contrib.sqla import ModelView
|
@@ -19,104 +19,106 @@ import datetime
|
|
19
19
|
from wtforms.widgets import ListWidget, CheckboxInput
|
20
20
|
from sqlalchemy.orm import backref
|
21
21
|
# Define a custom field type for the related domains
|
22
|
-
from flask_admin.form.fields import Select2TagsField,Select2Field
|
22
|
+
from flask_admin.form.fields import Select2TagsField, Select2Field
|
23
23
|
from wtforms import SelectField
|
24
24
|
|
25
|
+
|
25
26
|
class AdminModeField(SelectField):
|
26
27
|
def __init__(self, label=None, validators=None, **kwargs):
|
27
28
|
super(AdminModeField, self).__init__(label, validators, **kwargs)
|
28
|
-
if g.admin.mode in [AdminMode.agent,AdminMode.admin]:
|
29
|
-
self.choices = [
|
30
|
-
elif g.admin.mode==AdminMode.admin:
|
31
|
-
self.choices = [
|
32
|
-
elif g.admin.mode==AdminMode.super_admin:
|
33
|
-
self.choices = [(AdminMode.agent.value, 'agent'),(AdminMode.admin.value, 'Admin'),(AdminMode.super_admin.value, 'Super Admin')]
|
34
|
-
|
29
|
+
if g.admin.mode in [AdminMode.agent, AdminMode.admin]:
|
30
|
+
self.choices = [(AdminMode.agent.value, 'agent')]
|
31
|
+
elif g.admin.mode == AdminMode.admin:
|
32
|
+
self.choices = [(AdminMode.agent.value, 'agent'), (AdminMode.admin.value, 'Admin'),]
|
33
|
+
elif g.admin.mode == AdminMode.super_admin:
|
34
|
+
self.choices = [(AdminMode.agent.value, 'agent'), (AdminMode.admin.value, 'Admin'), (AdminMode.super_admin.value, 'Super Admin')]
|
35
35
|
|
36
36
|
|
37
37
|
class SubAdminsField(SelectField):
|
38
|
-
def __init__(self, label=None, validators=None
|
38
|
+
def __init__(self, label=None, validators=None, *args, **kwargs):
|
39
39
|
kwargs.pop("allow_blank")
|
40
|
-
super().__init__(label, validators
|
41
|
-
self.choices=[(admin.id,admin.name) for admin in g.admin.sub_admins]
|
42
|
-
self.choices+=[(g.admin.id,g.admin.name)]
|
40
|
+
super().__init__(label, validators, *args, **kwargs)
|
41
|
+
self.choices = [(admin.id, admin.name) for admin in g.admin.sub_admins]
|
42
|
+
self.choices += [(g.admin.id, g.admin.name)]
|
43
|
+
|
44
|
+
|
43
45
|
class AdminstratorAdmin(AdminLTEModelView):
|
44
46
|
column_hide_backrefs = False
|
45
|
-
column_list = ["name",'UserLinks','mode','can_add_admin','max_active_users','max_users','online_users','comment']
|
46
|
-
form_columns = ["name",'mode','can_add_admin','max_active_users','max_users','comment',"uuid"]
|
47
|
+
column_list = ["name", 'UserLinks', 'mode', 'can_add_admin', 'max_active_users', 'max_users', 'online_users', 'comment']
|
48
|
+
form_columns = ["name", 'mode', 'can_add_admin', 'max_active_users', 'max_users', 'comment', "uuid"]
|
47
49
|
list_template = 'model/admin_list.html'
|
48
50
|
# edit_modal = True
|
49
51
|
# form_overrides = {'work_with': Select2Field}
|
50
|
-
|
52
|
+
|
51
53
|
form_overrides = {
|
52
54
|
'mode': AdminModeField,
|
53
55
|
'parent_admin': SubAdminsField
|
54
56
|
}
|
55
57
|
column_labels = {
|
56
|
-
"Actions":_("actions"),
|
57
|
-
"UserLinks":_("user.user_links"),
|
58
|
+
"Actions": _("actions"),
|
59
|
+
"UserLinks": _("user.user_links"),
|
58
60
|
"name": _("user.name"),
|
59
|
-
"mode":_("Mode"),
|
60
|
-
"uuid":_("user.UUID"),
|
61
|
-
"comment":_("Note"),
|
62
|
-
'max_active_users':_("Max Active Users"),
|
63
|
-
'max_users':_('Max Users'),
|
64
|
-
"online_users":_("Online Users"),
|
65
|
-
'can_add_admin':_("Can add sub admin")
|
61
|
+
"mode": _("Mode"),
|
62
|
+
"uuid": _("user.UUID"),
|
63
|
+
"comment": _("Note"),
|
64
|
+
'max_active_users': _("Max Active Users"),
|
65
|
+
'max_users': _('Max Users'),
|
66
|
+
"online_users": _("Online Users"),
|
67
|
+
'can_add_admin': _("Can add sub admin")
|
66
68
|
|
67
69
|
}
|
68
70
|
form_args = {
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
'uuid': {
|
72
|
+
'validators': [Regexp(r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$', message=__("Should be a valid uuid"))]
|
73
|
+
# 'label': 'First Name',
|
74
|
+
# 'validators': [required()]
|
75
|
+
}}
|
76
|
+
|
75
77
|
column_descriptions = dict(
|
76
78
|
comment=_("Add some text that is only visible to super_admin."),
|
77
79
|
mode=_("Define the admin mode. "),
|
78
80
|
)
|
79
81
|
# create_modal = True
|
80
82
|
can_export = False
|
81
|
-
|
83
|
+
|
82
84
|
# column_list = ["domain",'sub_link_only', "mode","alias", "domain_ip", "cdn_ip"]
|
83
85
|
# column_editable_list=["domain"]
|
84
86
|
# column_filters=["domain","mode"]
|
85
|
-
|
86
|
-
|
87
|
+
|
87
88
|
column_searchable_list = ["name", "uuid"]
|
88
|
-
|
89
|
+
|
89
90
|
# form_columns=['domain','sub_link_only','alias','mode','cdn_ip','show_domains']
|
90
91
|
|
91
92
|
def _ul_formatter(view, context, model, name):
|
92
|
-
|
93
|
-
return Markup(" ".join([hiddify.get_user_link(model.uuid,d,'admin',model.name) for d in get_panel_domains()]))
|
94
|
-
|
93
|
+
|
94
|
+
return Markup(" ".join([hiddify.get_user_link(model.uuid, d, 'admin', model.name) for d in get_panel_domains()]))
|
95
|
+
|
95
96
|
@property
|
96
97
|
def can_create(self):
|
97
|
-
return g.admin.can_add_admin or g.admin.mode==AdminMode.super_admin
|
98
|
+
return g.admin.can_add_admin or g.admin.mode == AdminMode.super_admin
|
99
|
+
|
98
100
|
def _name_formatter(view, context, model, name):
|
99
|
-
proxy_path=hconfig(ConfigEnum.proxy_path)
|
100
|
-
d=get_panel_domains()[0]
|
101
|
+
proxy_path = hconfig(ConfigEnum.proxy_path)
|
102
|
+
d = get_panel_domains()[0]
|
101
103
|
if d:
|
102
|
-
link=f"<a target='_blank' href='/{proxy_path}/{model.uuid}/admin/#{model.name}'>{model.name} <i class='fa-solid fa-arrow-up-right-from-square'></i></a>"
|
104
|
+
link = f"<a target='_blank' href='/{proxy_path}/{model.uuid}/admin/#{model.name}'>{model.name} <i class='fa-solid fa-arrow-up-right-from-square'></i></a>"
|
103
105
|
if model.parent_admin:
|
104
|
-
return Markup(model.parent_admin.name +"‏‎ / ‏‎"+link)
|
106
|
+
return Markup(model.parent_admin.name + "‏‎ / ‏‎"+link)
|
105
107
|
return Markup(link)
|
106
108
|
else:
|
107
109
|
return model.name
|
108
110
|
|
109
111
|
def _online_users_formatter(view, context, model, name):
|
110
|
-
last_day=datetime.datetime.now()-datetime.timedelta(days=1)
|
111
|
-
u=model.recursive_users_query().filter(User.last_online>last_day).count()
|
112
|
-
t=model.recursive_users_query().count()
|
112
|
+
last_day = datetime.datetime.now()-datetime.timedelta(days=1)
|
113
|
+
u = model.recursive_users_query().filter(User.last_online > last_day).count()
|
114
|
+
t = model.recursive_users_query().count()
|
113
115
|
# actives=[u for u in model.recursive_users_query().all() if is_user_active(u)]
|
114
116
|
# allusers=model.recursive_users_query().count()
|
115
117
|
# onlines=[p for p in users if p.last_online and p.last_online>last_day]
|
116
118
|
# return Markup(f"<a class='btn btn-xs btn-default' href='{url_for('flask.user.index_view',admin_id=model.id)}'> {_('Online')}: {onlines}</a>")
|
117
|
-
rate=round(u*100/(t+0.000001))
|
118
|
-
state= "danger" if u>=t else ('warning' if
|
119
|
-
color= "#ff7e7e" if u>=t else ('#ffc107' if
|
119
|
+
rate = round(u*100/(t+0.000001))
|
120
|
+
state = "danger" if u >= t else ('warning' if rate > 80 else 'success')
|
121
|
+
color = "#ff7e7e" if u >= t else ('#ffc107' if rate > 80 else '#9ee150')
|
120
122
|
return Markup(f"""
|
121
123
|
<div class="progress progress-lg position-relative" style="min-width: 100px;">
|
122
124
|
<div class="progress-bar progress-bar-striped" role="progressbar" style="width: {rate}%;background-color: {color};" aria-valuenow="{rate}" aria-valuemin="0" aria-valuemax="100"></div>
|
@@ -124,14 +126,15 @@ class AdminstratorAdmin(AdminLTEModelView):
|
|
124
126
|
|
125
127
|
</div>
|
126
128
|
""")
|
129
|
+
|
127
130
|
def _max_users_formatter(view, context, model, name):
|
128
|
-
u=model.recursive_users_query().count()
|
129
|
-
if model.mode== AdminMode.super_admin:
|
131
|
+
u = model.recursive_users_query().count()
|
132
|
+
if model.mode == AdminMode.super_admin:
|
130
133
|
return f"{u} / ∞"
|
131
|
-
t=model.max_users
|
132
|
-
rate=round(u*100/(t+0.000001))
|
133
|
-
state= "danger" if u>=t else ('warning' if
|
134
|
-
color= "#ff7e7e" if u>=t else ('#ffc107' if
|
134
|
+
t = model.max_users
|
135
|
+
rate = round(u*100/(t+0.000001))
|
136
|
+
state = "danger" if u >= t else ('warning' if rate > 80 else 'success')
|
137
|
+
color = "#ff7e7e" if u >= t else ('#ffc107' if rate > 80 else '#9ee150')
|
135
138
|
return Markup(f"""
|
136
139
|
<div class="progress progress-lg position-relative" style="min-width: 100px;">
|
137
140
|
<div class="progress-bar progress-bar-striped" role="progressbar" style="width: {rate}%;background-color: {color};" aria-valuenow="{rate}" aria-valuemin="0" aria-valuemax="100"></div>
|
@@ -139,46 +142,45 @@ class AdminstratorAdmin(AdminLTEModelView):
|
|
139
142
|
|
140
143
|
</div>
|
141
144
|
""")
|
142
|
-
|
145
|
+
|
143
146
|
def _max_active_users_formatter(view, context, model, name):
|
144
|
-
|
145
|
-
actives=[u for u in model.recursive_users_query().all() if is_user_active(u)]
|
146
|
-
u=len(actives)
|
147
|
-
if model.mode== AdminMode.super_admin:
|
147
|
+
|
148
|
+
actives = [u for u in model.recursive_users_query().all() if is_user_active(u)]
|
149
|
+
u = len(actives)
|
150
|
+
if model.mode == AdminMode.super_admin:
|
148
151
|
return f"{u} / ∞"
|
149
|
-
t=model.max_active_users
|
150
|
-
rate=round(u*100/(t+0.000001))
|
151
|
-
state= "danger" if u>=t else ('warning' if
|
152
|
-
color= "#ff7e7e" if u>=t else ('#ffc107' if
|
152
|
+
t = model.max_active_users
|
153
|
+
rate = round(u*100/(t+0.000001))
|
154
|
+
state = "danger" if u >= t else ('warning' if rate > 80 else 'success')
|
155
|
+
color = "#ff7e7e" if u >= t else ('#ffc107' if rate > 80 else '#9ee150')
|
153
156
|
return Markup(f"""
|
154
157
|
<div class="progress progress-lg position-relative" style="min-width: 100px;">
|
155
158
|
<div class="progress-bar progress-bar-striped" role="progressbar" style="width: {rate}%;background-color: {color};" aria-valuenow="{rate}" aria-valuemin="0" aria-valuemax="100"></div>
|
156
159
|
<span class='badge position-absolute' style="left:auto;right:auto;width: 100%;font-size:1em">{u} {_('user.home.usage.from')} {t}</span>
|
157
160
|
|
158
161
|
</div>
|
159
|
-
""")
|
162
|
+
""")
|
160
163
|
|
161
164
|
column_formatters = {
|
162
165
|
'name': _name_formatter,
|
163
166
|
'online_users': _online_users_formatter,
|
164
167
|
'max_users': _max_users_formatter,
|
165
168
|
'max_active_users': _max_active_users_formatter,
|
166
|
-
'UserLinks':_ul_formatter
|
167
|
-
|
169
|
+
'UserLinks': _ul_formatter
|
170
|
+
|
168
171
|
}
|
172
|
+
|
169
173
|
def search_placeholder(self):
|
170
174
|
return f"{_('search')} {_('user.UUID')} {_('user.name')}"
|
171
175
|
|
172
|
-
|
173
176
|
# def is_accessible(self):
|
174
177
|
# return g.admin.mode==AdminMode.super_admin
|
175
178
|
|
176
|
-
|
177
179
|
def get_query(self):
|
178
|
-
|
180
|
+
# Get the base query
|
179
181
|
query = super().get_query()
|
180
182
|
|
181
|
-
admin_ids=g.admin.recursive_sub_admins_ids()
|
183
|
+
admin_ids = g.admin.recursive_sub_admins_ids()
|
182
184
|
query = query.filter(AdminUser.id.in_(admin_ids))
|
183
185
|
|
184
186
|
return query
|
@@ -188,67 +190,50 @@ class AdminstratorAdmin(AdminLTEModelView):
|
|
188
190
|
# Get the base count query
|
189
191
|
query = super().get_count_query()
|
190
192
|
|
191
|
-
admin_ids=g.admin.recursive_sub_admins_ids()
|
193
|
+
admin_ids = g.admin.recursive_sub_admins_ids()
|
192
194
|
query = query.filter(AdminUser.id.in_(admin_ids))
|
193
195
|
|
194
196
|
return query
|
195
197
|
|
196
|
-
|
197
198
|
def on_model_change(self, form, model, is_created):
|
198
|
-
|
199
|
+
|
199
200
|
# if model.id==1:
|
200
201
|
# model.parent_admin_id=0
|
201
202
|
# model.parent_admin=None
|
202
203
|
# else:
|
203
204
|
# model.parent_admin_id=1
|
204
205
|
# model.parent_admin=AdminUser.query.filter(AdminUser.id==1).first()
|
205
|
-
if model.id!=1 and model.parent_admin==None:
|
206
|
-
model.parent_admin_id=g.admin.id
|
207
|
-
model.parent_admin=g.admin
|
206
|
+
if model.id != 1 and model.parent_admin == None:
|
207
|
+
model.parent_admin_id = g.admin.id
|
208
|
+
model.parent_admin = g.admin
|
208
209
|
|
209
|
-
if g.admin.mode!=AdminMode.super_admin and model.mode==AdminMode.super_admin:
|
210
|
+
if g.admin.mode != AdminMode.super_admin and model.mode == AdminMode.super_admin:
|
210
211
|
raise ValidationError("Sub-Admin can not have more power!!!!")
|
211
|
-
if model.mode==AdminMode.agent and model.mode!=AdminMode.agent:
|
212
|
+
if model.mode == AdminMode.agent and model.mode != AdminMode.agent:
|
212
213
|
raise ValidationError("Sub-Admin can not have more power!!!!")
|
213
|
-
|
214
|
-
def on_model_delete(self, model):
|
215
|
-
if model.id==1 or model.id==g.admin.id:
|
216
|
-
raise ValidationError(_("Owner can not be deleted!"))
|
217
|
-
users=model.recursive_users_query().all()
|
218
|
-
for u in users:
|
219
|
-
u.added_by=g.admin.id
|
220
|
-
|
221
|
-
DailyUsage.query.filter(DailyUsage.admin_id.in_(model.recursive_sub_admins_ids())).update({'admin_id':g.admin.id})
|
222
|
-
AdminUser.query.filter(AdminUser.id.in_(model.recursive_sub_admins_ids())).delete()
|
223
|
-
|
224
|
-
db.session.commit()
|
225
|
-
|
226
214
|
|
215
|
+
def on_model_delete(self, model):
|
216
|
+
model.remove()
|
227
217
|
|
228
218
|
def get_query_for_parent_admin(self):
|
229
219
|
admin_user_id = self.get_pk_value()
|
230
220
|
sub_admins_ids = set(recursive_sub_admins_ids(AdminUser.query.get(admin_user_id)))
|
231
221
|
return AdminUser.query.filter(AdminUser.id.in_(sub_admins_ids)).with_entities(AdminUser.id, AdminUser.name)
|
232
222
|
|
233
|
-
|
234
223
|
def on_form_prefill(self, form, id=None):
|
235
|
-
|
236
|
-
|
237
|
-
if g.admin.mode!=AdminMode.super_admin:
|
224
|
+
|
225
|
+
if g.admin.mode != AdminMode.super_admin:
|
238
226
|
del form.mode
|
239
227
|
del form.can_add_admin
|
240
|
-
|
241
|
-
if g.admin.id==form._obj.id:
|
228
|
+
|
229
|
+
if g.admin.id == form._obj.id:
|
242
230
|
del form.max_users
|
243
231
|
del form.max_active_users
|
244
232
|
del form.comment
|
245
233
|
del form.can_add_admin
|
246
234
|
if getattr(form, 'mode'):
|
247
235
|
del form.mode
|
248
|
-
elif form._obj.mode==AdminMode.super_admin:
|
236
|
+
elif form._obj.mode == AdminMode.super_admin:
|
249
237
|
del form.max_users
|
250
238
|
del form.max_active_users
|
251
239
|
del form.can_add_admin
|
252
|
-
|
253
|
-
|
254
|
-
|
@@ -53,6 +53,8 @@ class Backup(FlaskView):
|
|
53
53
|
if restore_form.validate_on_submit():
|
54
54
|
set_hconfig(ConfigEnum.first_setup, False)
|
55
55
|
file = restore_form.restore_file.data
|
56
|
+
if isinstance(file, list):
|
57
|
+
file = file[0]
|
56
58
|
json_data = json.load(file)
|
57
59
|
|
58
60
|
hiddify.set_db_from_json(json_data,
|
@@ -16,25 +16,29 @@ from hiddifypanel.drivers import user_driver
|
|
16
16
|
class UserResource(Resource):
|
17
17
|
decorators = [hiddify.super_admin]
|
18
18
|
|
19
|
-
def get(self
|
20
|
-
uuid = request.args
|
19
|
+
def get(self):
|
20
|
+
uuid = request.args.get('uuid')
|
21
21
|
if uuid:
|
22
|
-
|
23
|
-
return jsonify(
|
22
|
+
user = user_by_uuid(uuid) or abort(404, "user not found")
|
23
|
+
return jsonify(user.to_dict())
|
24
24
|
|
25
|
-
|
26
|
-
return jsonify(
|
27
|
-
[product.to_dict() for product in products]
|
28
|
-
)
|
25
|
+
users = User.query.all() or abort(502, "WTF!")
|
26
|
+
return jsonify([user.to_dict() for user in users])
|
29
27
|
|
30
28
|
def post(self):
|
31
29
|
data = request.json
|
32
|
-
|
33
|
-
user = User.query.filter(User.uuid == data['uuid']).first() or abort(204)
|
30
|
+
uuid = data.get('uuid') or abort(422, "Parameter issue: 'uuid'")
|
34
31
|
hiddify.add_or_update_user(**data)
|
32
|
+
user = user_by_uuid(uuid) or abort(502, "unknown issue! user is not added")
|
35
33
|
user_driver.add_client(user)
|
36
34
|
hiddify.quick_apply_users()
|
35
|
+
return jsonify({'status': 200, 'msg': 'ok'})
|
37
36
|
|
37
|
+
def delete(self):
|
38
|
+
uuid = request.args.get('uuid') or abort(422, "Parameter issue: 'uuid'")
|
39
|
+
user = user_by_uuid(uuid) or abort(404, "user not found")
|
40
|
+
user.remove()
|
41
|
+
hiddify.quick_apply_users()
|
38
42
|
return jsonify({'status': 200, 'msg': 'ok'})
|
39
43
|
|
40
44
|
# start aliz dev
|
@@ -59,22 +63,27 @@ class AdminUserResource(Resource):
|
|
59
63
|
decorators = [hiddify.super_admin]
|
60
64
|
|
61
65
|
def get(self, uuid=None):
|
62
|
-
uuid = request.args
|
66
|
+
uuid = request.args.get('uuid')
|
63
67
|
if uuid:
|
64
|
-
|
65
|
-
return jsonify(
|
68
|
+
admin = get_admin_user_db(uuid) or abort(404, "user not found")
|
69
|
+
return jsonify(admin.to_dict())
|
66
70
|
|
67
|
-
|
68
|
-
return jsonify(
|
69
|
-
[product.to_dict() for product in products]
|
70
|
-
)
|
71
|
+
admins = AdminUser.query.all() or abort(502, "WTF!")
|
72
|
+
return jsonify([admin.to_dict() for admin in admins])
|
71
73
|
|
72
74
|
def post(self):
|
73
75
|
data = request.json
|
76
|
+
uuid = data.get('uuid') or abort(422, "Parameter issue: 'uuid'")
|
74
77
|
hiddify.add_or_update_admin(**data)
|
75
78
|
|
76
79
|
return jsonify({'status': 200, 'msg': 'ok'})
|
77
80
|
|
81
|
+
def delete(self):
|
82
|
+
uuid = request.args.get('uuid') or abort(422, "Parameter issue: 'uuid'")
|
83
|
+
admin = get_admin_user_db(uuid) or abort(404, "admin not found")
|
84
|
+
admin.remove()
|
85
|
+
return jsonify({'status': 200, 'msg': 'ok'})
|
86
|
+
|
78
87
|
|
79
88
|
# class DomainResource(Resource):
|
80
89
|
# def get(self,domain=None):
|
hiddifypanel/panel/common.py
CHANGED
@@ -27,11 +27,14 @@ def init_app(app):
|
|
27
27
|
# Create github issue link
|
28
28
|
issue_link = generate_github_issue_link_for_500_error(e, trace)
|
29
29
|
|
30
|
-
last_version = hiddify.get_latest_release_version('hiddifypanel')
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
last_version = hiddify.get_latest_release_version('hiddifypanel')//TODO: add dev update check
|
31
|
+
if "T" in hiddifypanel.__version__:
|
32
|
+
has_update = False
|
33
|
+
else:
|
34
|
+
has_update = "dev" not in hiddifypanel.__version__ and f'{last_version}' != hiddifypanel.__version__
|
35
|
+
return render_template('500.html', error=e, trace=trace, has_update=has_update, last_version=last_version), 500
|
36
|
+
# if e.code in [400,401,403]:
|
37
|
+
# return render_template('access-denied.html',error=e), e.code
|
35
38
|
|
36
39
|
return render_template('error.html', error=e), e.code
|
37
40
|
|
Binary file
|