def authenticate(self, request): try: payload = jwt.decode(jwe.decrypt(request.body, settings.JWE_SECRET), settings.JWT_SECRET, options={'verify_exp': False}, algorithm='HS256') except (jwt.InvalidTokenError, TypeError): raise AuthenticationFailed # The JWT `data` payload is expected in the following structure. # # {"provider": { # "idp": "https://login.circle.edu/idp/shibboleth", # "id": "CIR", # "user": { # "middleNames": "", # "familyName": "", # "givenName": "", # "fullname": "Circle User", # "suffix": "", # "username": "******" # } # }} data = json.loads(payload['data']) provider = data['provider'] institution = Institution.load(provider['id']) if not institution: raise AuthenticationFailed( 'Invalid institution id specified "{}"'.format(provider['id'])) username = provider['user']['username'] fullname = provider['user']['fullname'] user, created = get_or_create_user(fullname, username, reset_password=False) if created: user.given_name = provider['user'].get('givenName') user.middle_names = provider['user'].get('middleNames') user.family_name = provider['user'].get('familyName') user.suffix = provider['user'].get('suffix') user.date_last_login = datetime.utcnow() user.save() # User must be saved in order to have a valid _id user.register(username) send_mail(to_addr=user.username, mail=WELCOME_OSF4I, mimetype='html', user=user) if institution not in user.affiliated_institutions: user.affiliated_institutions.append(institution) user.save() return user, None
def authenticate(self, request): try: payload = jwt.decode( jwe.decrypt(request.body, settings.JWE_SECRET), settings.JWT_SECRET, options={'verify_exp': False}, algorithm='HS256' ) except (jwt.InvalidTokenError, TypeError): raise AuthenticationFailed # The JWT `data` payload is expected in the following structure. # # {"provider": { # "idp": "https://login.circle.edu/idp/shibboleth", # "id": "CIR", # "user": { # "middleNames": "", # "familyName": "", # "givenName": "", # "fullname": "Circle User", # "suffix": "", # "username": "******" # } # }} data = json.loads(payload['data']) provider = data['provider'] institution = Institution.load(provider['id']) if not institution: raise AuthenticationFailed('Invalid institution id specified "{}"'.format(provider['id'])) username = provider['user']['username'] fullname = provider['user']['fullname'] user, created = get_or_create_user(fullname, username, reset_password=False) if created: user.given_name = provider['user'].get('givenName') user.middle_names = provider['user'].get('middleNames') user.family_name = provider['user'].get('familyName') user.suffix = provider['user'].get('suffix') user.date_last_login = datetime.utcnow() user.save() # User must be saved in order to have a valid _id user.register(username) send_mail( to_addr=user.username, mail=WELCOME_OSF4I, mimetype='html', user=user ) if institution not in user.affiliated_institutions: user.affiliated_institutions.append(institution) user.save() return user, None
def update_or_create(inst_data): inst = Institution.load(inst_data['_id']) if inst: for key, val in inst_data.iteritems(): setattr(inst.node, inst.attribute_map[key], val) changed_fields = inst.node.save() if changed_fields: print('Updated {}: {}'.format(inst.name, changed_fields)) update_institution(inst) return inst, False else: inst = Institution(None) inst_data = {inst.attribute_map[k]: v for k, v in inst_data.iteritems()} new_inst = Node(**inst_data) new_inst.save() inst = Institution.load(new_inst.institution_id) print('Added new institution: {}'.format(new_inst.institution_id)) update_institution(inst) return new_inst, True
def get_institutions_to_add_remove(self, institutions, new_institutions): diff = relationship_diff( current_items={inst._id: inst for inst in institutions}, new_items={inst['_id']: inst for inst in new_institutions} ) insts_to_add = [] for inst_id in diff['add']: inst = Institution.load(inst_id) if not inst: raise exceptions.NotFound(detail='Institution with id "{}" was not found'.format(inst_id)) insts_to_add.append(inst) return insts_to_add, diff['remove'].values()
def update_or_create(inst_data): inst = Institution.load(inst_data['_id']) if inst: for key, val in inst_data.iteritems(): inst.key = val changed_fields = inst.save() if changed_fields: print('Updated {}: {}'.format(inst.name, changed_fields)) return inst, False else: new_inst = Institution(**inst_data) new_inst.save() print('Added new institution: {}'.format(new_inst._id)) return new_inst, True
def update(self, instance, validated_data): node = instance user = self.context['request'].user inst = validated_data.get('institution_id', None) if inst: inst = Institution.load(inst) if not inst: raise exceptions.NotFound if not inst.auth(user): raise exceptions.PermissionDenied node.primary_institution = inst node.save() return node
def update(self, instance, validated_data): node = instance user = self.context['request'].user inst = validated_data.get('institution_id', None) if inst: inst = Institution.load(inst) if not inst: raise exceptions.NotFound try: node.add_primary_institution(inst=inst, user=user) except UserNotAffiliatedError: raise exceptions.ValidationError(detail='User not affiliated with institution') node.save() return node node.remove_primary_institution(user) node.save() return node
def authenticate(self, request): """ Handle CAS institution authentication request. The JWT `data` payload is expected in the following structure: { "provider": { "idp": "", "id": "", "user": { "username": "", "fullname": "", "familyName": "", "givenName": "", "middleNames": "", "suffix": "", } } } :param request: the POST request :return: user, None if authentication succeed :raises: AuthenticationFailed if authentication fails """ try: payload = jwt.decode(jwe.decrypt(request.body, settings.JWE_SECRET), settings.JWT_SECRET, options={'verify_exp': False}, algorithm='HS256') except (jwt.InvalidTokenError, TypeError): raise AuthenticationFailed data = json.loads(payload['data']) provider = data['provider'] institution = Institution.load(provider['id']) if not institution: raise AuthenticationFailed( 'Invalid institution id specified "{}"'.format(provider['id'])) username = provider['user'].get('username') fullname = provider['user'].get('fullname') given_name = provider['user'].get('givenName') family_name = provider['user'].get('familyName') middle_names = provider['user'].get('middleNames') suffix = provider['user'].get('suffix') # use given name and family name to build full name if not provided if given_name and family_name and not fullname: fullname = given_name + ' ' + family_name # institution must provide `fullname`, otherwise we fail the authentication and inform sentry if not fullname: message = 'Institution login failed: fullname required' \ ' for user {} from institution {}'.format(username, provider['id']) sentry.log_message(message) raise AuthenticationFailed(message) # `get_or_create_user()` guesses names from fullname # replace the guessed ones if the names are provided from the authentication user, created = get_or_create_user(fullname, username, reset_password=False) if created: if given_name: user.given_name = given_name if family_name: user.family_name = family_name if middle_names: user.middle_names = middle_names if suffix: user.suffix = suffix user.update_date_last_login() # save and register user user.save() user.register(username) # send confirmation email send_mail(to_addr=user.username, mail=WELCOME_OSF4I, mimetype='html', user=user) if not user.is_affiliated_with_institution(institution): user.affiliated_institutions.add(institution) user.save() return user, None