Skip to main content

A complete authentication library including TOTP, HOTP, Active Directory, and more.

Project description

๐ŸŽ‰ 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: examples/generate_hotp_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 HOTP-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 โœ…

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

allsafe_auth-1.1.7.tar.gz (15.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

allsafe_auth-1.1.7-py3-none-any.whl (19.0 kB view details)

Uploaded Python 3

File details

Details for the file allsafe_auth-1.1.7.tar.gz.

File metadata

  • Download URL: allsafe_auth-1.1.7.tar.gz
  • Upload date:
  • Size: 15.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for allsafe_auth-1.1.7.tar.gz
Algorithm Hash digest
SHA256 5b8306aacd11fcfa2d0b6a0549eceb7734d520807de614cedde06b52090174ed
MD5 935beb60664b8c2461a810c7184859c6
BLAKE2b-256 6d9c113eaf0e0e5fdafc463b7dbaa1160ddfea1080dd94fc9611fac1f2ecc152

See more details on using hashes here.

File details

Details for the file allsafe_auth-1.1.7-py3-none-any.whl.

File metadata

  • Download URL: allsafe_auth-1.1.7-py3-none-any.whl
  • Upload date:
  • Size: 19.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for allsafe_auth-1.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 0367bc144428267b1851713b8c1baeb9173b244f5eaaa75b0bd7be916346a7cd
MD5 972663a5a5790d76b79b9cb41674b7db
BLAKE2b-256 a6f4108349a2791a6c856d39a1714d622af32049e287f013ff67d668a6ececc7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page