class LdapPersistence(BasePersistence):
    def __init__(self, manager):
        self.client = LdapClient(manager)

    def get_auth_config(self):
        entry = self.client.get(
            "ou=jans-auth,ou=configuration,o=jans",
            attributes=["jansRevision", "jansConfWebKeys", "jansConfDyn"],
        )

        if not entry:
            return {}

        config = {
            "id": entry.entry_dn,
            "jansRevision": entry["jansRevision"][0],
            "jansConfWebKeys": entry["jansConfWebKeys"][0],
            "jansConfDyn": entry["jansConfDyn"][0],
        }
        return config

    def modify_auth_config(self, id_, rev, conf_dynamic, conf_webkeys):
        modified, _ = self.client.modify(
            id_, {
                'jansRevision': [(self.client.MODIFY_REPLACE, [str(rev)])],
                'jansConfWebKeys':
                [(self.client.MODIFY_REPLACE, [json.dumps(conf_webkeys)])],
                'jansConfDyn': [
                    (self.client.MODIFY_REPLACE, [json.dumps(conf_dynamic)])
                ],
            })
        return modified
Exemplo n.º 2
0
class LDAPBackend(BaseBackend):
    def __init__(self, manager):
        super().__init__()
        self.manager = manager
        self.client = LdapClient(manager)
        self.type = "ldap"

    def get_entry(self, key, filter_="", attrs=None, **kwargs):
        def format_attrs(attrs):
            _attrs = {}
            for k, v in attrs.items():
                if len(v) < 2:
                    v = v[0]
                _attrs[k] = v
            return _attrs

        filter_ = filter_ or "(objectClass=*)"

        entry = self.client.get(key, filter_=filter_, attributes=attrs)
        if not entry:
            return None
        return Entry(entry.entry_dn,
                     format_attrs(entry.entry_attributes_as_dict))

    def modify_entry(self, key, attrs=None, **kwargs):
        attrs = attrs or {}
        del_flag = kwargs.get("delete_attr", False)

        if del_flag:
            mod = self.client.MODIFY_DELETE
        else:
            mod = self.client.MODIFY_REPLACE

        for k, v in attrs.items():
            if not isinstance(v, list):
                v = [v]
            attrs[k] = [(mod, v)]
        return self.client.modify(key, attrs)

    def update_people_entries(self):
        # add jansAdminUIRole to default admin user
        admin_inum = self.manager.config.get("admin_inum")
        id_ = f"inum={admin_inum},ou=people,o=jans"
        kwargs = {}

        entry = self.get_entry(id_, **kwargs)
        if not entry:
            return

        if "jansAdminUIRole" not in entry.attrs:
            entry.attrs["jansAdminUIRole"] = ["api-admin"]
            self.modify_entry(id_, entry.attrs, **kwargs)

    def update_scopes_entries(self):
        # add jansAdminUIRole claim to profile scope
        kwargs = {}

        entry = self.get_entry(self.jans_admin_ui_role_id, **kwargs)
        if not entry:
            return

        if self.jans_admin_ui_claim not in entry.attrs["jansClaim"]:
            entry.attrs["jansClaim"].append(self.jans_admin_ui_claim)
            self.modify_entry(self.jans_admin_ui_role_id, entry.attrs,
                              **kwargs)

    def update_clients_entries(self):
        jca_client_id = self.manager.config.get("jca_client_id")
        id_ = f"inum={jca_client_id},ou=clients,o=jans"
        kwargs = {}

        entry = self.get_entry(id_, **kwargs)
        if not entry:
            return

        should_update = False

        # modify redirect UI of config-api client
        hostname = self.manager.config.get("hostname")

        if f"https://{hostname}/admin" not in entry.attrs["jansRedirectURI"]:
            entry.attrs["jansRedirectURI"].append(f"https://{hostname}/admin")
            should_update = True

        # add jans_stat, SCIM users.read, SCIM users.write scopes to config-api client
        for scope in (self.jans_scim_scopes + self.jans_stat_scopes):
            if scope not in entry.attrs["jansScope"]:
                entry.attrs["jansScope"].append(scope)
                should_update = True

        if should_update:
            self.modify_entry(id_, entry.attrs, **kwargs)

    def update_scim_scopes_entries(self):
        # add jansAttrs to SCIM users.read and users.write scopes
        ids = self.jans_scim_scopes
        kwargs = {}

        for id_ in ids:
            entry = self.get_entry(id_, **kwargs)
            if not entry:
                continue

            if "jansAttrs" not in entry.attrs:
                entry.attrs["jansAttrs"] = self.jans_attrs
                self.modify_entry(id_, entry.attrs, **kwargs)

    def update_base_entries(self):
        # add jansManagerGrp to base entry
        entry = self.get_entry(JANS_BASE_ID)
        if not entry:
            return

        if not entry.attrs.get("jansManagerGrp"):
            entry.attrs["jansManagerGrp"] = JANS_MANAGER_GROUP
            self.modify_entry(JANS_BASE_ID, entry.attrs)