| 1 |
a47eb4c |
Dawsh |
2y ago |
import sqlalchemy |
| 2 |
9ddfbc8 |
Mardin |
2y ago |
from fastapi import APIRouter, Query |
| 3 |
c13a1aa |
Dawsh |
2y ago |
from fastapi import HTTPException |
| 4 |
d4ec019 |
Dawsh |
2y ago |
from fastapi_pagination.ext.sqlalchemy import paginate |
| 5 |
d4ec019 |
Dawsh |
2y ago |
from fastapi_pagination.links import Page |
| 6 |
a47eb4c |
Dawsh |
2y ago |
|
| 7 |
d6e2aad |
Dawsh |
2y ago |
from app import marznode |
| 8 |
c13a1aa |
Dawsh |
2y ago |
from app.db import crud |
| 9 |
db68a58 |
Dawsh |
2y ago |
from app.db.models import Service, User |
| 10 |
9ddfbc8 |
Mardin |
2y ago |
from app.dependencies import DBDep, AdminDep, SudoAdminDep |
| 11 |
db68a58 |
Dawsh |
2y ago |
from app.models.proxy import Inbound |
| 12 |
01cdf2e |
Dawsh |
2y ago |
from app.models.service import ServiceCreate, ServiceModify, ServiceResponse |
| 13 |
db68a58 |
Dawsh |
2y ago |
from app.models.user import UserResponse |
| 14 |
a47eb4c |
Dawsh |
2y ago |
|
| 15 |
9ddfbc8 |
Mardin |
2y ago |
router = APIRouter(prefix="/services", tags=["Service"]) |
| 16 |
a47eb4c |
Dawsh |
2y ago |
|
| 17 |
f7af2b3 |
Dawsh |
2y ago |
|
| 18 |
d4ec019 |
Dawsh |
2y ago |
@router.get("", response_model=Page[ServiceResponse]) |
| 19 |
9ddfbc8 |
Mardin |
2y ago |
def get_services(db: DBDep, admin: AdminDep, name: str = Query(None)): |
| 20 |
d4ec019 |
Dawsh |
2y ago |
query = db.query(Service) |
| 21 |
4708fcb |
Dawsh |
2y ago |
|
| 22 |
d4ec019 |
Dawsh |
2y ago |
if name: |
| 23 |
d4ec019 |
Dawsh |
2y ago |
query = query.filter(Service.name.ilike(f"%{name}%")) |
| 24 |
4708fcb |
Dawsh |
2y ago |
|
| 25 |
4708fcb |
Dawsh |
2y ago |
if not admin.is_sudo and not admin.all_services_access: |
| 26 |
4708fcb |
Dawsh |
2y ago |
query = query.filter(Service.id.in_(admin.service_ids)) |
| 27 |
4708fcb |
Dawsh |
2y ago |
|
| 28 |
d4ec019 |
Dawsh |
2y ago |
return paginate(query) |
| 29 |
d4ec019 |
Dawsh |
2y ago |
|
| 30 |
d4ec019 |
Dawsh |
2y ago |
|
| 31 |
2de9d72 |
Dawsh |
2y ago |
@router.post("", response_model=ServiceResponse) |
| 32 |
9ddfbc8 |
Mardin |
2y ago |
def add_service(new_service: ServiceCreate, db: DBDep, admin: SudoAdminDep): |
| 33 |
a47eb4c |
Dawsh |
2y ago |
""" |
| 34 |
d6e2aad |
Dawsh |
2y ago |
Add a new service |
| 35 |
a47eb4c |
Dawsh |
2y ago |
|
| 36 |
d6e2aad |
Dawsh |
2y ago |
- **name** service name |
| 37 |
d6e2aad |
Dawsh |
2y ago |
- **inbounds** list of inbound ids |
| 38 |
a47eb4c |
Dawsh |
2y ago |
""" |
| 39 |
a47eb4c |
Dawsh |
2y ago |
try: |
| 40 |
a47eb4c |
Dawsh |
2y ago |
return crud.create_service(db, new_service) |
| 41 |
a47eb4c |
Dawsh |
2y ago |
except sqlalchemy.exc.IntegrityError: |
| 42 |
a47eb4c |
Dawsh |
2y ago |
db.rollback() |
| 43 |
01cdf2e |
Dawsh |
2y ago |
raise HTTPException( |
| 44 |
01cdf2e |
Dawsh |
2y ago |
status_code=409, detail="Service by this name already exists" |
| 45 |
01cdf2e |
Dawsh |
2y ago |
) |
| 46 |
a47eb4c |
Dawsh |
2y ago |
|
| 47 |
a47eb4c |
Dawsh |
2y ago |
|
| 48 |
2de9d72 |
Dawsh |
2y ago |
@router.get("/{id}", response_model=ServiceResponse) |
| 49 |
9ddfbc8 |
Mardin |
2y ago |
def get_service(id: int, db: DBDep, admin: AdminDep): |
| 50 |
a47eb4c |
Dawsh |
2y ago |
""" |
| 51 |
a47eb4c |
Dawsh |
2y ago |
Get Service information with id |
| 52 |
a47eb4c |
Dawsh |
2y ago |
""" |
| 53 |
a47eb4c |
Dawsh |
2y ago |
dbservice = crud.get_service(db, id) |
| 54 |
a47eb4c |
Dawsh |
2y ago |
if not dbservice: |
| 55 |
a47eb4c |
Dawsh |
2y ago |
raise HTTPException(status_code=404, detail="Service not found") |
| 56 |
a47eb4c |
Dawsh |
2y ago |
|
| 57 |
33f2c28 |
Dawsh |
2y ago |
if not ( |
| 58 |
33f2c28 |
Dawsh |
2y ago |
admin.is_sudo or admin.all_services_access or id in admin.service_ids |
| 59 |
33f2c28 |
Dawsh |
2y ago |
): |
| 60 |
4708fcb |
Dawsh |
2y ago |
raise HTTPException(status_code=403, detail="You're not allowed") |
| 61 |
4708fcb |
Dawsh |
2y ago |
|
| 62 |
a47eb4c |
Dawsh |
2y ago |
return dbservice |
| 63 |
a47eb4c |
Dawsh |
2y ago |
|
| 64 |
a47eb4c |
Dawsh |
2y ago |
|
| 65 |
db68a58 |
Dawsh |
2y ago |
@router.get("/{id}/users", response_model=Page[UserResponse]) |
| 66 |
9ddfbc8 |
Mardin |
2y ago |
def get_service_users(id: int, db: DBDep, admin: SudoAdminDep): |
| 67 |
db68a58 |
Dawsh |
2y ago |
""" |
| 68 |
db68a58 |
Dawsh |
2y ago |
Get service users |
| 69 |
db68a58 |
Dawsh |
2y ago |
""" |
| 70 |
db68a58 |
Dawsh |
2y ago |
service = crud.get_service(db, id) |
| 71 |
db68a58 |
Dawsh |
2y ago |
|
| 72 |
db68a58 |
Dawsh |
2y ago |
if not service: |
| 73 |
db68a58 |
Dawsh |
2y ago |
raise HTTPException(status_code=404, detail="Service not found") |
| 74 |
db68a58 |
Dawsh |
2y ago |
|
| 75 |
fdd3f61 |
Dawsh |
2y ago |
query = ( |
| 76 |
fdd3f61 |
Dawsh |
2y ago |
db.query(User) |
| 77 |
fdd3f61 |
Dawsh |
2y ago |
.join(User.services) |
| 78 |
fdd3f61 |
Dawsh |
2y ago |
.where(Service.id == service.id) |
| 79 |
fdd3f61 |
Dawsh |
2y ago |
.filter(User.removed != True) |
| 80 |
fdd3f61 |
Dawsh |
2y ago |
) |
| 81 |
db68a58 |
Dawsh |
2y ago |
|
| 82 |
db68a58 |
Dawsh |
2y ago |
return paginate(query) |
| 83 |
db68a58 |
Dawsh |
2y ago |
|
| 84 |
db68a58 |
Dawsh |
2y ago |
|
| 85 |
db68a58 |
Dawsh |
2y ago |
@router.get("/{id}/inbounds", response_model=Page[Inbound]) |
| 86 |
9ddfbc8 |
Mardin |
2y ago |
def get_service_inbounds(id: int, db: DBDep, admin: SudoAdminDep): |
| 87 |
db68a58 |
Dawsh |
2y ago |
""" |
| 88 |
db68a58 |
Dawsh |
2y ago |
Get service inbounds |
| 89 |
db68a58 |
Dawsh |
2y ago |
""" |
| 90 |
db68a58 |
Dawsh |
2y ago |
service = crud.get_service(db, id) |
| 91 |
db68a58 |
Dawsh |
2y ago |
|
| 92 |
db68a58 |
Dawsh |
2y ago |
if not service: |
| 93 |
db68a58 |
Dawsh |
2y ago |
raise HTTPException(status_code=404, detail="Service not found") |
| 94 |
db68a58 |
Dawsh |
2y ago |
|
| 95 |
f1ab16c |
Dawsh |
2y ago |
query = ( |
| 96 |
f1ab16c |
Dawsh |
2y ago |
db.query(Inbound) |
| 97 |
f1ab16c |
Dawsh |
2y ago |
.join(Inbound.services) |
| 98 |
f1ab16c |
Dawsh |
2y ago |
.where(Service.id == service.id) |
| 99 |
f1ab16c |
Dawsh |
2y ago |
) |
| 100 |
db68a58 |
Dawsh |
2y ago |
|
| 101 |
db68a58 |
Dawsh |
2y ago |
return paginate(query) |
| 102 |
db68a58 |
Dawsh |
2y ago |
|
| 103 |
db68a58 |
Dawsh |
2y ago |
|
| 104 |
2de9d72 |
Dawsh |
2y ago |
@router.put("/{id}", response_model=ServiceResponse) |
| 105 |
9ddfbc8 |
Mardin |
2y ago |
async def modify_service( |
| 106 |
9ddfbc8 |
Mardin |
2y ago |
id: int, modification: ServiceModify, db: DBDep, admin: SudoAdminDep |
| 107 |
9ddfbc8 |
Mardin |
2y ago |
): |
| 108 |
a47eb4c |
Dawsh |
2y ago |
""" |
| 109 |
a47eb4c |
Dawsh |
2y ago |
Modify Service |
| 110 |
a47eb4c |
Dawsh |
2y ago |
|
| 111 |
a47eb4c |
Dawsh |
2y ago |
- **name** can be up to 64 characters |
| 112 |
ee1351a |
Dawsh |
2y ago |
- **inbounds** list of inbound ids. if not specified no change will be applied; |
| 113 |
ee1351a |
Dawsh |
2y ago |
in case of an empty list all inbounds would be removed. |
| 114 |
a47eb4c |
Dawsh |
2y ago |
""" |
| 115 |
a47eb4c |
Dawsh |
2y ago |
dbservice = crud.get_service(db, id) |
| 116 |
c13a1aa |
Dawsh |
2y ago |
if not dbservice: |
| 117 |
01cdf2e |
Dawsh |
2y ago |
raise HTTPException(status_code=404, detail="Service not found") |
| 118 |
d6e2aad |
Dawsh |
2y ago |
old_inbounds = {(i.node_id, i.protocol, i.tag) for i in dbservice.inbounds} |
| 119 |
a47eb4c |
Dawsh |
2y ago |
try: |
| 120 |
d6e2aad |
Dawsh |
2y ago |
response = crud.update_service(db, dbservice, modification) |
| 121 |
a47eb4c |
Dawsh |
2y ago |
except sqlalchemy.exc.IntegrityError: |
| 122 |
a47eb4c |
Dawsh |
2y ago |
db.rollback() |
| 123 |
f1ab16c |
Dawsh |
2y ago |
raise HTTPException( |
| 124 |
f1ab16c |
Dawsh |
2y ago |
status_code=409, detail="problem updating the service" |
| 125 |
f1ab16c |
Dawsh |
2y ago |
) |
| 126 |
d6e2aad |
Dawsh |
2y ago |
else: |
| 127 |
d6e2aad |
Dawsh |
2y ago |
for user in response.users: |
| 128 |
d377c4c |
Dawsh |
2y ago |
if user.activated: |
| 129 |
d377c4c |
Dawsh |
2y ago |
marznode.operations.update_user( |
| 130 |
d377c4c |
Dawsh |
2y ago |
user, old_inbounds=old_inbounds |
| 131 |
d377c4c |
Dawsh |
2y ago |
) |
| 132 |
d6e2aad |
Dawsh |
2y ago |
return response |
| 133 |
a47eb4c |
Dawsh |
2y ago |
|
| 134 |
a47eb4c |
Dawsh |
2y ago |
|
| 135 |
2de9d72 |
Dawsh |
2y ago |
@router.delete("/{id}") |
| 136 |
9ddfbc8 |
Mardin |
2y ago |
def remove_service(id: int, db: DBDep, admin: SudoAdminDep): |
| 137 |
a47eb4c |
Dawsh |
2y ago |
dbservice = crud.get_service(db, id) |
| 138 |
c13a1aa |
Dawsh |
2y ago |
if not dbservice: |
| 139 |
a47eb4c |
Dawsh |
2y ago |
raise HTTPException(status_code=404, detail="Service not found") |
| 140 |
01cdf2e |
Dawsh |
2y ago |
|
| 141 |
ee1351a |
Dawsh |
2y ago |
crud.remove_service(db, dbservice) |
| 142 |
ee1351a |
Dawsh |
2y ago |
return dict() |