Improved the handling in the OpenID Connect userinfo response of multiple meeting registrations with different email addresses for the same person.

- Legacy-Id: 18286
This commit is contained in:
Henrik Levkowetz 2020-07-28 14:01:20 +00:00
parent fb78f9add7
commit ae6513f1c9
2 changed files with 34 additions and 18 deletions

View file

@ -767,10 +767,13 @@ class OpenIDConnectTests(TestCase):
# Get a user for which we want to get access
person = PersonFactory()
RoleFactory(name_id='chair', person=person)
# an additional email
EmailFactory(person=person)
email_list = person.email_set.all().values_list('address', flat=True)
meeting = MeetingFactory(type_id='ietf', date=datetime.date.today())
MeetingRegistration.objects.create(
meeting=meeting, person=None, first_name=person.first_name(), last_name=person.last_name(),
email=person.email(), ticket_type='full_week', reg_type='remote', affiliation='Some Company',
email=email_list[0], ticket_type='full_week', reg_type='remote', affiliation='Some Company',
)
# Get access authorisation
@ -830,7 +833,21 @@ class OpenIDConnectTests(TestCase):
for key in [ 'email', 'family_name', 'given_name', 'meeting', 'name', 'roles',
'ticket_type', 'reg_type', 'affiliation', ]:
self.assertIn(key, userinfo)
self.assertIn('remote', set(userinfo['reg_type'].split()))
self.assertNotIn('hackathon', set(userinfo['reg_type'].split()))
# Create another registration, with a different email
MeetingRegistration.objects.create(
meeting=meeting, person=None, first_name=person.first_name(), last_name=person.last_name(),
email=email_list[1], ticket_type='one_day', reg_type='hackathon', affiliation='Some Company, Inc',
)
userinfo = client.do_user_info_request(state=params["state"], scope=args['scope'])
self.assertIn('hackathon', set(userinfo['reg_type'].split()))
self.assertIn('remote', set(userinfo['reg_type'].split()))
self.assertIn('full_week', set(userinfo['ticket_type'].split()))
self.assertIn('Some Company', userinfo['affiliation'])
# Check that ending a session works
r = client.do_end_session_request(state=params["state"], scope=args['scope'])
self.assertEqual(r.status_code, 302)
self.assertEqual(r.headers["Location"], urlreverse('ietf.ietfauth.views.login'))

View file

@ -249,33 +249,32 @@ class OidcExtraScopeClaims(oidc_provider.lib.claims.ScopeClaims):
from ietf.stats.models import MeetingRegistration
meeting = get_current_ietf_meeting()
person = self.user.person
reg = MeetingRegistration.objects.filter(person=person, meeting=meeting).first()
if not reg:
# No person match; try to match by email address. They could
# have registered with a new address and added it to the account
# later.
email_list = person.email_set.values_list('address')
reg = MeetingRegistration.objects.filter(email__in=email_list, meeting=meeting).first()
if reg:
email_list = person.email_set.values_list('address')
q = Q(person=person, meeting=meeting) | Q(email__in=email_list, meeting=meeting)
regs = MeetingRegistration.objects.filter(q).distinct()
for reg in regs:
if not reg.person_id:
reg.person = person
reg.save()
info = {}
if reg:
# maybe register attendence if logged in to follow a meeting
if regs:
# maybe register attendance if logged in to follow a meeting
today = datetime.date.today()
if meeting.date <= today <= meeting.end_date():
client = ClientRecord.objects.get(client_id=self.client.client_id)
if client.name == 'Meetecho' and not reg.attended:
reg.attended = True
reg.save()
if client.name == 'Meetecho':
for reg in regs:
if not reg.attended:
reg.attended = True
reg.save()
# fill in info to return
info = {
'meeting': reg.meeting.number,
'meeting': meeting.number,
# full_week, one_day, student:
'ticket_type': reg.ticket_type,
'ticket_type': ' '.join(set( reg.ticket_type for reg in regs )),
# in_person, onliine, hackathon:
'reg_type': reg.reg_type,
'affiliation': reg.affiliation,
'reg_type': ' '.join(set( reg.reg_type for reg in regs )),
'affiliation': ([ reg.affiliation for reg in regs if reg.affiliation ] or [''])[0],
}
return info