Compare commits
5 commits
e2f916debc
...
bc3f7984f5
| Author | SHA1 | Date | |
|---|---|---|---|
| bc3f7984f5 | |||
| c7f93d468e | |||
| 24ade65bb0 | |||
| 04a5798258 | |||
| 730c7ab966 |
5 changed files with 140 additions and 50 deletions
|
|
@ -0,0 +1,7 @@
|
||||||
|
from .capability import Capability
|
||||||
|
from .connection import Connection
|
||||||
|
from .device import Device, DeviceBase, DeviceCreate
|
||||||
|
from .user import User, UserBase, UserCreate, UserRead
|
||||||
|
|
||||||
|
__all__ = ["Capability", "Connection", "Device", "DeviceBase", "DeviceCreate",
|
||||||
|
"User", "UserBase", "UserCreate", "UserRead"]
|
||||||
|
|
@ -13,9 +13,11 @@ class Capability(Enum):
|
||||||
issue = "issue"
|
issue = "issue"
|
||||||
renew = "renew"
|
renew = "renew"
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
class UserCapabilityBase(SQLModel):
|
class UserCapabilityBase(SQLModel):
|
||||||
user_name: str = Field(primary_key=True, foreign_key="user.name")
|
|
||||||
capability_name: str = Field(primary_key=True)
|
capability_name: str = Field(primary_key=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -27,6 +29,8 @@ class UserCapabilityBase(SQLModel):
|
||||||
|
|
||||||
|
|
||||||
class UserCapability(UserCapabilityBase, table=True):
|
class UserCapability(UserCapabilityBase, table=True):
|
||||||
|
user_name: str = Field(primary_key=True, foreign_key="user.name")
|
||||||
|
|
||||||
user: "User" = Relationship(
|
user: "User" = Relationship(
|
||||||
back_populates="capabilities"
|
back_populates="capabilities",
|
||||||
)
|
)
|
||||||
75
api/kiwi_vpn_api/db_new/device.py
Normal file
75
api/kiwi_vpn_api/db_new/device.py
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from sqlalchemy.exc import IntegrityError
|
||||||
|
from sqlmodel import Field, Relationship, SQLModel, UniqueConstraint
|
||||||
|
|
||||||
|
from .connection import Connection
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .user import User
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceBase(SQLModel):
|
||||||
|
name: str
|
||||||
|
type: str
|
||||||
|
expiry: datetime | None
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceCreate(DeviceBase):
|
||||||
|
owner_name: str | None
|
||||||
|
|
||||||
|
|
||||||
|
class Device(DeviceBase, table=True, ):
|
||||||
|
__table_args__ = (UniqueConstraint(
|
||||||
|
"owner_name",
|
||||||
|
"name",
|
||||||
|
),)
|
||||||
|
|
||||||
|
id: int | None = Field(primary_key=True)
|
||||||
|
owner_name: str | None = Field(foreign_key="user.name")
|
||||||
|
|
||||||
|
owner: User = Relationship(
|
||||||
|
back_populates="devices",
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls, **kwargs) -> Device | None:
|
||||||
|
"""
|
||||||
|
Create a new device in the database.
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
with Connection.session as db:
|
||||||
|
device = cls.from_orm(DeviceCreate(**kwargs))
|
||||||
|
|
||||||
|
db.add(device)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(device)
|
||||||
|
|
||||||
|
return device
|
||||||
|
|
||||||
|
except IntegrityError:
|
||||||
|
# device already existed
|
||||||
|
return None
|
||||||
|
|
||||||
|
def update(self) -> None:
|
||||||
|
"""
|
||||||
|
Update this device in the database.
|
||||||
|
"""
|
||||||
|
|
||||||
|
with Connection.session as db:
|
||||||
|
db.add(self)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(self)
|
||||||
|
|
||||||
|
def delete(self) -> bool:
|
||||||
|
"""
|
||||||
|
Delete this device from the database.
|
||||||
|
"""
|
||||||
|
|
||||||
|
with Connection.session as db:
|
||||||
|
db.delete(self)
|
||||||
|
db.commit()
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Sequence
|
from typing import Any
|
||||||
|
|
||||||
from pydantic import root_validator
|
from pydantic import root_validator
|
||||||
from sqlalchemy.exc import IntegrityError
|
from sqlalchemy.exc import IntegrityError
|
||||||
from sqlmodel import Field, Relationship, SQLModel
|
from sqlmodel import Field, Relationship, SQLModel
|
||||||
|
|
||||||
from ..config import Config
|
from ..config import Config
|
||||||
from .capabilities import Capability, UserCapability
|
from .capability import Capability, UserCapability
|
||||||
from .connection import Connection
|
from .connection import Connection
|
||||||
|
from .device import Device
|
||||||
|
|
||||||
|
|
||||||
class UserBase(SQLModel):
|
class UserBase(SQLModel):
|
||||||
|
|
@ -33,6 +34,10 @@ class User(UserBase, table=True):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
devices: list[Device] = Relationship(
|
||||||
|
back_populates="owner",
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, **kwargs) -> User | None:
|
def create(cls, **kwargs) -> User | None:
|
||||||
"""
|
"""
|
||||||
|
|
@ -104,34 +109,19 @@ class User(UserBase, table=True):
|
||||||
db.delete(self)
|
db.delete(self)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
def extend_capabilities(self, capabilities: Sequence[Capability]) -> None:
|
def get_capabilities(self) -> set[Capability]:
|
||||||
"""
|
return set(
|
||||||
Extend this user's capabilities
|
capability._
|
||||||
"""
|
for capability in self.capabilities
|
||||||
|
|
||||||
for capability in capabilities:
|
|
||||||
user_capability = UserCapability(
|
|
||||||
user_name=self.name,
|
|
||||||
capability_name=capability.value,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if user_capability not in self.capabilities:
|
def set_capabilities(self, capabilities: set[Capability]) -> None:
|
||||||
self.capabilities.append(user_capability)
|
self.capabilities = [
|
||||||
|
UserCapability(
|
||||||
def remove_capabilities(self, capabilities: Sequence[Capability]) -> None:
|
|
||||||
"""
|
|
||||||
Remove from this user's capabilities
|
|
||||||
"""
|
|
||||||
|
|
||||||
for capability in capabilities:
|
|
||||||
try:
|
|
||||||
self.capabilities.remove(UserCapability(
|
|
||||||
user_name=self.name,
|
user_name=self.name,
|
||||||
capability_name=capability.value,
|
capability_name=capability.value,
|
||||||
))
|
) for capability in capabilities
|
||||||
|
]
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class UserCreate(UserBase):
|
class UserCreate(UserBase):
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,10 @@ from fastapi import FastAPI
|
||||||
|
|
||||||
from .config import Config, Settings
|
from .config import Config, Settings
|
||||||
from .db import Connection
|
from .db import Connection
|
||||||
from .db.schemata import User
|
# from .db.schemata import User
|
||||||
from .db_new import capabilities, connection, user
|
from .db_new import Capability
|
||||||
|
from .db_new import Connection as Connection_new
|
||||||
|
from .db_new import Device, User
|
||||||
from .routers import main_router
|
from .routers import main_router
|
||||||
|
|
||||||
settings = Settings.get()
|
settings = Settings.get()
|
||||||
|
|
@ -47,31 +49,43 @@ async def on_startup() -> None:
|
||||||
# connect to database
|
# connect to database
|
||||||
Connection.connect(await current_config.db.db_engine)
|
Connection.connect(await current_config.db.db_engine)
|
||||||
|
|
||||||
# some testing
|
# # some testing
|
||||||
with Connection.use() as db:
|
# with Connection.use() as db:
|
||||||
print(User.from_db(db, "admin"))
|
# print(User.from_db(db, "admin"))
|
||||||
print(User.from_db(db, "nonexistent"))
|
# print(User.from_db(db, "nonexistent"))
|
||||||
|
|
||||||
connection.Connection.connect("sqlite:///tmp/v2.db")
|
Connection_new.connect("sqlite:///tmp/v2.db")
|
||||||
|
|
||||||
user.User.create(
|
User.create(
|
||||||
name="Uwe",
|
name="Uwe",
|
||||||
password_clear="ulf",
|
password_clear="ulf",
|
||||||
email="uwe@feh.de",
|
email="uwe@feh.de",
|
||||||
)
|
)
|
||||||
|
|
||||||
print(user.User.get("Uwe"))
|
print(User.get(name="Uwe"))
|
||||||
print(user.User.authenticate("Uwe", "uwe"))
|
print(User.authenticate("Uwe", "uwe"))
|
||||||
|
|
||||||
uwe = user.User.authenticate("Uwe", "ulf")
|
uwe = User.authenticate("Uwe", "ulf")
|
||||||
|
|
||||||
uwe.extend_capabilities([capabilities.Capability.admin])
|
uwe.set_capabilities([Capability.admin])
|
||||||
uwe.update()
|
uwe.update()
|
||||||
print(uwe)
|
print(uwe.get_capabilities())
|
||||||
|
|
||||||
uwe.remove_capabilities([capabilities.Capability.admin])
|
uwe.set_capabilities([])
|
||||||
uwe.update()
|
uwe.update()
|
||||||
print(uwe)
|
print(uwe.get_capabilities())
|
||||||
|
|
||||||
|
with Connection_new.session as db:
|
||||||
|
db.add(uwe)
|
||||||
|
print(uwe.devices)
|
||||||
|
|
||||||
|
ipad = Device.create(
|
||||||
|
owner_name="Uwe",
|
||||||
|
name="iPad",
|
||||||
|
type="tablet",
|
||||||
|
)
|
||||||
|
# ipad = Device.
|
||||||
|
print(ipad)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue