• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Brunowar12 / TaskManagerSystem / 15166388190

21 May 2025 03:32PM UTC coverage: 92.47% (-0.3%) from 92.77%
15166388190

push

github

web-flow
Merge pull request #27 from Brunowar12/bugfix-and-pep

Bug fixes and code style cleanup

159 of 183 new or added lines in 24 files covered. (86.89%)

10 existing lines in 6 files now uncovered.

1621 of 1753 relevant lines covered (92.47%)

5.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.35
/projects/permissions.py
1
import logging
6✔
2

3
from django.conf import settings
6✔
4
from rest_framework.permissions import BasePermission
6✔
5

6
from .models import Project, ProjectMembership
6✔
7

8
logger = logging.getLogger(__name__)
6✔
9

10

11
def _get_project_from_obj(obj):
6✔
12
    """Gets a project object from any related object"""
13
    if isinstance(obj, Project):
6✔
14
        return obj
6✔
NEW
15
    return getattr(obj, "project", None)
×
16

17
def _user_is_owner(user, project):
6✔
18
    """Shortcut for project owner"""
19
    return project.owner_id == user.id
6✔
20

21
def _user_has_role(user, project, roles):
6✔
22
    """Checks if the user has one of the specified roles in the project"""
23
    return ProjectMembership.objects.filter(
6✔
24
        project=project,
25
        user=user,
26
        role__name__in=roles
27
    ).exists()
28

29
class IsProjectAdmin(BasePermission):
6✔
30
    """
31
    Permission class to check if a user is an admin of a project
32

33
    Checks if the user is the owner of the project or has an admin role
34
    """
35
    def has_permission(self, request, view) -> bool:
6✔
NEW
36
        return bool(request.user and request.user.is_authenticated)
×
37

38
    def has_object_permission(self, request, view, obj) -> bool:
6✔
39
        project = _get_project_from_obj(obj)
6✔
40
        user = request.user
6✔
41

42
        if project is None:
6✔
UNCOV
43
            return False
×
44

45
        if _user_is_owner(user, project):
6✔
46
            return True
6✔
47

48
        is_admin = _user_has_role(user, project, settings.ADMIN_ROLE_NAMES)
6✔
49

50
        if not is_admin:
6✔
51
            logger.warning(f"User {user.id} lacks admin role for project {project.id}")
6✔
52

53
        return is_admin
6✔
54

55

56
class IsProjectMinRole(BasePermission):
6✔
57
    """
58
    Permission class to check if a user has a certain role in a project
59
    """
60
    ROLE_ORDER = settings.ROLE_ORDER
6✔
61

62
    def __init__(self, min_role):
6✔
63
        if isinstance(min_role, (list, tuple)):
6✔
64
            if len(min_role) != 1:
6✔
NEW
65
                raise ValueError(f"Invalid role format: {min_role}")
×
66
            min_role = min_role[0]
6✔
67

68
        if not isinstance(min_role, str) or min_role not in self.ROLE_ORDER:
6✔
NEW
69
            raise ValueError(f"Unknown role: {min_role}")
×
70

71
        self.min_role = min_role
6✔
72

73
    def has_object_permission(self, request, view, obj) -> bool:
6✔
74
        project = _get_project_from_obj(obj)
6✔
75
        user = request.user
6✔
76

77
        if project is None:
6✔
NEW
78
            return False
×
79

80
        if _user_is_owner(user, project):
6✔
81
            return True
6✔
82

83
        try:
6✔
84
            membership = ProjectMembership.objects.select_related("role").get(
6✔
85
                project=obj, user=user
86
            )
87
        except ProjectMembership.DoesNotExist:
6✔
88
            return False
6✔
89

90
        user_rank = self.ROLE_ORDER.index(membership.role.name)
×
NEW
91
        min_rank = self.ROLE_ORDER.index(self.min_role)
×
92

NEW
93
        return user_rank >= min_rank
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc