blob: 331c3a21df9803059915f533c56ab426cfd5981a [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
Mitja Nikolaus78e3a052018-09-05 12:18:35 +02007from hiccup.allauth_adapters import FP_STAFF_GROUP_NAME
Dirk Vogtc9e10ab2016-10-12 13:58:15 +02008
9
Dirk Vogt7160b5e2016-10-12 17:04:40 +020010def user_owns_uuid(user, uuid):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020011 """Determine whether a user is owning the device with the given UUID.
12
13 Args:
14 user: The user making the request.
15 uuid: The UUID of the device to be manipulated.
16
17 Returns: True if the user owns the device.
18
19 """
Dirk Vogt7160b5e2016-10-12 17:04:40 +020020 try:
21 device = Device.objects.get(user=user)
Mitja Nikolausff2d1802018-09-13 11:15:18 +020022 except (ObjectDoesNotExist, TypeError):
23 # If the device does not exist or type of the given user is not
24 # correct, False is returned.
25 return False
Mitja Nikolause1389bd2018-08-30 17:09:04 +020026 except Exception as exception: # pylint: disable=broad-except
Mitja Nikolausff2d1802018-09-13 11:15:18 +020027 # All other exceptions are logged and False is returned.
Mitja Nikolause1389bd2018-08-30 17:09:04 +020028 logging.exception(exception)
Dirk Vogt7160b5e2016-10-12 17:04:40 +020029 return False
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020030 if uuid == device.uuid:
Dirk Vogt7160b5e2016-10-12 17:04:40 +020031 return True
32 return False
33
34
35def user_is_hiccup_staff(user):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020036 """Determine whether a user is part of the Hiccup staff.
37
38 Returns true if either the user is part of the group
Mitja Nikolaus1037bb52018-11-05 10:22:22 +010039 "FairphoneSoftwareTeam".
Mitja Nikolaus6a679132018-08-30 14:35:29 +020040
41 Args:
42 user: The user making the request.
43
44 Returns: True if user is part of the Hiccup staff.
45
46 """
Mitja Nikolaus1037bb52018-11-05 10:22:22 +010047 return user.groups.filter(name=FP_STAFF_GROUP_NAME).exists()
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020048
Dirk Vogt7160b5e2016-10-12 17:04:40 +020049
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +020050class HasStatsAccess(BasePermission):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020051 """Authorization requires to be part of the Hiccup staff."""
52
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +020053 def has_permission(self, request, view):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020054 """Check if user is part of the Hiccup staff."""
Borjan Tchakalofffa134bd2018-04-09 16:16:11 +020055 return user_is_hiccup_staff(request.user)
Dirk Vogt7160b5e2016-10-12 17:04:40 +020056
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020057
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020058class HasRightsOrIsDeviceOwnerDeviceCreation(BasePermission):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020059 """Authorization requires to be part of Hiccup staff or device owner."""
60
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020061 def has_permission(self, request, view):
Mitja Nikolaus6a679132018-08-30 14:35:29 +020062 """Return true if user is part of Hiccp staff or device owner."""
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020063 if user_is_hiccup_staff(request.user):
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020064 return True
Dirk Vogt57a615d2017-05-04 22:29:54 +020065
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020066 # special case:
67 # user is the owner of a device. in this case creations are allowed.
68 # we have to check if the device with the supplied uuid indeed
69 # belongs to the user
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020070 if request.method == "POST":
71 if "uuid" not in request.data:
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020072 return False
Dirk Vogt7160b5e2016-10-12 17:04:40 +020073 return user_owns_uuid(request.user, request.data["uuid"])
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020074 return False
Mitja Nikolaus4d759da2018-08-28 15:31:29 +020075
76
77# Security requirements for swagger documentation
78SWAGGER_SECURITY_REQUIREMENTS_OAUTH = [{"Google OAuth": []}]
Mitja Nikolaus78e3a052018-09-05 12:18:35 +020079SWAGGER_SECURITY_REQUIREMENTS_DEVICE_TOKEN = [
80 {"Device token authentication": []}
81]
Mitja Nikolaus4d759da2018-08-28 15:31:29 +020082SWAGGER_SECURITY_REQUIREMENTS_ALL = (
83 SWAGGER_SECURITY_REQUIREMENTS_OAUTH
84 + SWAGGER_SECURITY_REQUIREMENTS_DEVICE_TOKEN
85)