Skip to main content

Overview

The Energy CMMS API uses Django’s built-in authentication system with session-based authentication. All API endpoints require authentication, with most requiring staff member permissions.

Authentication Methods

Session Authentication (Primary)

The API uses Django’s session-based authentication, which requires:
  1. Login through the admin interface
  2. CSRF token for state-changing requests
  3. Session cookie for subsequent requests

Login Configuration

# energia/settings.py
LOGIN_URL = '/admin/login/'
LOGIN_REDIRECT_URL = '/app/'

Making Authenticated Requests

Step 1: Obtain CSRF Token

For AJAX requests, include the CSRF token in your headers:
const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;

fetch('/api/endpoint/', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-CSRFToken': csrfToken
  },
  credentials: 'same-origin',
  body: JSON.stringify(data)
});
The session cookie is automatically included in same-origin requests. For cross-origin requests:
fetch('https://softcom.ccg.hn/api/endpoint/', {
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json'
  }
});

Authentication Decorators

@login_required

Requires user to be authenticated:
from django.contrib.auth.decorators import login_required

@login_required
def api_endpoint(request):
    # Only authenticated users can access
    return JsonResponse({'status': 'success'})

@staff_member_required

Requires user to be staff member:
from django.contrib.admin.views.decorators import staff_member_required

@staff_member_required
def admin_api_endpoint(request):
    # Only staff members can access
    return JsonResponse({'status': 'success'})

CSRF Protection

CSRF Configuration

# energia/settings.py
CSRF_TRUSTED_ORIGINS = [
    'https://softcom.ccg.hn',
    'http://softcom.ccg.hn',
    'https://*.ccg.hn',
    'http://10.30.1.11',
    'http://127.0.0.1:8000'
]
For specific endpoints that require external access without CSRF:
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def webhook_endpoint(request):
    # External webhooks without CSRF protection
    return JsonResponse({'status': 'received'})
Only use @csrf_exempt for webhook endpoints that validate requests through other means (e.g., signature verification).

Request Examples

GET Request

fetch('/activos/api/buscar-activos-json/?q=pump&cat_id=5', {
  credentials: 'same-origin',
  headers: {
    'Accept': 'application/json'
  }
})
.then(response => response.json())
.then(data => console.log(data.results));

POST Request

const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;

fetch('/activos/api/guardar-pin/', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-CSRFToken': csrfToken
  },
  credentials: 'same-origin',
  body: JSON.stringify({
    visor_id: 1,
    activo_id: 123,
    x: 150.5,
    y: 200.3,
    color: '#FF0000',
    nota: 'Equipment location'
  })
})
.then(response => response.json())
.then(data => console.log(data));

User Permissions

Accessing Current User

In API views, access the authenticated user:
@login_required
def my_endpoint(request):
    user = request.user
    
    # Check permissions
    if user.has_perm('activos.view_activo'):
        # User has permission
        pass
    
    # Check staff status
    if user.is_staff:
        # User is staff member
        pass

Permission Checks

from django.contrib.auth.models import User

# Check specific permission
if request.user.has_perm('mantenimiento.add_ordentrabajo'):
    # Can create work orders
    pass

# Check multiple permissions
if request.user.has_perms(['activos.view_activo', 'activos.change_activo']):
    # Can view and edit assets
    pass

Security Best Practices

HTTPS in Production

# energia/settings.py (Production)
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
USE_X_FORWARDED_HOST = True
USE_X_FORWARDED_PORT = True

Session Security

# Recommended production settings
SESSION_COOKIE_SECURE = True  # Only send cookie over HTTPS
SESSION_COOKIE_HTTPONLY = True  # Prevent JavaScript access
SESSION_COOKIE_SAMESITE = 'Lax'  # CSRF protection

Password Validation

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

Error Responses

401 Unauthorized

{
  "error": "Authentication required",
  "redirect": "/admin/login/"
}

403 Forbidden

{
  "error": "Permission denied",
  "required_permission": "activos.change_activo"
}

Testing Authentication

Test API authentication locally:
from django.test import Client
from django.contrib.auth.models import User

client = Client()

# Create test user
user = User.objects.create_user('testuser', '[email protected]', 'password')
user.is_staff = True
user.save()

# Login
client.login(username='testuser', password='password')

# Make authenticated request
response = client.get('/activos/api/buscar-activos-json/')
assert response.status_code == 200

Next Steps

Assets API

Learn about asset management endpoints

Maintenance API

Explore maintenance operations

Build docs developers (and LLMs) love