Created
April 14, 2026 18:42
-
-
Save GoodnessEzeokafor/998c0ce74a40445433770d77d9980b8d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from urllib.parse import urlencode, quote | |
| from cryptography.hazmat.primitives import serialization, hashes | |
| from cryptography.hazmat.primitives.asymmetric import padding | |
| from cryptography.hazmat.backends import default_backend | |
| import time as time_module | |
| QRMASTER_PUBLIC_KEY = """-----BEGIN PUBLIC KEY----- | |
| MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqxqOJg0kqL4/xoNf0iDb | |
| jz/oM7ujsXOd92vQDkwO/rCP9wwZY0AvrMhcc56X4LmIbsbc1EZQ5ryMrIDbyCgt | |
| pgJJTQG/u/FBiwG2Yvqgx+9keVGZhBA+Oph34HFPWz4OEB+Py4QkaJPXALkjjh2Z | |
| f7Lgpv5gO8gRyg/o9FwCOZyEGiUmVorwPvwT3oMeNPCHxzlpGzdqV1kfqNmbS4Zk | |
| CiXGNhxxN0LJDnhaJJUl4bcnUjpcIxUlgSMX2CcooffIk3E1ROP051Xf/zmUWE6D | |
| TcGetf6ni2s2irDCgeanylyjLTgM6xaOYWqtG0yUC5lyzO46yTmE1Q47XMM2h1KJ | |
| swIDAQAB | |
| -----END PUBLIC KEY-----""" | |
| QRMASTER_CARD_HOST = "http://cz.uclbrt.com" | |
| def get_key_link( | |
| self, | |
| mobile: str, | |
| community_no: str, | |
| card_no: str = "", | |
| area_code: str = "86", | |
| card_type: int = 0, | |
| ) -> str: | |
| """ | |
| Generate the QR code access link for a key holder. | |
| This does NOT call the API. It builds the payload locally, encrypts it | |
| with QRMaster's RSA public key, and returns the card host URL with the | |
| encrypted data as a query param. The card host decrypts it server-side. | |
| Args: | |
| mobile: Phone number of the key owner | |
| community_no: Community number from QRMaster dashboard | |
| card_no: The cardNo returned from generate_card (optional) | |
| area_code: Phone area code (default: "86") | |
| card_type: 0=room, 1=floor, 2=building (default: 0) | |
| Returns: | |
| str: Full URL to the QR code key link | |
| Raises: | |
| QRMasterError: If encryption fails | |
| """ | |
| try: | |
| payload = { | |
| "id": self.account_sid, | |
| "token": self.auth_token, | |
| "communityNo": community_no, | |
| "time": int(time_module.time()), | |
| "mobile": mobile, | |
| "areaCode": area_code, | |
| "cardNo": card_no, | |
| "cardType": card_type, | |
| } | |
| # URL-encode the payload the same way PHP's http_build_query does | |
| query_string = urlencode(payload) | |
| # Load the RSA public key | |
| public_key = serialization.load_pem_public_key( | |
| QRMASTER_PUBLIC_KEY.encode(), | |
| backend=default_backend(), | |
| ) | |
| # Encrypt with PKCS1 v1.5 padding (matches PHP openssl_public_encrypt default) | |
| encrypted = public_key.encrypt( | |
| query_string.encode(), | |
| padding.PKCS1v15(), | |
| ) | |
| # Base64 encode then URL-encode, matching PHP's base64_encode + urlencode | |
| encrypted_b64 = base64.b64encode(encrypted).decode() | |
| data_param = quote(encrypted_b64) | |
| link = f"{QRMASTER_CARD_HOST}/apiLogin/?data={data_param}" | |
| logger.debug(f"Generated QRMaster key link for mobile {mobile}") | |
| return link | |
| except Exception as e: | |
| logger.error(f"Failed to generate QRMaster key link: {str(e)}") | |
| raise QRMasterError(f"Key link generation failed: {str(e)}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment