def test_user_unconfirmed(self, app, institution, url_auth_institution): username, fullname, password = '******', 'Foo Bar', 'FuAsKeEr' user = OSFUser.create_unconfirmed(username, password, fullname) user.save() # Unconfirmed user has a usable password created during sign-up assert user.has_usable_password() with capture_signals() as mock_signals: res = app.post( url_auth_institution, make_payload(institution, username, family_name='User', given_name='Fake', fullname='Fake User')) assert res.status_code == 204 assert mock_signals.signals_sent() == set([signals.user_confirmed]) user = OSFUser.objects.filter(username=username).first() assert user # User becomes active and all names are updated assert user.is_active assert user.fullname == 'Fake User' assert user.family_name == 'User' assert user.given_name == 'Fake' # Pending email verifications must be cleared assert not user.email_verifications # Previously unconfirmed user must be given a new password during institution auth assert user.has_usable_password() assert not user.check_password(password) # Confirm affiliation assert institution in user.affiliated_institutions.all()
def register_unconfirmed(username, password, fullname, campaign=None, accepted_terms_of_service=None): from osf.models import OSFUser user = get_user(email=username) if not user: user = OSFUser.create_unconfirmed( username=username, password=password, fullname=fullname, campaign=campaign, accepted_terms_of_service=accepted_terms_of_service) user.save() signals.unconfirmed_user_created.send(user) elif not user.is_registered: # User is in db but not registered user.add_unconfirmed_email(username) user.set_password(password) user.fullname = fullname user.update_guessed_names() user.save() else: raise DuplicateEmailError( 'OSFUser {0!r} already exists'.format(username)) return user
def test_user_external_unconfirmed(self, app, institution, url_auth_institution): # Create an unconfirmed user with pending external identity username, fullname = '*****@*****.**', 'Foo Bar' external_id_provider, external_id, status = 'ORCID', '1234-1234-1234-1234', 'CREATE' external_identity = {external_id_provider: {external_id: status}} accepted_terms_of_service = timezone.now() user = OSFUser.create_unconfirmed( username=username, password=None, fullname=fullname, external_identity=external_identity, campaign=None, accepted_terms_of_service=accepted_terms_of_service ) user.save() assert not user.has_usable_password() assert user.external_identity # Send confirm email in order to add new email verifications send_confirm_email( user, user.username, external_id_provider=external_id_provider, external_id=external_id ) user.save() assert user.email_verifications email_verifications = user.email_verifications with capture_signals() as mock_signals: res = app.post( url_auth_institution, make_payload( institution, username, family_name='User', given_name='Fake', fullname='Fake User', department='Fake User', ), expect_errors=True ) assert res.status_code == 403 assert not mock_signals.signals_sent() user = OSFUser.objects.filter(username=username).first() assert user # User remains untouched, including affiliation, external identity email verifcaitons assert user.fullname == fullname assert user.given_name == 'Foo' assert user.family_name == 'Bar' assert institution not in user.affiliated_institutions.all() assert external_identity == user.external_identity assert email_verifications == user.email_verifications assert accepted_terms_of_service == user.accepted_terms_of_service assert not user.has_usable_password()
def register_unconfirmed(username, password, fullname, campaign=None): from osf.models import OSFUser user = get_user(email=username) if not user: user = OSFUser.create_unconfirmed( username=username, password=password, fullname=fullname, campaign=campaign, ) user.save() signals.unconfirmed_user_created.send(user) elif not user.is_registered: # User is in db but not registered user.add_unconfirmed_email(username) user.set_password(password) user.fullname = fullname user.update_guessed_names() user.save() else: raise DuplicateEmailError('OSFUser {0!r} already exists'.format(username)) return user
def external_login_email_post(): """ View to handle email submission for first-time oauth-login user. HTTP Method: POST """ form = ResendConfirmationForm(request.form) session = get_session() if not session.is_external_first_login: raise HTTPError(http.UNAUTHORIZED) external_id_provider = session.data['auth_user_external_id_provider'] external_id = session.data['auth_user_external_id'] fullname = session.data['auth_user_fullname'] service_url = session.data['service_url'] # TODO: @cslzchen use user tags instead of destination destination = 'dashboard' for campaign in campaigns.get_campaigns(): if campaign != 'institution': # Handle different url encoding schemes between `furl` and `urlparse/urllib`. # OSF use `furl` to parse service url during service validation with CAS. However, `web_url_for()` uses # `urlparse/urllib` to generate service url. `furl` handles `urlparser/urllib` generated urls while ` but # not vice versa. campaign_url = furl.furl(campaigns.campaign_url_for(campaign)).url external_campaign_url = furl.furl( campaigns.external_campaign_url_for(campaign)).url if campaigns.is_proxy_login(campaign): # proxy campaigns: OSF Preprints and branded ones if check_service_url_with_proxy_campaign( str(service_url), campaign_url, external_campaign_url): destination = campaign # continue to check branded preprints even service url matches osf preprints if campaign != 'osf-preprints': break elif service_url.startswith(campaign_url): # osf campaigns: OSF Prereg and ERPC destination = campaign break if form.validate(): clean_email = form.email.data user = get_user(email=clean_email) external_identity = { external_id_provider: { external_id: None, }, } try: ensure_external_identity_uniqueness(external_id_provider, external_id, user) except ValidationError as e: raise HTTPError(http.FORBIDDEN, e.message) if user: # 1. update user oauth, with pending status external_identity[external_id_provider][external_id] = 'LINK' if external_id_provider in user.external_identity: user.external_identity[external_id_provider].update( external_identity[external_id_provider]) else: user.external_identity.update(external_identity) # 2. add unconfirmed email and send confirmation email user.add_unconfirmed_email(clean_email, external_identity=external_identity) user.save() send_confirm_email(user, clean_email, external_id_provider=external_id_provider, external_id=external_id, destination=destination) # 3. notify user message = language.EXTERNAL_LOGIN_EMAIL_LINK_SUCCESS.format( external_id_provider=external_id_provider, email=user.username) kind = 'success' # 4. remove session and osf cookie remove_session(session) else: # 1. create unconfirmed user with pending status external_identity[external_id_provider][external_id] = 'CREATE' user = OSFUser.create_unconfirmed( username=clean_email, password=None, fullname=fullname, external_identity=external_identity, campaign=None) # TODO: [#OSF-6934] update social fields, verified social fields cannot be modified user.save() # 3. send confirmation email send_confirm_email(user, user.username, external_id_provider=external_id_provider, external_id=external_id, destination=destination) # 4. notify user message = language.EXTERNAL_LOGIN_EMAIL_CREATE_SUCCESS.format( external_id_provider=external_id_provider, email=user.username) kind = 'success' # 5. remove session remove_session(session) status.push_status_message(message, kind=kind, trust=False) else: forms.push_errors_to_status(form.errors) # Don't go anywhere return {'form': form, 'external_id_provider': external_id_provider}
def external_login_email_post(): """ View to handle email submission for first-time oauth-login user. HTTP Method: POST """ form = ResendConfirmationForm(request.form) session = get_session() if not session.is_external_first_login: raise HTTPError(http.UNAUTHORIZED) external_id_provider = session.data['auth_user_external_id_provider'] external_id = session.data['auth_user_external_id'] fullname = session.data.get('auth_user_fullname') or form.name.data service_url = session.data['service_url'] # TODO: @cslzchen use user tags instead of destination destination = 'dashboard' for campaign in campaigns.get_campaigns(): if campaign != 'institution': # Handle different url encoding schemes between `furl` and `urlparse/urllib`. # OSF use `furl` to parse service url during service validation with CAS. However, `web_url_for()` uses # `urlparse/urllib` to generate service url. `furl` handles `urlparser/urllib` generated urls while ` but # not vice versa. campaign_url = furl.furl(campaigns.campaign_url_for(campaign)).url external_campaign_url = furl.furl(campaigns.external_campaign_url_for(campaign)).url if campaigns.is_proxy_login(campaign): # proxy campaigns: OSF Preprints and branded ones if check_service_url_with_proxy_campaign(str(service_url), campaign_url, external_campaign_url): destination = campaign # continue to check branded preprints even service url matches osf preprints if campaign != 'osf-preprints': break elif service_url.startswith(campaign_url): # osf campaigns: OSF Prereg and ERPC destination = campaign break if form.validate(): clean_email = form.email.data user = get_user(email=clean_email) external_identity = { external_id_provider: { external_id: None, }, } try: ensure_external_identity_uniqueness(external_id_provider, external_id, user) except ValidationError as e: raise HTTPError(http.FORBIDDEN, e.message) if user: # 1. update user oauth, with pending status external_identity[external_id_provider][external_id] = 'LINK' if external_id_provider in user.external_identity: user.external_identity[external_id_provider].update(external_identity[external_id_provider]) else: user.external_identity.update(external_identity) if not user.accepted_terms_of_service and form.accepted_terms_of_service.data: user.accepted_terms_of_service = timezone.now() # 2. add unconfirmed email and send confirmation email user.add_unconfirmed_email(clean_email, external_identity=external_identity) user.save() send_confirm_email( user, clean_email, external_id_provider=external_id_provider, external_id=external_id, destination=destination ) # 3. notify user message = language.EXTERNAL_LOGIN_EMAIL_LINK_SUCCESS.format( external_id_provider=external_id_provider, email=user.username ) kind = 'success' # 4. remove session and osf cookie remove_session(session) else: # 1. create unconfirmed user with pending status external_identity[external_id_provider][external_id] = 'CREATE' accepted_terms_of_service = timezone.now() if form.accepted_terms_of_service.data else None user = OSFUser.create_unconfirmed( username=clean_email, password=None, fullname=fullname, external_identity=external_identity, campaign=None, accepted_terms_of_service=accepted_terms_of_service ) # TODO: [#OSF-6934] update social fields, verified social fields cannot be modified user.save() # 3. send confirmation email send_confirm_email( user, user.username, external_id_provider=external_id_provider, external_id=external_id, destination=destination ) # 4. notify user message = language.EXTERNAL_LOGIN_EMAIL_CREATE_SUCCESS.format( external_id_provider=external_id_provider, email=user.username ) kind = 'success' # 5. remove session remove_session(session) status.push_status_message(message, kind=kind, trust=False) else: forms.push_errors_to_status(form.errors) # Don't go anywhere return { 'form': form, 'external_id_provider': external_id_provider, 'auth_user_fullname': fullname }