Source code for qcportal.auth.models
from enum import Enum
from pydantic import BaseModel, Field, field_validator, ConfigDict
from ..common_types import Max128Str
from ..exceptions import InvalidPasswordError, InvalidUsernameError, InvalidGroupnameError
[docs]
class AuthTypeEnum(str, Enum):
password = "password"
[docs]
def is_valid_password(password: str) -> None:
# Null character not allowed
if "\x00" in password:
raise InvalidPasswordError("Password contains a NUL character")
# Password should be somewhat long
if len(password) == 0:
raise InvalidPasswordError("Password is empty")
if len(password) < 6:
raise InvalidPasswordError("Password must contain at least 6 characters")
[docs]
def is_valid_username(username: str) -> None:
if len(username) == 0:
raise InvalidUsernameError("Username is empty")
# Null character not allowed
if "\x00" in username:
raise InvalidUsernameError("Username contains a NUL character")
# Spaces are not allowed
if " " in username:
raise InvalidUsernameError("Username contains spaces")
# Username cannot be all numbers
if username.isdecimal():
raise InvalidUsernameError("Username cannot be all numbers")
[docs]
def is_valid_groupname(groupname: str) -> None:
if len(groupname) == 0:
raise InvalidGroupnameError("Groupname is empty")
# Null character not allowed
if "\x00" in groupname:
raise InvalidGroupnameError("Groupname contains a NUL character")
# Spaces are not allowed
if " " in groupname:
raise InvalidGroupnameError("Groupname contains spaces")
# Groupname cannot be all numbers
if groupname.isdecimal():
raise InvalidGroupnameError("Groupname cannot be all numbers")
[docs]
class GroupInfo(BaseModel):
"""
Information about a group
"""
id: int | None = Field(None, description="ID of the group")
groupname: str = Field(..., description="The name of the group")
description: str = Field("", description="Text description of the group")
model_config = ConfigDict(extra="forbid")
@field_validator("groupname", mode="before")
@classmethod
def _valid_groupname(cls, v):
"""Makes sure the groupname is a valid string"""
try:
is_valid_groupname(v)
return v
except Exception as e:
raise ValueError(str(e))
[docs]
class UserInfo(BaseModel):
"""
Information about a user
"""
# id may be None when used for initial creation
id: int | None = Field(None, frozen=True, description="The id of the user")
auth_type: AuthTypeEnum = Field(
AuthTypeEnum.password, frozen=True, description="Type of authentication the user uses"
)
username: str = Field(..., frozen=True, description="The username of this user")
role: str = Field(..., description="The role this user belongs to")
groups: list[str] = Field([], description="Groups this user belongs to")
enabled: bool = Field(..., description="Whether this user is enabled or not")
fullname: Max128Str = Field("", description="The full name or description of the user")
organization: Max128Str = Field("", description="The organization the user belongs to")
email: Max128Str = Field("", description="The email address for the user")
model_config = ConfigDict(extra="forbid")
@field_validator("username", mode="before")
@classmethod
def _valid_username(cls, v):
"""Makes sure the username is a valid string"""
try:
is_valid_username(v)
return v
except Exception as e:
raise ValueError(str(e))
@field_validator("groups", mode="after")
@classmethod
def _valid_groupnames(cls, v):
"""Makes sure the groupnames are valid strings"""
try:
for x in v:
is_valid_groupname(x)
return v
except Exception as e:
raise ValueError(str(e))