Exemplo n.º 1
0
    async def get(self) -> None:
        """
        Get the dynamic configuration endpoint.
        ---
        description: Presents a YAML-configured editor to allow viewing and modification of dynamic config
        responses:
            200:
                description: View of dynamic configuration
            403:
                description: Unauthorized to access this page
        """

        if not self.user:
            return

        if not can_edit_dynamic_config(self.user, self.groups):
            raise tornado.web.HTTPError(
                403,
                "Only application admins are authorized to view this page.")

        dynamic_config = await ddb.get_dynamic_config_yaml()

        self.write({
            "dynamicConfig": dynamic_config.decode("utf-8"),
            "sha256": sha256(dynamic_config).hexdigest(),
        })
Exemplo n.º 2
0
    async def get(self):
        """
        Provide information about site configuration for the frontend
        :return:
        """
        is_contractor = config.config_plugin().is_contractor(self.user)
        site_config = {
            "consoleme_logo": await get_random_security_logo(),
            "google_tracking_uri": config.get("google_analytics.tracking_url"),
            "documentation_url": config.get("documentation_page"),
            "support_contact": config.get("support_contact"),
            "support_chat_url": config.get("support_chat_url"),
            "security_logo": config.get("security_logo.image"),
            "security_url": config.get("security_logo.url"),
        }

        user_profile = {
            "site_config":
            site_config,
            "user":
            self.user,
            "can_logout":
            config.get("auth.set_auth_cookie"),
            "is_contractor":
            is_contractor,
            "employee_photo_url":
            config.config_plugin().get_employee_photo_url(self.user),
            "employee_info_url":
            config.config_plugin().get_employee_info_url(self.user),
            "authorization": {
                "can_edit_policies":
                can_admin_policies(self.user, self.groups),
                "can_create_roles": can_create_roles(self.user, self.groups),
                "can_delete_roles": can_delete_roles(self.user, self.groups),
            },
            "pages": {
                "header": {
                    "custom_header_message_title":
                    config.get("headers.custom_header_message.title", ""),
                    "custom_header_message_text":
                    config.get("headers.custom_header_message.text", ""),
                },
                "groups": {
                    "enabled": config.get("headers.group_access.enabled",
                                          False)
                },
                "users": {
                    "enabled": config.get("headers.group_access.enabled",
                                          False)
                },
                "policies": {
                    "enabled":
                    config.get("headers.policies.enabled", True)
                    and not is_contractor
                },
                "self_service": {
                    "enabled":
                    config.get("enable_self_service", True)
                    and not is_contractor
                },
                "api_health": {
                    "enabled":
                    is_in_group(
                        self.user,
                        self.groups,
                        config.get("groups.can_edit_health_alert", []),
                    )
                },
                "audit": {
                    "enabled":
                    is_in_group(self.user, self.groups,
                                config.get("groups.can_audit", []))
                },
                "config": {
                    "enabled": can_edit_dynamic_config(self.user, self.groups)
                },
            },
            "accounts":
            await get_account_id_to_name_mapping(),
        }

        self.set_header("Content-Type", "application/json")
        self.write(user_profile)
Exemplo n.º 3
0
    async def get(self):
        """
        Provide information about site configuration for the frontend
        :return:
        """
        is_contractor = config.config_plugin().is_contractor(self.user)
        site_config = {
            "consoleme_logo": await get_random_security_logo(),
            "google_analytics": {
                "tracking_id": config.get("google_analytics.tracking_id"),
                "options": config.get("google_analytics.options", {}),
            },
            "documentation_url": config.get(
                "documentation_page", "https://hawkins.gitbook.io/consoleme/"
            ),
            "support_contact": config.get("support_contact"),
            "support_chat_url": config.get(
                "support_chat_url", "https://discord.com/invite/nQVpNGGkYu"
            ),
            "security_logo": config.get("security_logo.image"),
            "security_url": config.get("security_logo.url"),
            # If site_config.landing_url is set, users will be redirected to the landing URL after authenticating
            # on the frontend.
            "landing_url": config.get("site_config.landing_url"),
            "temp_policy_support": config.get("policies.temp_policy_support"),
            "notifications": {
                "enabled": config.get("site_config.notifications.enabled"),
                "request_interval": config.get(
                    "site_config.notifications.request_interval", 60
                ),
            },
            "cloudtrail_denies_policy_generation": config.get(
                "celery.cache_cloudtrail_denies.enabled", False
            ),
        }

        custom_page_header: Dict[str, str] = await get_custom_page_header(
            self.user, self.groups
        )
        user_profile = {
            "site_config": site_config,
            "user": self.user,
            "can_logout": config.get("auth.set_auth_cookie", False),
            "is_contractor": is_contractor,
            "employee_photo_url": config.config_plugin().get_employee_photo_url(
                self.user
            ),
            "employee_info_url": config.config_plugin().get_employee_info_url(
                self.user
            ),
            "authorization": {
                "can_edit_policies": can_admin_policies(self.user, self.groups),
                "can_create_roles": can_create_roles(self.user, self.groups),
                "can_delete_iam_principals": can_delete_iam_principals(
                    self.user, self.groups
                ),
            },
            "pages": {
                "header": {
                    "custom_header_message_title": custom_page_header.get(
                        "custom_header_message_title", ""
                    ),
                    "custom_header_message_text": custom_page_header.get(
                        "custom_header_message_text", ""
                    ),
                    "custom_header_message_route": custom_page_header.get(
                        "custom_header_message_route", ""
                    ),
                },
                "groups": {
                    "enabled": config.get("headers.group_access.enabled", False)
                },
                "users": {"enabled": config.get("headers.group_access.enabled", False)},
                "policies": {
                    "enabled": config.get("headers.policies.enabled", True)
                    and not is_contractor
                },
                "self_service": {
                    "enabled": config.get("enable_self_service", True)
                    and not is_contractor
                },
                "api_health": {
                    "enabled": is_in_group(
                        self.user,
                        self.groups,
                        config.get("groups.can_edit_health_alert", []),
                    )
                },
                "audit": {
                    "enabled": is_in_group(
                        self.user, self.groups, config.get("groups.can_audit", [])
                    )
                },
                "config": {"enabled": can_edit_dynamic_config(self.user, self.groups)},
            },
            "accounts": await get_account_id_to_name_mapping(),
        }

        self.set_header("Content-Type", "application/json")
        self.write(user_profile)
Exemplo n.º 4
0
    async def post(self):
        """
        Post an update to the dynamic configuration endpoint.
        ---
        description: Update dynamic configuration
        responses:
            200:
                description: Update successful.
            403:
                description: Unauthorized to access this page
        """

        if not self.user:
            return
        if not can_edit_dynamic_config(self.user, self.groups):
            raise tornado.web.HTTPError(
                403,
                "Only application admins are authorized to view this page.")
        existing_dynamic_config = await ddb.get_dynamic_config_yaml()
        if existing_dynamic_config:
            existing_dynamic_config_sha256 = sha256(
                existing_dynamic_config).hexdigest()
        else:
            existing_dynamic_config_sha256 = None
        result = {"status": "success"}
        log_data = {
            "function":
            f"{__name__}.{self.__class__.__name__}.{sys._getframe().f_code.co_name}",
            "user": self.user,
            "existing_dynamic_config_sha256": existing_dynamic_config_sha256,
        }
        log.debug(log_data)

        data = tornado.escape.json_decode(self.request.body)
        try:
            existing_sha256 = data.get("existing_sha256")
            new_sha256 = sha256(data["new_config"].encode("utf-8")).hexdigest()
            if existing_sha256 == new_sha256:
                raise Exception(
                    "You didn't change the dynamic configuration. Try again!")
            if (existing_dynamic_config_sha256
                    and not existing_dynamic_config_sha256 == existing_sha256):
                raise Exception(
                    "Dynamic configuration was updated by another user before your changes were processed. "
                    "Please refresh your page and try again.")

            await ddb.update_dynamic_config(data["new_config"], self.user)
        except Exception as e:
            result["status"] = "error"
            result[
                "error"] = f"There was an error processing your request: {e}"
            sentry_sdk.capture_exception()
            self.write(json.dumps(result, cls=SetEncoder))
            await self.finish()
            return

        result["newConfig"] = data["new_config"]
        result["newsha56"] = new_sha256
        self.write(result)
        await self.finish()
        return