Capabilities
This commit is contained in:
parent
9625336df9
commit
e2f916debc
3 changed files with 83 additions and 3 deletions
32
api/kiwi_vpn_api/db_new/capabilities.py
Normal file
32
api/kiwi_vpn_api/db_new/capabilities.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
from enum import Enum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sqlmodel import Field, Relationship, SQLModel
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .user import User
|
||||
|
||||
|
||||
class Capability(Enum):
|
||||
admin = "admin"
|
||||
login = "login"
|
||||
issue = "issue"
|
||||
renew = "renew"
|
||||
|
||||
|
||||
class UserCapabilityBase(SQLModel):
|
||||
user_name: str = Field(primary_key=True, foreign_key="user.name")
|
||||
capability_name: str = Field(primary_key=True)
|
||||
|
||||
@property
|
||||
def _(self) -> Capability:
|
||||
return Capability(self.capability_name)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return self.capability_name
|
||||
|
||||
|
||||
class UserCapability(UserCapabilityBase, table=True):
|
||||
user: "User" = Relationship(
|
||||
back_populates="capabilities"
|
||||
)
|
|
@ -1,12 +1,13 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
from typing import Any, Sequence
|
||||
|
||||
from pydantic import root_validator
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlmodel import Field, SQLModel
|
||||
from sqlmodel import Field, Relationship, SQLModel
|
||||
|
||||
from ..config import Config
|
||||
from .capabilities import Capability, UserCapability
|
||||
from .connection import Connection
|
||||
|
||||
|
||||
|
@ -24,6 +25,14 @@ class UserBase(SQLModel):
|
|||
class User(UserBase, table=True):
|
||||
password: str
|
||||
|
||||
capabilities: list[UserCapability] = Relationship(
|
||||
back_populates="user",
|
||||
sa_relationship_kwargs={
|
||||
"lazy": "joined",
|
||||
"cascade": "all, delete-orphan",
|
||||
},
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def create(cls, **kwargs) -> User | None:
|
||||
"""
|
||||
|
@ -94,6 +103,37 @@ class User(UserBase, table=True):
|
|||
with Connection.session as db:
|
||||
db.delete(self)
|
||||
db.commit()
|
||||
|
||||
def extend_capabilities(self, capabilities: Sequence[Capability]) -> None:
|
||||
"""
|
||||
Extend this user's capabilities
|
||||
"""
|
||||
|
||||
for capability in capabilities:
|
||||
user_capability = UserCapability(
|
||||
user_name=self.name,
|
||||
capability_name=capability.value,
|
||||
)
|
||||
|
||||
if user_capability not in self.capabilities:
|
||||
self.capabilities.append(user_capability)
|
||||
|
||||
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,
|
||||
capability_name=capability.value,
|
||||
))
|
||||
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
class UserCreate(UserBase):
|
||||
password: str | None = Field(default=None)
|
||||
password_clear: str | None = Field(default=None)
|
||||
|
|
|
@ -15,7 +15,7 @@ from fastapi import FastAPI
|
|||
from .config import Config, Settings
|
||||
from .db import Connection
|
||||
from .db.schemata import User
|
||||
from .db_new import connection, user
|
||||
from .db_new import capabilities, connection, user
|
||||
from .routers import main_router
|
||||
|
||||
settings = Settings.get()
|
||||
|
@ -65,6 +65,14 @@ async def on_startup() -> None:
|
|||
|
||||
uwe = user.User.authenticate("Uwe", "ulf")
|
||||
|
||||
uwe.extend_capabilities([capabilities.Capability.admin])
|
||||
uwe.update()
|
||||
print(uwe)
|
||||
|
||||
uwe.remove_capabilities([capabilities.Capability.admin])
|
||||
uwe.update()
|
||||
print(uwe)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
uvicorn.run(
|
||||
|
|
Loading…
Reference in a new issue