def setUp(self) -> None: """Set up user models in storage for use in testing.""" super(UserIdByFirebaseAuthIdModelTests, self).setUp() # type: ignore[no-untyped-call] auth_models.UserIdByFirebaseAuthIdModel(id=self.USER_AUTH_ID, user_id=self.USER_ID).put()
def associate_multi_auth_ids_with_user_ids( auth_id_user_id_pairs: List[auth_domain.AuthIdUserIdPair]) -> None: """Commits the associations between auth IDs and user IDs. Args: auth_id_user_id_pairs: list(auth_domain.AuthIdUserIdPair). The associations to commit. Raises: Exception. One or more auth associations already exist. """ # Turn list(pair) to pair(list): https://stackoverflow.com/a/7558990/4859885 auth_ids, user_ids = python_utils.ZIP(*auth_id_user_id_pairs) user_id_collisions = get_multi_user_ids_from_auth_ids(auth_ids) if any(user_id is not None for user_id in user_id_collisions): user_id_collisions_text = ', '.join( '{auth_id=%r: user_id=%r}' % (auth_id, user_id) for auth_id, user_id in python_utils.ZIP( auth_ids, user_id_collisions) if user_id is not None) raise Exception('already associated: %s' % user_id_collisions_text) auth_id_collisions = get_multi_auth_ids_from_user_ids(user_ids) if any(auth_id is not None for auth_id in auth_id_collisions): auth_id_collisions_text = ', '.join( '{user_id=%r: auth_id=%r}' % (user_id, auth_id) for user_id, auth_id in python_utils.ZIP( user_ids, auth_id_collisions) if auth_id is not None) raise Exception('already associated: %s' % auth_id_collisions_text) # A new {auth_id: user_id} mapping needs to be created. We know the model # doesn't exist because get_auth_id_from_user_id returned None. assoc_by_auth_id_models = [ auth_models.UserIdByFirebaseAuthIdModel(id=auth_id, user_id=user_id) for auth_id, user_id in python_utils.ZIP(auth_ids, user_ids) ] auth_models.UserIdByFirebaseAuthIdModel.update_timestamps_multi( assoc_by_auth_id_models) auth_models.UserIdByFirebaseAuthIdModel.put_multi(assoc_by_auth_id_models) # The {user_id: auth_id} mapping needs to be created, but the model used to # store the relationship might already exist because other services use it # as well (e.g. user_services uses UserAuthDetailsModel.parent_user_id). In # such situations, the return value of get_multi_auth_ids_from_user_ids # would be None, so that isn't strong enough to determine whether we need to # create a new model rather than update an existing one. assoc_by_user_id_models = [ auth_models.UserAuthDetailsModel(id=user_id, firebase_auth_id=auth_id) for auth_id, user_id, assoc_by_user_id_model in python_utils.ZIP( auth_ids, user_ids, auth_models.UserAuthDetailsModel.get_multi(user_ids)) if (assoc_by_user_id_model is None or assoc_by_user_id_model.firebase_auth_id is None) ] if assoc_by_user_id_models: auth_models.UserAuthDetailsModel.update_timestamps_multi( assoc_by_user_id_models) auth_models.UserAuthDetailsModel.put_multi(assoc_by_user_id_models)
def test_reports_nothing_for_valid_id(self) -> None: model_with_valid_id = auth_models.UserIdByFirebaseAuthIdModel( id='123', user_id='1', created_on=self.NOW, last_updated=self.NOW) output = (self.pipeline | beam.Create([model_with_valid_id]) | beam.ParDo( auth_validation.ValidateUserIdByFirebaseAuthIdModelId())) self.assert_pcoll_equal(output, [])
def associate_auth_id_with_user_id( auth_id_user_id_pair: auth_domain.AuthIdUserIdPair ) -> None: """Commits the association between auth ID and user ID. Args: auth_id_user_id_pair: auth_domain.AuthIdUserIdPair. The association to commit. Raises: Exception. The IDs are already associated with a value. """ auth_id, user_id = auth_id_user_id_pair user_id_collision = get_user_id_from_auth_id(auth_id, include_deleted=True) if user_id_collision is not None: raise Exception('auth_id=%r is already associated with user_id=%r' % ( auth_id, user_id_collision)) auth_id_collision = get_auth_id_from_user_id(user_id, include_deleted=True) if auth_id_collision is not None: raise Exception('user_id=%r is already associated with auth_id=%r' % ( user_id, auth_id_collision)) # A new {auth_id: user_id} mapping needs to be created. We know the model # doesn't exist because get_auth_id_from_user_id returned None, even with # include_deleted=True. assoc_by_auth_id_model = ( auth_models.UserIdByFirebaseAuthIdModel(id=auth_id, user_id=user_id)) assoc_by_auth_id_model.update_timestamps() assoc_by_auth_id_model.put() # The {user_id: auth_id} mapping needs to be created, but the model used to # store the relationship might already exist because other services use it # as well (e.g. user_services uses UserAuthDetailsModel.parent_user_id). In # such situations, the return value of get_auth_id_from_user_id would be # None, so that isn't strong enough to determine whether we need to create a # new model rather than update an existing one. # # NOTE: We use get_multi(include_deleted=True) because get() returns None # for models with deleted=True, but we need to make changes to those models # when managing deletion. (assoc_by_user_id_model,) = auth_models.UserAuthDetailsModel.get_multi( [user_id], include_deleted=True) if (assoc_by_user_id_model is None or assoc_by_user_id_model.firebase_auth_id is None): assoc_by_user_id_model = auth_models.UserAuthDetailsModel( id=user_id, firebase_auth_id=auth_id) assoc_by_user_id_model.update_timestamps() assoc_by_user_id_model.put()
def test_reports_error_for_invalid_id(self) -> None: model_with_invalid_id = auth_models.UserIdByFirebaseAuthIdModel( id='-!\'"', user_id='1', created_on=self.NOW, last_updated=self.NOW) output = (self.pipeline | beam.Create([model_with_invalid_id]) | beam.ParDo( auth_validation.ValidateUserIdByFirebaseAuthIdModelId())) self.assert_pcoll_equal(output, [ base_validation_errors.ModelIdRegexError( model_with_invalid_id, feconf.FIREBASE_AUTH_ID_REGEX), ])