blob: 8b10eb9e48980cbaf17a996675c38adacbf40c08 [file] [log] [blame]
Mitja Nikolaus6a679132018-08-30 14:35:29 +02001"""Authorization permission classes for accessing the API."""
Mitja Nikolause1389bd2018-08-30 17:09:04 +02002import logging
Mitja Nikolaus6a679132018-08-30 14:35:29 +02003
Mitja Nikolausff2d1802018-09-13 11:15:18 +02004from django.core.exceptions import ObjectDoesNotExist
Dirk Vogtc9e10ab2016-10-12 13:58:15 +02005from rest_framework.permissions import BasePermission
Mitja Nikolausbcaf5022018-08-30 16:40:38 +02006from crashreports.models import Device
Dirk Vogtc9e10ab2016-10-12 13:58:15 +02007
8
Dirk Vogt7160b5e2016-10-12 17:04:40 +02009def user_owns_uuid(user, uuid):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020010 """Determine whether a user is owning the device with the given UUID.
11
12 Args:
13 user: The user making the request.
14 uuid: The UUID of the device to be manipulated.
15
16 Returns: True if the user owns the device.
17
18 """
Dirk Vogt7160b5e2016-10-12 17:04:40 +020019 try:
20 device = Device.objects.get(user=user)
Mitja Nikolausff2d1802018-09-13 11:15:18 +020021 except (ObjectDoesNotExist, TypeError):
22 # If the device does not exist or type of the given user is not
23 # correct, False is returned.
24 return False
Mitja Nikolause1389bd2018-08-30 17:09:04 +020025 except Exception as exception: # pylint: disable=broad-except
Mitja Nikolausff2d1802018-09-13 11:15:18 +020026 # All other exceptions are logged and False is returned.
Mitja Nikolause1389bd2018-08-30 17:09:04 +020027 logging.exception(exception)
Dirk Vogt7160b5e2016-10-12 17:04:40 +020028 return False
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020029 if uuid == device.uuid:
Dirk Vogt7160b5e2016-10-12 17:04:40 +020030 return True
31 return False
32
33
34def user_is_hiccup_staff(user):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020035 """Determine whether a user is part of the Hiccup staff.
36
37 Returns true if either the user is part of the group
38 "FairphoneSoftwareTeam", or he/she has all permissions for manipulating
39 crashreports, heartbeats and logfiles.
40
41 Args:
42 user: The user making the request.
43
44 Returns: True if user is part of the Hiccup staff.
45
46 """
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020047 if user.groups.filter(name="FairphoneSoftwareTeam").exists():
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +020048 return True
Mitja Nikolausb4e3bec2018-08-30 17:16:21 +020049 return user.has_perms(
50 [
51 # Crashreports
52 "crashreports.add_crashreport",
53 "crashreports.change_crashreport",
54 "crashreports.del_crashreport",
55 # Heartbeats
56 "heartbeat.add_crashreport",
57 "heartbeat.change_crashreport",
58 "heartbeat.del_crashreport",
59 # Logfiles
60 "heartbeat.add_logfile",
61 "heartbeat.change_logfile",
62 "heartbeat.del_logfile",
63 ]
64 )
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020065
Dirk Vogt7160b5e2016-10-12 17:04:40 +020066
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +020067class HasStatsAccess(BasePermission):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020068 """Authorization requires to be part of the Hiccup staff."""
69
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +020070 def has_permission(self, request, view):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020071 """Check if user is part of the Hiccup staff."""
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +020072 return user_is_hiccup_staff(request.user)
Dirk Vogt7160b5e2016-10-12 17:04:40 +020073
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020074
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020075class HasRightsOrIsDeviceOwnerDeviceCreation(BasePermission):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020076 """Authorization requires to be part of Hiccup staff or device owner."""
77
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020078 def has_permission(self, request, view):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020079 """Return true if user is part of Hiccp staff or device owner."""
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020080 if user_is_hiccup_staff(request.user):
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020081 return True
Dirk Vogt57a615d2017-05-04 22:29:54 +020082
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020083 # special case:
84 # user is the owner of a device. in this case creations are allowed.
85 # we have to check if the device with the supplied uuid indeed
86 # belongs to the user
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020087 if request.method == "POST":
88 if "uuid" not in request.data:
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020089 return False
Dirk Vogt7160b5e2016-10-12 17:04:40 +020090 return user_owns_uuid(request.user, request.data["uuid"])
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020091 return False