hiddifypanel 9.0.0.dev23__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.
Files changed (25) hide show
  1. hiddifypanel/VERSION +1 -1
  2. hiddifypanel/VERSION.py +2 -2
  3. hiddifypanel/drivers/user_driver.py +2 -2
  4. hiddifypanel/models/admin.py +12 -0
  5. hiddifypanel/models/user.py +8 -0
  6. hiddifypanel/panel/admin/AdminstratorAdmin.py +88 -103
  7. hiddifypanel/panel/admin/Backup.py +2 -0
  8. hiddifypanel/panel/commercial/restapi/resources.py +36 -23
  9. hiddifypanel/panel/common.py +8 -5
  10. hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
  11. hiddifypanel/translations/en/LC_MESSAGES/messages.po +215 -434
  12. hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
  13. hiddifypanel/translations/fa/LC_MESSAGES/messages.po +227 -444
  14. hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
  15. hiddifypanel/translations/pt/LC_MESSAGES/messages.po +232 -472
  16. hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
  17. hiddifypanel/translations/ru/LC_MESSAGES/messages.po +223 -433
  18. hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
  19. hiddifypanel/translations/zh/LC_MESSAGES/messages.po +210 -424
  20. {hiddifypanel-9.0.0.dev23.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/METADATA +5 -5
  21. {hiddifypanel-9.0.0.dev23.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/RECORD +25 -25
  22. {hiddifypanel-9.0.0.dev23.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/LICENSE.md +0 -0
  23. {hiddifypanel-9.0.0.dev23.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/WHEEL +0 -0
  24. {hiddifypanel-9.0.0.dev23.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/entry_points.txt +0 -0
  25. {hiddifypanel-9.0.0.dev23.dist-info → hiddifypanel-9.0.0.dev25.dist-info}/top_level.txt +0 -0
hiddifypanel/VERSION CHANGED
@@ -1 +1 @@
1
- 9.0.0.dev23
1
+ 9.0.0.dev25
hiddifypanel/VERSION.py CHANGED
@@ -1,3 +1,3 @@
1
- __version__='9.0.0.dev23'
1
+ __version__='9.0.0.dev25'
2
2
  from datetime import datetime
3
- __release_date__= datetime.strptime('2023-10-30','%Y-%m-%d')
3
+ __release_date__= datetime.strptime('2023-11-02','%Y-%m-%d')
@@ -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)
@@ -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
 
@@ -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 = [ (AdminMode.agent.value, 'agent')]
30
- elif g.admin.mode==AdminMode.admin:
31
- self.choices = [ (AdminMode.agent.value, 'agent'),(AdminMode.admin.value, 'Admin'),]
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,*args, **kwargs):
38
+ def __init__(self, label=None, validators=None, *args, **kwargs):
39
39
  kwargs.pop("allow_blank")
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)]
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
- 'uuid': {
70
- '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"))]
71
- # 'label': 'First Name',
72
- # 'validators': [required()]
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 +"&rlm;&lrm; / &rlm;&lrm;"+link)
106
+ return Markup(model.parent_admin.name + "&rlm;&lrm; / &rlm;&lrm;"+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 rate>80 else 'success')
119
- color= "#ff7e7e" if u>=t else ('#ffc107' if rate>80 else '#9ee150')
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 rate>80 else 'success')
134
- color= "#ff7e7e" if u>=t else ('#ffc107' if rate>80 else '#9ee150')
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 rate>80 else 'success')
152
- color= "#ff7e7e" if u>=t else ('#ffc107' if rate>80 else '#9ee150')
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
- # Get the base query
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,
@@ -14,32 +14,38 @@ from hiddifypanel.drivers import user_driver
14
14
 
15
15
 
16
16
  class UserResource(Resource):
17
- def get(self, uuid=None):
18
- uuid = request.args['uuid'] if 'uuid' in request.args else None
17
+ decorators = [hiddify.super_admin]
18
+
19
+ def get(self):
20
+ uuid = request.args.get('uuid')
19
21
  if uuid:
20
- product = User.query.filter(User.uuid == uuid).first() or abort(204)
21
- return jsonify(product.to_dict())
22
+ user = user_by_uuid(uuid) or abort(404, "user not found")
23
+ return jsonify(user.to_dict())
22
24
 
23
- products = User.query.all() or abort(204)
24
- return jsonify(
25
- [product.to_dict() for product in products]
26
- )
25
+ users = User.query.all() or abort(502, "WTF!")
26
+ return jsonify([user.to_dict() for user in users])
27
27
 
28
28
  def post(self):
29
29
  data = request.json
30
- ### because add_client method accepts a user object not uuid the api returns 502 error.I have a possible fix for this
31
- user = User.query.filter(User.uuid == data['uuid']).first() or abort(204)
30
+ uuid = data.get('uuid') or abort(422, "Parameter issue: 'uuid'")
32
31
  hiddify.add_or_update_user(**data)
32
+ user = user_by_uuid(uuid) or abort(502, "unknown issue! user is not added")
33
33
  user_driver.add_client(user)
34
34
  hiddify.quick_apply_users()
35
+ return jsonify({'status': 200, 'msg': 'ok'})
35
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()
36
42
  return jsonify({'status': 200, 'msg': 'ok'})
37
-
38
- ### start aliz dev
39
- ### desc : it is better to have a delete method to manage users more programatically :)
43
+
44
+ # start aliz dev
45
+ # desc : it is better to have a delete method to manage users more programatically :)
40
46
  def delete(self, uuid=None):
41
47
  uuid = request.args['uuid'] if 'uuid' in request.args else None
42
- if uuid:
48
+ if uuid:
43
49
  user = User.query.filter(User.uuid == uuid).first() or abort(204)
44
50
  if user is not None:
45
51
  hiddify.remove_user(uuid)
@@ -47,30 +53,37 @@ class UserResource(Resource):
47
53
  hiddify.quick_apply_users()
48
54
  return jsonify({'status': 200, 'msg': 'ok'})
49
55
  else:
50
- return jsonify({'status': 204, 'msg': 'user not found'})
56
+ return jsonify({'status': 204, 'msg': 'user not found'})
51
57
  else:
52
58
  return jsonify({'status': 204, 'msg': 'uuid not found'})
53
- ### end aliz dev
59
+ # end aliz dev
54
60
 
55
61
 
56
62
  class AdminUserResource(Resource):
63
+ decorators = [hiddify.super_admin]
64
+
57
65
  def get(self, uuid=None):
58
- uuid = request.args['uuid'] if 'uuid' in request.args else None
66
+ uuid = request.args.get('uuid')
59
67
  if uuid:
60
- product = AdminUser.query.filter(AdminUser.uuid == uuid).first() or abort(204)
61
- return jsonify(product.to_dict())
68
+ admin = get_admin_user_db(uuid) or abort(404, "user not found")
69
+ return jsonify(admin.to_dict())
62
70
 
63
- products = AdminUser.query.all() or abort(204)
64
- return jsonify(
65
- [product.to_dict() for product in products]
66
- )
71
+ admins = AdminUser.query.all() or abort(502, "WTF!")
72
+ return jsonify([admin.to_dict() for admin in admins])
67
73
 
68
74
  def post(self):
69
75
  data = request.json
76
+ uuid = data.get('uuid') or abort(422, "Parameter issue: 'uuid'")
70
77
  hiddify.add_or_update_admin(**data)
71
78
 
72
79
  return jsonify({'status': 200, 'msg': 'ok'})
73
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
+
74
87
 
75
88
  # class DomainResource(Resource):
76
89
  # def get(self,domain=None):
@@ -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
- has_update = "T" not in hiddifypanel.__version__ and "dev" not in hiddifypanel.__version__ and f'{last_version}' != hiddifypanel.__version__
32
- return render_template('500.html', error=e, trace=trace, has_update=has_update, last_version=last_version, issue_link=issue_link), 500
33
- # if e.code in [400, 401, 403]:
34
- # return render_template('access-denied.html', error=e), e.code
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