def test_multiple_suggestions(): name_gen = generate_valid_usernames('a') generated_output = list(islice(name_gen, 4)) assert generated_output[0] == 'a0' assert generated_output[1] == 'a1' assert generated_output[2] == 'a2' assert generated_output[3] == 'a3'
def test_multiple_suggestions(): name_gen = generate_valid_usernames("a") generated_output = list(islice(name_gen, 4)) assert generated_output[0] == "a0" assert generated_output[1] == "a1" assert generated_output[2] == "a2" assert generated_output[3] == "a3"
def _get_and_link_federated_user_info(self, username, email, internal_create=False): db_user = model.user.verify_federated_login(self._federated_service, username) if not db_user: # Fetch list of blacklisted domains blacklisted_domains = model.config.app_config.get( "BLACKLISTED_EMAIL_DOMAINS") # We must create the user in our db. Check to see if this is allowed (except for internal # creation, which is always allowed). if not internal_create and not can_create_user( email, blacklisted_domains): return (None, DISABLED_MESSAGE) valid_username = None for valid_username in generate_valid_usernames(username): if model.user.is_username_unique(valid_username): break if not valid_username: logger.error("Unable to pick a username for user: %s", username) return ( None, "Unable to pick a username. Please report this to your administrator.", ) prompts = model.user.get_default_user_prompts(features) try: db_user = model.user.create_federated_user( valid_username, email, self._federated_service, username, set_password_notification=False, email_required=self._requires_email, confirm_username=features.USERNAME_CONFIRMATION, prompts=prompts, ) except model.InvalidEmailAddressException as iae: return (None, str(iae)) else: # Update the db attributes from the federated service. if email and db_user.email != email: db_user.email = email db_user.save() return (db_user, None)
def test_generate_valid_usernames(input_username, expected_output): name_gen = generate_valid_usernames(input_username) generated_output = list(islice(name_gen, 1))[0] assert generated_output == expected_output
def _conduct_oauth_login(auth_system, login_service, lid, lusername, lemail, metadata=None, captcha_verified=False): """ Conducts login from the result of an OAuth service's login flow and returns the status of the login, as well as the followup step. """ service_id = login_service.service_id() service_name = login_service.service_name() # Check for an existing account *bound to this service*. If found, conduct login of that account # and redirect. user_obj = model.user.verify_federated_login(service_id, lid) if user_obj is not None: return _oauthresult(user_obj=user_obj, service_name=service_name) # If the login service has a bound field name, and we have a defined internal auth type that is # not the database, then search for an existing account with that matching field. This allows # users to setup SSO while also being backed by something like LDAP. bound_field_name = login_service.login_binding_field() if auth_system.federated_service is not None and bound_field_name is not None: # Perform lookup. logger.debug('Got oauth bind field name of "%s"', bound_field_name) lookup_value = None if bound_field_name == "sub": lookup_value = lid elif bound_field_name == "username": lookup_value = lusername elif bound_field_name == "email": lookup_value = lemail if lookup_value is None: logger.error("Missing lookup value for OAuth login") return _oauthresult( service_name=service_name, error_message="Configuration error in this provider") (user_obj, err) = auth_system.link_user(lookup_value) if err is not None: logger.debug("%s %s not found: %s", bound_field_name, lookup_value, err) msg = "%s %s not found in backing auth system" % (bound_field_name, lookup_value) return _oauthresult(service_name=service_name, error_message=msg) # Found an existing user. Bind their internal auth account to this service as well. result = _attach_service(login_service, user_obj, lid, lusername) if result.error_message is not None: return result return _oauthresult(user_obj=user_obj, service_name=service_name) # Otherwise, we need to create a new user account. blacklisted_domains = app.config.get("BLACKLISTED_EMAIL_DOMAINS", []) if not can_create_user(lemail, blacklisted_domains=blacklisted_domains): error_message = "User creation is disabled. Please contact your administrator" return _oauthresult(service_name=service_name, error_message=error_message) if features.RECAPTCHA and not captcha_verified: return _oauthresult(service_name=service_name, requires_verification=True) # Try to create the user try: # Generate a valid username. new_username = None for valid in generate_valid_usernames(lusername): if model.user.get_user_or_org(valid): continue new_username = valid break requires_password = auth_system.requires_distinct_cli_password prompts = model.user.get_default_user_prompts(features) user_obj = model.user.create_federated_user( new_username, lemail, service_id, lid, set_password_notification=requires_password, metadata=metadata or {}, confirm_username=features.USERNAME_CONFIRMATION, prompts=prompts, email_required=features.MAILING, ) # Success, tell analytics analytics.track(user_obj.username, "register", {"service": service_name.lower()}) return _oauthresult(user_obj=user_obj, service_name=service_name) except model.InvalidEmailAddressException: message = ("The e-mail address {0} is already associated " "with an existing {1} account. \n" "Please log in with your username and password and " "associate your {2} account to use it in the future.") message = message.format(lemail, app.config["REGISTRY_TITLE_SHORT"], service_name) return _oauthresult(service_name=service_name, error_message=message, register_redirect=True) except model.DataModelException as ex: return _oauthresult(service_name=service_name, error_message=str(ex))