Beispiel #1
0
def test_delete_namespace_via_marker(initialized_db):
    def create_transaction(db):
        return db.transaction()

    # Create a user and then mark it for deletion.
    user = create_user_noverify("foobar",
                                "*****@*****.**",
                                email_required=False)

    # Add some repositories.
    create_repository("foobar", "somerepo", user)
    create_repository("foobar", "anotherrepo", user)

    # Mark the user for deletion.
    queue = WorkQueue("testgcnamespace", create_transaction)
    marker_id = mark_namespace_for_deletion(user, [], queue)

    # Delete the user.
    with check_transitive_modifications():
        delete_namespace_via_marker(marker_id, [])

    # Ensure the user was actually deleted.
    with pytest.raises(User.DoesNotExist):
        User.get(id=user.id)

    with pytest.raises(DeletedNamespace.DoesNotExist):
        DeletedNamespace.get(id=marker_id)
Beispiel #2
0
def get_organizations(deleted=False):
    query = User.select().where(User.organization == True, User.robot == False)

    if not deleted:
        query = query.where(User.id.not_in(DeletedNamespace.select(DeletedNamespace.namespace)))

    return query
Beispiel #3
0
def mark_namespace_for_deletion(user, queues, namespace_gc_queue, force=False):
    """ Marks a namespace (as referenced by the given user) for deletion. A queue item will be added
      to delete the namespace's repositories and storage, while the namespace itself will be
      renamed, disabled, and delinked from other tables.
  """
    if not user.enabled:
        return None

    if not force and not user.organization:
        # Ensure that the user is not the sole admin for any organizations. If so, then the user
        # cannot be deleted before those organizations are deleted or reassigned.
        organizations = get_solely_admined_organizations(user)
        if len(organizations) > 0:
            message = (
                "Cannot delete %s as you are the only admin for organizations: "
                % user.username)
            for index, org in enumerate(organizations):
                if index > 0:
                    message = message + ", "

                message = message + org.username

            raise DataModelException(message)

    # Delete all queue items for the user.
    for queue in queues:
        queue.delete_namespaced_items(user.username)

    # Delete non-repository related items. This operation is very quick, so we can do so here.
    _delete_user_linked_data(user)

    with db_transaction():
        original_username = user.username
        user = db_for_update(User.select().where(User.id == user.id)).get()

        # Mark the namespace as deleted and ready for GC.
        try:
            marker = DeletedNamespace.create(
                namespace=user,
                original_username=original_username,
                original_email=user.email)
        except IntegrityError:
            return

        # Disable the namespace itself, and replace its various unique fields with UUIDs.
        user.enabled = False
        user.username = str(uuid4())
        user.email = str(uuid4())
        user.save()

    # Add a queueitem to delete the namespace.
    marker.queue_id = namespace_gc_queue.put(
        [str(user.id)],
        json.dumps({
            "marker_id": marker.id,
            "original_username": original_username,
        }),
    )
    marker.save()
    return marker.id
Beispiel #4
0
def delete_namespace_via_marker(marker_id, queues):
    """ Deletes a namespace referenced by the given DeletedNamespace marker ID. """
    try:
        marker = DeletedNamespace.get(id=marker_id)
    except DeletedNamespace.DoesNotExist:
        return

    delete_user(marker.namespace, queues)
Beispiel #5
0
def get_active_users(disabled=True, deleted=False):
    query = User.select().where(User.organization == False, User.robot == False)

    if not disabled:
        query = query.where(User.enabled == True)

    if not deleted:
        query = query.where(User.id.not_in(DeletedNamespace.select(DeletedNamespace.namespace)))

    return query
Beispiel #6
0
def get_organizations(disabled=True, deleted=False):
    query = User.select().where(User.organization == True, User.robot == False)

    if not disabled:
        query = query.where(User.enabled == True)
    else:
        # NOTE: Deleted users are already disabled, so we don't need this extra check.
        if not deleted:
            query = query.where(User.id.not_in(DeletedNamespace.select(DeletedNamespace.namespace)))

    return query