Skip to main content

QuantumLock™ Guia de Integração

Como Integrar Licenciamento Quântico no Seu Software

Este guia completo mostra como proteger seu software com licenças QuantumLock™.


📋 Índice

  1. Visão Geral
  2. Fluxo de Licenciamento
  3. Modelos de Integração
  4. Integração Backend (SaaS)
  5. Integração Desktop
  6. Integração API/Microservices
  7. Feature Gating
  8. Distribuição de Licenças
  9. Renovação e Expiração
  10. Segurança

Visão Geral

O QuantumLock™ oferece três modelos de integração:

ModeloCaso de UsoComponente
OnlineSaaS, APIsSDK + API
OfflineDesktop, EmbarcadosSDK + Validator
HíbridoApps conectadosSDK + Validator + API

Fluxo de Licenciamento

┌─────────────────────────────────────────────────────────────────────────────┐
│ FLUXO DE LICENCIAMENTO │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ SUA APP │────▶│ GERAR LICENÇA│────▶│ ENTREGAR AO │ │
│ │ BACKEND │ │ (via API) │ │ SEU CLIENTE │ │
│ └──────────┘ └──────────────┘ └─────────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌──────────────────────────────────────┐ │
│ │ │ SEU CLIENTE USA │ │
│ │ │ (Desktop/Mobile/Web/API) │ │
│ │ └──────────────────┬───────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌─────────────────────┐ │
│ │ VALIDAÇÃO │◀─ ─ ─ ─ ─▶│ VALIDAÇÃO OFFLINE │ │
│ │ ONLINE (API) │ │ (arquivo .lic) │ │
│ └──────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Modelos de Integração

1. Modelo Online (SaaS)

Ideal para aplicações web e APIs onde há conectividade constante.

# Seu backend gera licenças via API
from quantumlock.sdk import QuantumLockClient

client = QuantumLockClient(api_key=os.environ["QUANTUMLOCK_API_KEY"])

# Quando cliente compra seu produto
def on_purchase(customer_email, plan):
features = get_features_for_plan(plan)

license = client.generate_license(
end_customer_id=customer_email,
features=features,
valid_days=365
)

# Salvar no seu banco
save_license(customer_email, license)

# Enviar para o cliente
send_license_email(customer_email, license)

2. Modelo Offline (Desktop)

Para softwares que rodam sem internet.

# No software do seu cliente
from quantumlock.sdk import HybridLicenseValidator

# Configurar modo offline
validator = HybridLicenseValidator() # Usa QUANTUMLOCK_LICENSE_PATH

def main():
# Verificar licença no startup (< 5ms)
result = validator.validate()

if not result.is_valid:
show_license_dialog(result.message)
sys.exit(1)

# Software liberado!
print(f"Bem-vindo, {result.customer_name}!")
run_application()

3. Modelo Híbrido (Recomendado)

Validação offline instantânea com verificação online em background.

from quantumlock.sdk import HybridLicenseValidator

# Cria validador híbrido
validator = HybridLicenseValidator()

# Callback quando licença for revogada
@validator.on_revoked
def handle_revocation(result):
show_revoked_dialog()
disable_features()

# Callback quando entrar em grace period
@validator.on_grace_period
def handle_grace(result):
show_reconnect_warning(result.grace_period_ends)

def startup():
# Validação instantânea (< 5ms)
result = validator.validate()

if result.is_valid:
print(f"✅ Licença válida: {result.status.value}")
print(f" Mode: {result.validation_mode}")
return True
else:
print(f"❌ {result.message}")
return False

Integração Backend (SaaS)

Arquitetura Recomendada

┌─────────────────────────────────────────────────────────────────┐
│ SEU BACKEND SAAS │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ User Service │ │ License Service│ │
│ │ │────▶│ (QuantumLock) │ │
│ └────────────────┘ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────┐ │
│ │ QuantumLock SDK Client │ │
│ └───────────┬────────────┘ │
│ │ │
└────────────────────────────────┼───────────────────────────────┘


┌────────────────────────┐
│ QuantumLock™ API │
│ (api.quantumlock. │
│ softquantus.com) │
└────────────────────────┘

Exemplo: FastAPI License Service

# license_service.py
from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
from quantumlock.sdk import QuantumLockClient
import os

app = FastAPI()

# Singleton client
_client = None

def get_client() -> QuantumLockClient:
global _client
if _client is None:
_client = QuantumLockClient(
api_key=os.environ["QUANTUMLOCK_API_KEY"]
)
return _client


class CreateLicenseRequest(BaseModel):
customer_email: str
plan: str # "basic", "premium", "enterprise"


class LicenseResponse(BaseModel):
license_key: str
features: list
valid_until: str


# Mapeamento de planos para features
PLAN_FEATURES = {
"basic": ["basic"],
"premium": ["basic", "premium", "api_access"],
"enterprise": ["basic", "premium", "api_access", "enterprise", "unlimited"]
}


@app.post("/api/licenses/create", response_model=LicenseResponse)
async def create_license(
request: CreateLicenseRequest,
client: QuantumLockClient = Depends(get_client)
):
"""Cria licença quando cliente compra produto"""

features = PLAN_FEATURES.get(request.plan, ["basic"])

try:
license = client.generate_license(
end_customer_id=request.customer_email,
features=features,
valid_days=365
)

return LicenseResponse(
license_key=license["license_key"],
features=license["features"],
valid_until=license["valid_until"]
)

except Exception as e:
raise HTTPException(status_code=500, detail=str(e))


@app.post("/api/licenses/validate")
async def validate_license(
license_key: str,
customer_email: str,
client: QuantumLockClient = Depends(get_client)
):
"""Valida licença do cliente"""

result = client.validate_license(
license_key=license_key,
end_customer_id=customer_email
)

return result

Integração Desktop

Estrutura de Projeto

myapp/
├── main.py
├── licensing/
│ ├── __init__.py
│ ├── checker.py # Verificação de licença
│ └── features.py # Feature gating
├── features/
│ ├── basic.py
│ ├── premium.py
│ └── enterprise.py
└── config/
└── license.lic # Arquivo de licença

Implementação

# licensing/checker.py
import os
import sys
from pathlib import Path
from quantumlock.sdk import LicenseValidator, LicenseError

class LicenseChecker:
"""Gerenciador de licença da aplicação"""

# Locais onde procurar licença
LICENSE_PATHS = [
Path.home() / ".myapp" / "license.lic",
Path("/etc/myapp/license.lic"),
Path(os.environ.get("MYAPP_LICENSE", "")),
]

def __init__(self):
self.validator = None
self.license_path = None

def find_license(self) -> Path:
"""Procura arquivo de licença"""
for path in self.LICENSE_PATHS:
if path and path.exists():
return path
return None

def check(self) -> bool:
"""Verifica licença"""
self.license_path = self.find_license()

if not self.license_path:
return False

self.validator = LicenseValidator(
license_path=str(self.license_path)
)

try:
return self.validator.validate()
except LicenseError:
return False

def get_features(self) -> list:
"""Retorna features licenciadas"""
if self.validator and self.validator._is_valid:
info = self.validator.get_license_info()
return info.get("features", [])
return []

def has_feature(self, feature: str) -> bool:
"""Verifica se feature está licenciada"""
return feature in self.get_features()


# Singleton global
license_checker = LicenseChecker()
# licensing/features.py
from functools import wraps
from licensing.checker import license_checker

class FeatureNotLicensed(Exception):
pass

def require_feature(feature: str):
"""Decorador para proteger funções"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
if not license_checker.has_feature(feature):
raise FeatureNotLicensed(
f"Feature '{feature}' não está licenciada"
)
return func(*args, **kwargs)
return wrapper
return decorator

def require_any_feature(*features):
"""Requer pelo menos uma das features"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for feature in features:
if license_checker.has_feature(feature):
return func(*args, **kwargs)
raise FeatureNotLicensed(
f"Nenhuma feature licenciada: {features}"
)
return wrapper
return decorator
# main.py
import sys
from licensing.checker import license_checker
from licensing.features import require_feature, FeatureNotLicensed
from features import basic, premium

def show_license_required():
print("=" * 50)
print(" LICENÇA NECESSÁRIA")
print("=" * 50)
print()
print("Esta aplicação requer uma licença válida.")
print()
print("Para adquirir: https://portal.softquantus.com")
print()
print("Após obter a licença, coloque o arquivo em:")
print(f" ~/.myapp/license.lic")
print()

def main():
# Verificar licença
if not license_checker.check():
show_license_required()
sys.exit(1)

# Mostrar features disponíveis
features = license_checker.get_features()
print(f"Licença válida! Features: {', '.join(features)}")

# Executar aplicação
basic.run() # Sempre disponível

try:
premium.run() # Só se tiver "premium"
except FeatureNotLicensed:
print("Premium features não disponíveis")

if __name__ == "__main__":
main()

Integração API/Microservices

Arquitetura com Gateway

┌─────────────────────────────────────────────────────────────────┐
│ API GATEWAY │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ Auth Middleware│────▶│License Checker │ │
│ └────────────────┘ └───────┬────────┘ │
│ │ │
│ ┌───────────────────────┼───────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Service A │ │ Service B │ │ Service C │ │
│ │ (basic) │ │ (premium) │ │(enterprise)│ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
└────────────────────────────────────────────────────────────────┘

Middleware de Licença

# middleware/license_middleware.py
from fastapi import Request, HTTPException
from starlette.middleware.base import BaseHTTPMiddleware
from quantumlock.sdk import LicenseValidator

class LicenseMiddleware(BaseHTTPMiddleware):
"""Middleware para verificar licença em cada request"""

# Rotas que não precisam de licença
EXEMPT_PATHS = ["/health", "/docs", "/openapi.json"]

# Mapeamento de rotas para features requeridas
ROUTE_FEATURES = {
"/api/premium/": ["premium", "enterprise"],
"/api/enterprise/": ["enterprise"],
"/api/analytics/": ["analytics"],
}

def __init__(self, app, license_path: str):
super().__init__(app)
self.validator = LicenseValidator(license_path=license_path)
self.validator.validate()

async def dispatch(self, request: Request, call_next):
path = request.url.path

# Rotas isentas
if path in self.EXEMPT_PATHS:
return await call_next(request)

# Verificar se licença está válida
if not self.validator._is_valid:
raise HTTPException(
status_code=503,
detail="Licença inválida ou expirada"
)

# Verificar feature para a rota
for route_prefix, required_features in self.ROUTE_FEATURES.items():
if path.startswith(route_prefix):
has_feature = any(
self.validator.has_feature(f)
for f in required_features
)
if not has_feature:
raise HTTPException(
status_code=403,
detail=f"Features requeridas: {required_features}"
)
break

return await call_next(request)


# app.py
from fastapi import FastAPI
from middleware.license_middleware import LicenseMiddleware

app = FastAPI()

# Adicionar middleware
app.add_middleware(
LicenseMiddleware,
license_path="/etc/myapi/license.lic"
)

@app.get("/api/basic/data")
def basic_data():
return {"tier": "basic"}

@app.get("/api/premium/data")
def premium_data():
return {"tier": "premium", "exclusive": True}

@app.get("/api/enterprise/data")
def enterprise_data():
return {"tier": "enterprise", "unlimited": True}

Feature Gating

Padrões Recomendados

1. Decorador Simples

from quantumlock.sdk import LicenseValidator

validator = LicenseValidator(license_path="/etc/app/license.lic")
validator.validate()

@validator.require_feature("premium")
def premium_function():
"""Só executa com feature premium"""
return expensive_computation()

2. Context Manager

from contextlib import contextmanager

@contextmanager
def licensed_feature(feature: str):
if not validator.has_feature(feature):
raise FeatureNotLicensed(feature)
yield

# Uso
with licensed_feature("analytics"):
run_analytics()

3. Feature Flags

class FeatureFlags:
"""Flags baseadas em licença"""

def __init__(self, validator: LicenseValidator):
self.validator = validator
self._cache = {}

def __getattr__(self, name: str) -> bool:
if name.startswith("_"):
return super().__getattr__(name)

if name not in self._cache:
self._cache[name] = self.validator.has_feature(name)

return self._cache[name]

# Uso
flags = FeatureFlags(validator)

if flags.premium:
show_premium_ui()

if flags.analytics:
enable_analytics()

4. UI Conditional

# Para aplicações com GUI
def build_menu(validator: LicenseValidator):
menu = ["File", "Edit", "View"]

if validator.has_feature("premium"):
menu.append("Premium Tools")

if validator.has_feature("enterprise"):
menu.append("Enterprise Admin")

return menu

Distribuição de Licenças

Fluxo Recomendado

1. Cliente compra seu produto


2. Seu sistema gera licença via API


3. Licença armazenada no seu banco


4. Cliente recebe licença (email/portal/API)


5. Cliente instala licença no software


6. Software valida e libera features

Métodos de Entrega

Via Email

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

def send_license_email(customer_email: str, license: dict):
msg = MIMEMultipart()
msg["Subject"] = "Sua licença MyApp"
msg["From"] = "licenses@mycompany.com"
msg["To"] = customer_email

body = f"""
Obrigado por adquirir MyApp!

Sua licença: {license['license_key']}
Válida até: {license['valid_until']}
Features: {', '.join(license['features'])}

Instruções:
1. Baixe o arquivo de licença em anexo
2. Salve em ~/.myapp/license.lic
3. Inicie o MyApp

Suporte: support@mycompany.com
"""

msg.attach(MIMEText(body, "plain"))

# Anexar arquivo de licença
license_content = json.dumps(license, indent=2)
attachment = MIMEApplication(license_content.encode())
attachment["Content-Disposition"] = 'attachment; filename="license.lic"'
msg.attach(attachment)

# Enviar
with smtplib.SMTP("smtp.mycompany.com") as server:
server.send_message(msg)

Via Portal (Download)

# endpoint para download
@app.get("/api/licenses/{license_id}/download")
async def download_license(
license_id: str,
current_user = Depends(get_current_user)
):
license = get_license_from_db(license_id, current_user.id)

if not license:
raise HTTPException(404, "Licença não encontrada")

content = json.dumps(license.data, indent=2)

return Response(
content=content,
media_type="application/json",
headers={
"Content-Disposition": f"attachment; filename=license.lic"
}
)

Via API (Provisioning Automático)

# Seu cliente busca licença via API
@app.get("/api/licenses/current")
async def get_current_license(
api_key: str = Header(..., alias="X-API-Key")
):
"""Cliente pode buscar sua licença atual"""

customer = get_customer_by_api_key(api_key)
license = get_active_license(customer.id)

return license.data

Renovação e Expiração

Verificação de Expiração

from datetime import datetime, timedelta

def check_license_expiry(validator: LicenseValidator):
"""Verifica e alerta sobre expiração"""

if not validator._is_valid:
return {"status": "expired", "action_required": True}

info = validator.get_license_info()
valid_until = datetime.fromisoformat(
info["valid_until"].replace("Z", "+00:00")
)

days_left = (valid_until - datetime.now(valid_until.tzinfo)).days

if days_left <= 0:
return {"status": "expired", "action_required": True}
elif days_left <= 30:
return {"status": "expiring_soon", "days_left": days_left}
else:
return {"status": "active", "days_left": days_left}

Notificação Automática

# job_scheduler.py
from apscheduler.schedulers.background import BackgroundScheduler

def check_expiring_licenses():
"""Job diário para verificar licenças expirando"""

expiring = get_licenses_expiring_soon(days=30)

for license in expiring:
# Notificar cliente
send_renewal_reminder(
customer_email=license.customer_email,
days_left=license.days_until_expiry,
renewal_link=f"https://mycompany.com/renew/{license.id}"
)

scheduler = BackgroundScheduler()
scheduler.add_job(check_expiring_licenses, "cron", hour=9)
scheduler.start()

Segurança

Boas Práticas

  1. Nunca exponha sua API Key

    # ❌ Errado
    api_key = "ql_abc123..."

    # ✅ Correto
    api_key = os.environ["QUANTUMLOCK_API_KEY"]
  2. Proteja o arquivo de licença

    chmod 600 /etc/myapp/license.lic
    chown myapp:myapp /etc/myapp/license.lic
  3. Validação em múltiplos pontos

    # Validar no startup
    def startup():
    if not check_license():
    sys.exit(1)

    # Validar em operações críticas
    @require_feature("enterprise")
    def critical_operation():
    ...
  4. Cache com TTL

    from functools import lru_cache
    from datetime import datetime, timedelta

    _last_check = None
    _cached_result = None

    def validate_with_cache():
    global _last_check, _cached_result

    # Re-validar a cada hora
    if _last_check and datetime.now() - _last_check < timedelta(hours=1):
    return _cached_result

    _cached_result = validator.validate()
    _last_check = datetime.now()
    return _cached_result
  5. Logs de auditoria

    import logging

    audit_logger = logging.getLogger("license.audit")

    def on_license_check(result: bool, feature: str = None):
    audit_logger.info(
    f"License check: valid={result}, feature={feature}, "
    f"user={current_user}, ip={client_ip}"
    )

📞 Suporte


© 2025 SoftQuantus. Todos os direitos reservados.