<commit_before>import BTrees
import persistent
import transaction
import ZODB

from os import path
from ZODB import FileStorage

from zerodb.crypto import rand, sha512
from zerodb.intid import IdStore as BaseIdStore


class IdStore(BaseIdStore):
    family = BTrees.family32


class User(persistent.Persistent):
    """
    Persistent class to store users
    """

    def __init__(self, username, pubkey, realm="ZEO", administrator=False, root=None):
        """
        :param str username: Username
        :param str pubkey: ECC public key
        :param str realm: Authentication realm
        :param bool administrator: Whether it is a super-user (can create
            trees for others)
        :param str root: Oid of root of the tree. Could be None or 8-byte string
        """
        self.username = username
        self.pubkey = pubkey
        self.realm = realm
        self.administrator = administrator
        self.root = root


def session_key(h_up, nonce):
    return sha512(h_up + ":" + nonce)


class PermissionsDatabase(object):
    """
    Class which represent permission storages:
    Config file with root users and ZODB db with others.

    ZODB db consists of two trees:
    str -> int: username -> user uid
    int -> obj: IdStore user uid -> User object

    When database is empty, we populate it with data for all users from
    config file.
    """
    realm = None
    family = BTrees.family32
    uid_pack = "i"  # family32 -> "i", family64 -> "q"

    def __init__(self, filename, realm=None):
        """
        :param str filename: Config file with users and their password hashes
        :param str realm: ZODB's default permissions realm
        """
        self.storage_filename = path.splitext(filename)[0] + ".db"
        self.storage = FileStorage.FileStorage(self.storage_filename)
        self.db = ZODB.DB(self.storage)
        self.db_conn = self.db.open()
        self.db_root = self.db_conn.root()
        root = self.db_root
        with transaction.manager:
            root["users"] = IdStore()  # uid -> user
            root["usernames"] = self.family.OI.BTree()  # username -> uid

        self.filename = filename
        self.load()

        # Frankly speaking, this realm-based security is questionable
        # Keep it here for now
        if realm:
            if self.realm and self.realm != realm:
                raise ValueError("Specified realm %r differs from database "
                                 "realm %r" % (realm or '', self.realm))
            else:
                self.realm = realm

        self.noncekey = rand(32)

    def close(self):
        """
        Close connection to the database<commit_msg>Critical bugfix - changes were removed after restart<commit_after>import BTrees
import persistent
import transaction
import ZODB

from os import path
from ZODB import FileStorage

from zerodb.crypto import rand, sha512
from zerodb.intid import IdStore as BaseIdStore


class IdStore(BaseIdStore):
    family = BTrees.family32


class User(persistent.Persistent):
    """
    Persistent class to store users
    """

    def __init__(self, username, pubkey, realm="ZEO", administrator=False, root=None):
        """
        :param str username: Username
        :param str pubkey: ECC public key
        :param str realm: Authentication realm
        :param bool administrator: Whether it is a super-user (can create
            trees for others)
        :param str root: Oid of root of the tree. Could be None or 8-byte string
        """
        self.username = username
        self.pubkey = pubkey
        self.realm = realm
        self.administrator = administrator
        self.root = root


def session_key(h_up, nonce):
    return sha512(h_up + ":" + nonce)


class PermissionsDatabase(object):
    """
    Class which represent permission storages:
    Config file with root users and ZODB db with others.

    ZODB db consists of two trees:
    str -> int: username -> user uid
    int -> obj: IdStore user uid -> User object

    When database is empty, we populate it with data for all users from
    config file.
    """
    realm = None
    family = BTrees.family32
    uid_pack = "i"  # family32 -> "i", family64 -> "q"

    def __init__(self, filename, realm=None):
        """
        :param str filename: Config file with users and their password hashes
        :param str realm: ZODB's default permissions realm
        """
        self.storage_filename = path.splitext(filename)[0] + ".db"
        self.storage = FileStorage.FileStorage(self.storage_filename)
        self.db = ZODB.DB(self.storage)
        self.db_conn = self.db.open()
        self.db_root = self.db_conn.root()
        root = self.db_root
        with transaction.manager:
            if not "users" in root:
                root["users"] = IdStore()  # uid -> user
            if not "usernames" in root:
                root["usernames"] = self.family.OI.BTree()  # username -> uid

        self.filename = filename
        self.load()

        # Frankly speaking, this realm-based security is questionable
        # Keep it here for now
        if realm:
            if self.realm and self.realm != realm:
                raise ValueError("Specified realm %r differs from database "
                                 "realm %r" % (realm or '', self.realm))
            else:
                self.realm = realm

        self.noncekey = rand(32)

    def close(self):
        """
        Close connection to the database
{'fraction_non_alphanumeric': 0.08786610878661087, 'fraction_numerical': 0.006549026741859196, 'mean_word_length': 2.2170860152135754, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '938805', 'n_tokens_mistral': 1577, 'n_tokens_neox': 1510, 'n_words': 525}