%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /opt/imunify360/venv/lib64/python3.8/site-packages/defence360agent/contracts/
Upload File :
Create Path :
Current File : //opt/imunify360/venv/lib64/python3.8/site-packages/defence360agent/contracts/secure_site_id.py

"""
This program is free software: you can redistribute it and/or modify it under 
the terms of the GNU General Public License as published by 
the Free Software Foundation, either version 3 of the License, 
or (at your option) any later version.


This program 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 General Public License for more details.


You should have received a copy of the GNU General Public License
 along with this program.  If not, see <https://www.gnu.org/licenses/>.

Copyright © 2019 Cloud Linux Software Inc.

This software is also available under ImunifyAV commercial license,
see <https://www.imunify360.com/legal/eula>
"""
import os
import pwd
import uuid
from pathlib import Path
from typing import Dict, List, Literal, Optional

from defence360agent.contracts.permissions import logger
from defence360agent.model import instance
from defence360agent.secure_site.model import SecureSite
from defence360agent.subsys.panels.hosting_panel import HostingPanel

SECURE_SITE_ID_FILE_NAME = ".secure_site_id"


class SecureSiteIdError(Exception):
    """Exception representing issues related to SecureSite id"""


def add_secure_site_user(
    user: str, value: Literal["basic", "pro"]
) -> Optional[str]:
    """Save subscription type to the DB and generate id file"""

    secure_site, _ = SecureSite.get_or_create(user=user)
    secure_site.subscription_type = value
    secure_site.save()
    logger.info("Applied setting SecureSite=%s for user %s", value, user)

    try:
        secure_site_id = _get_or_generate_id(user)
    except SecureSiteIdError:
        # User no longer exists
        return

    return secure_site_id


async def get_secure_site_users() -> List[Dict]:
    """
    Get a list of SecureSite users, their subscription types and unique ids
    """

    users = []
    user_to_email = await HostingPanel().get_user_to_email()
    with instance.db.transaction():
        for user, secure_site_uid in sorted(
            (await _secure_site_user_to_id()).items()
        ):
            record, _ = SecureSite.get_or_create(user=user)
            users.append(
                {
                    "email": user_to_email.get(user, ""),
                    "username": user,
                    "id": secure_site_uid,
                    "subscription_type": record.subscription_type,
                }
            )
    return users


async def _secure_site_user_to_id() -> Dict[str, str]:
    """Get a list of users and their SecureSite ids"""

    user_to_id = {}
    for user in await HostingPanel().get_users():
        try:
            user_to_id[user] = _get_or_generate_id(user)
        except SecureSiteIdError:
            # User does not exist
            continue

    return user_to_id


def _get_or_generate_id(user: str) -> str:
    """
    Read SecureSite id if exists or generate a new one and write into the file
    """
    # DEF-22427
    # Temporary stab, to not create ssi file
    # Should be reverted when secure site release
    return "my_secure_site_id"
    # id_file = _get_secure_site_id_file(user)
    # try:
    #     return _read_id(id_file)
    # except (FileNotFoundError, SecureSiteIdError):
    #     secure_site_id = uuid.uuid1().hex
    #     return _write_id(secure_site_id, id_file)


def _write_id(secure_site_id: str, id_file: Path) -> str:
    """Write SecureSite id to file"""

    id_file.write_text(
        "# DO NOT EDIT\n"
        "# This file contains SecureSite id unique to this user\n"
        "\n"
        f"{secure_site_id}\n"
    )
    return secure_site_id


def _read_id(id_file: Path) -> str:
    """Read SecureSite id from file"""

    with id_file.open("r") as f:
        for line in reversed(f.readlines()):
            if line and not line.startswith("#"):
                if secure_site_id := line.strip():
                    return secure_site_id

    raise SecureSiteIdError


def _get_secure_site_id_file(user: str) -> Optional[Path]:
    """Get a file with SecureSite id and create it if does not exist"""

    try:
        user_pwd = pwd.getpwnam(user)
    except KeyError as e:
        logger.error("No such user: %s", user)
        raise SecureSiteIdError from e
    else:
        id_file = Path(user_pwd.pw_dir) / SECURE_SITE_ID_FILE_NAME
        if not id_file.exists():
            try:
                id_file.touch()
            except FileNotFoundError as e:
                logger.error("No such user homedir: %s", user)
                raise SecureSiteIdError from e
            os.chown(id_file, user_pwd.pw_uid, user_pwd.pw_gid)

    return id_file

Zerion Mini Shell 1.0