Skip to main content
The authentication service provides core security functions for user authentication, password hashing, and credential verification.

Overview

Location: services/auth.py This module handles:
  • Secure password hashing using bcrypt
  • Password verification against stored hashes
  • User authentication with username and password
  • Session token generation

Functions

hash_password

Generates a bcrypt hash from a plain text password.
plain
string
required
The plain text password to hash
Returns: str - The bcrypt-hashed password as a UTF-8 string
from services.auth import hash_password

# Hash a password for storage
hashed = hash_password("my_secure_password")
print(hashed)
# Output: $2b$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
This function uses bcrypt with automatic salt generation for secure password hashing. Never store plain text passwords.

verify_password

Verifies a plain text password against a stored bcrypt hash.
plain
string
required
The plain text password to verify
hashed
string
required
The stored bcrypt hash to compare against
Returns: bool - True if the password matches, False otherwise
from services.auth import verify_password

# Verify user login
stored_hash = "$2b$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy"
user_input = "my_secure_password"

if verify_password(user_input, stored_hash):
    print("Password is correct")
else:
    print("Invalid password")
This function catches all exceptions and returns False for any error, including malformed hashes. This provides safe failure behavior.

get_user_by_username

Retrieves a user record from the database by username.
db
Session
required
SQLAlchemy database session
username
string
required
The username to search for
Returns: Optional[User] - The User model instance or None if not found
from services.auth import get_user_by_username
from data.db.session import SessionLocal

with SessionLocal() as db:
    user = get_user_by_username(db, "admin")
    if user:
        print(f"Found user: {user.username}, Role: {user.role}")
    else:
        print("User not found")

authenticate

Authenticates a user with username and password credentials.
db
Session
required
SQLAlchemy database session
username
string
required
The username to authenticate
password
string
required
The plain text password to verify
Returns: Optional[Dict] - User information dictionary or None if authentication fails The returned dictionary contains:
  • id (int): User ID
  • username (str): Username
  • role (str): User role (admin, assistant, artist)
  • artist_id (Optional[int]): Associated artist ID if applicable
from services.auth import authenticate
from data.db.session import SessionLocal

with SessionLocal() as db:
    user_data = authenticate(db, "admin", "password123")
    
    if user_data:
        print(f"Login successful!")
        print(f"User ID: {user_data['id']}")
        print(f"Role: {user_data['role']}")
        print(f"Artist ID: {user_data.get('artist_id')}")
    else:
        print("Invalid credentials or inactive user")
This function automatically updates the user’s last_login timestamp on successful authentication. Ensure the database session is committed after calling this function.

Authentication Flow

1

User provides credentials

The application collects username and password from the login form.
2

Call authenticate function

Pass the credentials to authenticate() with a database session.
3

Validation checks

The function verifies:
  • User exists in the database
  • User account is active (is_active = True)
  • Password matches the stored hash
4

Return user data or None

On success, returns a dictionary with user information. On failure, returns None.

Security Considerations

The service uses bcrypt with automatic salt generation. Bcrypt is designed to be slow, making brute-force attacks computationally expensive. Each password gets a unique salt, preventing rainbow table attacks.
Be aware that the authentication function may be vulnerable to timing attacks. Consider implementing constant-time comparison or rate limiting to prevent username enumeration.
The authenticate() function explicitly checks for active users. Inactive users cannot log in even with correct credentials, providing a soft-delete mechanism.

Permissions Service

Role-based access control and authorization

User Model

User data model and schema

Build docs developers (and LLMs) love