Skip to content

Commit 9c8c74b

Browse files
committed
fix(filestore): minimize api calls per login
1 parent 08110e7 commit 9c8c74b

File tree

2 files changed

+81
-91
lines changed

2 files changed

+81
-91
lines changed

users/filestore.py

+78-78
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,94 @@ def get_filestore_token(user_login, host, verify):
9292
return r_userlogin.text, r_userlogin.status_code
9393

9494

95-
def add_filestore_auth(user: User):
96-
""" Uses the filebrowser api to add the user.username's filebrowser account and return their auth jwt.
95+
def login_filestore_user(user: User):
96+
""" Uses the filebrowser api to login the user.username's filebrowser account and return their auth jwt.
97+
Handles multiple situations: valid login, add new filebrowser user, update from django password reset.
9798
9899
Args:
99100
user (User): The User model this action is for.
100101
101102
Returns:
102103
fs_user_token (string): Updated filebrowser api jwt for user.username.
103104
"""
105+
106+
fs_user_token = None
104107
if not user.is_authenticated:
105108
return None
106-
verify, host = get_rest_host()
107-
# get auth for setting new user
108-
admin_login = get_admin_login()
109-
admin_token, status = get_filestore_token(admin_login, host, verify)
110-
if not admin_token:
109+
# try user auth
110+
fs_user_token, status = use_filestore_auth(user)
111+
if status == 403:
112+
# unable to login, new user or old?
113+
if user.username == os.environ["STORE_ADMIN_USERNAME"]:
114+
return None # root admin not allowed to alter scope or other properties of itself
115+
verify, host = get_rest_host()
116+
admin_login = get_admin_login()
117+
admin_token, status = get_filestore_token(admin_login, host, verify)
118+
if not admin_token:
119+
return None
120+
fs_user_json = get_filestore_user_json(user, host, verify, admin_token)
121+
if fs_user_json:
122+
# if django allauth pass updated by oauth, update pass
123+
fs_user_token = set_filestore_pass(user, host, verify, admin_token, fs_user_json)
124+
elif not fs_user_token:
125+
# otherwise user needs to be added
126+
fs_user_token = add_filestore_auth(user, host, verify, admin_token)
127+
128+
return fs_user_token
129+
130+
131+
def get_filestore_user_json(user: User, host, verify, admin_token):
132+
# find user, they may not have a valid password, loop through all
133+
try:
134+
r_users = requests.get(f"https://{host}/storemng/api/users",
135+
headers={"X-Auth": admin_token}, verify=verify, timeout=FS_API_TIMEOUT)
136+
r_users.raise_for_status()
137+
except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError) as err:
138+
print(err)
139+
return None
140+
for r_user in json.loads(r_users.text):
141+
if r_user["username"] == user.username:
142+
return r_user
143+
144+
return None
145+
146+
147+
def set_filestore_pass(user: User, host, verify, admin_token, fs_user_json):
148+
""" Uses the filebrowser api to reset the user.username's filebrowser account password and return their auth jwt.
149+
150+
Args:
151+
user (User): The User model this action is for.
152+
153+
Returns:
154+
fs_user_token (string): Updated filebrowser api jwt for user.username.
155+
"""
156+
fs_user_json["password"] = user.password
157+
fs_user = {
158+
"what": "user",
159+
"which": ["all"],
160+
"data": fs_user_json,
161+
}
162+
try:
163+
r_useradd = requests.put(f"https://{host}/storemng/api/users/{fs_user_json['id']}",
164+
data=json.dumps(fs_user), headers={"X-Auth": admin_token}, verify=verify, timeout=FS_API_TIMEOUT)
165+
r_useradd.raise_for_status()
166+
except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError) as err:
167+
print(err)
111168
return None
169+
170+
fs_user_token, status = use_filestore_auth(user)
171+
return fs_user_token
172+
173+
174+
def add_filestore_auth(user: User, host, verify, admin_token):
175+
""" Uses the filebrowser api to add the user.username's filebrowser account and return their auth jwt.
176+
177+
Args:
178+
user (User): The User model this action is for.
179+
180+
Returns:
181+
fs_user_token (string): Updated filebrowser api jwt for user.username.
182+
"""
112183
# get user defaults from global settings
113184
try:
114185
r_gset = requests.get(f"https://{host}/storemng/api/settings",
@@ -198,77 +269,6 @@ def set_filestore_scope(user: User):
198269
return fs_user_token
199270

200271

201-
def set_filestore_pass(user: User):
202-
""" Uses the filebrowser api to reset the user.username's filebrowser account password and return their auth jwt.
203-
204-
Args:
205-
user (User): The User model this action is for.
206-
207-
Returns:
208-
fs_user_token (string): Updated filebrowser api jwt for user.username.
209-
"""
210-
if not user.is_authenticated:
211-
return None
212-
if user.username == os.environ["STORE_ADMIN_USERNAME"]:
213-
return None # root admin not allowed pass renew
214-
verify, host = get_rest_host()
215-
# get auth for removing user
216-
admin_login = get_admin_login()
217-
admin_token, status = get_filestore_token(admin_login, host, verify)
218-
if not admin_token:
219-
return None
220-
# find user without valid pass, loop through all
221-
edit_user = {}
222-
try:
223-
r_users = requests.get(f"https://{host}/storemng/api/users",
224-
headers={"X-Auth": admin_token}, verify=verify, timeout=FS_API_TIMEOUT)
225-
r_users.raise_for_status()
226-
except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError) as err:
227-
print(err)
228-
return False
229-
for r_user in json.loads(r_users.text):
230-
if r_user["username"] == user.username:
231-
edit_user = r_user
232-
break
233-
print(edit_user)
234-
# return False
235-
edit_user["password"] = user.password
236-
fs_user = {
237-
"what": "user",
238-
"which": ["all"],
239-
"data": edit_user,
240-
}
241-
try:
242-
r_useradd = requests.put(f"https://{host}/storemng/api/users/{edit_user['id']}",
243-
data=json.dumps(fs_user), headers={"X-Auth": admin_token}, verify=verify, timeout=FS_API_TIMEOUT)
244-
r_useradd.raise_for_status()
245-
except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError) as err:
246-
print(err)
247-
return None
248-
249-
fs_user_token, status = use_filestore_auth(user)
250-
return fs_user_token
251-
252-
253-
def is_filestore_user(user: User):
254-
verify, host = get_rest_host()
255-
admin_login = get_admin_login()
256-
admin_token, status = get_filestore_token(admin_login, host, verify)
257-
# find user, loop through all
258-
try:
259-
r_users = requests.get(f"https://{host}/storemng/api/users",
260-
headers={"X-Auth": admin_token}, verify=verify, timeout=FS_API_TIMEOUT)
261-
r_users.raise_for_status()
262-
except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError) as err:
263-
print(err)
264-
return False
265-
for r_user in json.loads(r_users.text):
266-
if r_user["username"] == user.username:
267-
return True
268-
269-
return False
270-
271-
272272
def delete_filestore_user(user: User):
273273
""" Uses the filebrowser api to delete the user.username's filebrowser account and files.
274274

users/views.py

+3-13
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@
2424
from rest_framework.parsers import JSONParser
2525
from rest_framework.schemas import AutoSchema
2626

27-
from .filestore import (add_filestore_auth, delete_filestore_user,
28-
is_filestore_user, set_filestore_pass,
29-
set_filestore_scope, use_filestore_auth)
27+
from .filestore import (delete_filestore_user, login_filestore_user,
28+
set_filestore_scope)
3029
from .forms import (DeviceForm, SceneForm, SocialSignupForm, UpdateDeviceForm,
3130
UpdateSceneForm, UpdateStaffForm)
3231
from .models import Device, Scene
@@ -611,16 +610,7 @@ def storelogin(request):
611610
except (ValueError, SocialAccount.DoesNotExist) as err:
612611
return JsonResponse({"error": err}, status=status.HTTP_403_FORBIDDEN)
613612

614-
fs_user_token = None
615-
if user.is_authenticated:
616-
# try user auth
617-
if is_filestore_user(user):
618-
fs_user_token, status = use_filestore_auth(user)
619-
if status == 403: # if django allauth pass updated by oauth, update pass
620-
fs_user_token = set_filestore_pass(user)
621-
elif not fs_user_token:
622-
# otherwise user needs to be added
623-
fs_user_token = add_filestore_auth(user)
613+
fs_user_token = login_filestore_user(user)
624614

625615
response = HttpResponse()
626616
if fs_user_token:

0 commit comments

Comments
 (0)