Example #1
0
    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)
Example #3
0
    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, [])
Example #4
0
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()
Example #5
0
    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),
        ])