-
Notifications
You must be signed in to change notification settings - Fork 0
Authentication API
This module provides user registration and email verification functionality for both startup and investor roles.
Endpoint: POST /api/auth/register/
Description: Register a new user account with role-specific profile creation.
Common fields (required for all roles):
-
email(string, required): User's email address -
password(string, required): Password (must meet Django password validation rules) -
first_name(string, required): User's first name (max 150 characters) -
last_name(string, required): User's last name (max 150 characters) -
role(string, required): User role - either"startup"or"investor"
Startup-specific fields:
-
company_name(string, required): Company name (max 255 characters) -
description(string, optional): Company description -
website(string, optional): Company website URL -
phone(string, optional): Contact phone number (max 20 characters)
Investor-specific fields:
-
investment_range_min(decimal, required): Minimum investment amount (max 12 digits, 2 decimal places) -
investment_range_max(decimal, optional): Maximum investment amount (max 12 digits, 2 decimal places)
Startup Registration:
POST /api/auth/register/
Content-Type: application/json
{
"email": "alice@example.com",
"password": "SecurePass123!",
"first_name": "Alice",
"last_name": "Smith",
"role": "startup",
"company_name": "Handmade Co",
"description": "Woodwork & ceramics",
"website": "https://example.com",
"phone": "+380123456789"
}Investor Registration:
POST /api/auth/register/
Content-Type: application/json
{
"email": "bob@investor.com",
"password": "SecurePass123!",
"first_name": "Bob",
"last_name": "Johnson",
"role": "investor",
"investment_range_min": 10000.00,
"investment_range_max": 100000.00
}Status Code: 201 Created
{
"id": 123,
"email": "alice@example.com",
"detail": "Verification email sent."
}Validation Error - 400 Bad Request
{
"email": ["Enter a valid email address."],
"password": ["This password is too short. It must contain at least 8 characters."]
}Missing Required Field - 400 Bad Request
{
"first_name": ["This field is required."]
}{
"company_name": ["This field is required for startups"]
}{
"investment_range_min": ["This field is required for investors"]
}Duplicate Email - 201 Created (Anti-enumeration)
{
"detail": "Verification email sent."
}Passwords must meet Django's default validation rules:
- At least 8 characters
- Not entirely numeric
- Not too similar to user information
- Not a commonly used password
Endpoint: GET /api/auth/verify/<str:uid>/<str:token>/
Description: Verify user's email address using the token sent via email.
-
uid(string): Base64-encoded user ID -
token(string): Verification token
GET /api/auth/verify/MQ/abc123-def456/Status Code: 200 OK
{
"detail": "Email verified successfully."
}Already Verified - 200 OK
{
"detail": "Email already verified. You can log in."
}After successful verification:
- User's
is_activestatus is set totrue - User can now log in
Invalid or Expired Token - 400 Bad Request
{
"detail": "Invalid or expired token."
}Invalid Verification Link - 400 Bad Request
{
"detail": "Invalid verification link."
}This API implements a strict anti-enumeration approach to prevent attackers from discovering registered email addresses:
- All registration attempts return HTTP 201 with identical messages
- Duplicate email registrations are silently ignored:
- No new user is created
- No verification email is sent
- Response is identical to successful registration
- From the client's perspective, responses are indistinguishable
Rationale: This prevents attackers from determining which emails are registered by observing different response codes or messages.
Trade-off: Users won't know if they're already registered, but overall security is improved.
- Users are created with
is_active=Falseby default - Verification email is sent automatically upon registration
- Users must verify their email before they can authenticate
- Verification tokens are single-use and expire after a period
from django.urls import path
from .views import RegisterView, VerifyEmailView
urlpatterns = [
path('register/', RegisterView.as_view(), name='register'),
path('verify/<str:uid>/<str:token>/', VerifyEmailView.as_view(), name='verify-email')
]docker-compose exec backend python manage.py test apps.authentication# Registration tests only
docker-compose exec backend python manage.py test apps.authentication.tests.RegistrationTestCase
# Email verification tests only
docker-compose exec backend python manage.py test apps.authentication.tests.EmailVerificationTestCaseThe test suite covers:
- ✅ Successful startup registration
- ✅ Successful investor registration
- ✅ Missing first_name validation
- ✅ Missing last_name validation
- ✅ Password validation (weak passwords rejected)
- ✅ Email format validation
- ✅ Missing required fields (company_name, investment_range_min)
- ✅ Role-specific validation
- ✅ Duplicate email anti-enumeration
- ✅ Successful email verification
- ✅ Invalid tokens
- ✅ Invalid UIDs
- ✅ Non-existent users
By default, emails are printed to the console for development:
# settings.py
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'View emails in Docker logs:
docker-compose logs -f backendPOST /api/auth/register/
Content-Type: application/json
{
"email": "startup@test.com",
"password": "SecurePass123!",
"first_name": "John",
"last_name": "Doe",
"role": "startup",
"company_name": "Test Startup",
"description": "Innovative solutions",
"website": "https://test.com",
"phone": "+380123456789"
}POST /api/auth/register/
Content-Type: application/json
{
"email": "investor@test.com",
"password": "SecurePass123!",
"first_name": "Jane",
"last_name": "Smith",
"role": "investor",
"investment_range_min": 50000,
"investment_range_max": 500000
}# Replace <uid> and <token> with values from verification email
curl http://localhost:8000/api/auth/verify/<uid>/<token>/Solution: Check Docker logs for email output:
docker-compose logs backend | grep -A 10 "Verify your email"Solution: Ensure all required fields are provided:
- Common:
email,password,first_name,last_name,role - Startup:
company_nameis required - Investor:
investment_range_minis required
Solution: Ensure password meets requirements:
- Minimum 8 characters
- Mix of letters and numbers
- Not a common password
Solution: Rebuild Docker container:
docker-compose down
docker-compose up --build -d
docker-compose exec backend python manage.py migrate
docker-compose exec backend python manage.py test apps.authentication- Users are created with
is_active=Falseand must verify their email before logging in - Verification links are sent to the email provided during registration
- In DEBUG mode, verification links point to
localhost:8000 - In production, verification links use
FRONTEND_URLfrom settings - All profile fields beyond the required ones are auto-populated with default values