Skip to main content

Django SAAS Framework

Project description

apt install libpango-1.0-0 libpangoft2-1.0-0 libffi-dev libxml2 libxslt1.1 pip install weasyprint

ViewSet Rule

All concrete ViewSets MUST define a base queryset.

The BaseAPIView only applies multi-tenant filters and permissions, it does not define the base queryset.

Example:

    class PessoaViewSet(BaseAPIView):
        queryset = Pessoa.objects.select_related('user', 'endereco')

Translate (Project Rule)

All text returned by the API MUST be translated using the Translate class.

Frontend applications must not translate text.

Example:

python
from django_resaas.classes.Translate import Translate

return Response({
    'alert_error': Translate.tdc(request, 'Permission denied')
}, status=403)

CoreFileMiddleware

This middleware protects access to media files.

Only requests with a valid token are allowed.

Behavior

  • Intercepts requests to MEDIA_URL
  • Validates token from querystring
  • Returns translated error messages

Example

/media/document.pdf?token=XYZ

Unauthorized response

{
  "alert_error": "Nao autorizado"
}

CoreMiddleware

Este middleware controla o acesso às rotas da API.

O acesso é permitido apenas para:

  • Frontends autorizados (FEK + FEP)
  • Endereços IP autorizados

Comportamento

  • Ignora URLs públicas definidas em settings.AUTH_URL
  • Valida headers FEK e FEP
  • Caso inválido, retorna erro traduzido via Translate

Headers esperados

FEK: Frontend Key
FEP: Frontend Password

Resposta não autorizada

{
  "code": 10001,
  "alert_error": "Não autorizado"
}

File Token Configuration

A biblioteca suporta dois tipos de token para acesso a ficheiros:

  • 🔐 Token permanente (não expira)
  • ⏱️ Token temporário (com TTL)

Settings

DJANGO_REST_AUTH = {
    'FILE_TOKEN': {
        'ENABLE_TEMPORARY': True,
        'TEMP_TTL': 300,
        'ENABLE_PERMANENT': True,
    },
    'REQUIRE_FE_CREDENTIALS': True,
    'TENANT_HEADERS': {
        'ENTIDADE': 'E',
        'SUCURSAL': 'S',
        'GRUPO': 'G',
        'TIPO_ENTIDADE': 'ET',
        'LANG': 'L',
    }
}

Email Templates

A biblioteca permite substituir os templates de email via settings.

Exemplo:

DJANGO_REST_AUTH = {
    'EMAIL_TEMPLATES': {
        'REGISTER_CONFIRM': 'emails/confirmacao.html',
        'PASSWORD_RESET': 'emails/reset.html',
        'GENERIC_RESET': 'emails/generico.html',
    }
}

E no settings.py:

TEMPLATES[0]['DIRS'] += [BASE_DIR / 'templates']

No projeto final:

project/
└── templates/
    └── emails/
        ├── meu_confirmacao.html
        ├── meu_reset.html
        └── meu_generico.html
📘 PADRÃO DE PERISSÕES  FRAMEWORK MULTI-TENANT

Este projeto implementa um sistema de permissões centralizado, multi-tenant e orientado a APIs, baseado em:

Django Permissions (auth_permission)

Groups (auth_group)

Contexto dinâmico via headers

Validação automática no BaseAPIView

Uma única query por request (alta performance)

🧱 Conceitos Fundamentais
🔹 Tipo de Entidade

Classificação da organização (ex: Clínica, Escola, Empresa).

🔹 Entidade

Organização principal (ex: Clínica ABC).

🔹 Sucursal

Unidade da entidade (ex: Filial Luanda).

🔹 Grupo

Papel do utilizador numa sucursal (ex: Admin, RH, Médico).

🔹 Utilizador

Pode pertencer a:

múltiplas Entidades

múltiplas Sucursais

múltiplos Grupos

🧭 Contexto Obrigatório (Headers)

Todo request autenticado DEVE enviar os headers abaixo:

Header	Descrição
ET	ID do Tipo de Entidade
E	ID da Entidade
S	ID da Sucursal
G	ID do Grupo
L	Idioma 

📌 Sem estes headers, o acesso é negado.

🔐 Modelo de Permissões (Padrão)

O sistema segue o padrão Django com extensão para list.

CRUD padrão
Action (DRF)	Permissão
list	list_<model>
retrieve	view_<model>
create	add_<model>
update	change_<model>
partial_update	change_<model>
destroy	delete_<model>

📌 <model> é o nome do model em minúsculas.

Exemplo (Colaborador)
list_colaborador
view_colaborador
add_colaborador
change_colaborador
delete_colaborador

⚙️ Permissões Automáticas

Após cada migrate, o sistema cria automaticamente:

list_<model>

Apenas para os apps definidos em:

settings.MY_APPS


✔️ Não  risco de duplicação
✔️ Usa get_or_create()
✔️ (codename, content_type) é único no Django

✨ Permissões Customizadas no Model

Models podem definir permissões adicionais:

class Colaborador(models.Model):
    class Meta:
        permissions = (
            ('icon', 'Menu Icon'),
            ('list_contauser', 'Can list Conta User'),
        )


Estas permissões:

são criadas pelo Django

podem ser atribuídas a grupos

podem ser usadas nas views

🧠 Verificação de Permissões

Toda a verificação acontece via:

isPermited(request=request, role=[codename])


Internamente, o sistema valida numa única query:

user  grupo

grupo  sucursal

sucursal  entidade

entidade  tipo_entidade

grupo possui a permissão solicitada

Se qualquer condição falhar  acesso negado.

🧩 BaseAPIView (Automático)

Todas as APIs devem herdar de:

ds.views.BaseAPIView

O que o BaseAPIView faz

✔️ valida permissões automaticamente

✔️ injeta contexto (entidade_id, sucursal_id, etc.)

✔️ filtra queryset por tenant

✔️ implementa soft delete

✔️ não usa decorators

🔁 Mapeamento de Permissões por Action
🔹 Mapa padrão (interno)
permission_action_map = {
    'list': 'list',
    'retrieve': 'view',
    'create': 'add',
    'update': 'change',
    'partial_update': 'change',
    'destroy': 'delete',
}

✍️ method_permission (Override por ViewSet)

Cada ViewSet pode estender ou sobrescrever permissões usando:

method_permission = {}

Prioridade
method_permission  >  permission_action_map

📌 Exemplos Práticos
✔️ ViewSet simples (CRUD padrão)
class ColaboradorViewSet(BaseAPIView):
    queryset = Colaborador.objects.all()
    serializer_class = ColaboradorSerializer


Permissões usadas automaticamente:

list_colaborador
add_colaborador
change_colaborador
delete_colaborador

✔️ Action custom (bulk_create)
class ColaboradorViewSet(BaseAPIView):
    queryset = Colaborador.objects.all()
    serializer_class = ColaboradorSerializer

    method_permission = {
        'bulk_create': 'add',
    }

    @action(detail=False, methods=['post'])
    def bulk_create(self, request):
        ...


Permissão exigida:

add_colaborador

✔️ Sobrescrever permissão de action padrão
class ColaboradorViewSet(BaseAPIView):
    method_permission = {
        'list': 'view',
    }


Agora o list exige:

view_colaborador

🚫 O que NÃO fazer

❌ Criar views sem herdar de BaseAPIView
❌ Ignorar headers de contexto
❌ Usar decorators de permissão em views
❌ Implementar lógica de tenant fora do core

⚡ Performance

✔️ 1 query por request para permissões

✔️ Usa exists() + JOIN

✔️ Sem carregar objetos em memória

✔️ Escala bem com muitos utilizadores

🏁 Conclusão

Este padrão fornece:

🔒 Segurança forte

⚡ Alta performance

🔁 Reutilização total

🧱 Arquitetura de framework

📦 Preparado para múltiplos domínios (RH, Clínica, Escola, etc.)

Se quiseres, posso:

gerar isto em Markdown final

criar um diagrama de fluxo

documentar BaseRHViewSet

criar exemplos reais do RH

É  dizer 🚀



# MetanoStack Architecture Rules

## Core Principles

1. Every model MUST inherit from BaseModel
2. Every serializer MUST inherit from BaseSerializer
3. Every viewset MUST inherit from BaseAPIView
4. No relative imports allowed
5. One class per file
6. User model must be django_resaas User
7. Multi-tenant enforced via middleware
8. No business logic inside ViewSets
9. Serializers define API contract (OpenAPI source of truth)
10. RH must support skills (Especialidades)

## Forbidden Patterns

- class X(models.Model)
- class X(ModelSerializer)
- class X(ModelViewSet)
- from . import something
- Big models.py files

## Structure Standard

module/
 ├─ models/
 ├─ serializers/
 ├─ views/
 ├─ services/
 └─ urls.py

## Enterprise Compliance

- Audit fields required
- UUID primary keys
- Soft delete via estado
- Multi-tenant aware


    INSTALLED_APPS = [
        'corsheaders',
        ...
    ]

    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.common.CommonMiddleware',
        ...
    ]

    CORS_ALLOWED_ORIGINS = [
        "http://84.247.162.222:9000",
    ]

    CORS_ALLOW_CREDENTIALS = True

    from corsheaders.defaults import default_headers
    CORS_ALLOW_HEADERS = list(default_headers) + [
        "fek",
        "fep",
    ]

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_resaas-0.0.22.tar.gz (86.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_resaas-0.0.22-py3-none-any.whl (133.2 kB view details)

Uploaded Python 3

File details

Details for the file django_resaas-0.0.22.tar.gz.

File metadata

  • Download URL: django_resaas-0.0.22.tar.gz
  • Upload date:
  • Size: 86.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for django_resaas-0.0.22.tar.gz
Algorithm Hash digest
SHA256 da9495eed154b4960a505b4cbf02db4bd0486aa9f4792ce4e56f97dbbb366b31
MD5 771437f0f608e1c56376a22c1abb723a
BLAKE2b-256 6cd2904de73308e1d8b44c092d9b76ea1bc26da3f9e5dcd15cbf2f60ea438c3a

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_resaas-0.0.22.tar.gz:

Publisher: publish_pypi.yml on metanochava/django_resaas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_resaas-0.0.22-py3-none-any.whl.

File metadata

  • Download URL: django_resaas-0.0.22-py3-none-any.whl
  • Upload date:
  • Size: 133.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for django_resaas-0.0.22-py3-none-any.whl
Algorithm Hash digest
SHA256 66e31607f58140f82074e33bb77e93cfe7a007219438f0bca5f1e2cd5d96d5d2
MD5 ea67239bd8a6c0a02b1ae7da71102f3e
BLAKE2b-256 2017114e3f10cfbfd4df2329ad821785ace1028448bf7854fd193dc3e1bda294

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_resaas-0.0.22-py3-none-any.whl:

Publisher: publish_pypi.yml on metanochava/django_resaas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page