Example #1
0
File: views.py Project: mattipt/amy
def _match_training_request_to_person(request,
                                      training_request,
                                      create=False,
                                      person=None):
    if create:
        try:
            training_request.person = Person.objects.create_user(
                username=create_username(training_request.personal,
                                         training_request.family),
                personal=training_request.personal,
                family=training_request.family,
                email=training_request.email,
            )
        except IntegrityError:
            # email address is not unique
            messages.error(
                request, 'Could not create a new person, because '
                'there already exists a person with '
                'exact email address.')
            return False

    else:
        training_request.person = person

    # as per #1270:
    # https://github.com/swcarpentry/amy/issues/1270#issuecomment-407515948
    # let's rewrite everything that's possible to rewrite
    try:
        training_request.person.personal = training_request.personal
        training_request.person.middle = training_request.middle
        training_request.person.family = training_request.family
        training_request.person.email = training_request.email
        training_request.person.country = training_request.country
        training_request.person.github = training_request.github
        training_request.person.affiliation = training_request.affiliation
        training_request.person.domains.set(training_request.domains.all())
        training_request.person.occupation = (
            training_request.get_occupation_display() if
            training_request.occupation else training_request.occupation_other)
        training_request.person.data_privacy_agreement = \
            training_request.data_privacy_agreement

        training_request.person.may_contact = True
        training_request.person.is_active = True

        training_request.person.save()
        training_request.person.synchronize_usersocialauth()
        training_request.save()

        messages.success(request, 'Request matched with the person.')

        return True
    except IntegrityError:
        # email or github not unique
        messages.error(
            request, "It was impossible to update related person's "
            "data. Probably email address or GitHub "
            "handle used in the training request are not "
            " unique amongst person entries.")
        return False
Example #2
0
    def test_noned_names(self):
        """This is a regression test against #1682
        (https://github.com/carpentries/amy/issues/1682).

        The error was: family name was allowed to be null, which caused 500 errors
        when trying to save person without the family name due to name normalization."""
        username = create_username(personal=None, family=None)
        self.assertEqual(username, "_")
Example #3
0
def _match_training_request_to_person(request, training_request, create=False,
                                      person=None):
    if create:
        try:
            training_request.person = Person.objects.create_user(
                username=create_username(training_request.personal,
                                         training_request.family),
                personal=training_request.personal,
                family=training_request.family,
                email=training_request.email,
            )
        except IntegrityError:
            # email address is not unique
            messages.error(request, 'Could not create a new person, because '
                                    'there already exists a person with '
                                    'exact email address.')
            return False

    else:
        training_request.person = person

    # as per #1270:
    # https://github.com/swcarpentry/amy/issues/1270#issuecomment-407515948
    # let's rewrite everything that's possible to rewrite
    try:
        training_request.person.personal = training_request.personal
        training_request.person.middle = training_request.middle
        training_request.person.family = training_request.family
        training_request.person.email = training_request.email
        training_request.person.country = training_request.country
        training_request.person.github = training_request.github
        training_request.person.affiliation = training_request.affiliation
        training_request.person.domains.set(training_request.domains.all())
        training_request.person.occupation = (
            training_request.get_occupation_display()
            if training_request.occupation else
            training_request.occupation_other)
        training_request.person.data_privacy_agreement = \
            training_request.data_privacy_agreement

        training_request.person.may_contact = True
        training_request.person.is_active = True

        training_request.person.save()
        training_request.person.synchronize_usersocialauth()
        training_request.save()

        messages.success(request, 'Request matched with the person.')

        return True
    except IntegrityError:
        # email or github not unique
        messages.error(request, "It was impossible to update related person's "
                                "data. Probably email address or GitHub "
                                "handle used in the training request are not "
                                " unique amongst person entries.")
        return False
Example #4
0
    def fake_duplicated_people(self, count=5):
        self.stdout.write('Generating {} fake '
                          'people duplications...'.format(count))

        for _ in range(count):
            p = Person.objects.order_by('?').first()
            p.id = None

            # avoid integrity errors due to unique constraints
            p.username = create_username(p.personal, p.family)
            p.twitter = None
            p.github = None
            p.email = self.faker.email()

            p.save()
Example #5
0
 def parse(self, presentation):
     return Task(
         event=self.event,
         person=Person.objects.get_or_create(
             email=presentation['speaker']['email'],
             defaults={
                 'username': create_username('', presentation['speaker']['username']),
                 'personal': presentation['speaker']['name'].rsplit(' ', 1)[0],
                 'family': presentation['speaker']['name'].rsplit(' ', 1)[-1],
                 'url': presentation['speaker']['absolute_url'],
             }
         )[0],
         role=Role.objects.get(name='presenter'),
         title=presentation['title'],
         url=presentation['absolute_url'],
     )
Example #6
0
 def parse(self, presentation):
     return Task(
         event=self.event,
         person=Person.objects.get_or_create(
             email=presentation['speaker']['email'],
             defaults={
                 'username': create_username('', presentation['speaker']['username']),
                 'personal': presentation['speaker']['name'].rsplit(' ', 1)[0],
                 'family': presentation['speaker']['name'].rsplit(' ', 1)[-1],
                 'url': presentation['speaker']['absolute_url'],
             }
         )[0],
         role=Role.objects.get(name='presenter'),
         title=presentation['title'],
         url=presentation['absolute_url'],
     )
Example #7
0
 def parse(self, sponsor):
     return Sponsorship(
         organization=Organization.objects.get_or_create(
             domain=urlparse(sponsor['external_url']).netloc,
             defaults={
                 'fullname': sponsor['name'],
                 'notes': sponsor['annotation'],
             },
         )[0],
         event=self.event,
         amount=sponsor['level']['cost'],
         contact=Person.objects.get_or_create(
             email=sponsor['contact_email'],
             defaults={
                 'username': create_username('', sponsor['contact_name']),
                 'personal': sponsor['contact_name'].rsplit(' ', 1)[0],
                 'family': sponsor['contact_name'].rsplit(' ', 1)[-1],
             },
         )[0],
     )
Example #8
0
 def parse(self, sponsor):
     domain = urlparse(sponsor['external_url']).netloc
     organization = Organization.objects.filter(
         Q(fullname=sponsor['name']) | Q(domain=domain)
     ).first()
     if not organization:
         organization = Organization.objects.create(
             fullname=sponsor['name'],
             domain=domain,
             notes=sponsor['annotation'],
         )
     return Sponsorship(
         organization=organization,
         event=self.event,
         amount=sponsor['level']['cost'],
         contact=Person.objects.get_or_create(
             email=sponsor['contact_email'],
             defaults={
                 'username': create_username('', sponsor['contact_name']),
                 'personal': sponsor['contact_name'].rsplit(' ', 1)[0],
                 'family': sponsor['contact_name'].rsplit(' ', 1)[-1],
             },
         )[0],
     )
Example #9
0
 def test_nonlatin_characters(self):
     """Ensure correct behavior for non-latin names."""
     username = create_username(personal='Grzegorz',
                                family='Brzęczyszczykiewicz')
     self.assertEqual(username, 'brzczyszczykiewicz_grzegorz')
Example #10
0
 def test_conflicting_name(self):
     """Ensure `create_username` works correctly when conflicting username
     already exists."""
     username = create_username(personal='Harry', family='Potter')
     self.assertEqual(username, 'potter_harry_2')
Example #11
0
 def test_nonconflicting_name(self):
     """Ensure `create_username` works correctly when there's no conflicts
     in the database."""
     username = create_username(personal='Hermione', family='Granger')
     self.assertEqual(username, 'granger_hermione')
Example #12
0
    def fake_person(self, *, is_instructor, is_trainer=False):
        airport = choice(Airport.objects.all())

        email = choice([self.faker.email(),
                        self.faker.safe_email(),
                        self.faker.free_email(),
                        self.faker.company_email()])

        gender = choice(Person.GENDER_CHOICES)[0]

        if gender == 'F':
            personal_name = self.faker.first_name_female()
            family_name = self.faker.last_name_female()
        elif gender == 'M':
            personal_name = self.faker.first_name_male()
            family_name = self.faker.last_name_male()
        else:
            personal_name = self.faker.first_name()
            family_name = self.faker.last_name()

        social_username = self.faker.user_name()

        if randbool(0.6):
            # automatically generate username
            username = create_username(personal_name, family_name)
        else:
            # assume that the username is provided by the person
            username = social_username

        github = social_username
        twitter = social_username
        url = self.faker.url() if randbool(0.5) else ''

        person = Person.objects.create(
            personal=personal_name,
            family=family_name,
            email=email,
            gender=gender,
            may_contact=randbool(0.5),
            publish_profile=randbool(0.5),
            airport=airport,
            twitter=twitter,
            github=github,
            url=url,
            username=username,
            country=choice(Countries)[0],
        )

        if is_instructor:
            # Add one or more instructor badges
            awards = []
            badges = sample(Badge.objects.instructor_badges())
            for badge in badges:
                date = self.faker.date_time_between(start_date='-5y').date()
                awards.append(Award(person=person, badge=badge, awarded=date))
            Award.objects.bulk_create(awards)

            if randbool(0.75):
                # Add one or more qualifications
                Qualification.objects.bulk_create(
                    Qualification(person=person, lesson=lesson)
                    for lesson in sample(Lesson.objects.all())
                )

        if is_trainer:
            date = self.faker.date_time_between(start_date='-5y').date()
            trainer = Badge.objects.get(name='trainer')
            Award.objects.create(person=person, badge=trainer, awarded=date)

        return person
Example #13
0
 def test_conflicting_name(self):
     """Ensure `create_username` works correctly when conflicting username
     already exists."""
     username = create_username(personal='Harry', family='Potter')
     self.assertEqual(username, 'potter_harry_2')
Example #14
0
 def test_nonconflicting_name(self):
     """Ensure `create_username` works correctly when there's no conflicts
     in the database."""
     username = create_username(personal='Hermione', family='Granger')
     self.assertEqual(username, 'granger_hermione')
Example #15
0
 def test_nonlatin_characters(self):
     """Ensure correct behavior for non-latin names."""
     username = create_username(personal='Grzegorz',
                                family='Brzęczyszczykiewicz')
     self.assertEqual(username, 'brzczyszczykiewicz_grzegorz')
Example #16
0
 def test_reached_number_of_tries(self):
     """Ensure we don't DoS ourselves."""
     tries = 1
     with self.assertRaises(InternalError):
         create_username(personal='Harry', family='Potter', tries=tries)
Example #17
0
 def test_reached_number_of_tries(self):
     """Ensure we don't DoS ourselves."""
     tries = 1
     with self.assertRaises(InternalError):
         create_username(personal='Harry', family='Potter', tries=tries)
Example #18
0
 def test_hyphenated_name(self):
     """Ensure people with hyphens in names have correct usernames
     generated."""
     username = create_username(personal='Andy', family='Blanking-Crush')
     self.assertEqual(username, 'blanking-crush_andy')
Example #19
0
 def test_hyphenated_name(self):
     """Ensure people with hyphens in names have correct usernames
     generated."""
     username = create_username(personal='Andy', family='Blanking-Crush')
     self.assertEqual(username, 'blanking-crush_andy')
def profileupdaterequest_accept(request, request_id, person_id=None):
    """
    Accept the profile update by rewriting values to selected user's profile.

    IMPORTANT: we do not rewrite all of the data users input (like
    other gender, or other lessons).  All of it is still in
    the database model ProfileUpdateRequest, but does not get written to the
    Person model object.
    """
    profileupdate = get_object_or_404(ProfileUpdateRequest, active=True,
                                      pk=request_id)
    airport = get_object_or_404(Airport,
                                iata__iexact=profileupdate.airport_iata)

    if person_id is None:
        person = Person()
        # since required perms change depending on `person_id`, we have to
        # check the perms programmatically; here user is required
        # `workshops.add_person` in order to add a new person
        if not request.user.has_perm('workshops.add_person'):
            raise PermissionDenied
    else:
        person = get_object_or_404(Person, pk=person_id)
        person_name = str(person)
        # since required perms change depending on `person_id`, we have to
        # check the perms programmatically; here user is required
        # `workshops.change_person` in order to set existing person's fields
        if not request.user.has_perm('workshops.change_person'):
            raise PermissionDenied

    person.personal = profileupdate.personal
    person.middle = profileupdate.middle
    person.family = profileupdate.family
    person.email = profileupdate.email
    person.affiliation = profileupdate.affiliation
    person.country = profileupdate.country
    person.airport = airport
    person.github = profileupdate.github
    person.twitter = profileupdate.twitter
    person.url = profileupdate.website
    # if occupation is "Other", simply save the `occupation_other` field,
    # otherwise get full display of occupation (since it's a choice field)
    if profileupdate.occupation == '':
        person.occupation = profileupdate.occupation_other
    else:
        person.occupation = profileupdate.get_occupation_display()
    person.orcid = profileupdate.orcid
    person.gender = profileupdate.gender
    person.user_notes = profileupdate.notes

    with transaction.atomic():
        # we need person to exist in the database in order to set domains and
        # lessons
        if not person.id:
            try:
                person.username = create_username(person.personal,
                                                  person.family)
                person.save()
            except IntegrityError:
                messages.error(
                    request,
                    'Cannot update profile: some database constraints weren\'t'
                    ' fulfilled. Make sure that user name, GitHub user name,'
                    ' Twitter user name, or email address are unique.'
                )
                return redirect(profileupdate.get_absolute_url())

        person.domains.set(list(profileupdate.domains.all()))
        person.languages.set(profileupdate.languages.all())

        try:
            person.save()
        except IntegrityError:
            messages.error(
                request,
                'Cannot update profile: some database constraints weren\'t'
                'fulfilled. Make sure that user name, GitHub user name,'
                'Twitter user name, or email address are unique.'
            )
            return redirect(profileupdate.get_absolute_url())

        # Since Person.lessons uses a intermediate model Qualification, we
        # ought to operate on Qualification objects instead of using
        # Person.lessons as a list.

        # erase old lessons
        Qualification.objects.filter(person=person).delete()
        # add new
        Qualification.objects.bulk_create([
            Qualification(person=person, lesson=L)
            for L in profileupdate.lessons.all()
        ])

        profileupdate.active = False
        profileupdate.save()

    if person_id is None:
        messages.success(request,
                         'New person was added successfully.')
    else:
        messages.success(request,
                         '{} was updated successfully.'.format(person_name))

    return redirect(person.get_absolute_url())