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
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, "_")
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
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()
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'], )
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], )
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], )
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')
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')
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')
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
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)
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())