Skip to content

Commit 3114a5e

Browse files
Merge branch 'development' into 'master'
Security patch for all API endpoint to avoid a user to interact with other's VM See merge request hosting/api!38
2 parents 42818af + 1682af1 commit 3114a5e

40 files changed

+925
-722
lines changed

.gitignore

-4
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ frontend/typings
5454
frontend/.DS_Store
5555
frontend/Thumbs.db
5656

57-
# Bakend dynamic config file
58-
59-
backend/proxmox_api/config/vm_creation_status.json
60-
*/vm_creation_status.json
6157

6258

6359
# Test db

.gitlab-ci.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ angular_code_quality:
3333
- NG_CLI_ANALYTICS=ci
3434
- npm install -g @angular/cli
3535
script:
36-
- ng lint > code_quality.txt
36+
- ng add @angular-eslint/schematics --skip-confirmation
37+
- ng lint --force > code_quality.txt
38+
- cat code_quality.txt
3739
artifacts:
3840
paths:
3941
- frontend/code_quality.txt

backend/proxmox_api/config/configuration.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,5 @@
6565
MAIN_DNS_SERVER_IP = "192.168.104.28"
6666

6767

68+
VM_CREATION_STATUS_JSON = "proxmox_api/config/vm_creation_status.json" # json file of all vm creating and there status. If an error occur during the creation, the vm is deleted and the error code is kepts until the user get it. This is a informationnal dictionnary and cannot be trust at 100%.
6869

69-
VM_CREATION_STATUS_JSON = "proxmox_api/config/vm_creation_status.json" # json file of all vm creating and there status. If an error occur during the creation, the vm is deleted and the error code is kepts until the user get it. This is a informationnal dictionnary and cannot be trust at 100%.
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"160": {"status": "creating"}, "188": {"status": "creating"}, "193": {"status": "creating"}, "194": {"status": "creating"}, "157": {"status": "creating"}, "9998": {"status": "creating"}, "9998": {"status": "created"}}
1+
{}

backend/proxmox_api/controllers/default_controller.py

+27-58
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def create_vm(body=None): # noqa: E501
8585
return {"error": "Your are not allowed to be here"}, 403
8686

8787
user_id = slugify(cas['sub'].replace('_', '-'))
88-
88+
8989
admin = False
9090
if "attributes" in cas:
9191
if "memberOf" in cas["attributes"]:
@@ -138,6 +138,8 @@ def delete_vm_id_with_error(vmid): #API endpoint to delete a VM when an error oc
138138
admin = True;
139139

140140
user_id = slugify(cas['sub'].replace('_', '-'))
141+
if not admin and dbfct.get_vm_userid(vmid) != user_id : # if not admin, we check if the user is the owner of the vm
142+
return {'error' : "Forbidden"} , 403
141143
if admin:
142144
freezeAccountState = 0
143145
else:
@@ -186,6 +188,8 @@ def delete_vm_id(vmid): # noqa: E501
186188
admin = True;
187189

188190
user_id = slugify(cas['sub'].replace('_', '-'))
191+
if not admin and dbfct.get_vm_userid(vmid) != user_id : # if not admin, we check if the user is the owner of the vm
192+
return {'error' : "Forbidden"} , 403
189193
if admin:
190194
freezeAccountState = 0
191195
else:
@@ -199,19 +203,6 @@ def delete_vm_id(vmid): # noqa: E501
199203

200204
if freezeAccountState >= 3 and not admin: # if freeze state 1 or 2 user still have access to proxmox
201205
return {"status": "cotisation expired"}, 403
202-
203-
user_id = slugify(cas['sub'].replace('_', '-'))
204-
body,statusCode = proxmox.get_freeze_state(user_id)
205-
if statusCode != 200:
206-
return body, statusCode
207-
try:
208-
freezeAccountState = int(body["freezeState"])
209-
except Exception as e:
210-
return {"error": "error while getting freeze state"}, 500
211-
212-
if freezeAccountState >= 3 and not admin: # if freeze state 1 or 2 user still have access to proxmox
213-
return {"status": "cotisation expired"}, 403
214-
215206

216207
node = proxmox.get_node_from_vm(vmid)
217208
if not node : #doesn't exist
@@ -263,45 +254,12 @@ def delete_vm_in_thread(vmid, user_id, node="", dueToError=False):
263254
node = proxmox.get_node_from_vm(vmid)
264255
if not node:
265256
return {"status": "vm not exists"}, 404
266-
if "attributes" in cas:
267-
if "memberOf" in cas["attributes"]:
268-
if is_admin(cas["attributes"]["memberOf"]):
269-
return proxmox.delete_vm(vmid, node)
270257
if vmid in map(int, proxmox.get_vm(user_id)[0]):
271258
return proxmox.delete_vm(vmid, node)
272259
else:
273260
return {"status": "error"}, 500
274261

275262

276-
################
277-
## DEPRECATED ##
278-
################
279-
# Reason : must be remplaced by the freeze state
280-
def is_cotisation_uptodate():
281-
headers = {"Authorization": connexion.request.headers["Authorization"]}
282-
status_code, cas = util.check_cas_token(headers)
283-
if status_code != 200:
284-
return {"Error": "You are UNAUTHORIZED to connect to CAS"}, 403
285-
if "attributes" in cas:
286-
if "memberOf" in cas["attributes"]:
287-
if is_admin(cas["attributes"]["memberOf"]):
288-
return {"status": "function denied for admin"}, 403
289-
290-
id = cas['attributes']['id']
291-
292-
r = requests.get("https://adh6.minet.net/api/member/" + id, headers=headers)
293-
294-
if status_code != 200:
295-
return {"Error": "You are UNAUTHORIZED to connect to adh6"}, 403
296-
297-
strdate = cas['departureDate']
298-
date = datetime.strptime(strdate, '%Y-%m-%d')
299-
if date > datetime.today():
300-
return {"uptodate": 1}, 201;
301-
else:
302-
return {"uptodate": 0}, 201;
303-
304-
305263
def get_dns(): # noqa: E501
306264
"""check if a user has signed the hosting charter
307265
@@ -463,8 +421,9 @@ def get_vm_id(vmid): # noqa: E501
463421

464422

465423
node = proxmox.get_node_from_vm(vmid)
466-
467-
if node == None and not admin: # exist in the db but not in proxmox. It's a error
424+
if not admin and dbfct.get_vm_userid(vmid) != user_id : # if not admin, we check if the user is the owner of the vm
425+
return {'error' : "Forbidden"} , 403
426+
elif node == None and not admin: # exist in the db but not in proxmox. It's a error
468427
return {"error": "VM not found in proxmox"}, 500
469428
elif node == None and admin:
470429
return {'error' : "VM no found"} , 404
@@ -571,6 +530,8 @@ def renew_ip():
571530
admin = True;
572531

573532
user_id = slugify(cas['sub'].replace('_', '-'))
533+
if not admin and dbfct.get_vm_userid(vmid) != user_id : # if not admin, we check if the user is the owner of the vm
534+
return {'error' : "Forbidden"} , 403
574535
if admin :
575536
freezeAccountState = 0 # Un admin n'a pas d'expiration de compte
576537
else :
@@ -618,6 +579,8 @@ def delete_dns_id(dnsid): # noqa: E501
618579
if is_admin(cas["attributes"]["memberOf"]):
619580
admin = True;
620581
user_id = slugify(cas['sub'].replace('_', '-'))
582+
if not admin and dbfct.get_entry_userid(dnsid) != user_id : # if not admin, we check if the user is the owner of the vm
583+
return {'error' : "Forbidden"} , 403
621584
if admin:
622585
freezeAccountState = 0
623586
else:
@@ -667,6 +630,8 @@ def get_dns_id(dnsid): # noqa: E501
667630
if is_admin(cas["attributes"]["memberOf"]):
668631
admin = True;
669632
user_id = slugify(cas['sub'].replace('_', '-'))
633+
if not admin and dbfct.get_entry_userid(dnsid) != user_id : # if not admin, we check if the user is the owner of the vm
634+
return {'error' : "Forbidden"} , 403
670635
if admin:
671636
freezeAccountState = 0
672637
else:
@@ -720,7 +685,6 @@ def patch_vm(vmid, body=None): # noqa: E501
720685
"""
721686
if connexion.request.is_json:
722687
requetsBody = VmItem.from_dict(connexion.request.get_json()) # noqa: E501
723-
724688
try:
725689
vmid = int(vmid)
726690
except:
@@ -739,6 +703,8 @@ def patch_vm(vmid, body=None): # noqa: E501
739703
admin = True
740704

741705
user_id = slugify(cas['sub'].replace('_', '-'))
706+
if not admin and dbfct.get_vm_userid(vmid) != user_id : # if not admin, we check if the user is the owner of the vm
707+
return {'error' : "Forbidden"} , 403
742708
if admin:
743709
freezeAccountState = 0
744710
else:
@@ -755,7 +721,7 @@ def patch_vm(vmid, body=None): # noqa: E501
755721

756722
user_id = slugify(cas['sub'].replace('_', '-'))
757723

758-
if vmid in map(int, proxmox.get_vm(user_id)[0]) or admin:
724+
if admin or dbfct.get_vm_userid(vmid) == user_id : # if not admin, we check if the user is the owner of the vm
759725
node = proxmox.get_node_from_vm(vmid)
760726
if not node:
761727
return {"status": "vm not exists"}, 404
@@ -865,6 +831,8 @@ def update_credentials():
865831
admin = True;
866832

867833
user_id = slugify(cas['sub'].replace('_', '-'))
834+
if not admin and dbfct.get_vm_userid(vmid) != user_id : # if not admin, we check if the user is the owner of the vm
835+
return {'error' : "Forbidden"} , 403
868836
if admin :
869837
freezeAccountState = 0 # Un admin n'a pas d'expiration de compte
870838
else :
@@ -904,7 +872,7 @@ def get_need_to_be_restored(vmid):
904872

905873
user_id = slugify(cas['sub'].replace('_', '-'))
906874
admin = False
907-
875+
908876
try:
909877
vmid = int(vmid)
910878
except:
@@ -914,7 +882,8 @@ def get_need_to_be_restored(vmid):
914882
if "memberOf" in cas["attributes"]:
915883
if is_admin(cas["attributes"]["memberOf"]): # partie admin pour renvoyer l'owner en plus
916884
admin = True
917-
885+
if not admin and dbfct.get_vm_userid(vmid) != user_id : # if not admin, we check if the user is the owner of the vm
886+
return {'error' : "Forbidden"} , 403
918887
if admin :
919888
freezeAccountState = 0 # Un admin n'a pas d'expiration de compte
920889
else :
@@ -955,14 +924,14 @@ def get_account_state(username):
955924
user_id = slugify(cas['sub'].replace('_', '-'))
956925
username = username.replace('_', '-')
957926
admin = False
958-
print(user_id, username)
959927

960928
if "attributes" in cas:
961929
if "memberOf" in cas["attributes"]:
962930
if is_admin(cas["attributes"]["memberOf"]): # partie admin pour renvoyer l'owner en plus
963931
admin = True
964-
if not admin and user_id != username:
932+
if admin and user_id == username:
933+
return {"freezeState" : "0"}, 200 # we fake it
934+
elif admin or user_id == username:
935+
return proxmox.get_freeze_state(username)
936+
else :
965937
return {"error": "You are not allowed to check this account"}, 403
966-
elif admin :
967-
return {"freezeState" : "0"}, 200
968-
return proxmox.get_freeze_state(username)

backend/proxmox_api/db/db_functions.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def get_user_list(user_id=None, searchItem = None): # filter is for the user nam
4242
else :
4343
return User.query.all()
4444

45-
45+
# Return all the VM of an user
4646
def get_vm_list(user_id=""):
4747
if user_id != "": # dans ce cas on affiche ce qui est lié à l'user
4848
if User.query.filter_by(id=user_id).first() is None:

0 commit comments

Comments
 (0)