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()
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()
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()