| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 | import base64
import hashlib
import hmac
import os
import time
from pydantic import BaseModel, Field
from configs import dify_config
class SignedUrlParams(BaseModel):
    sign_key: str = Field(..., description="The sign key")
    timestamp: str = Field(..., description="Timestamp")
    nonce: str = Field(..., description="Nonce")
    sign: str = Field(..., description="Signature")
class UrlSigner:
    @classmethod
    def get_signed_url(cls, url: str, sign_key: str, prefix: str) -> str:
        signed_url_params = cls.get_signed_url_params(sign_key, prefix)
        return (
            f"{url}?timestamp={signed_url_params.timestamp}"
            f"&nonce={signed_url_params.nonce}&sign={signed_url_params.sign}"
        )
    @classmethod
    def get_signed_url_params(cls, sign_key: str, prefix: str) -> SignedUrlParams:
        timestamp = str(int(time.time()))
        nonce = os.urandom(16).hex()
        sign = cls._sign(sign_key, timestamp, nonce, prefix)
        return SignedUrlParams(sign_key=sign_key, timestamp=timestamp, nonce=nonce, sign=sign)
    @classmethod
    def verify(cls, sign_key: str, timestamp: str, nonce: str, sign: str, prefix: str) -> bool:
        recalculated_sign = cls._sign(sign_key, timestamp, nonce, prefix)
        return sign == recalculated_sign
    @classmethod
    def _sign(cls, sign_key: str, timestamp: str, nonce: str, prefix: str) -> str:
        if not dify_config.SECRET_KEY:
            raise Exception("SECRET_KEY is not set")
        data_to_sign = f"{prefix}|{sign_key}|{timestamp}|{nonce}"
        secret_key = dify_config.SECRET_KEY.encode()
        sign = hmac.new(secret_key, data_to_sign.encode(), hashlib.sha256).digest()
        encoded_sign = base64.urlsafe_b64encode(sign).decode()
        return encoded_sign
 |