Exemplo n.º 1
0
def check_registration_email(regform,
                             email,
                             registration=None,
                             management=False):
    """Checks whether an email address is suitable for registration.

    :param regform: The registration form
    :param email: The email address
    :param registration: The existing registration (in case of
                         modification)
    :param management: If it's a manager adding a new registration
    """
    email = email.lower().strip()
    user = get_user_by_email(email)
    email_registration = regform.get_registration(email=email)
    user_registration = regform.get_registration(user=user) if user else None
    if registration is not None:
        if email_registration and email_registration != registration:
            return dict(status='error', conflict='email-already-registered')
        elif user_registration and user_registration != registration:
            return dict(status='error', conflict='user-already-registered')
        elif user and registration.user and registration.user != user:
            return dict(status='warning' if management else 'error',
                        conflict='email-other-user',
                        user=user.full_name)
        elif not user and registration.user:
            return dict(status='warning' if management else 'error',
                        conflict='email-no-user',
                        user=registration.user.full_name)
        elif user:
            return dict(status='ok',
                        user=user.full_name,
                        self=(not management and user == session.user),
                        same=(user == registration.user))
        elif not validate_email(email):
            return dict(status='error', conflict='email-invalid')
        elif regform.require_user and (management
                                       or email != registration.email):
            return dict(status='warning' if management else 'error',
                        conflict='no-user')
        else:
            return dict(status='ok', user=None)
    else:
        if email_registration:
            return dict(status='error', conflict='email-already-registered')
        elif user_registration:
            return dict(status='error', conflict='user-already-registered')
        elif user:
            return dict(status='ok',
                        user=user.full_name,
                        self=(not management and user == session.user),
                        same=False)
        elif not validate_email(email):
            return dict(status='error', conflict='email-invalid')
        elif regform.require_user:
            return dict(status='warning' if management else 'error',
                        conflict='no-user')
        else:
            return dict(status='ok', user=None)
Exemplo n.º 2
0
    def import_members_from_csv(self, f):
        with csv_text_io_wrapper(f) as ftxt:
            reader = csv.reader(ftxt.read().splitlines())

        emails = set()
        for num_row, row in enumerate(reader, 1):
            if len(row) != 1:
                raise UserValueError(
                    _('Row {}: malformed CSV data').format(num_row))
            email = row[0].strip().lower()

            if email and not validate_email(email):
                raise UserValueError(
                    _('Row {row}: invalid email address: {email}').format(
                        row=num_row, email=email))
            if email in emails:
                raise UserValueError(
                    _('Row {}: email address is not unique').format(num_row))
            emails.add(email)

        users = set(
            User.query.filter(~User.is_deleted, User.all_emails.in_(emails)))
        users_emails = {user.email for user in users}
        unknown_emails = emails - users_emails
        new_members = users - self.role.members
        return new_members, users, unknown_emails
Exemplo n.º 3
0
    def _synchronize_email(self, email, silent=False):
        from indico.modules.users import logger
        from indico.modules.users.tasks import update_gravatars
        from indico.modules.users.util import get_user_by_email

        if not validate_email(email, check_dns=False):
            logger.warning(
                'Cannot sync email for %r to %r; address is invalid', self,
                email)
            if not silent:
                flash(
                    _("Your email address could not be synchronized from '{old_value}' to "
                      "'{new_value}' since the new email address is not valid."
                      ).format(old_value=self.email, new_value=email),
                    'warning')
            return False

        if email not in self.secondary_emails:
            if other := get_user_by_email(email):
                logger.warning(
                    'Cannot sync email for %r to %r; already used by %r', self,
                    email, other)
                if not silent:
                    flash(
                        _("Your email address could not be synchronized from '{old_value}' to "
                          "'{new_value}' due to a conflict with another Indico profile."
                          ).format(old_value=self.email, new_value=email),
                        'warning')
                return False
            self.secondary_emails.add(email)
            signals.users.email_added.send(self, email=email, silent=silent)
Exemplo n.º 4
0
def check_registration_email(regform, email, registration=None, management=False):
    """Checks whether an email address is suitable for registration.

    :param regform: The registration form
    :param email: The email address
    :param registration: The existing registration (in case of
                         modification)
    :param management: If it's a manager adding a new registration
    """
    email = email.lower().strip()
    user = get_user_by_email(email)
    email_registration = regform.get_registration(email=email)
    user_registration = regform.get_registration(user=user) if user else None
    if registration is not None:
        if email_registration and email_registration != registration:
            return dict(status='error', conflict='email-already-registered')
        elif user_registration and user_registration != registration:
            return dict(status='error', conflict='user-already-registered')
        elif user and registration.user and registration.user != user:
            return dict(status='warning' if management else 'error', conflict='email-other-user', user=user.full_name)
        elif not user and registration.user:
            return dict(status='warning' if management else 'error', conflict='email-no-user',
                        user=registration.user.full_name)
        elif user:
            return dict(status='ok', user=user.full_name, self=(not management and user == session.user),
                        same=(user == registration.user))
        elif not validate_email(email):
            return dict(status='error', conflict='email-invalid')
        elif regform.require_user and (management or email != registration.email):
            return dict(status='warning' if management else 'error', conflict='no-user')
        else:
            return dict(status='ok', user=None)
    else:
        if email_registration:
            return dict(status='error', conflict='email-already-registered')
        elif user_registration:
            return dict(status='error', conflict='user-already-registered')
        elif user:
            return dict(status='ok', user=user.full_name, self=(not management and user == session.user), same=False)
        elif not validate_email(email):
            return dict(status='error', conflict='email-invalid')
        elif regform.require_user:
            return dict(status='warning' if management else 'error', conflict='no-user')
        else:
            return dict(status='ok', user=None)
Exemplo n.º 5
0
def import_registrations_from_csv(regform,
                                  fileobj,
                                  skip_moderation=True,
                                  notify_users=False):
    """Import event registrants from a CSV file into a form."""
    with csv_text_io_wrapper(fileobj) as ftxt:
        reader = csv.reader(ftxt.read().splitlines())
    query = db.session.query(Registration.email).with_parent(regform).filter(
        Registration.is_active)
    registered_emails = {email for (email, ) in query}
    used_emails = set()
    todo = []
    for row_num, row in enumerate(reader, 1):
        try:
            first_name, last_name, affiliation, position, phone, email = [
                value.strip() for value in row
            ]
            email = email.lower()
        except ValueError:
            raise UserValueError(
                _('Row {}: malformed CSV data - please check that the number of columns is correct'
                  ).format(row_num))

        if not email:
            raise UserValueError(
                _('Row {}: missing e-mail address').format(row_num))
        if not validate_email(email):
            raise UserValueError(
                _('Row {}: invalid e-mail address').format(row_num))
        if not first_name or not last_name:
            raise UserValueError(
                _('Row {}: missing first or last name').format(row_num))
        if email in registered_emails:
            raise UserValueError(
                _('Row {}: a registration with this email already exists').
                format(row_num))
        if email in used_emails:
            raise UserValueError(
                _('Row {}: email address is not unique').format(row_num))

        used_emails.add(email)
        todo.append({
            'email': email,
            'first_name': first_name.title(),
            'last_name': last_name.title(),
            'affiliation': affiliation,
            'phone': phone,
            'position': position
        })
    return [
        create_registration(regform,
                            data,
                            notify_user=notify_users,
                            skip_moderation=skip_moderation) for data in todo
    ]
Exemplo n.º 6
0
def import_registrations_from_csv(regform, fileobj, skip_moderation=True, notify_users=False):
    """Import event registrants from a CSV file into a form."""
    with csv_text_io_wrapper(fileobj) as ftxt:
        reader = csv.reader(ftxt.read().splitlines())
    reg_data = (db.session.query(Registration.user_id, Registration.email)
                .with_parent(regform)
                .filter(Registration.is_active)
                .all())
    registered_user_ids = {rd.user_id for rd in reg_data if rd.user_id is not None}
    registered_emails = {rd.email for rd in reg_data}
    used_emails = set()
    email_row_map = {}
    todo = []
    for row_num, row in enumerate(reader, 1):
        try:
            first_name, last_name, affiliation, position, phone, email = [value.strip() for value in row]
            email = email.lower()
        except ValueError:
            raise UserValueError(_('Row {}: malformed CSV data - please check that the number of columns is correct')
                                 .format(row_num))

        if not email:
            raise UserValueError(_('Row {}: missing e-mail address').format(row_num))
        if not validate_email(email):
            raise UserValueError(_('Row {}: invalid e-mail address').format(row_num))
        if not first_name or not last_name:
            raise UserValueError(_('Row {}: missing first or last name').format(row_num))
        if email in registered_emails:
            raise UserValueError(_('Row {}: a registration with this email already exists').format(row_num))

        user = get_user_by_email(email)
        if user and user.id in registered_user_ids:
            raise UserValueError(_('Row {}: a registration for this user already exists').format(row_num))
        if email in used_emails:
            raise UserValueError(_('Row {}: email address is not unique').format(row_num))
        if conflict_row_num := email_row_map.get(email):
            raise UserValueError(_('Row {}: email address belongs to the same user as in row {}')
                                 .format(row_num, conflict_row_num))

        used_emails.add(email)
        if user:
            email_row_map.update((e, row_num) for e in user.all_emails)

        todo.append({
            'email': email,
            'first_name': first_name.title(),
            'last_name': last_name.title(),
            'affiliation': affiliation,
            'phone': phone,
            'position': position
        })
Exemplo n.º 7
0
Arquivo: util.py Projeto: javfg/indico
def import_user_records_from_csv(fileobj, columns):
    """Parse and do basic validation of user data from a CSV file.

    :param fileobj: the CSV file to be read
    :param columns: A list of column names, 'first_name', 'last_name', & 'email' are compulsory.
    :return: A list dictionaries each representing one row,
             the keys of which are given by the column names.
    """
    with csv_text_io_wrapper(fileobj) as ftxt:
        reader = csv.reader(ftxt.read().splitlines())
    used_emails = set()
    email_row_map = {}
    user_records = []
    for row_num, row in enumerate(reader, 1):
        values = [value.strip() for value in row]
        if len(columns) != len(values):
            raise UserValueError(
                _('Row {}: malformed CSV data - please check that the number of columns is correct'
                  ).format(row_num))
        record = dict(zip(columns, values))

        if not record['email']:
            raise UserValueError(
                _('Row {}: missing e-mail address').format(row_num))
        record['email'] = record['email'].lower()

        if not validate_email(record['email']):
            raise UserValueError(
                _('Row {}: invalid e-mail address').format(row_num))
        if not record['first_name'] or not record['last_name']:
            raise UserValueError(
                _('Row {}: missing first or last name').format(row_num))
        record['first_name'] = record['first_name'].title()
        record['last_name'] = record['last_name'].title()

        if record['email'] in used_emails:
            raise UserValueError(
                _('Row {}: email address is not unique').format(row_num))
        if conflict_row_num := email_row_map.get(record['email']):
            raise UserValueError(
                _('Row {}: email address belongs to the same user as in row {}'
                  ).format(row_num, conflict_row_num))

        used_emails.add(record['email'])
        if user := get_user_by_email(record['email']):
            email_row_map.update((e, row_num) for e in user.all_emails)
Exemplo n.º 8
0
def import_registrations_from_csv(regform, fileobj, skip_moderation=True, notify_users=False):
    """Import event registrants from a CSV file into a form."""
    reader = csv.reader(fileobj.read().splitlines())
    query = db.session.query(Registration.email).with_parent(regform).filter(Registration.is_active)
    registered_emails = {email for (email,) in query}
    used_emails = set()
    todo = []
    for row_num, row in enumerate(reader, 1):
        try:
            first_name, last_name, affiliation, position, phone, email = [to_unicode(value).strip() for value in row]
            email = email.lower()
        except ValueError:
            raise UserValueError(_('Row {}: malformed CSV data - please check that the number of columns is correct')
                                 .format(row_num))

        if not email:
            raise UserValueError(_('Row {}: missing e-mail address').format(row_num))
        if not validate_email(email):
            raise UserValueError(_('Row {}: invalid e-mail address').format(row_num))
        if not first_name or not last_name:
            raise UserValueError(_('Row {}: missing first or last name').format(row_num))
        if email in registered_emails:
            raise UserValueError(_('Row {}: a registration with this email already exists').format(row_num))
        if email in used_emails:
            raise UserValueError(_('Row {}: email address is not unique').format(row_num))

        used_emails.add(email)
        todo.append({
            'email': email,
            'first_name': first_name.title(),
            'last_name': last_name.title(),
            'affiliation': affiliation,
            'phone': phone,
            'position': position
        })
    return [create_registration(regform, data, notify_user=notify_users, skip_moderation=skip_moderation)
            for data in todo]
Exemplo n.º 9
0
 def validate_contact_emails(self, field):
     for email in field.data:
         if not validate_email(email):
             raise ValidationError(_('Invalid email address: {}').format(escape(email)))
Exemplo n.º 10
0
def import_contributions_from_csv(event, f):
    """Import timetable contributions from a CSV file into an event."""
    reader = csv.reader(f.read().splitlines())
    contrib_data = []

    for num_row, row in enumerate(reader, 1):
        try:
            start_dt, duration, title, first_name, last_name, affiliation, email = \
                [to_unicode(value).strip() for value in row]
            email = email.lower()
        except ValueError:
            raise UserValueError(_('Row {}: malformed CSV data - please check that the number of columns is correct')
                                 .format(num_row))
        try:
            parsed_start_dt = event.tzinfo.localize(dateutil.parser.parse(start_dt)) if start_dt else None
        except ValueError:
            raise UserValueError(_("Row {row}: can't parse date: \"{date}\"").format(row=num_row, date=start_dt))

        try:
            parsed_duration = timedelta(minutes=int(duration)) if duration else None
        except ValueError:
            raise UserValueError(_("Row {row}: can't parse duration: {duration}").format(row=num_row,
                                                                                         duration=duration))

        if not title:
            raise UserValueError(_("Row {}: contribution title is required").format(num_row))

        if email and not validate_email(email):
            raise UserValueError(_("Row {row}: invalid email address: {email}").format(row=num_row, email=email))

        contrib_data.append({
            'start_dt': parsed_start_dt,
            'duration': parsed_duration or timedelta(minutes=20),
            'title': title,
            'speaker': {
                'first_name': first_name,
                'last_name': last_name,
                'affiliation': affiliation,
                'email': email
            }
        })

    # now that we're sure the data is OK, let's pre-allocate the friendly ids
    # for the contributions in question
    Contribution.allocate_friendly_ids(event, len(contrib_data))
    contributions = []
    all_changes = defaultdict(list)

    for contrib_fields in contrib_data:
        speaker_data = contrib_fields.pop('speaker')

        with track_time_changes() as changes:
            contribution = create_contribution(event, contrib_fields, extend_parent=True)

        contributions.append(contribution)
        for key, val in changes[event].viewitems():
            all_changes[key].append(val)

        email = speaker_data['email']
        if not email:
            continue

        # set the information of the speaker
        person = get_event_person(event, {
            'firstName': speaker_data['first_name'],
            'familyName': speaker_data['last_name'],
            'affiliation': speaker_data['affiliation'],
            'email': email
        })
        link = ContributionPersonLink(person=person, is_speaker=True)
        link.populate_from_dict({
            'first_name': speaker_data['first_name'],
            'last_name': speaker_data['last_name'],
            'affiliation': speaker_data['affiliation']
        })
        contribution.person_links.append(link)

    return contributions, all_changes
Exemplo n.º 11
0
 def validate_contact_emails(self, field):
     for email in field.data:
         if not validate_email(email):
             raise ValidationError(
                 _('Invalid email address: {}').format(escape(email)))
Exemplo n.º 12
0
 def _indico_email(value):
     if value and not validate_email(value):
         raise ValidationError(_('Invalid email address'))
Exemplo n.º 13
0
 def _proc_email(val):
     val = conv(val).strip()
     if not validate_email(val):
         raise click.UsageError(u'invalid email')
     return val
Exemplo n.º 14
0
 def _validate_item(self, line):
     if not validate_email(line):
         raise ValueError(_('Invalid email address: {}').format(escape(line)))
Exemplo n.º 15
0
 def _check_email(email):
     if validate_email(email):
         return True
     _warn('Invalid email address')
     return False
Exemplo n.º 16
0
 def _check_email(email):
     if validate_email(email):
         return True
     _warn('Invalid email address')
     return False
Exemplo n.º 17
0
 def _validate_item(self, line):
     if not validate_email(line):
         raise ValueError(
             _('Invalid email address: {}').format(escape(line)))
Exemplo n.º 18
0
def import_contributions_from_csv(event, f):
    """Import timetable contributions from a CSV file into an event."""
    with csv_text_io_wrapper(f) as ftxt:
        reader = csv.reader(ftxt.read().splitlines())

    contrib_data = []
    for num_row, row in enumerate(reader, 1):
        try:
            start_dt, duration, title, first_name, last_name, affiliation, email = (
                value.strip() for value in row)
            email = email.lower()
        except ValueError:
            raise UserValueError(
                _('Row {}: malformed CSV data - please check that the number of columns is correct'
                  ).format(num_row))
        try:
            parsed_start_dt = event.tzinfo.localize(
                dateutil.parser.parse(start_dt)) if start_dt else None
        except ValueError:
            raise UserValueError(
                _('Row {row}: can\'t parse date: "{date}"').format(
                    row=num_row, date=start_dt))

        try:
            parsed_duration = timedelta(
                minutes=int(duration)) if duration else None
        except ValueError:
            raise UserValueError(
                _("Row {row}: can't parse duration: {duration}").format(
                    row=num_row, duration=duration))

        if not title:
            raise UserValueError(
                _('Row {}: contribution title is required').format(num_row))

        if email and not validate_email(email):
            raise UserValueError(
                _('Row {row}: invalid email address: {email}').format(
                    row=num_row, email=email))

        contrib_data.append({
            'start_dt':
            parsed_start_dt,
            'duration':
            parsed_duration or timedelta(minutes=20),
            'title':
            title,
            'speaker': {
                'first_name': first_name,
                'last_name': last_name,
                'affiliation': affiliation,
                'email': email
            }
        })

    # now that we're sure the data is OK, let's pre-allocate the friendly ids
    # for the contributions in question
    Contribution.allocate_friendly_ids(event, len(contrib_data))
    contributions = []
    all_changes = defaultdict(list)

    for contrib_fields in contrib_data:
        speaker_data = contrib_fields.pop('speaker')

        with track_time_changes() as changes:
            contribution = create_contribution(event,
                                               contrib_fields,
                                               extend_parent=True)

        contributions.append(contribution)
        for key, val in changes[event].items():
            all_changes[key].append(val)

        email = speaker_data['email']
        if not email:
            continue

        # set the information of the speaker
        person = get_event_person(event, speaker_data)
        link = ContributionPersonLink(person=person, is_speaker=True)
        link.populate_from_dict({
            'first_name': speaker_data['first_name'],
            'last_name': speaker_data['last_name'],
            'affiliation': speaker_data['affiliation']
        })
        contribution.person_links.append(link)

    return contributions, all_changes
Exemplo n.º 19
0
 def _proc_email(val):
     val = conv(val).strip()
     if not validate_email(val):
         raise click.UsageError(u'invalid email')
     return val