async def check_permission(cls, driver: "Driver", connection_type: str, headers: dict, body: Optional[dict]) -> str: """ :说明: 钉钉协议鉴权。参考 `鉴权 <https://ding-doc.dingtalk.com/doc#/serverapi2/elzz1p>`_ """ timestamp = headers.get("timestamp") sign = headers.get("sign") # 检查连接方式 if connection_type not in ["http"]: raise RequestDenied( 405, "Unsupported connection type, available type: `http`") # 检查 timestamp if not timestamp: raise RequestDenied(400, "Missing `timestamp` Header") # 检查 sign secret = driver.config.secret if secret: if not sign: log("WARNING", "Missing Signature Header") raise RequestDenied(400, "Missing `sign` Header") string_to_sign = f"{timestamp}\n{secret}" sig = hmac.new(secret.encode("utf-8"), string_to_sign.encode("utf-8"), "sha256").digest() if sign != base64.b64encode(sig).decode("utf-8"): log("WARNING", "Signature Header is invalid") raise RequestDenied(403, "Signature is invalid") else: log("WARNING", "Ding signature check ignored!") return body["chatbotUserId"]
async def check_permission(cls, driver: "Driver", connection_type: str, headers: dict, body: Optional[bytes]) -> str: """ :说明: 钉钉协议鉴权。参考 `鉴权 <https://ding-doc.dingtalk.com/doc#/serverapi2/elzz1p>`_ """ timestamp = headers.get("timestamp") sign = headers.get("sign") # 检查连接方式 if connection_type not in ["http"]: raise RequestDenied( 405, "Unsupported connection type, available type: `http`") # 检查 timestamp if not timestamp: raise RequestDenied(400, "Missing `timestamp` Header") # 检查 sign secret = cls.ding_config.secret if secret: if not sign: log("WARNING", "Missing Signature Header") raise RequestDenied(400, "Missing `sign` Header") sign_base64 = calc_hmac_base64(str(timestamp), secret) if sign != sign_base64.decode('utf-8'): log("WARNING", "Signature Header is invalid") raise RequestDenied(403, "Signature is invalid") else: log("WARNING", "Ding signature check ignored!") return json.loads(body.decode())["chatbotUserId"]
def get_auth_bearer(access_token: Optional[str] = None) -> Optional[str]: if not access_token: return None scheme, _, param = access_token.partition(" ") if scheme.lower() not in ["bearer", "token"]: raise RequestDenied(401, "Not authenticated") return param
async def check_permission(cls, driver: "Driver", connection_type: str, headers: dict, body: Optional[dict]) -> str: if connection_type == 'ws': raise RequestDenied( status_code=501, reason='Websocket connection is not implemented') self_id: Optional[str] = headers.get('bot') if self_id is None: raise RequestDenied(status_code=400, reason='Header `Bot` is required.') self_id = str(self_id).strip() await SessionManager.new( int(self_id), host=cls.mirai_config.host, # type: ignore port=cls.mirai_config.port, #type: ignore auth_key=cls.mirai_config.auth_key) # type: ignore return self_id
async def check_permission(cls, driver: "Driver", connection_type: str, headers: dict, body: Optional[dict]) -> str: """ :说明: CQHTTP (OneBot) 协议鉴权。参考 `鉴权 <https://github.com/howmanybots/onebot/blob/master/v11/specs/communication/authorization.md>`_ """ x_self_id = headers.get("x-self-id") x_signature = headers.get("x-signature") token = get_auth_bearer(headers.get("authorization")) cqhttp_config = CQHTTPConfig(**driver.config.dict()) # 检查连接方式 if connection_type not in ["http", "websocket"]: log("WARNING", "Unsupported connection type") raise RequestDenied(405, "Unsupported connection type") # 检查self_id if not x_self_id: log("WARNING", "Missing X-Self-ID Header") raise RequestDenied(400, "Missing X-Self-ID Header") # 检查签名 secret = cqhttp_config.secret if secret and connection_type == "http": if not x_signature: log("WARNING", "Missing Signature Header") raise RequestDenied(401, "Missing Signature") sig = hmac.new(secret.encode("utf-8"), json.dumps(body).encode(), "sha1").hexdigest() if x_signature != "sha1=" + sig: log("WARNING", "Signature Header is invalid") raise RequestDenied(403, "Signature is invalid") access_token = cqhttp_config.access_token if access_token and access_token != token: log( "WARNING", "Authorization Header is invalid" if token else "Missing Authorization Header") raise RequestDenied( 403, "Authorization Header is invalid" if token else "Missing Authorization Header") return str(x_self_id)
async def check_permission(cls, driver: "Driver", connection_type: str, headers: dict, body: Optional[dict]) -> NoReturn: raise RequestDenied( status_code=501, reason=f'Connection {connection_type} not implented')