check issue permission
This commit is contained in:
parent
2d39c4aaa3
commit
d8bdb46a5c
4 changed files with 51 additions and 15 deletions
|
@ -23,7 +23,6 @@ class DeviceBase(SQLModel):
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
type: str
|
type: str
|
||||||
expiry: datetime | None
|
|
||||||
|
|
||||||
|
|
||||||
class DeviceCreate(DeviceBase):
|
class DeviceCreate(DeviceBase):
|
||||||
|
@ -37,11 +36,13 @@ class DeviceRead(DeviceBase):
|
||||||
Representation of a device read via the API
|
Representation of a device read via the API
|
||||||
"""
|
"""
|
||||||
|
|
||||||
approved: bool
|
id: int | None = Field(primary_key=True)
|
||||||
owner_name: str | None
|
approved: bool | None = Field(default=None)
|
||||||
|
expiry: datetime | None = Field(default=None)
|
||||||
|
owner_name: str = Field(foreign_key="user.name")
|
||||||
|
|
||||||
|
|
||||||
class Device(DeviceBase, table=True):
|
class Device(DeviceRead, table=True):
|
||||||
"""
|
"""
|
||||||
Representation of `device` table
|
Representation of `device` table
|
||||||
"""
|
"""
|
||||||
|
@ -51,10 +52,6 @@ class Device(DeviceBase, table=True):
|
||||||
"name",
|
"name",
|
||||||
),)
|
),)
|
||||||
|
|
||||||
id: int | None = Field(primary_key=True)
|
|
||||||
approved: bool = Field(default=False)
|
|
||||||
owner_name: str | None = Field(foreign_key="user.name")
|
|
||||||
|
|
||||||
# no idea, but "User" (in quotes) doesn't work here
|
# no idea, but "User" (in quotes) doesn't work here
|
||||||
# might be a future problem?
|
# might be a future problem?
|
||||||
owner: User = Relationship(
|
owner: User = Relationship(
|
||||||
|
@ -74,8 +71,7 @@ class Device(DeviceBase, table=True):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with Connection.session as db:
|
with Connection.session as db:
|
||||||
new_device = cls.from_orm(device)
|
new_device = cls.from_orm(device, {"owner_name": owner.name})
|
||||||
new_device.owner = owner
|
|
||||||
|
|
||||||
db.add(new_device)
|
db.add(new_device)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
|
@ -281,3 +281,23 @@ class User(UserBase, table=True):
|
||||||
|
|
||||||
# deny be default
|
# deny be default
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def can_issue(self, device: Device) -> bool:
|
||||||
|
"""
|
||||||
|
Check if this user can issue a certificate without approval.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
device.approved in (None, False)
|
||||||
|
and (self.is_admin or self.has_tag(TagValue.issue))
|
||||||
|
)
|
||||||
|
|
||||||
|
def can_renew(self, device: Device) -> bool:
|
||||||
|
"""
|
||||||
|
Check if this user can renew a certificate without approval.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return (
|
||||||
|
device.approved is True
|
||||||
|
and (self.is_admin or self.has_tag(TagValue.renew))
|
||||||
|
)
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
/device endpoints.
|
/device endpoints.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, status
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
|
|
||||||
from ..db import Connection, Device, DeviceCreate, DeviceRead, User
|
from ..db import Connection, Device, DeviceCreate, DeviceRead, User
|
||||||
|
@ -106,7 +108,20 @@ async def request_certificate(
|
||||||
db.add(device)
|
db.add(device)
|
||||||
dn = DistinguishedName.build(device)
|
dn = DistinguishedName.build(device)
|
||||||
|
|
||||||
easy_rsa.issue(
|
if current_user.can_issue(device):
|
||||||
dn=dn,
|
device.approved = True
|
||||||
cert_type=CertificateType.server,
|
|
||||||
)
|
if (cert := easy_rsa.issue(
|
||||||
|
dn=dn,
|
||||||
|
cert_type=CertificateType.server,
|
||||||
|
)) is not None:
|
||||||
|
assert (expiry := cert.get_notAfter()) is not None
|
||||||
|
|
||||||
|
date_format, encoding = "%Y%m%d%H%M%SZ", "ascii"
|
||||||
|
expiry = datetime.strptime(
|
||||||
|
expiry.decode(encoding),
|
||||||
|
date_format,
|
||||||
|
)
|
||||||
|
device.expiry = expiry
|
||||||
|
|
||||||
|
db.commit()
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
- approved: bool
|
- approved: bool
|
||||||
- expiry
|
- expiry
|
||||||
|
|
||||||
|
## Device status
|
||||||
|
- created (approved = NULL): device has been newly created
|
||||||
|
- requested (approved = false): certificate has been requested (issue or renew)
|
||||||
|
- issued (approved = true): certificate has been granted (may be expired)
|
||||||
|
|
||||||
## Permissions
|
## Permissions
|
||||||
- admin cannot "admin" itself (to prevent self decapitation)
|
- admin cannot "admin" itself (to prevent self decapitation)
|
||||||
- admin can "edit", "admin" and "create" everything else
|
- admin can "edit", "admin" and "create" everything else
|
||||||
|
@ -37,5 +42,5 @@
|
||||||
- admin: add or remove tag, delete, generate password
|
- admin: add or remove tag, delete, generate password
|
||||||
|
|
||||||
### Device
|
### Device
|
||||||
- edit: change type, delete
|
- edit: change type, delete, request
|
||||||
- admin: approve
|
- admin: approve
|
||||||
|
|
Loading…
Reference in a new issue