def run_before_app_restore(self, app_id):
        from yunohost.app import app_setting
        from yunohost.utils.legacy import migrate_legacy_permission_settings

        # Migrate old settings
        legacy_permission_settings = [
            "skipped_uris",
            "unprotected_uris",
            "protected_uris",
            "skipped_regex",
            "unprotected_regex",
            "protected_regex",
        ]
        if any(
                app_setting(app_id, setting) is not None
                for setting in legacy_permission_settings):
            migrate_legacy_permission_settings(app=app_id)
Exemplo n.º 2
0
    def migrate_app_permission(app=None):
        logger.info(m18n.n("migration_0011_migrate_permission"))

        apps = _installed_apps()

        if app:
            if app not in apps:
                logger.error(
                    "Can't migrate permission for app %s because it ain't installed..."
                    % app
                )
                apps = []
            else:
                apps = [app]

        for app in apps:
            permission = app_setting(app, "allowed_users")
            path = app_setting(app, "path")
            domain = app_setting(app, "domain")

            url = "/" if domain and path else None
            if permission:
                known_users = list(user_list()["users"].keys())
                allowed = [
                    user for user in permission.split(",") if user in known_users
                ]
            else:
                allowed = ["all_users"]
            permission_create(
                app + ".main",
                url=url,
                allowed=allowed,
                show_tile=True,
                protected=False,
                sync_perm=False,
            )

            app_setting(app, "allowed_users", delete=True)

            # Migrate classic public app still using the legacy unprotected_uris
            if (
                app_setting(app, "unprotected_uris") == "/"
                or app_setting(app, "skipped_uris") == "/"
            ):
                user_permission_update(app + ".main", add="visitors", sync_perm=False)

        permission_sync_to_user()
Exemplo n.º 3
0
def permission_url(
    operation_logger,
    permission,
    url=None,
    add_url=None,
    remove_url=None,
    auth_header=None,
    clear_urls=False,
    sync_perm=True,
):
    """
    Update urls related to a permission for a specific application

    Keyword argument:
        permission  -- Name of the permission (e.g. mail or nextcloud or wordpress.editors)
        url         -- (optional) URL for which access will be allowed/forbidden.
        add_url     -- (optional) List of additional url to add for which access will be allowed/forbidden
        remove_url  -- (optional) List of additional url to remove for which access will be allowed/forbidden
        auth_header -- (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application
        clear_urls  -- (optional) Clean all urls (url and additional_urls)
    """
    from yunohost.app import app_setting
    from yunohost.utils.ldap import _get_ldap_interface

    ldap = _get_ldap_interface()

    # By default, manipulate main permission
    if "." not in permission:
        permission = permission + ".main"

    app = permission.split(".")[0]

    if url or add_url:
        domain = app_setting(app, "domain")
        path = app_setting(app, "path")
        if domain is None or path is None:
            raise YunohostError("unknown_main_domain_path", app=app)
        else:
            app_main_path = domain + path

    # Fetch existing permission

    existing_permission = user_permission_info(permission)

    show_tile = existing_permission["show_tile"]

    if url is None:
        url = existing_permission["url"]
    else:
        url = _validate_and_sanitize_permission_url(url, app_main_path, app)

        if url.startswith("re:") and existing_permission["show_tile"]:
            logger.warning(
                m18n.n("regex_incompatible_with_tile",
                       regex=url,
                       permission=permission))
            show_tile = False

    current_additional_urls = existing_permission["additional_urls"]
    new_additional_urls = copy.copy(current_additional_urls)

    if add_url:
        for ur in add_url:
            if ur in current_additional_urls:
                logger.warning(
                    m18n.n("additional_urls_already_added",
                           permission=permission,
                           url=ur))
            else:
                ur = _validate_and_sanitize_permission_url(
                    ur, app_main_path, app)
                new_additional_urls += [ur]

    if remove_url:
        for ur in remove_url:
            if ur not in current_additional_urls:
                logger.warning(
                    m18n.n("additional_urls_already_removed",
                           permission=permission,
                           url=ur))

        new_additional_urls = [
            u for u in new_additional_urls if u not in remove_url
        ]

    if auth_header is None:
        auth_header = existing_permission["auth_header"]

    if clear_urls:
        url = None
        new_additional_urls = []
        show_tile = False

    # Guarantee uniqueness of all values, which would otherwise make ldap.update angry.
    new_additional_urls = set(new_additional_urls)

    # Actually commit the change

    operation_logger.related_to.append(("app", permission.split(".")[0]))
    operation_logger.start()

    try:
        ldap.update(
            "cn=%s,ou=permission" % permission,
            {
                "URL": [url] if url is not None else [],
                "additionalUrls": new_additional_urls,
                "authHeader": [str(auth_header).upper()],
                "showTile": [str(show_tile).upper()],
            },
        )
    except Exception as e:
        raise YunohostError("permission_update_failed",
                            permission=permission,
                            error=e)

    if sync_perm:
        permission_sync_to_user()

    logger.debug(m18n.n("permission_updated", permission=permission))
    return user_permission_info(permission)
Exemplo n.º 4
0
def user_permission_list(short=False,
                         full=False,
                         ignore_system_perms=False,
                         absolute_urls=False):
    """
    List permissions and corresponding accesses
    """

    # Fetch relevant informations
    from yunohost.app import app_setting, _installed_apps
    from yunohost.utils.ldap import _get_ldap_interface, _ldap_path_extract

    ldap = _get_ldap_interface()
    permissions_infos = ldap.search(
        "ou=permission,dc=yunohost,dc=org",
        "(objectclass=permissionYnh)",
        [
            "cn",
            "groupPermission",
            "inheritPermission",
            "URL",
            "additionalUrls",
            "authHeader",
            "label",
            "showTile",
            "isProtected",
        ],
    )

    # Parse / organize information to be outputed
    apps = sorted(_installed_apps())
    apps_base_path = {
        app: app_setting(app, "domain") + app_setting(app, "path")
        for app in apps
        if app_setting(app, "domain") and app_setting(app, "path")
    }

    permissions = {}
    for infos in permissions_infos:

        name = infos["cn"][0]
        if ignore_system_perms and name.split(".")[0] in SYSTEM_PERMS:
            continue

        app = name.split(".")[0]

        perm = {}
        perm["allowed"] = [
            _ldap_path_extract(p, "cn")
            for p in infos.get("groupPermission", [])
        ]

        if full:
            perm["corresponding_users"] = [
                _ldap_path_extract(p, "uid")
                for p in infos.get("inheritPermission", [])
            ]
            perm["auth_header"] = infos.get("authHeader", [False])[0] == "TRUE"
            perm["label"] = infos.get("label", [None])[0]
            perm["show_tile"] = infos.get("showTile", [False])[0] == "TRUE"
            perm["protected"] = infos.get("isProtected", [False])[0] == "TRUE"
            perm["url"] = infos.get("URL", [None])[0]
            perm["additional_urls"] = infos.get("additionalUrls", [])

            if absolute_urls:
                app_base_path = (
                    apps_base_path[app] if app in apps_base_path else ""
                )  # Meh in some situation where the app is currently installed/removed, this function may be called and we still need to act as if the corresponding permission indeed exists ... dunno if that's really the right way to proceed but okay.
                perm["url"] = _get_absolute_url(perm["url"], app_base_path)
                perm["additional_urls"] = [
                    _get_absolute_url(url, app_base_path)
                    for url in perm["additional_urls"]
                ]

        permissions[name] = perm

    # Make sure labels for sub-permissions are the form " Applabel (Sublabel) "
    if full:
        subpermissions = {
            k: v
            for k, v in permissions.items() if not k.endswith(".main")
        }
        for name, infos in subpermissions.items():
            main_perm_name = name.split(".")[0] + ".main"
            if main_perm_name not in permissions:
                logger.debug(
                    "Uhoh, unknown permission %s ? (Maybe we're in the process or deleting the perm for this app...)"
                    % main_perm_name)
                continue
            main_perm_label = permissions[main_perm_name]["label"]
            infos["sublabel"] = infos["label"]
            infos["label"] = "%s (%s)" % (main_perm_label, infos["label"])

    if short:
        permissions = list(permissions.keys())

    return {"permissions": permissions}