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. HOTP โ€” Generate QR Code for MFA Setup

๐Ÿ“„ File: examples/generate_hotp_qr.py

from allsafe_auth.authentication.hotp import HOTP
from allsafe_auth.utils.qr_code_generator import QRCodeGenerator

if __name__ == "__main__":
    # Example secret key (in real app, store per-user)
    secret_key = "JBSWY3DPEHPK3PXP"
    account_name = "daniel.destaw@allsafe.com.et"
    issuer_name = "AllSafe"

    # Generate QR code URI
    uri = QRCodeGenerator.generate_uri(issuer_name, account_name, secret_key)

    # Save QR code image
    qr_filename = "hotp_qr_code.png"
    QRCodeGenerator.save_to_file(uri, qr_filename)

    print(f"โœ… HOTP QR code saved as '{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.5.tar.gz (15.1 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.5-py3-none-any.whl (19.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: allsafe_auth-1.1.5.tar.gz
  • Upload date:
  • Size: 15.1 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.5.tar.gz
Algorithm Hash digest
SHA256 a292e2bab1a93a65cf2c42332cd0e3db9d9cf5c48d7a672f73b2debf959223f8
MD5 f80b2d1a6e86d8443ca20232e2e3e2c9
BLAKE2b-256 1885d286bfefce4fdc312a4f2aa5fbe66c79f9ce0f2e2412b214db77ec68ce5f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: allsafe_auth-1.1.5-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.5-py3-none-any.whl
Algorithm Hash digest
SHA256 f21f518622cdf3fc6be90aac05696dc2647bf650e70de67927c7471249d51957
MD5 82a9e7be73d7ceef4666a796cbfb5ed8
BLAKE2b-256 deba0593f24d42821f02839ac2ac42677008f244d77aae51465042e562e5c1de

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