Source code for privacyidea.models.customuserattribute
# 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 sqlalchemy import (
Sequence,
Unicode,
Integer,
ForeignKey,
UnicodeText
)
from sqlalchemy.orm import Mapped, mapped_column
from privacyidea.lib.utils import convert_column_to_unicode
from privacyidea.models import db
from privacyidea.models.utils import MethodsMixin
log = logging.getLogger(__name__)
PRIVACYIDEA_TIMESTAMP = "__timestamp__"
SAFE_STORE = "PI_DB_SAFE_STORE"
[docs]
class CustomUserAttribute(MethodsMixin, db.Model):
"""
The table "customuserattribute" is used to store additional, custom attributes
for users.
A user is identified by the user_id, the resolver_id and the realm_id.
The additional attributes are stored in Key and Value.
The Type can hold extra information like e.g. an encrypted value / password.
Note: Since the users are external, i.e. no objects in this database,
there is no logic reference on a database level.
Since users could be deleted from user stores
without privacyIDEA realizing that, this table could pile up
with remnants of attributes.
"""
__tablename__ = 'customuserattribute'
id: Mapped[int] = mapped_column(Integer, Sequence("customuserattribute_seq"), primary_key=True)
user_id: Mapped[str | None] = mapped_column(Unicode(320), default='', index=True)
resolver: Mapped[str | None] = mapped_column(Unicode(120), default='', index=True)
realm_id: Mapped[int | None] = mapped_column(Integer, ForeignKey('realm.id'))
Key: Mapped[str] = mapped_column(Unicode(255), nullable=False)
Value: Mapped[str | None] = mapped_column(UnicodeText, default='')
Type: Mapped[str | None] = mapped_column(Unicode(100), default='')
def __init__(self, user_id, resolver, realm_id, Key, Value, Type=None):
"""
Create a new customuserattribute for a user tuple
"""
self.user_id = user_id
self.resolver = resolver
self.realm_id = realm_id
self.Key = Key
self.Value = convert_column_to_unicode(Value)
self.Type = Type