django-agent-studio 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ """
2
+ Django Agent Studio - Visual agent builder and management interface.
3
+
4
+ A Django app that provides a two-pane interface for building and testing
5
+ custom GPT-like agents. Uses agent-frontend for the chat interfaces and
6
+ integrates with django_agent_runtime for agent execution.
7
+ """
8
+
9
+ __version__ = "0.1.0"
10
+
11
+ default_app_config = "django_agent_studio.apps.DjangoAgentStudioConfig"
12
+
@@ -0,0 +1,4 @@
1
+ """
2
+ API module for django_agent_studio.
3
+ """
4
+
@@ -0,0 +1,160 @@
1
+ """
2
+ DRF Permission classes for Dynamic Tool access control.
3
+
4
+ These permissions integrate with the DynamicToolPermissionService
5
+ to enforce access levels on API endpoints.
6
+ """
7
+
8
+ from rest_framework import permissions
9
+ from rest_framework.request import Request
10
+ from rest_framework.views import APIView
11
+
12
+ from django_agent_studio.services.permissions import get_permission_service
13
+
14
+
15
+ class BaseDynamicToolPermission(permissions.BasePermission):
16
+ """
17
+ Base class for dynamic tool permissions.
18
+
19
+ Subclasses should set `required_level` to the minimum access level needed.
20
+ """
21
+
22
+ required_level: str = None
23
+ message = "You do not have permission to perform this action."
24
+
25
+ def has_permission(self, request: Request, view: APIView) -> bool:
26
+ if not request.user or not request.user.is_authenticated:
27
+ return False
28
+
29
+ # Get agent from view kwargs if available
30
+ agent = self._get_agent(request, view)
31
+
32
+ service = get_permission_service()
33
+ return service.has_level(request.user, self.required_level, agent)
34
+
35
+ def _get_agent(self, request: Request, view: APIView):
36
+ """Try to get the agent from the view."""
37
+ from django_agent_runtime.models import AgentDefinition
38
+
39
+ agent_id = view.kwargs.get('agent_id') or view.kwargs.get('pk')
40
+ if agent_id:
41
+ try:
42
+ return AgentDefinition.objects.get(id=agent_id)
43
+ except AgentDefinition.DoesNotExist:
44
+ return None
45
+ return None
46
+
47
+
48
+ class CanViewDynamicTools(BaseDynamicToolPermission):
49
+ """Permission to view discovered functions and tools."""
50
+
51
+ required_level = 'viewer'
52
+ message = "You need at least Viewer access to view dynamic tools."
53
+
54
+
55
+ class CanScanProject(BaseDynamicToolPermission):
56
+ """Permission to scan project for functions."""
57
+
58
+ required_level = 'scanner'
59
+ message = "You need at least Scanner access to scan the project."
60
+
61
+
62
+ class CanRequestTool(BaseDynamicToolPermission):
63
+ """Permission to request tool creation (with approval)."""
64
+
65
+ required_level = 'requester'
66
+ message = "You need at least Requester access to request tool creation."
67
+
68
+
69
+ class CanCreateTool(BaseDynamicToolPermission):
70
+ """Permission to create tools directly without approval."""
71
+
72
+ required_level = 'creator'
73
+ message = "You need Creator access to create tools directly."
74
+
75
+
76
+ class CanApproveTool(BaseDynamicToolPermission):
77
+ """Permission to approve/reject tool requests."""
78
+
79
+ required_level = 'admin'
80
+ message = "You need Admin access to approve tool requests."
81
+
82
+
83
+ class CanManagePermissions(BaseDynamicToolPermission):
84
+ """Permission to manage other users' access levels."""
85
+
86
+ required_level = 'admin'
87
+ message = "You need Admin access to manage permissions."
88
+
89
+
90
+ class DynamicToolObjectPermission(permissions.BasePermission):
91
+ """
92
+ Object-level permission for dynamic tools.
93
+
94
+ Checks if user can modify/delete a specific tool.
95
+ """
96
+
97
+ def has_object_permission(self, request: Request, view: APIView, obj) -> bool:
98
+ if not request.user or not request.user.is_authenticated:
99
+ return False
100
+
101
+ service = get_permission_service()
102
+
103
+ # Read operations need viewer access
104
+ if request.method in permissions.SAFE_METHODS:
105
+ return service.can_view(request.user, obj.agent)
106
+
107
+ # Delete needs admin
108
+ if request.method == 'DELETE':
109
+ return service.can_delete_tool(request.user, obj)
110
+
111
+ # Modify needs creator
112
+ return service.can_modify_tool(request.user, obj)
113
+
114
+
115
+ class IsOwnerOrHasDynamicToolAccess(permissions.BasePermission):
116
+ """
117
+ Combined permission: owner of agent OR has dynamic tool access.
118
+
119
+ This allows the existing owner-based access to work alongside
120
+ the new permission system.
121
+ """
122
+
123
+ required_level: str = 'viewer'
124
+
125
+ def has_permission(self, request: Request, view: APIView) -> bool:
126
+ if not request.user or not request.user.is_authenticated:
127
+ return False
128
+
129
+ # Superusers always have access
130
+ if request.user.is_superuser:
131
+ return True
132
+
133
+ # Check if user owns the agent
134
+ from django_agent_runtime.models import AgentDefinition
135
+
136
+ agent_id = view.kwargs.get('agent_id') or view.kwargs.get('pk')
137
+ if agent_id:
138
+ try:
139
+ agent = AgentDefinition.objects.get(id=agent_id)
140
+ if agent.owner == request.user:
141
+ return True
142
+ except AgentDefinition.DoesNotExist:
143
+ pass
144
+
145
+ # Fall back to permission service
146
+ service = get_permission_service()
147
+ agent = self._get_agent(request, view)
148
+ return service.has_level(request.user, self.required_level, agent)
149
+
150
+ def _get_agent(self, request: Request, view: APIView):
151
+ from django_agent_runtime.models import AgentDefinition
152
+
153
+ agent_id = view.kwargs.get('agent_id') or view.kwargs.get('pk')
154
+ if agent_id:
155
+ try:
156
+ return AgentDefinition.objects.get(id=agent_id)
157
+ except AgentDefinition.DoesNotExist:
158
+ return None
159
+ return None
160
+