Skip to main content

🎉 complete authentication system using allsafe-auth, integrating:

  • 🔐 Active Directory (LDAP) Authentication
  • 🔐 HOTP / TOTP Multi-Factor Authentication
  • 🖼️ QR Code Generation for MFA Setup
  • 🧑‍💼 User Listing from AD
  • 🌐 Django Inertia.js Integration

✅ Summary of All Functionality

Here's a clean breakdown of what you have and how to use it.


🔐 1. TOTP — Generate QR Code for MFA Setup

📄 File: generate_totp_qr.py

from allsafe_auth.authentication.totp import TOTP
from allsafe_auth.utils.qr_code_generator import QRCodeGenerator

if __name__ == "__main__":
    secret_key = "JBSWY3DPEHPK3PXP"
    account_name = "allsafe@example.com"
    issuer_name = "allsafe"
    qr_filename = "totp_qr_code.png"

    totp = TOTP(secret_key)
    print(f"Current TOTP: {totp.generate()}")

    uri = QRCodeGenerator.generate_uri(issuer_name, account_name, secret_key)
    QRCodeGenerator.save_to_file(uri, qr_filename)

This generates a QR code that can be scanned with apps like Google Authenticator or Authy to set up TOTP-based MFA.


🔐 2. TOTP — Verify One-Time Password

📄 File: examples/verify_totp_simple.py

from allsafe_auth.authentication.totp import TOTP

if __name__ == "__main__":
    secret_key = "JBSWY3DPEHPK3PXP"
    totp_verifier = TOTP(secret_key)
    expected_otp = totp_verifier.generate()

    user_otp = input("Enter the OTP from your authenticator app: ")

    if user_otp == expected_otp:
        print("✅ OTP verification successful!")
    else:
        print("❌ OTP verification failed.")

Verifies the TOTP code generated by an authenticator app using the same shared secret.


🔐 3. Active Directory Authentication + List Users

📄 File: examples/ad_authentication.py

from allsafe_auth.authentication.active_directory import ActiveDirectoryAuthenticator

# Configuration
AD_SERVER_IP = "10.195.130.34"
AD_DOMAIN = "allsafe.com.et"
AD_SEARCH_BASE = "DC=allsafe,DC=com,DC=et"

ADMIN_USER = "Administrator"
ADMIN_PASS = "password"

ad_auth = ActiveDirectoryAuthenticator(
    server_ip=AD_SERVER_IP,
    domain=AD_DOMAIN,
    search_base=AD_SEARCH_BASE
)

# Test Authentication
username = input("Enter username: ")
password = input("Enter password: ")

user_data = ad_auth.authenticate(username, password)

if user_data:
    print("✅ Login successful!")
    print("User Info:", user_data)
else:
    print("❌ Authentication failed.")

# Test User Listing
users = ad_auth.list_users(ADMIN_USER, ADMIN_PASS)
print(f"\n📄 Found {len(users)} users:")
for user in users:
    print(f" - {user['sAMAccountName'][0]}")

Authenticates against AD and lists all users using admin credentials.


🔐 4. Combined Flow: AD + TOTP

📄 File: examples/verify_totp_and_ad.py

from allsafe_auth.authentication.active_directory import ActiveDirectoryAuthenticator
from allsafe_auth.authentication.totp import TOTP

# AD Config
AD_SERVER_IP = "10.19.13.34"
AD_DOMAIN = "allsafe.com.et"
AD_SEARCH_BASE = "DC=allsafe,DC=com,DC=et"
TOTP_SECRET_KEY = "JBSWY3DPEHPK3PXP"


def main():
    ad_auth = ActiveDirectoryAuthenticator(
        server_ip=AD_SERVER_IP,
        domain=AD_DOMAIN,
        search_base=AD_SEARCH_BASE
    )

    username = input("Enter username: ")
    password = input("Enter password: ")
    totp_code = input("Enter TOTP from your authenticator app: ")

    print("\n[Step 1] Authenticating with Active Directory...")
    user_info = ad_auth.authenticate(username, password)

    if not user_info:
        print("❌ Authentication failed: Invalid username or password.")
        return

    print(f"✅ Successfully authenticated '{username}' via Active Directory.")

    print("\n[Step 2] Verifying TOTP...")
    totp_verifier = TOTP(TOTP_SECRET_KEY)
    expected_otp = totp_verifier.generate()

    if totp_code == expected_otp:
        print("✅ TOTP verification successful!")
        print("🔓 Full access granted.")
    else:
        print("❌ TOTP verification failed.")
        print("🔐 Access denied.")


if __name__ == "__main__":
    main()

Combines both steps:

  1. Authenticate via AD
  2. Validate TOTP code before granting access

🌐 5. Django View with Inertia Support

📄 File: views.py (partial)

from allsafe_auth.authentication.active_directory import ActiveDirectoryAuthenticator
from allsafe_auth.authentication.totp import TOTP
from inertia import render

# AD Config
AD_SERVER_IP = "10.19.13.34"
AD_DOMAIN = "allsafe.com.et"
AD_SEARCH_BASE = "DC=allsafe,DC=com,DC=et"
TOTP_SECRET_KEY = "JBSWY3DPEHPK3PXP"


@csrf_exempt
def ad_totp_login(request):
    if request.method != 'POST':
        return render(request, "logins/login_page", {
            "errors": {"login": "Only POST requests allowed"},
            "old": {}
        })

    try:
        data = json.loads(request.body)
        username = data.get('username')
        password = data.get('password')
        mfa_code = data.get('mfaCode')
        mfa_type = data.get('mfaType', 'authenticator')

        # Step 1: AD Authentication
        ad_auth = ActiveDirectoryAuthenticator(
            server_ip=AD_SERVER_IP,
            domain=AD_DOMAIN,
            search_base=AD_SEARCH_BASE
        )
        user_info = ad_auth.authenticate(username, password)

        if not user_info:
            return render(request, "logins/login_page", {
                "errors": {"login": "Invalid username or password"},
                "old": data
            })

        # Step 2: TOTP Verification
        if mfa_type == 'authenticator':
            totp = TOTP(TOTP_SECRET_KEY)
            expected_otp = totp.generate()

            if mfa_code != expected_otp:
                return render(request, "logins/login_page", {
                    "errors": {"login": "Invalid MFA code"},
                    "old": data
                })

        # Success
        return render(request, "somepage")

    except Exception as e:
        return render(request, "logins/login_page", {
            "errors": {"login": str(e)},
            "old": data
        })

Integrates with your React frontend using Inertia.js and protects /resource_dashboard.


📋 6. Example Output

After running the combined script or using the Django login view:

Enter username: daniel.destaw
Enter password: ***********
Enter TOTP from your authenticator app: 359864

[Step 1] Authenticating with Active Directory...
✅ Successfully authenticated 'daniel.destaw' via Active Directory.

[Step 2] Verifying TOTP...
✅ TOTP verification successful!
🔓 Full access granted.

And on success, redirects to /somepage.


🧾 7. List All AD Users Using Admin Account

You can also run this inside any script or view:

# Inside main() or a view
users = ad_auth.list_users("Administrator", "password@@")
print(f"\n📄 Found {len(users)} users:")
for user in users:
    print(f" - {user['sAMAccountName'][0]}")

Output:

📄 Found 5 users:
 - Administrator
 - Guest
 - DefaultAccount
 - krbtgt
 - daniel.destaw

✅ What’s Working?

Feature Status
AD Authentication
TOTP Verification
HOTP QR Code Generation
User Listing from AD
Django Inertia Integration

Release files for allsafe-auth 1.1.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for allsafe-auth 1.1.8
File Size Uploaded
allsafe_auth-1.1.8.tar.gz 15.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for allsafe-auth 1.1.8
File Interpreter ABI Platform
allsafe_auth-1.1.8-py3-none-any.whl Python 3 none any Details

Total release size:34.0 kB

Release files / allsafe_auth-1.1.8.tar.gz

Download URL allsafe_auth-1.1.8.tar.gz
Size 15.0 kB
Tags Source
SHA-256 checksum
How to use checksums
4e031b7120c24f5d714044e72b483adeb2794bde15c1837989353a8b6e4ebaad
BLAKE2b-256 checksum
How to use checksums
bd210e5be1b8ff0ee6e81ad3a9e38f2a71c1b6fdb65e3a68a96f95c73d2158a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.10.12

Release files / allsafe_auth-1.1.8-py3-none-any.whl

Download URL allsafe_auth-1.1.8-py3-none-any.whl
Size 19.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f1833d6259ab6191eb7f01938ea3fb5a8ad6868a48391c0a508d8b15abc47729
BLAKE2b-256 checksum
How to use checksums
276095b1d4a12bfc4bc341c68eac5eb6cb7b8086ad555046e428130ef2add44b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.10.12

Release history Release notifications | RSS feed

This release

1.1.8 This release

2 release files

1.1.7

2 release files

1.1.6

2 release files

1.1.5

2 release files

1.1.4

2 release files

1.1.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page