Example #1
0
File: users.py Project: fph/indico
    def migrate_users(self):
        print cformat('%{white!}migrating users')

        seen_identities = set()

        for avatar in committing_iterator(self._iter_avatars(), 5000):
            if getattr(avatar, '_mergeTo', None):
                print cformat('%{red!}!!!%{reset} '
                              '%{yellow!}Skipping {} - merged into {}').format(avatar.id, avatar._mergeTo.id)
                continue
            elif avatar.status == 'Not confirmed':
                print cformat('%{yellow!}!!!%{reset} '
                              '%{yellow!}Skipping {} - not activated').format(avatar.id)
                continue
            elif not avatar.name.strip() and not avatar.surName.strip():
                links = {(obj, role): list(objs)
                         for obj, x in avatar.linkedTo.iteritems()
                         for role, objs in x.iteritems()
                         if objs}
                if not avatar.identities and not links:
                    print cformat('%{yellow!}!!!%{reset} '
                                  '%{yellow!}Skipping {} - no names and no identities/links').format(avatar.id)
                    continue

            user = self._user_from_avatar(avatar)
            self._fix_collisions(user, avatar)
            db.session.add(user)
            settings = self._settings_from_avatar(avatar)
            user_settings.set_multi(user, settings)
            # favorite users cannot be migrated here since the target user might not have been migrated yet
            # XXX: adapt to new categories for 2.0
            user.favorite_categories = set(filter(None, avatar.linkedTo['category']['favorite']))
            db.session.flush()
            print cformat('%{green}+++%{reset} '
                          '%{white!}{:6d}%{reset} %{cyan}{}%{reset} [%{blue!}{}%{reset}] '
                          '{{%{cyan!}{}%{reset}}}').format(user.id, user.full_name, user.email,
                                                           ', '.join(user.secondary_emails))
            # migrate API keys
            self._migrate_api_keys(avatar, user)
            # migrate identities of non-deleted avatars
            if not user.is_deleted:
                for old_identity in avatar.identities:
                    identity = None
                    username = convert_to_unicode(old_identity.login).strip().lower()

                    if not username:
                        print cformat("%{red!}!!!%{reset} "
                                      "%{yellow!}Empty username: {}. Skipping identity.").format(
                                          old_identity)
                        continue

                    provider = {
                        'LocalIdentity': 'indico',
                        'LDAPIdentity': self.ldap_provider_name
                    }.get(old_identity.__class__.__name__)

                    if provider is None:
                        print cformat("%{red!}!!!%{reset} "
                                      "%{yellow!}Unsupported provider: {}. Skipping identity.").format(
                            old_identity.__class__.__name__)
                        continue

                    if (provider, username) in seen_identities:
                        print cformat("%{red!}!!!%{reset} "
                                      "%{yellow!}Duplicate identity: {}, {}. Skipping.").format(provider, username)
                        continue

                    if provider == 'indico' and not self.ignore_local_accounts:
                        identity = Identity(provider=provider, identifier=username)

                        if not hasattr(old_identity, 'algorithm'):  # plaintext password
                            if not old_identity.password:
                                # password is empty, skip identity
                                print cformat("%{red!}!!!%{reset} "
                                              "%{yellow!}Identity '{}' has empty password. Skipping identity.").format(
                                                  old_identity.login)
                                continue
                            identity.password = old_identity.password
                        else:
                            assert old_identity.algorithm == 'bcrypt'
                            identity.password_hash = old_identity.password

                    elif provider == self.ldap_provider_name:
                        identity = Identity(provider=provider, identifier=username)

                    if identity:
                        print cformat('%{blue!}<->%{reset}  %{yellow}{}%{reset}').format(identity)
                        user.identities.add(identity)
                        seen_identities.add((provider, username))

            for merged_avatar in getattr(avatar, '_mergeFrom', ()):
                if merged_avatar.id == avatar.id:
                    continue
                merged = self._user_from_avatar(merged_avatar, is_deleted=True, merged_into_id=user.id)
                print cformat('%{blue!}***%{reset} '
                              '%{white!}{:6d}%{reset} %{cyan}{}%{reset} [%{blue!}{}%{reset}] '
                              '{{%{cyan!}{}%{reset}}}').format(merged.id, merged.full_name, merged.email,
                                                               ', '.join(merged.secondary_emails))
                self._fix_collisions(merged, merged_avatar)
                db.session.add(merged)
                db.session.flush()
Example #2
0
    def migrate_users(self):
        print cformat('%{white!}migrating users')

        seen_identities = set()

        for avatar in committing_iterator(self._iter_avatars(), 5000):
            if getattr(avatar, '_mergeTo', None):
                print cformat('%{red!}!!!%{reset} '
                              '%{yellow!}Skipping {} - merged into {}').format(
                                  avatar.id, avatar._mergeTo.id)
                continue
            elif avatar.status == 'Not confirmed':
                print cformat('%{yellow!}!!!%{reset} '
                              '%{yellow!}Skipping {} - not activated').format(
                                  avatar.id)
                continue
            elif not avatar.name.strip() and not avatar.surName.strip():
                links = {(obj, role): list(objs)
                         for obj, x in avatar.linkedTo.iteritems()
                         for role, objs in x.iteritems() if objs}
                if not avatar.identities and not links:
                    print cformat(
                        '%{yellow!}!!!%{reset} '
                        '%{yellow!}Skipping {} - no names and no identities/links'
                    ).format(avatar.id)
                    continue

            user = self._user_from_avatar(avatar)
            self._fix_collisions(user, avatar)
            db.session.add(user)
            settings = self._settings_from_avatar(avatar)
            user_settings.set_multi(user, settings)
            # favorite users cannot be migrated here since the target user might not have been migrated yet
            # XXX: adapt to new categories for 2.0
            user.favorite_categories = set(
                filter(None, avatar.linkedTo['category']['favorite']))
            db.session.flush()
            print cformat(
                '%{green}+++%{reset} '
                '%{white!}{:6d}%{reset} %{cyan}{}%{reset} [%{blue!}{}%{reset}] '
                '{{%{cyan!}{}%{reset}}}').format(
                    user.id, user.full_name, user.email,
                    ', '.join(user.secondary_emails))
            # migrate API keys
            self._migrate_api_keys(avatar, user)
            # migrate identities of non-deleted avatars
            if not user.is_deleted:
                for old_identity in avatar.identities:
                    identity = None
                    username = convert_to_unicode(
                        old_identity.login).strip().lower()

                    if not username:
                        print cformat(
                            "%{red!}!!!%{reset} "
                            "%{yellow!}Empty username: {}. Skipping identity."
                        ).format(old_identity)
                        continue

                    provider = {
                        'LocalIdentity': 'indico',
                        'LDAPIdentity': self.ldap_provider_name
                    }.get(old_identity.__class__.__name__)

                    if provider is None:
                        print cformat(
                            "%{red!}!!!%{reset} "
                            "%{yellow!}Unsupported provider: {}. Skipping identity."
                        ).format(old_identity.__class__.__name__)
                        continue

                    if (provider, username) in seen_identities:
                        print cformat(
                            "%{red!}!!!%{reset} "
                            "%{yellow!}Duplicate identity: {}, {}. Skipping."
                        ).format(provider, username)
                        continue

                    if provider == 'indico' and not self.ignore_local_accounts:
                        identity = Identity(provider=provider,
                                            identifier=username)

                        if not hasattr(old_identity,
                                       'algorithm'):  # plaintext password
                            if not old_identity.password:
                                # password is empty, skip identity
                                print cformat(
                                    "%{red!}!!!%{reset} "
                                    "%{yellow!}Identity '{}' has empty password. Skipping identity."
                                ).format(old_identity.login)
                                continue
                            identity.password = old_identity.password
                        else:
                            assert old_identity.algorithm == 'bcrypt'
                            identity.password_hash = old_identity.password

                    elif provider == self.ldap_provider_name:
                        identity = Identity(provider=provider,
                                            identifier=username)

                    if identity:
                        print cformat(
                            '%{blue!}<->%{reset}  %{yellow}{}%{reset}').format(
                                identity)
                        user.identities.add(identity)
                        seen_identities.add((provider, username))

            for merged_avatar in getattr(avatar, '_mergeFrom', ()):
                if merged_avatar.id == avatar.id:
                    continue
                merged = self._user_from_avatar(merged_avatar,
                                                is_deleted=True,
                                                merged_into_id=user.id)
                print cformat(
                    '%{blue!}***%{reset} '
                    '%{white!}{:6d}%{reset} %{cyan}{}%{reset} [%{blue!}{}%{reset}] '
                    '{{%{cyan!}{}%{reset}}}').format(
                        merged.id, merged.full_name, merged.email,
                        ', '.join(merged.secondary_emails))
                self._fix_collisions(merged, merged_avatar)
                db.session.add(merged)
                db.session.flush()
Example #3
0
    def migrate_users(self):
        seen_identities = set()

        for avatar in committing_iterator(self._iter_avatars(), 5000):
            if getattr(avatar, '_mergeTo', None):
                self.print_warning('Skipping {} - merged into {}'.format(avatar.id, avatar._mergeTo.id))
                merged_user = self.global_ns.avatar_merged_user.get(avatar._mergeTo.id)
                if merged_user:
                    self.global_ns.avatar_merged_user[avatar.id] = merged_user
                else:
                    # if the merge target hasn't yet been migrated, keep track of it
                    self.unresolved_merge_targets[avatar._mergeTo.id].add(avatar.id)
                continue
            elif avatar.status == 'Not confirmed':
                self.print_warning('Skipping {} - not activated'.format(avatar.id))
                continue
            elif not avatar.name.strip() and not avatar.surName.strip():
                links = {(obj, role): list(objs)
                         for obj, x in avatar.linkedTo.iteritems()
                         for role, objs in x.iteritems()
                         if objs}
                if not avatar.identities and not links:
                    self.print_warning('Skipping {} - no names and no identities/links'.format(avatar.id))
                    continue

            user = self._user_from_avatar(avatar)
            self._fix_collisions(user, avatar)
            db.session.add(user)
            settings = self._settings_from_avatar(avatar)
            user_settings.set_multi(user, settings)
            # favorite users cannot be migrated here since the target user might not have been migrated yet
            for old_categ in avatar.linkedTo['category']['favorite']:
                if old_categ:
                    self.global_ns.user_favorite_categories[old_categ.id].add(user)
            db.session.flush()
            self.print_success('%[white!]{:6d}%[reset] %[cyan]{}%[reset] [%[blue!]{}%[reset]] '
                               '{{%[cyan!]{}%[reset]}}'.format(user.id, user.full_name, user.email,
                                                               ', '.join(user.secondary_emails)))
            # migrate API keys
            self._migrate_api_keys(avatar, user)
            # migrate identities of avatars
            for old_identity in avatar.identities:
                identity = None
                username = convert_to_unicode(old_identity.login).strip().lower()

                if not username:
                    self.print_warning("Empty username: {}. Skipping identity.".format(old_identity))
                    continue

                provider = {
                    'LocalIdentity': 'indico',
                    'LDAPIdentity': self.ldap_provider_name
                }.get(old_identity.__class__.__name__)

                if provider is None:
                    self.print_error("Unsupported provider: {}. Skipping identity.".format(
                        old_identity.__class__.__name__))
                    continue

                if (provider, username) in seen_identities:
                    self.print_error("Duplicate identity: {}, {}. Skipping.".format(provider, username))
                    continue

                if provider == 'indico' and not self.ignore_local_accounts:
                    identity = Identity(provider=provider, identifier=username)

                    if not hasattr(old_identity, 'algorithm'):  # plaintext password
                        if not old_identity.password:
                            # password is empty, skip identity
                            self.print_error("Identity '{}' has empty password. Skipping identity.".format(
                                              old_identity.login))
                            continue
                        identity.password = old_identity.password
                    else:
                        assert old_identity.algorithm == 'bcrypt'
                        identity.password_hash = old_identity.password

                elif provider == self.ldap_provider_name:
                    identity = Identity(provider=provider, identifier=username)

                if identity:
                    self.print_info('%[blue!]<->%[reset]  %[yellow]{}%[reset]'.format(identity))
                    user.identities.add(identity)
                    seen_identities.add((provider, username))

            if hasattr(avatar, 'personalInfo') and avatar.personalInfo._basket._users:
                self.favorite_avatars[user.id] = avatar.personalInfo._basket._users

            # Map old merged identities (no longer in AvatarHolder)
            # to newly created user
            for merged_avatar in getattr(avatar, '_mergeFrom', ()):
                if merged_avatar.id != avatar.id:
                    self.global_ns.avatar_merged_user[merged_avatar.id] = user

            self.global_ns.avatar_merged_user[avatar.id] = user
            if avatar.id in self.unresolved_merge_targets:
                del self.unresolved_merge_targets[avatar.id]
                self._resolve_merge_targets(avatar.id, user)
        db.session.flush()