mirror of
https://github.com/remnawave/python-sdk.git
synced 2026-08-04 06:35:09 +00:00
feat: Добавить поддержку OAuth2 Telegram и новые модели для тегов и отзыва пользователей
This commit is contained in:
parent
5f86d7383c
commit
4507d9a60b
9 changed files with 84 additions and 6 deletions
|
|
@ -38,6 +38,7 @@ pip install git+https://github.com/sm1ky/remnawave-api.git@development
|
|||
|
||||
| Contract Version | Remnawave Panel Version |
|
||||
| ---------------- | ----------------------- |
|
||||
| 1.1.2 | 1.6.3 |
|
||||
| 1.1.1 | 1.6.1, 1.6.2 |
|
||||
| 1.1.0 | 1.6.0 |
|
||||
| 1.0.8 | 1.5.7 |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[project]
|
||||
name = "remnawave-api"
|
||||
version = "1.1.1"
|
||||
version = "1.1.2"
|
||||
description = "A Python SDK for interacting with the Remnawave API."
|
||||
authors = [
|
||||
{name = "Artem",email = "sm1ky@forestsnet.com"}
|
||||
|
|
@ -32,8 +32,10 @@ classifiers = [
|
|||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/sm1ky/remnawave-api"
|
||||
Panel Page = "https://remna.st/"
|
||||
"Panel Page" = "https://remna.st/"
|
||||
Developer = "https://t.me/forests_dev"
|
||||
"Community Chat" = "https://t.me/+xQs17zMzwCY1NzYy"
|
||||
"Update Channel" = "https://t.me/remnawave"
|
||||
|
||||
[tool.poetry.group.test.dependencies]
|
||||
ruff = "^0.4.4"
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from remnawave_api.models import (
|
|||
RegisterRequestDto,
|
||||
RegisterResponseDto,
|
||||
StatusResponseDto,
|
||||
LoginTelegramRequestDto,
|
||||
)
|
||||
from remnawave_api.rapid import BaseController, get, post
|
||||
|
||||
|
|
@ -35,3 +36,11 @@ class AuthController(BaseController):
|
|||
) -> StatusResponseDto:
|
||||
"""Get status"""
|
||||
...
|
||||
|
||||
@post("/auth/oauth2/tg/callback", response_class=LoginResponseDto)
|
||||
async def oauth2_tg_callback(
|
||||
self,
|
||||
body: Annotated[LoginTelegramRequestDto, PydanticBody()],
|
||||
) -> LoginResponseDto:
|
||||
"""OAuth2 Telegram callback"""
|
||||
...
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Annotated
|
||||
from typing import Annotated, Optional
|
||||
|
||||
from rapid_api_client import Path, Query
|
||||
from rapid_api_client.annotations import PydanticBody
|
||||
|
|
@ -11,6 +11,8 @@ from remnawave_api.models import (
|
|||
UpdateUserRequestDto,
|
||||
UserResponseDto,
|
||||
UsersResponseDto,
|
||||
TagsResponseDto,
|
||||
RevokeUserRequestDto
|
||||
)
|
||||
from remnawave_api.rapid import BaseController, delete, get, patch, post
|
||||
|
||||
|
|
@ -62,6 +64,7 @@ class UsersController(BaseController):
|
|||
async def revoke_user_subscription(
|
||||
self,
|
||||
uuid: Annotated[str, Path(description="UUID of the user")],
|
||||
body: Optional[Annotated[RevokeUserRequestDto, PydanticBody()]] = None,
|
||||
) -> UserResponseDto:
|
||||
"""Revoke User Subscription"""
|
||||
...
|
||||
|
|
@ -155,4 +158,11 @@ class UsersController(BaseController):
|
|||
tag: Annotated[str, Path(description="Tag of the user")],
|
||||
) -> UsersResponseDto:
|
||||
"""Get Users By Tag"""
|
||||
...
|
||||
|
||||
@get("/users/tags", response_class=TagsResponseDto)
|
||||
async def get_all_tags(
|
||||
self,
|
||||
) -> TagsResponseDto:
|
||||
"""Get All Tags"""
|
||||
...
|
||||
|
|
@ -10,6 +10,7 @@ from .auth import (
|
|||
RegisterRequestDto,
|
||||
RegisterResponseDto,
|
||||
StatusResponseDto,
|
||||
LoginTelegramRequestDto
|
||||
)
|
||||
from .bandwidthstats import NodesUsageResponseDto, NodeUsageResponseDto, NodesRealtimeUsageResponseDto, NodeRealtimeUsageResponseDto
|
||||
from .hosts import (
|
||||
|
|
@ -81,6 +82,8 @@ from .users import (
|
|||
UserLastConnectedNodeDto,
|
||||
UserResponseDto,
|
||||
UsersResponseDto,
|
||||
TagsResponseDto,
|
||||
RevokeUserRequestDto
|
||||
)
|
||||
from .users_bulk_actions import (
|
||||
BulkAllResetTrafficUsersResponseDto,
|
||||
|
|
@ -181,5 +184,8 @@ __all__ = [
|
|||
"CreateHWIDUser",
|
||||
"HWIDUserResponseDto",
|
||||
"HWIDUserResponseDtoList",
|
||||
"HWIDDeleteRequest"
|
||||
"HWIDDeleteRequest",
|
||||
"LoginTelegramRequestDto",
|
||||
"TagsResponseDto",
|
||||
"RevokeUserRequestDto"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -24,3 +24,12 @@ class RegisterRequestDto(BaseModel):
|
|||
class StatusResponseDto(BaseModel):
|
||||
is_login_allowed: bool = Field(alias="isLoginAllowed")
|
||||
is_register_allowed: bool = Field(alias="isRegisterAllowed")
|
||||
|
||||
class LoginTelegramRequestDto(BaseModel):
|
||||
id: int
|
||||
first_name: str
|
||||
last_name: str
|
||||
username: str
|
||||
photo_url: str
|
||||
auth_date: int
|
||||
hash: str
|
||||
|
|
@ -143,3 +143,16 @@ class UsersResponseDto(BaseModel):
|
|||
|
||||
class DeleteUserResponseDto(BaseModel):
|
||||
is_deleted: bool = Field(alias="isDeleted")
|
||||
|
||||
class TagsResponseDto(BaseModel):
|
||||
tags: List[str]
|
||||
|
||||
class RevokeUserRequestDto(BaseModel):
|
||||
short_uuid: Optional[str] = Field(
|
||||
None,
|
||||
serialization_alias="shortUuid",
|
||||
description="Optional. If not provided, a new short UUID will be generated by Remnawave. Please note that it is strongly recommended to allow Remnawave to generate the short UUID.",
|
||||
min_length=6,
|
||||
max_length=48,
|
||||
pattern=r"^[a-zA-Z0-9_-]+$",
|
||||
)
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import pytest
|
||||
|
||||
from remnawave_api.models import LoginRequestDto, LoginResponseDto
|
||||
from remnawave_api.models import LoginRequestDto, LoginResponseDto, LoginTelegramRequestDto
|
||||
from remnawave_api.exceptions import ForbiddenError, ApiError
|
||||
from tests.conftest import REMNAWAVE_ADMIN_PASSWORD, REMNAWAVE_ADMIN_USERNAME
|
||||
|
||||
|
||||
|
|
@ -13,3 +14,22 @@ async def test_auth(remnawave):
|
|||
)
|
||||
)
|
||||
assert isinstance(login, LoginResponseDto)
|
||||
|
||||
try:
|
||||
telegram_login = await remnawave.auth.oauth2_tg_callback(
|
||||
LoginTelegramRequestDto(
|
||||
id=123456789,
|
||||
first_name="Test",
|
||||
last_name="User",
|
||||
username="testuser",
|
||||
photo_url="https://example.com/photo.jpg",
|
||||
auth_date=1234567890,
|
||||
hash="examplehash",
|
||||
)
|
||||
)
|
||||
pytest.fail("Expected 403 error, but got successful response")
|
||||
except ForbiddenError as e:
|
||||
assert e.status_code == 403, f"Expected 403, got {e.status_code}"
|
||||
print(f"Получено ожидаемое исключение: {e}")
|
||||
except ApiError as e:
|
||||
pytest.fail(f"Неожиданное исключение: {e}")
|
||||
|
|
@ -14,6 +14,8 @@ from remnawave_api.models import (
|
|||
UpdateUserRequestDto,
|
||||
UserResponseDto,
|
||||
UsersResponseDto,
|
||||
TagsResponseDto,
|
||||
RevokeUserRequestDto
|
||||
)
|
||||
from tests.utils import generate_email, generate_random_string
|
||||
|
||||
|
|
@ -118,7 +120,10 @@ async def test_users(remnawave) -> None:
|
|||
assert update_user.description == update_description
|
||||
|
||||
revoke_user_subscription = await remnawave.users.revoke_user_subscription(
|
||||
uuid=string_uuid
|
||||
uuid=string_uuid,
|
||||
# body=RevokeUserRequestDto(
|
||||
# short_uuid="fokfaa"
|
||||
# )
|
||||
)
|
||||
assert isinstance(revoke_user_subscription, UserResponseDto)
|
||||
assert revoke_user_subscription.uuid == create_user.uuid
|
||||
|
|
@ -127,3 +132,6 @@ async def test_users(remnawave) -> None:
|
|||
delete_user = await remnawave.users.delete_user(uuid=string_uuid)
|
||||
assert isinstance(delete_user, DeleteUserResponseDto)
|
||||
assert delete_user.is_deleted is True
|
||||
|
||||
users_tags = await remnawave.users.get_all_tags()
|
||||
assert isinstance(users_tags, TagsResponseDto)
|
||||
Loading…
Add table
Add a link
Reference in a new issue