예제 #1
0
    def verify(self):
        """
        Verifies if the credentials are valid to start a new session.
        :return:
        """
        self.session = self.get_session()
        # try to get the version of the remote JSON API
        version = self.get_version()
        if not version or not version.get('version'):
            message = _("Please install senaite.jsonapi on the source system")
            return False, message

        # try to get the current logged in user
        user = self.get_authenticated_user()
        if not user or user.get("authenticated") is False:
            message = _("Wrong username/password")
            return False, message

        # remember the credentials in the storage
        storage = self.get_storage()

        for k, v in self.credentials.iteritems():
            storage["credentials"][k] = v

        for k, v in self.config.iteritems():
            storage["configuration"][k] = v

        storage["last_fetch_time"] = DateTime()

        message = "Data fetched and saved: {}".format(self.domain_name)
        return True, message
예제 #2
0
파일: views.py 프로젝트: jean/senaite.sync
    def import_users(self, domain):
        """Import the users from the storage identified by domain
        """
        logger.info("*** IMPORT USERS {} ***".format(domain))

        storage = self.get_storage(domain=domain)
        userstore = storage["users"]

        for username, userdata in userstore.items():

            if ploneapi.user.get(username):
                logger.info("Skipping existing user {}".format(username))
                continue
            email = userdata.get("email", "")
            roles = userdata.get("roles", ())
            # TODO handle groups
            # groups = userdata.get("groups",  groups=groups)())
            logger.info("Creating user {}".format(username))
            message = _("Created new user {} with password {}".format(
                username, username))
            # create new user with the same password as the username
            ploneapi.user.create(
                email=email,
                username=username,
                password=username,
                roles=roles,
            )
            self.add_status_message(message, "info")
            logger.info(message)
예제 #3
0
    def __call__(self):
        protect.CheckAuthenticator(self.request.form)

        self.portal = api.get_portal()
        self.request.set('disable_plone.rightcolumn', 1)
        self.request.set('disable_border', 1)

        # Handle form submit
        form = self.request.form

        if not form.get("dataform", False):
            return self.template()

        domain_name = form.get("domain_name", None)

        # Handle "Clear this Storage" action
        if form.get("clear_storage", False):
            del self.storage[domain_name]
            delete_soup(self.portal, domain_name)
            message = _("Cleared Storage {}".format(domain_name))
            self.add_status_message(message, "info")
            return self.template()

        # Get the necessary data for the domain
        storage = self.get_storage(domain_name)
        credentials = storage["credentials"]
        config = storage["configuration"]

        # Handle "Import" action
        if form.get("import", False):
            step = ImportStep(credentials, config)

        # Handle "Update" action
        else:
            fetch_time = form.get("mod_date_limit", None) or \
                storage.get("last_fetch_time", None)
            if not fetch_time:
                message = 'Cannot get last fetched time, please re-run ' \
                          'the Fetch step.'
                self.add_status_message(message, "error")
                return self.template()
            if isinstance(fetch_time, str):
                try:
                    fetch_time = DateTime(fetch_time)
                except:
                    message = 'Please enter a valid Date & Time'
                    self.add_status_message(message, "error")
                    return self.template()

            step = UpdateStep(credentials, config, fetch_time)

        step.run()
        return self.template()
예제 #4
0
    def _import_users(self):
        """Import the users from the storage identified by domain
        """
        if not self.import_users:
            return

        logger.info("*** Importing Users: {} ***".format(self.domain_name))

        for user in self.yield_items("users"):
            username = user.get("username")
            if ploneapi.user.get(username):
                logger.debug("Skipping existing user {}".format(username))
                continue
            email = user.get("email", "")
            if not email:
                email = "{}@example.com".format(username)
            roles = user.get("roles", ())
            groups = user.get("groups", ())
            logger.debug("Creating user {}".format(username))
            message = _("Created new user {} with password {}".format(
                username, username))
            # create new user with the same password as the username
            ploneapi.user.create(
                email=email,
                username=username,
                password=username,
                roles=roles,
            )
            for group in groups:
                # Try to add the user to the group if group exists.
                try:
                    ploneapi.group.add_user(groupname=group, username=username)
                except KeyError:
                    continue

            logger.debug(message)

        logger.info("*** Users Were Imported: {} ***".format(self.domain_name))
예제 #5
0
파일: views.py 프로젝트: jean/senaite.sync
    def __call__(self):
        protect.CheckAuthenticator(self.request.form)

        self.portal = api.get_portal()
        self.request.set('disable_plone.rightcolumn', 1)
        self.request.set('disable_border', 1)

        # Handle form submit
        form = self.request.form
        fetchform = form.get("fetchform", False)
        dataform = form.get("dataform", False)
        if not any([fetchform, dataform]):
            return self.template()

        # remember the form field values
        url = form.get("url", "")
        if not url.startswith("http"):
            url = "http://{}".format(url)
        self.url = url
        self.username = form.get("ac_name", None)
        self.password = form.get("ac_password", None)

        # Handle "Import" action
        if form.get("import", False):
            domain = form.get("domain", None)
            self.import_registry_records(domain)
            self.import_users(domain)
            self.import_data(domain)
            logger.info("*** END OF DATA IMPORT {} ***".format(domain))
            return self.template()

        # Handle "Clear this Storage" action
        if form.get("clear_storage", False):
            domain = form.get("domain", None)
            del self.storage[domain]
            message = _("Cleared Storage {}".format(domain))
            self.add_status_message(message, "info")
            return self.template()

        # Handle "Clear all Storages" action
        if form.get("clear", False):
            self.flush_storage()
            message = _("Cleared Data Storage")
            self.add_status_message(message, "info")
            return self.template()

        # Handle "Fetch" action
        if form.get("fetch", False):
            # check if all mandatory fields have values
            if not all([self.url, self.username, self.password]):
                message = _("Please fill in all required fields")
                self.add_status_message(message, "error")
                return self.template()

            # initialize the session
            self.session = self.get_session(self.username, self.password)

            # remember the credentials in the storage
            storage = self.get_storage(self.url)
            storage["credentials"]["username"] = self.username
            storage["credentials"]["password"] = self.password

            # try to get the version of the remote JSON API
            version = self.get_version()
            if not version or not version.get('version'):
                message = _(
                    "Please install senaite.jsonapi on the source system")
                self.add_status_message(message, "error")
                return self.template()

            # try to get the current logged in user
            user = self.get_authenticated_user()
            if not user or user.get("authenticated") is False:
                message = _("Wrong username/password")
                self.add_status_message(message, "error")
                return self.template()

            domain = self.url
            # Fetch all users from the source
            self.fetch_users(domain)
            # Start the fetch process beginning from the portal object
            self.fetch_data(domain, uid="0")
            # Fetch registry records that contain the word bika or senaite
            self.fetch_registry_records(domain, keys=["bika", "senaite"])
            logger.info("*** FETCHING DATA FINISHED {} ***".format(domain))

        # always render the template
        return self.template()
예제 #6
0
파일: views.py 프로젝트: jean/senaite.sync
    def import_data(self, domain):
        """Import the data from the storage identified by domain
        """
        logger.info("*** IMPORT DATA {} ***".format(domain))

        storage = self.get_storage(domain=domain)
        datastore = storage["data"]
        indexstore = storage["index"]
        uidmap = storage["uidmap"]
        credentials = storage["credentials"]

        # At some points api cannot retrieve objects by UID in the end of
        # creation process. Thus we keep them in an dictionary to access easily.
        objmap = {}
        # We will create objects from top to bottom, but will update from bottom
        # to up.
        ordered_uids = []

        # initialize a new session with the stored credentials for later requests
        username = credentials.get("username")
        password = credentials.get("password")
        self.session = self.get_session(username, password)
        logger.info("Initialized a new session for user {}".format(username))

        # Get UIDs grouped by their parent path
        ppaths = indexstore.get("by_parent_path")
        if ppaths is None:
            message = _(
                "No parent path info found in the import data. "
                "Please install senaite.jsonapi>=1.1.1 on the source instance "
                "and clear&refetch this storage")
            self.add_status_message(message, "warning")
            return

        # Import by paths from top to bottom
        for ppath in sorted(ppaths):
            # nothing to do
            if not ppath:
                continue

            logger.info("Importing items for parent path {}".format(ppath))
            uids = ppaths[ppath]

            for uid in uids:
                ordered_uids.append(uid)
                # get the data for this uid
                data = datastore[uid]
                # check if the object exists in this instance
                remote_path = data.get("path")
                local_path = self.translate_path(remote_path)
                existing = self.portal.unrestrictedTraverse(
                    str(local_path), None)

                if existing:
                    # remember the UID -> object UID mapping for the update step
                    uidmap[uid] = api.get_uid(existing)
                    objmap[uid] = existing
                else:
                    # get the container object by path
                    container_path = self.translate_path(ppath)
                    container = self.portal.unrestrictedTraverse(
                        str(container_path), None)
                    # create an object slug in this container
                    obj = self.create_object_slug(container, data)
                    # remember the UID -> object UID mapping for the update step
                    uidmap[uid] = api.get_uid(obj)
                    objmap[uid] = obj

        # When creation process is done, commit the transaction to avoid
        # ReferenceField relation problems.
        transaction.commit()

        # UIDs were added from up to bottom. Reverse the list to update objects
        # from bottom to up.
        ordered_uids.reverse()

        # Update all objects with the given data
        for uid in ordered_uids:
            obj = objmap.get(uid, None)
            if obj is None:
                logger.warn("Object not found: {} ".format(uid))
                continue
            logger.info("Update object {} with import data".format(
                api.get_path(obj)))
            self.update_object_with_data(obj, datastore[uid], domain)

        self.reindex_updated_objects()
예제 #7
0
    def __call__(self):
        protect.CheckAuthenticator(self.request.form)

        self.portal = api.get_portal()
        self.request.set('disable_plone.rightcolumn', 1)
        self.request.set('disable_border', 1)

        # Handle form submit
        form = self.request.form
        fetchform = form.get("fetchform", False)

        if not fetchform:
            return self.template()

        self.url = form.get("url", "")
        if not self.url.startswith("http"):
            self.url = "https://{}".format(self.url)

        self.domain_name = form.get("domain_name", None)
        self.username = form.get("ac_name", None)
        self.password = form.get("ac_password", None)

        # check if all mandatory fields have values
        if not all([self.domain_name, self.url, self.username, self.password]):
            message = _("Please fill in all required fields")
            self.add_status_message(message, "error")
            return self.template()

        self.auto_sync = (form.get("auto_sync") == 'on')

        self.import_settings = (form.get("import_settings") == 'on')
        self.import_users = (form.get("import_users") == 'on')
        self.import_registry = (form.get("import_registry") == 'on')

        self.remote_prefix = form.get("remote_prefix", None)
        self.local_prefix = form.get("local_prefix", None)

        self.full_sync_types = utils.filter_content_types(
                                    form.get("full_sync_types"))
        self.unwanted_content_types = utils.filter_content_types(
                                    form.get("unwanted_content_types"))
        self.read_only_types = utils.filter_content_types(
                                    form.get("read_only_types"))
        self.update_only_types = utils.filter_content_types(
                                    form.get("update_only_types"))
        self.prefixable_types = utils.filter_content_types(
                                    form.get("prefixable_types"))

        # Prefix Validation
        if not self.validate_prefix():
            return self.template()

        credentials = dict(
            url=self.url,
            domain_name=self.domain_name,
            ac_name=self.username,
            ac_password=self.password)

        config = dict(
            auto_sync=self.auto_sync,
            import_settings=self.import_settings,
            import_users=self.import_users,
            import_registry=self.import_registry,
            remote_prefix=self.remote_prefix,
            local_prefix=self.local_prefix,
            full_sync_types=self.full_sync_types,
            unwanted_content_types=self.unwanted_content_types,
            read_only_types=self.read_only_types,
            update_only_types=self.update_only_types,
            prefixable_types=self.prefixable_types,
        )

        fs = FetchStep(credentials, config)
        verified, message = fs.verify()
        if verified:
            fs.run()
            self.add_status_message(message, "info")
        else:
            self.add_status_message(message, "error")

        # render the template
        return self.template()