quark
This commit is contained in:
parent
972359cb49
commit
1ed3b587c7
4 changed files with 111 additions and 63 deletions
|
@ -14,34 +14,6 @@ from sqlalchemy.orm import Session, relationship
|
||||||
ORMBaseModel = declarative_base()
|
ORMBaseModel = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
class User(ORMBaseModel):
|
|
||||||
__tablename__ = "users"
|
|
||||||
|
|
||||||
name = Column(String, primary_key=True, index=True)
|
|
||||||
password = Column(String, nullable=False)
|
|
||||||
|
|
||||||
capabilities: list[UserCapability] = relationship(
|
|
||||||
"UserCapability", lazy="joined", cascade="all, delete-orphan"
|
|
||||||
)
|
|
||||||
certificates: list[Certificate] = relationship(
|
|
||||||
"Certificate", lazy="select", back_populates="owner"
|
|
||||||
)
|
|
||||||
distinguished_names: list[DistinguishedName] = relationship(
|
|
||||||
"DistinguishedName", lazy="select", back_populates="owner"
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def load(cls, db: Session, name: str) -> User | None:
|
|
||||||
"""
|
|
||||||
Load user from database by name.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return (db
|
|
||||||
.query(User)
|
|
||||||
.filter(User.name == name)
|
|
||||||
.first())
|
|
||||||
|
|
||||||
|
|
||||||
class UserCapability(ORMBaseModel):
|
class UserCapability(ORMBaseModel):
|
||||||
__tablename__ = "user_capabilities"
|
__tablename__ = "user_capabilities"
|
||||||
|
|
||||||
|
@ -54,53 +26,43 @@ class UserCapability(ORMBaseModel):
|
||||||
capability = Column(String, primary_key=True)
|
capability = Column(String, primary_key=True)
|
||||||
|
|
||||||
|
|
||||||
class DistinguishedName(ORMBaseModel):
|
class User(ORMBaseModel):
|
||||||
__tablename__ = "distinguished_names"
|
__tablename__ = "users"
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
name = Column(String, primary_key=True, index=True)
|
||||||
|
password = Column(String, nullable=False)
|
||||||
|
|
||||||
owner_name = Column(String, ForeignKey("users.name"))
|
|
||||||
cn_only = Column(Boolean, default=True, nullable=False)
|
|
||||||
country = Column(String(2))
|
country = Column(String(2))
|
||||||
state = Column(String)
|
state = Column(String)
|
||||||
city = Column(String)
|
city = Column(String)
|
||||||
organization = Column(String)
|
organization = Column(String)
|
||||||
organizational_unit = Column(String)
|
organizational_unit = Column(String)
|
||||||
|
|
||||||
email = Column(String)
|
email = Column(String)
|
||||||
common_name = Column(String, nullable=False)
|
|
||||||
|
capabilities: list[UserCapability] = relationship(
|
||||||
|
"UserCapability", lazy="joined", cascade="all, delete-orphan"
|
||||||
|
)
|
||||||
|
devices: list[Device] = relationship(
|
||||||
|
"Device", lazy="select", back_populates="owner"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Device(ORMBaseModel):
|
||||||
|
__tablename__ = "devices"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||||
|
|
||||||
|
owner_name = Column(String, ForeignKey("users.name"))
|
||||||
|
name = Column(String)
|
||||||
|
type = Column(String)
|
||||||
|
expiry = Column(DateTime, default=datetime.datetime.now)
|
||||||
|
|
||||||
owner: User = relationship(
|
owner: User = relationship(
|
||||||
"User", lazy="joined", back_populates="distinguished_names"
|
"User", lazy="joined", back_populates="distinguished_names"
|
||||||
)
|
)
|
||||||
|
|
||||||
UniqueConstraint(
|
UniqueConstraint(
|
||||||
country,
|
owner_name,
|
||||||
state,
|
name,
|
||||||
city,
|
|
||||||
organization,
|
|
||||||
organizational_unit,
|
|
||||||
email,
|
|
||||||
common_name,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Certificate(ORMBaseModel):
|
|
||||||
__tablename__ = "certificates"
|
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
||||||
|
|
||||||
owner_name = Column(String, ForeignKey("users.name"))
|
|
||||||
dn_id = Column(
|
|
||||||
Integer,
|
|
||||||
ForeignKey("distinguished_names.id"),
|
|
||||||
nullable=False,
|
|
||||||
)
|
|
||||||
expiry = Column(DateTime, default=datetime.datetime.now)
|
|
||||||
|
|
||||||
distinguished_name: DistinguishedName = relationship(
|
|
||||||
"DistinguishedName", lazy="joined"
|
|
||||||
)
|
|
||||||
|
|
||||||
owner: User = relationship(
|
|
||||||
"User", lazy="joined", back_populates="certificates"
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -79,6 +79,36 @@ class DistinguishedName(DistinguishedNameBase):
|
||||||
# distinguished name already existed
|
# distinguished name already existed
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def delete(
|
||||||
|
self,
|
||||||
|
db: Session,
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Delete this distinguished name from the database.
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_dn = models.DistinguishedName(**dict(self))
|
||||||
|
db.refresh(db_dn)
|
||||||
|
|
||||||
|
# .load(
|
||||||
|
# db=db,
|
||||||
|
# country=self.country,
|
||||||
|
# state=self.state,
|
||||||
|
# city=self.city,
|
||||||
|
# organization=self.organization,
|
||||||
|
# organizational_unit=self.organizational_unit,
|
||||||
|
# email=self.email,
|
||||||
|
# common_name=self.common_name,
|
||||||
|
# )
|
||||||
|
|
||||||
|
if db_dn is None:
|
||||||
|
# nonexistent user
|
||||||
|
return False
|
||||||
|
|
||||||
|
db.delete(db_dn)
|
||||||
|
db.commit()
|
||||||
|
return True
|
||||||
|
|
||||||
##########
|
##########
|
||||||
# table: certificates
|
# table: certificates
|
||||||
##########
|
##########
|
||||||
|
|
|
@ -56,3 +56,33 @@ async def add_distinguished_name(
|
||||||
|
|
||||||
# return the created user on success
|
# return the created user on success
|
||||||
return new_dn
|
return new_dn
|
||||||
|
|
||||||
|
|
||||||
|
# @router.delete(
|
||||||
|
# "",
|
||||||
|
# responses={
|
||||||
|
# status.HTTP_200_OK: Responses.OK,
|
||||||
|
# status.HTTP_400_BAD_REQUEST: Responses.NOT_INSTALLED,
|
||||||
|
# status.HTTP_401_UNAUTHORIZED: Responses.NEEDS_USER,
|
||||||
|
# status.HTTP_403_FORBIDDEN: Responses.NEEDS_ADMIN,
|
||||||
|
# status.HTTP_404_NOT_FOUND: Responses.ENTRY_DOESNT_EXIST,
|
||||||
|
# },
|
||||||
|
# )
|
||||||
|
# async def remove_distinguished_name(
|
||||||
|
# user_name: str,
|
||||||
|
# _: User = Depends(get_current_user_if_admin),
|
||||||
|
# db: Session | None = Depends(Connection.get),
|
||||||
|
# ):
|
||||||
|
# """
|
||||||
|
# DELETE ./{user_name}: Remove a user from the database.
|
||||||
|
# """
|
||||||
|
|
||||||
|
# # get the user
|
||||||
|
# user = User.from_db(
|
||||||
|
# db=db,
|
||||||
|
# name=user_name,
|
||||||
|
# )
|
||||||
|
|
||||||
|
# # fail if deletion was unsuccessful
|
||||||
|
# if user is None or not user.delete(db):
|
||||||
|
# raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
26
api/plan.md
Normal file
26
api/plan.md
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
## Server props
|
||||||
|
- default DN parts: country, state, city, org, OU
|
||||||
|
- "customizable" flags for DN parts
|
||||||
|
- flag: use client-to-client
|
||||||
|
- force cipher, tls-cipher, auth params
|
||||||
|
- server name
|
||||||
|
- default certification length
|
||||||
|
- default certificate algo
|
||||||
|
|
||||||
|
## User props
|
||||||
|
- username
|
||||||
|
- password
|
||||||
|
- custom DN parts: country, state, city, org, OU
|
||||||
|
- email
|
||||||
|
|
||||||
|
## User caps
|
||||||
|
- admin: administrator
|
||||||
|
- login: can log into the web interface
|
||||||
|
- certify: can certify own devices without approval
|
||||||
|
- renew: can renew certificates for own devices
|
||||||
|
|
||||||
|
## Device props
|
||||||
|
- name
|
||||||
|
- type (icon)
|
||||||
|
- is active
|
||||||
|
- certified until
|
Loading…
Reference in a new issue