Source code for privacyidea.models.tokengroup

# SPDX-FileCopyrightText: (C) 2025 NetKnights GmbH <https://netknights.it>
# SPDX-FileCopyrightText: (C) 2025 Paul Lettich <paul.lettich@netknights.it>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# This code is free software; you can redistribute it and/or
# modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
# as published by the Free Software Foundation; either
# version 3 of the License, or any later version.
#
# This code is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with this program.  If not, see <http://www.gnu.org/licenses/>.
import logging
from typing import TYPE_CHECKING

from sqlalchemy import Unicode, Integer, UniqueConstraint, select
from sqlalchemy.orm import Mapped, mapped_column, relationship

from privacyidea.lib.log import log_with
from privacyidea.models import db
from privacyidea.models.config import (TimestampMethodsMixin)

if TYPE_CHECKING:
    from privacyidea.models.token import Token

log = logging.getLogger(__name__)


[docs] class Tokengroup(TimestampMethodsMixin, db.Model): """ The tokengroup table contains the definition of available token groups. A token can then be assigned to several of these tokengroups. """ __tablename__ = 'tokengroup' id: Mapped[int] = mapped_column(Integer, primary_key=True, nullable=False) name: Mapped[str] = mapped_column(Unicode(255), default='', unique=True, nullable=False) Description: Mapped[str | None] = mapped_column(Unicode(2000), default='') # Define relationship back to Token for deletion cascade tokens: Mapped[list['Token']] = relationship('Token', secondary='tokentokengroup', back_populates='tokengroup_list') @log_with(log) def __init__(self, groupname: str, description: str | None = None): self.name = groupname self.Description = description
[docs] class TokenTokengroup(TimestampMethodsMixin, db.Model): """ This table stores the assignment of tokens to tokengroups. A token can be assigned to several different token groups. """ __tablename__ = 'tokentokengroup' __table_args__ = (UniqueConstraint('token_id', 'tokengroup_id', name='ttgix_2'),) id: Mapped[int] = mapped_column(Integer, primary_key=True) token_id: Mapped[int | None] = mapped_column(Integer, db.ForeignKey('token.id')) tokengroup_id: Mapped[int | None] = mapped_column(Integer, db.ForeignKey('tokengroup.id')) def __init__(self, tokengroup_id: int = 0, token_id: int = 0, tokengroupname: str | None = None): """ Create a new TokenTokengroup assignment :param tokengroup_id: The id of the token group :param tokengroupname: the name of the tokengroup :param token_id: The id of the token """ if tokengroup_id: self.tokengroup_id = tokengroup_id elif tokengroupname: stmt = select(Tokengroup).filter_by(name=tokengroupname) group = db.session.execute(stmt).scalar_one_or_none() if not group: raise Exception("tokengroup does not exist") self.tokengroup_id = group.id self.token_id = token_id