#
#   Copyright © 2022 Evilham
#   Copyright © 2021,2022 IsardVDI S.L.
#
#   This file is part of DD
#
#   DD 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 (at your
#   option) any later version.
#
#   DD 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 DD. If not, see <https://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: AGPL-3.0-or-later

import os
from typing import Any, Dict, Optional

from admin.lib.postgres import Postgres

from saml_service import SamlService

class NextcloudSaml(SamlService):
    client_description : str = "Nextcloud Service Provider"
    pg : Optional[Postgres]

    def __init__(self) -> None:
        super(NextcloudSaml, self).__init__("nextcloud")

    def connect_to_db(self) -> None:
        """
        This is defined, though not currently used.
        """
        self.pg = Postgres(
            "dd-apps-postgresql",
            "nextcloud",
            os.environ["NEXTCLOUD_POSTGRES_USER"],
            os.environ["NEXTCLOUD_POSTGRES_PASSWORD"],
        )

    def configure(self) -> None:
        srv_base = f"https://nextcloud.{self.domain}"
        nc_saml_url= f"{srv_base}/apps/user_saml/saml"
        nc_redir_url = f"{nc_saml_url}/acs"
        nc_logout_url = f"{nc_saml_url}/sls"
        client_id = f"{nc_saml_url}/metadata"
        client_overrides : Dict[str, Any] = {
            "name": self.client_name,
            "description": self.client_description,
            "clientId": client_id,

            "enabled": True,
            "redirectUris": [
                nc_redir_url
            ],
            "frontchannelLogout": True,
            "protocol": "saml",
            "webOrigins": [srv_base],
            "attributes": {
                "saml.assertion.signature": True,
                "saml.force.post.binding": True,
                "saml_assertion_consumer_url_post": nc_redir_url,
                "saml.server.signature": True,
                "saml.server.signature.keyinfo.ext": False,
                "saml.signing.certificate": self.public_cert,
                "saml_single_logout_service_url_redirect": nc_logout_url,
                "saml.signature.algorithm": "RSA_SHA256",
                "saml_force_name_id_format": False,
                "saml.client.signature": False,
                "saml.authnstatement": True,
                "saml_name_id_format": "username",
                "saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#",
            },
            "protocolMappers": [
                {
                    "name": "username",
                    "protocol": "saml",
                    "protocolMapper": "saml-user-attribute-mapper",
                    "consentRequired": False,
                    "config": {
                        "attribute.nameformat": "Basic",
                        "user.attribute": "username",
                        "friendly.name": "username",
                        "attribute.name": "username",
                    },
                },
                {
                    "name": "quota",
                    "protocol": "saml",
                    "protocolMapper": "saml-user-attribute-mapper",
                    "consentRequired": False,
                    "config": {
                        "attribute.nameformat": "Basic",
                        "user.attribute": "quota",
                        "friendly.name": "quota",
                        "attribute.name": "quota",
                    },
                },
                {
                    "name": "email",
                    "protocol": "saml",
                    "protocolMapper": "saml-user-property-mapper",
                    "consentRequired": False,
                    "config": {
                        "attribute.nameformat": "Basic",
                        "user.attribute": "email",
                        "friendly.name": "email",
                        "attribute.name": "email",
                    },
                },
                {
                    "name": "displayname",
                    "protocol": "saml",
                    "protocolMapper": "saml-javascript-mapper",
                    "consentRequired": False,
                    "config": {
                        "single": False,
                        "Script": '/**\n * Available variables: \n * user - the current user\n * realm - the current realm\n * clientSession - the current clientSession\n * userSession - the current userSession\n * keycloakSession - the current keycloakSession\n */\n\n\n//insert your code here...\nvar Output = user.getFirstName()+" "+user.getLastName();\nOutput;\n',
                        "attribute.nameformat": "Basic",
                        "friendly.name": "displayname",
                        "attribute.name": "displayname",
                    },
                },
                {
                    "name": "Roles",
                    "protocol": "saml",
                    "protocolMapper": "saml-role-list-mapper",
                    "consentRequired": False,
                    "config": {
                        "single": True,
                        "attribute.nameformat": "Basic",
                        "friendly.name": "Roles",
                        "attribute.name": "Roles",
                    },
                },
                {
                    "name": "group_list",
                    "protocol": "saml",
                    "protocolMapper": "saml-group-membership-mapper",
                    "consentRequired": False,
                    "config": {
                        "single": True,
                        "attribute.nameformat": "Basic",
                        "full.path": False,
                        "friendly.name": "member",
                        "attribute.name": "member",
                    },
                },
            ],
        }
        self.set_client(client_id, client_overrides)


if __name__ == "__main__":
    import logging as log
    log.info("Configuring SAML client for Nextcloud")
    NextcloudSaml().configure()
