maquinaweb-shared-auth 0.2.60__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.
- maquinaweb_shared_auth-0.2.60.dist-info/METADATA +1003 -0
- maquinaweb_shared_auth-0.2.60.dist-info/RECORD +28 -0
- maquinaweb_shared_auth-0.2.60.dist-info/WHEEL +5 -0
- maquinaweb_shared_auth-0.2.60.dist-info/top_level.txt +1 -0
- shared_auth/__init__.py +7 -0
- shared_auth/abstract_models.py +897 -0
- shared_auth/app.py +9 -0
- shared_auth/authentication.py +55 -0
- shared_auth/conf.py +33 -0
- shared_auth/decorators.py +122 -0
- shared_auth/exceptions.py +23 -0
- shared_auth/fields.py +51 -0
- shared_auth/management/__init__.py +0 -0
- shared_auth/management/commands/__init__.py +0 -0
- shared_auth/management/commands/generate_permissions.py +147 -0
- shared_auth/managers.py +344 -0
- shared_auth/middleware.py +281 -0
- shared_auth/mixins.py +475 -0
- shared_auth/models.py +191 -0
- shared_auth/permissions.py +266 -0
- shared_auth/permissions_cache.py +249 -0
- shared_auth/permissions_helpers.py +251 -0
- shared_auth/router.py +22 -0
- shared_auth/serializers.py +439 -0
- shared_auth/storage_backend.py +6 -0
- shared_auth/urls.py +8 -0
- shared_auth/utils.py +356 -0
- shared_auth/views.py +40 -0
shared_auth/mixins.py
ADDED
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Mixins para facilitar a criação de models com referências ao sistema de auth
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from django.db import models
|
|
6
|
+
from rest_framework import status, viewsets
|
|
7
|
+
from rest_framework.response import Response
|
|
8
|
+
|
|
9
|
+
from shared_auth.managers import BaseAuthManager
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class OrganizationMixin(models.Model):
|
|
13
|
+
"""
|
|
14
|
+
Mixin para models que pertencem a uma organização
|
|
15
|
+
|
|
16
|
+
Adiciona:
|
|
17
|
+
- Campo organization_id
|
|
18
|
+
- Property organization (lazy loading)
|
|
19
|
+
- Métodos úteis
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
class Rascunho(OrganizationMixin):
|
|
23
|
+
titulo = models.CharField(max_length=200)
|
|
24
|
+
|
|
25
|
+
# Uso
|
|
26
|
+
rascunho.organization # Acessa organização automaticamente
|
|
27
|
+
rascunho.organization_members # Acessa membros
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
organization_id = models.IntegerField(
|
|
31
|
+
db_index=True,
|
|
32
|
+
help_text="ID da organização no sistema de autenticação",
|
|
33
|
+
null=True,
|
|
34
|
+
default=None,
|
|
35
|
+
)
|
|
36
|
+
objects = BaseAuthManager()
|
|
37
|
+
|
|
38
|
+
class Meta:
|
|
39
|
+
abstract = True
|
|
40
|
+
indexes = [
|
|
41
|
+
models.Index(fields=["organization_id"]),
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
def prefetch_organizations(cls, queryset, request, org_ids=None):
|
|
46
|
+
if not hasattr(request, "_orgs_dict"):
|
|
47
|
+
from shared_auth.utils import get_organization_model
|
|
48
|
+
|
|
49
|
+
Organization = get_organization_model()
|
|
50
|
+
if org_ids is None:
|
|
51
|
+
org_ids = list(
|
|
52
|
+
queryset.values_list("organization_id", flat=True).distinct()
|
|
53
|
+
)
|
|
54
|
+
if not org_ids:
|
|
55
|
+
request._orgs_dict = {}
|
|
56
|
+
return queryset
|
|
57
|
+
|
|
58
|
+
orgs_qs = Organization.objects.filter(pk__in=org_ids)
|
|
59
|
+
request._orgs_dict = {org.pk: org for org in orgs_qs}
|
|
60
|
+
|
|
61
|
+
return queryset
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def organization(self):
|
|
65
|
+
if not hasattr(self, "_cached_organization"):
|
|
66
|
+
from shared_auth.utils import get_organization_model
|
|
67
|
+
|
|
68
|
+
Organization = get_organization_model()
|
|
69
|
+
self._cached_organization = Organization.objects.get_or_fail(
|
|
70
|
+
self.organization_id
|
|
71
|
+
)
|
|
72
|
+
return self._cached_organization
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def organization_members(self):
|
|
76
|
+
"""Retorna membros da organização"""
|
|
77
|
+
return self.organization.members
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def organization_users(self):
|
|
81
|
+
"""Retorna usuários da organização"""
|
|
82
|
+
return self.organization.users
|
|
83
|
+
|
|
84
|
+
def is_organization_active(self):
|
|
85
|
+
"""Verifica se a organização está ativa"""
|
|
86
|
+
return self.organization.is_active()
|
|
87
|
+
|
|
88
|
+
def get_organization_name(self):
|
|
89
|
+
"""Retorna nome da organização (safe)"""
|
|
90
|
+
try:
|
|
91
|
+
return self.organization.name
|
|
92
|
+
except Exception:
|
|
93
|
+
return None
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class UserMixin(models.Model):
|
|
97
|
+
"""
|
|
98
|
+
Mixin para models que pertencem a um usuário
|
|
99
|
+
|
|
100
|
+
Adiciona:
|
|
101
|
+
- Campo user_id
|
|
102
|
+
- Property user (lazy loading)
|
|
103
|
+
- Métodos úteis
|
|
104
|
+
|
|
105
|
+
Usage:
|
|
106
|
+
class Rascunho(UserMixin):
|
|
107
|
+
titulo = models.CharField(max_length=200)
|
|
108
|
+
|
|
109
|
+
# Uso
|
|
110
|
+
rascunho.user # Acessa usuário automaticamente
|
|
111
|
+
rascunho.user_email # Acessa email
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
user_id = models.IntegerField(
|
|
115
|
+
db_index=True,
|
|
116
|
+
help_text="ID do usuário no sistema de autenticação",
|
|
117
|
+
null=True,
|
|
118
|
+
default=None,
|
|
119
|
+
)
|
|
120
|
+
objects = BaseAuthManager()
|
|
121
|
+
|
|
122
|
+
class Meta:
|
|
123
|
+
abstract = True
|
|
124
|
+
indexes = [
|
|
125
|
+
models.Index(fields=["user_id"]),
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def user(self):
|
|
130
|
+
"""
|
|
131
|
+
Acessa usuário do banco de auth (lazy loading com cache)
|
|
132
|
+
"""
|
|
133
|
+
if not hasattr(self, "_cached_user"):
|
|
134
|
+
from shared_auth.utils import get_user_model
|
|
135
|
+
|
|
136
|
+
User = get_user_model()
|
|
137
|
+
self._cached_user = User.objects.get_or_fail(self.user_id)
|
|
138
|
+
return self._cached_user
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def user_email(self):
|
|
142
|
+
"""Retorna email do usuário (safe)"""
|
|
143
|
+
try:
|
|
144
|
+
return self.user.email
|
|
145
|
+
except Exception:
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def user_full_name(self):
|
|
150
|
+
"""Retorna nome completo do usuário (safe)"""
|
|
151
|
+
try:
|
|
152
|
+
return self.user.get_full_name()
|
|
153
|
+
except Exception:
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def user_organizations(self):
|
|
158
|
+
"""Retorna organizações do usuário"""
|
|
159
|
+
return self.user.organizations
|
|
160
|
+
|
|
161
|
+
def is_user_active(self):
|
|
162
|
+
"""Verifica se o usuário está ativo"""
|
|
163
|
+
try:
|
|
164
|
+
return self.user.is_active and self.user.deleted_at is None
|
|
165
|
+
except Exception:
|
|
166
|
+
return False
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class OrganizationUserMixin(OrganizationMixin, UserMixin):
|
|
170
|
+
"""
|
|
171
|
+
Mixin combinado para models que pertencem a organização E usuário
|
|
172
|
+
|
|
173
|
+
Adiciona tudo dos dois mixins + validações
|
|
174
|
+
|
|
175
|
+
Usage:
|
|
176
|
+
class Rascunho(OrganizationUserMixin):
|
|
177
|
+
titulo = models.CharField(max_length=200)
|
|
178
|
+
|
|
179
|
+
# Uso
|
|
180
|
+
rascunho.organization # Organização
|
|
181
|
+
rascunho.user # Usuário
|
|
182
|
+
rascunho.validate_user_belongs_to_organization() # Validação
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
class Meta:
|
|
186
|
+
abstract = True
|
|
187
|
+
indexes = [
|
|
188
|
+
models.Index(fields=["organization_id", "user_id"]),
|
|
189
|
+
]
|
|
190
|
+
|
|
191
|
+
def validate_user_belongs_to_organization(self):
|
|
192
|
+
"""
|
|
193
|
+
Valida se o usuário pertence à organização
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
bool: True se pertence, False caso contrário
|
|
197
|
+
"""
|
|
198
|
+
from shared_auth.utils import get_member_model
|
|
199
|
+
|
|
200
|
+
Member = get_member_model()
|
|
201
|
+
return Member.objects.filter(
|
|
202
|
+
user_id=self.user_id, organization_id=self.organization_id
|
|
203
|
+
).exists()
|
|
204
|
+
|
|
205
|
+
def user_can_access(self, user_id):
|
|
206
|
+
"""
|
|
207
|
+
Verifica se um usuário pode acessar este registro
|
|
208
|
+
(se pertence à mesma organização)
|
|
209
|
+
"""
|
|
210
|
+
from shared_auth.utils import get_member_model
|
|
211
|
+
|
|
212
|
+
Member = get_member_model()
|
|
213
|
+
return Member.objects.filter(
|
|
214
|
+
user_id=user_id, organization_id=self.organization_id
|
|
215
|
+
).exists()
|
|
216
|
+
|
|
217
|
+
class RequirePermissionMixin:
|
|
218
|
+
required_permission = None
|
|
219
|
+
required_permissions = None
|
|
220
|
+
base_permission = None
|
|
221
|
+
translate_action_to_perm = {
|
|
222
|
+
'list': 'view',
|
|
223
|
+
'retrieve': 'view',
|
|
224
|
+
'create': 'add',
|
|
225
|
+
'update': 'change',
|
|
226
|
+
'partial_update': 'change',
|
|
227
|
+
'destroy': 'delete',
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
def check_permissions(self, request):
|
|
231
|
+
if hasattr(super(), 'check_permissions'):
|
|
232
|
+
super().check_permissions(request)
|
|
233
|
+
|
|
234
|
+
if self.base_permission and self.action in self.translate_action_to_perm:
|
|
235
|
+
perm = f"{self.translate_action_to_perm.get(self.action)}_{self.base_permission}"
|
|
236
|
+
if not self.check_permission(perm):
|
|
237
|
+
self.permission_denied(
|
|
238
|
+
request,
|
|
239
|
+
message=f"Permissão '{perm}' necessária."
|
|
240
|
+
)
|
|
241
|
+
if self.required_permission:
|
|
242
|
+
if not self.check_permission(self.required_permission):
|
|
243
|
+
self.permission_denied(
|
|
244
|
+
request,
|
|
245
|
+
message=f"Permissão '{self.required_permission}' necessária."
|
|
246
|
+
)
|
|
247
|
+
if self.required_permissions:
|
|
248
|
+
has_any = any(
|
|
249
|
+
self.check_permission(perm)
|
|
250
|
+
for perm in self.required_permissions
|
|
251
|
+
)
|
|
252
|
+
if not has_any:
|
|
253
|
+
self.permission_denied(
|
|
254
|
+
request,
|
|
255
|
+
message=f"Uma das permissões necessárias: {', '.join(self.required_permissions)}"
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
def check_permission(self, permission_codename):
|
|
259
|
+
"""
|
|
260
|
+
Verifica se usuário tem permissão específica.
|
|
261
|
+
|
|
262
|
+
OTIMIZADO: Passa request para habilitar cache de permissões.
|
|
263
|
+
|
|
264
|
+
Args:
|
|
265
|
+
permission_codename: Código da permissão (ex: 'create_invoices')
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
bool: True se tem permissão
|
|
269
|
+
|
|
270
|
+
Usage:
|
|
271
|
+
if self.check_permission('create_invoices'):
|
|
272
|
+
# Usuário pode criar faturas
|
|
273
|
+
pass
|
|
274
|
+
"""
|
|
275
|
+
from shared_auth.permissions_helpers import user_has_permission
|
|
276
|
+
|
|
277
|
+
system_id = self.get_system_id()
|
|
278
|
+
if not system_id:
|
|
279
|
+
return False
|
|
280
|
+
|
|
281
|
+
organization_id = self.get_organization_id()
|
|
282
|
+
if not organization_id:
|
|
283
|
+
return False
|
|
284
|
+
|
|
285
|
+
user = self.get_user()
|
|
286
|
+
if not user or not user.is_authenticated:
|
|
287
|
+
return False
|
|
288
|
+
|
|
289
|
+
return user_has_permission(
|
|
290
|
+
user.id,
|
|
291
|
+
organization_id,
|
|
292
|
+
permission_codename,
|
|
293
|
+
system_id,
|
|
294
|
+
request=getattr(self, 'request', None)
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
def require_permission(self, permission_codename):
|
|
298
|
+
"""
|
|
299
|
+
Retorna erro se usuário não tiver permissão.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
permission_codename: Código da permissão
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
Response com erro 403 ou None se tem permissão
|
|
306
|
+
|
|
307
|
+
Usage:
|
|
308
|
+
response = self.require_permission('create_invoices')
|
|
309
|
+
if response:
|
|
310
|
+
return response
|
|
311
|
+
"""
|
|
312
|
+
if not self.check_permission(permission_codename):
|
|
313
|
+
return Response(
|
|
314
|
+
{"detail": f"Permissão '{permission_codename}' necessária."},
|
|
315
|
+
status=status.HTTP_403_FORBIDDEN
|
|
316
|
+
)
|
|
317
|
+
return None
|
|
318
|
+
|
|
319
|
+
def get_user_permissions(self):
|
|
320
|
+
"""
|
|
321
|
+
Lista todas as permissões do usuário no sistema atual.
|
|
322
|
+
|
|
323
|
+
Returns:
|
|
324
|
+
list[Permission]: Permissões do usuário
|
|
325
|
+
|
|
326
|
+
Usage:
|
|
327
|
+
perms = self.get_user_permissions()
|
|
328
|
+
for perm in perms:
|
|
329
|
+
print(perm.codename)
|
|
330
|
+
"""
|
|
331
|
+
from shared_auth.permissions_helpers import get_user_permissions
|
|
332
|
+
|
|
333
|
+
system_id = self.get_system_id()
|
|
334
|
+
if not system_id:
|
|
335
|
+
return []
|
|
336
|
+
|
|
337
|
+
organization_id = self.get_organization_id()
|
|
338
|
+
if not organization_id:
|
|
339
|
+
return []
|
|
340
|
+
|
|
341
|
+
user = self.get_user()
|
|
342
|
+
if not user or not user.is_authenticated:
|
|
343
|
+
return []
|
|
344
|
+
|
|
345
|
+
return get_user_permissions(
|
|
346
|
+
user.id,
|
|
347
|
+
organization_id,
|
|
348
|
+
system_id,
|
|
349
|
+
request=getattr(self, 'request', None)
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
def get_user_permission_codenames(self):
|
|
353
|
+
"""
|
|
354
|
+
Lista codenames das permissões do usuário.
|
|
355
|
+
|
|
356
|
+
Returns:
|
|
357
|
+
List[str]: Lista de codenames
|
|
358
|
+
|
|
359
|
+
Usage:
|
|
360
|
+
codenames = self.get_user_permission_codenames()
|
|
361
|
+
# ['create_invoices', 'edit_invoices']
|
|
362
|
+
"""
|
|
363
|
+
return [perm.codename for perm in self.get_user_permissions()]
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
class LoggedOrganizationPermMixin:
|
|
368
|
+
"""
|
|
369
|
+
Mixin para ViewSets que dependem de uma organização logada.
|
|
370
|
+
Integra com a lib maquinaweb-shared-auth.
|
|
371
|
+
|
|
372
|
+
NÃO use diretamente. Use LoggedOrganizationViewSet.
|
|
373
|
+
"""
|
|
374
|
+
|
|
375
|
+
def get_organization_id(self):
|
|
376
|
+
"""Obtém o ID da organização logada via maquinaweb-shared-auth"""
|
|
377
|
+
return getattr(self.request, 'organization_id', None)
|
|
378
|
+
|
|
379
|
+
def get_organization_ids(self):
|
|
380
|
+
"""Obtém os IDs das organizações permitidas via maquinaweb-shared-auth"""
|
|
381
|
+
return getattr(self.request, 'organization_ids', [])
|
|
382
|
+
|
|
383
|
+
def get_user(self):
|
|
384
|
+
"""Obtém o usuário atual autenticado"""
|
|
385
|
+
return self.request.user
|
|
386
|
+
|
|
387
|
+
def get_system_id(self):
|
|
388
|
+
"""
|
|
389
|
+
Obtém o ID do sistema.
|
|
390
|
+
|
|
391
|
+
Busca em:
|
|
392
|
+
1. Settings SYSTEM_ID
|
|
393
|
+
2. Header X-System-ID
|
|
394
|
+
"""
|
|
395
|
+
from django.conf import settings
|
|
396
|
+
|
|
397
|
+
system_id = getattr(settings, 'SYSTEM_ID', None)
|
|
398
|
+
if system_id:
|
|
399
|
+
return system_id
|
|
400
|
+
|
|
401
|
+
# Tentar pegar do header
|
|
402
|
+
header_value = self.request.headers.get('X-System-ID')
|
|
403
|
+
if header_value:
|
|
404
|
+
try:
|
|
405
|
+
return int(header_value)
|
|
406
|
+
except (ValueError, TypeError):
|
|
407
|
+
pass
|
|
408
|
+
|
|
409
|
+
return None
|
|
410
|
+
|
|
411
|
+
def check_logged_organization(self):
|
|
412
|
+
"""Verifica se há uma organização logada"""
|
|
413
|
+
return self.get_organization_id() is not None
|
|
414
|
+
|
|
415
|
+
def require_logged_organization(self):
|
|
416
|
+
"""Retorna erro se não houver organização logada"""
|
|
417
|
+
if not self.check_logged_organization():
|
|
418
|
+
return Response(
|
|
419
|
+
{
|
|
420
|
+
"detail": "Nenhuma organização logada. Defina uma organização antes de continuar."
|
|
421
|
+
},
|
|
422
|
+
status=status.HTTP_403_FORBIDDEN,
|
|
423
|
+
)
|
|
424
|
+
return None
|
|
425
|
+
|
|
426
|
+
def get_queryset(self):
|
|
427
|
+
"""Filtra os objetos pela organização logada, se aplicável"""
|
|
428
|
+
queryset = super().get_queryset()
|
|
429
|
+
|
|
430
|
+
response = self.require_logged_organization()
|
|
431
|
+
if response:
|
|
432
|
+
return queryset.none()
|
|
433
|
+
|
|
434
|
+
organization_id = self.get_organization_id()
|
|
435
|
+
if hasattr(queryset.model, "organization_id"):
|
|
436
|
+
return queryset.filter(organization_id=organization_id)
|
|
437
|
+
elif hasattr(queryset.model, "organization"):
|
|
438
|
+
return queryset.filter(organization_id=organization_id)
|
|
439
|
+
return queryset
|
|
440
|
+
|
|
441
|
+
def perform_create(self, serializer):
|
|
442
|
+
"""Define a organização automaticamente ao criar um objeto"""
|
|
443
|
+
response = self.require_logged_organization()
|
|
444
|
+
if response:
|
|
445
|
+
# CORRIGIDO: Lançar exceção em vez de retornar Response
|
|
446
|
+
from rest_framework.exceptions import PermissionDenied
|
|
447
|
+
raise PermissionDenied("Nenhuma organização logada.")
|
|
448
|
+
|
|
449
|
+
organization_id = self.get_organization_id()
|
|
450
|
+
|
|
451
|
+
if "organization" in serializer.fields:
|
|
452
|
+
serializer.save(organization_id=organization_id)
|
|
453
|
+
else:
|
|
454
|
+
serializer.save()
|
|
455
|
+
|
|
456
|
+
class LoggedOrganizationMixin(RequirePermissionMixin, LoggedOrganizationPermMixin, viewsets.ModelViewSet):
|
|
457
|
+
pass
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
class PrefetchOrganizationsMixin(LoggedOrganizationMixin):
|
|
461
|
+
def get_queryset(self):
|
|
462
|
+
queryset = super().get_queryset()
|
|
463
|
+
return OrganizationMixin.prefetch_organizations(queryset, self.request)
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
class TimestampedMixin(models.Model):
|
|
467
|
+
"""
|
|
468
|
+
Mixin para adicionar timestamps
|
|
469
|
+
"""
|
|
470
|
+
|
|
471
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
472
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
473
|
+
|
|
474
|
+
class Meta:
|
|
475
|
+
abstract = True
|
shared_auth/models.py
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Models READ-ONLY para acesso aos dados de autenticação
|
|
3
|
+
ATENÇÃO: Estes models NÃO devem ser usados para criar migrations
|
|
4
|
+
|
|
5
|
+
Para customizar estes models, herde dos models abstratos em shared_auth.abstract_models
|
|
6
|
+
e configure no settings.py. Veja a documentação em abstract_models.py
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .abstract_models import (
|
|
10
|
+
AbstractGroupOrganizationPermissions,
|
|
11
|
+
AbstractGroupPermissions,
|
|
12
|
+
AbstractMemberSystemGroup,
|
|
13
|
+
AbstractOrganizationGroup,
|
|
14
|
+
AbstractPermission,
|
|
15
|
+
AbstractPlan,
|
|
16
|
+
AbstractSharedMember,
|
|
17
|
+
AbstractSharedOrganization,
|
|
18
|
+
AbstractSharedToken,
|
|
19
|
+
AbstractSubscription,
|
|
20
|
+
AbstractSystem,
|
|
21
|
+
AbstractUser,
|
|
22
|
+
)
|
|
23
|
+
from .conf import (
|
|
24
|
+
GROUP_ORG_PERMISSIONS_TABLE,
|
|
25
|
+
GROUP_PERMISSIONS_TABLE,
|
|
26
|
+
MEMBER_SYSTEM_GROUP_TABLE,
|
|
27
|
+
ORGANIZATION_GROUP_TABLE,
|
|
28
|
+
PERMISSION_TABLE,
|
|
29
|
+
PLAN_TABLE,
|
|
30
|
+
SUBSCRIPTION_TABLE,
|
|
31
|
+
SYSTEM_TABLE,
|
|
32
|
+
)
|
|
33
|
+
from .managers import (
|
|
34
|
+
GroupOrganizationPermissionsManager,
|
|
35
|
+
MemberSystemGroupManager,
|
|
36
|
+
PermissionManager,
|
|
37
|
+
SubscriptionManager,
|
|
38
|
+
SystemManager,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class SharedToken(AbstractSharedToken):
|
|
43
|
+
"""
|
|
44
|
+
Model READ-ONLY padrão da tabela authtoken_token
|
|
45
|
+
|
|
46
|
+
Para customizar, crie seu próprio model herdando de AbstractSharedToken
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
class Meta(AbstractSharedToken.Meta):
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class SharedOrganization(AbstractSharedOrganization):
|
|
54
|
+
"""
|
|
55
|
+
Model READ-ONLY padrão da tabela organization
|
|
56
|
+
|
|
57
|
+
Para customizar, crie seu próprio model herdando de AbstractSharedOrganization
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
class Meta(AbstractSharedOrganization.Meta):
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class User(AbstractUser):
|
|
65
|
+
"""
|
|
66
|
+
Model READ-ONLY padrão da tabela auth_user
|
|
67
|
+
|
|
68
|
+
Para customizar, crie seu próprio model herdando de AbstractUser
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
class Meta(AbstractUser.Meta):
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class SharedMember(AbstractSharedMember):
|
|
76
|
+
"""
|
|
77
|
+
Model READ-ONLY padrão da tabela organization_member
|
|
78
|
+
|
|
79
|
+
Para customizar, crie seu próprio model herdando de AbstractSharedMember
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
class Meta(AbstractSharedMember.Meta):
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class OrganizationGroup(AbstractOrganizationGroup):
|
|
87
|
+
"""
|
|
88
|
+
Model READ-ONLY padrão da tabela organization_organizationgroup
|
|
89
|
+
Representa um grupo de organizações com assinatura compartilhada
|
|
90
|
+
|
|
91
|
+
Para customizar, crie seu próprio model herdando de AbstractOrganizationGroup
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
class Meta(AbstractOrganizationGroup.Meta):
|
|
95
|
+
db_table = ORGANIZATION_GROUP_TABLE
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class System(AbstractSystem):
|
|
100
|
+
"""
|
|
101
|
+
Model READ-ONLY padrão da tabela plans_system
|
|
102
|
+
Representa um sistema externo que usa este serviço de autenticação
|
|
103
|
+
|
|
104
|
+
Para customizar, crie seu próprio model herdando de AbstractSystem
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
objects = SystemManager()
|
|
108
|
+
|
|
109
|
+
class Meta(AbstractSystem.Meta):
|
|
110
|
+
db_table = SYSTEM_TABLE
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class Permission(AbstractPermission):
|
|
114
|
+
"""
|
|
115
|
+
Model READ-ONLY padrão da tabela organization_permissions
|
|
116
|
+
Define permissões específicas de cada sistema
|
|
117
|
+
|
|
118
|
+
Para customizar, crie seu próprio model herdando de AbstractPermission
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
objects = PermissionManager()
|
|
122
|
+
|
|
123
|
+
class Meta(AbstractPermission.Meta):
|
|
124
|
+
db_table = PERMISSION_TABLE
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class GroupPermissions(AbstractGroupPermissions):
|
|
128
|
+
"""
|
|
129
|
+
Model READ-ONLY padrão da tabela organization_grouppermissions
|
|
130
|
+
Grupos base de permissões (usados nos planos)
|
|
131
|
+
|
|
132
|
+
Para customizar, crie seu próprio model herdando de AbstractGroupPermissions
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
class Meta(AbstractGroupPermissions.Meta):
|
|
136
|
+
db_table = GROUP_PERMISSIONS_TABLE
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class Plan(AbstractPlan):
|
|
140
|
+
"""
|
|
141
|
+
Model READ-ONLY padrão da tabela plans_plan
|
|
142
|
+
Planos oferecidos por cada sistema, com conjunto de permissões
|
|
143
|
+
|
|
144
|
+
Para customizar, crie seu próprio model herdando de AbstractPlan
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
class Meta(AbstractPlan.Meta):
|
|
148
|
+
db_table = PLAN_TABLE
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class Subscription(AbstractSubscription):
|
|
152
|
+
"""
|
|
153
|
+
Model READ-ONLY padrão da tabela plans_subscription
|
|
154
|
+
Assinatura de uma organização a um plano
|
|
155
|
+
|
|
156
|
+
Para customizar, crie seu próprio model herdando de AbstractSubscription
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
objects = SubscriptionManager()
|
|
160
|
+
|
|
161
|
+
class Meta(AbstractSubscription.Meta):
|
|
162
|
+
db_table = SUBSCRIPTION_TABLE
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class GroupOrganizationPermissions(AbstractGroupOrganizationPermissions):
|
|
166
|
+
"""
|
|
167
|
+
Model READ-ONLY padrão da tabela organization_grouporganizationpermissions
|
|
168
|
+
Grupos de permissões criados pela organização para distribuir aos usuários
|
|
169
|
+
|
|
170
|
+
Para customizar, crie seu próprio model herdando de AbstractGroupOrganizationPermissions
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
objects = GroupOrganizationPermissionsManager()
|
|
174
|
+
|
|
175
|
+
class Meta(AbstractGroupOrganizationPermissions.Meta):
|
|
176
|
+
db_table = GROUP_ORG_PERMISSIONS_TABLE
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class MemberSystemGroup(AbstractMemberSystemGroup):
|
|
180
|
+
"""
|
|
181
|
+
Model READ-ONLY padrão da tabela organization_membersystemgroup
|
|
182
|
+
Relaciona um membro a um grupo de permissões em um sistema específico
|
|
183
|
+
|
|
184
|
+
Para customizar, crie seu próprio model herdando de AbstractMemberSystemGroup
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
objects = MemberSystemGroupManager()
|
|
188
|
+
|
|
189
|
+
class Meta(AbstractMemberSystemGroup.Meta):
|
|
190
|
+
db_table = MEMBER_SYSTEM_GROUP_TABLE
|
|
191
|
+
|