diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml new file mode 100644 index 00000000..20176374 --- /dev/null +++ b/.github/workflows/e2e.yaml @@ -0,0 +1,44 @@ +# Temporary execution of E2E tests using MySQL becuase it's failing +# in the `testing.yml` workflows and affects deployments and releases. +# See https://github.com/torrust/torrust-index/issues/580 +name: E2E Testing + +on: + push: + pull_request: + +env: + CARGO_TERM_COLOR: always + +jobs: + e2e: + name: E2E + runs-on: ubuntu-latest + + strategy: + matrix: + toolchain: [stable, nightly] + + steps: + - id: checkout + name: Checkout Repository + uses: actions/checkout@v4 + + - id: setup + name: Setup Toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ matrix.toolchain }} + + - id: cache + name: Enable Job Cache + uses: Swatinem/rust-cache@v2 + + # Temporary Cleaning to avoid Rust Compiler Bug + - id: clean + name: Make Build Clean + run: cargo clean + + - id: test-mysql + name: Run Integration Tests (MySQL) + run: ./contrib/dev-tools/container/e2e/mysql/run-e2e-tests.sh diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index 075ae057..4c3dfebc 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -156,6 +156,6 @@ jobs: name: Run Integration Tests (SQLite) run: ./contrib/dev-tools/container/e2e/sqlite/run-e2e-tests.sh - - id: test-mysql - name: Run Integration Tests (MySQL) - run: ./contrib/dev-tools/container/e2e/mysql/run-e2e-tests.sh + #- id: test-mysql + # name: Run Integration Tests (MySQL) + # run: ./contrib/dev-tools/container/e2e/mysql/run-e2e-tests.sh diff --git a/Cargo.lock b/Cargo.lock index 9d6dd97a..3190f6d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3825,7 +3825,7 @@ dependencies = [ [[package]] name = "torrust-index" -version = "3.0.0-rc.1" +version = "3.0.0" dependencies = [ "anyhow", "argon2", @@ -3891,7 +3891,7 @@ dependencies = [ [[package]] name = "torrust-index-located-error" -version = "3.0.0-rc.1" +version = "3.0.0" dependencies = [ "thiserror", "tracing", diff --git a/Cargo.toml b/Cargo.toml index 68daa021..8943d980 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ license = "AGPL-3.0-only" publish = true repository = "https://github.com/torrust/torrust-tracker" rust-version = "1.72" -version = "3.0.0-rc.1" +version = "3.0.0" [profile.dev.package.sqlx-macros] opt-level = 3 @@ -89,7 +89,7 @@ text-to-png = "0" thiserror = "1" tokio = { version = "1", features = ["fs", "io-util", "macros", "net", "rt-multi-thread", "signal", "sync", "time"] } toml = "0" -torrust-index-located-error = { version = "3.0.0-rc.1", path = "packages/located-error" } +torrust-index-located-error = { version = "3.0.0", path = "packages/located-error" } tower = { version = "0.4", features = ["timeout"] } tower-http = { version = "0", features = ["compression-full", "cors", "propagate-header", "request-id", "trace"] } trace = "0.1.7" diff --git a/src/lib.rs b/src/lib.rs index 057a4bc7..13586a17 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -112,20 +112,28 @@ //! && mkdir -p ./storage/database //! ``` //! -//! Then you can run it with: `./target/release/main` +//! Then you can run it with: `./target/release/torrust-index` //! //! ## Run with docker //! //! You can run the index with a pre-built docker image: //! //! ```text -//! mkdir -p ./storage/database \ +//! cd /tmp \ +//! && mkdir torrust-index \ +//! && cd torrust-index \ +//! && mkdir -p ./storage/index/lib/database \ +//! && mkdir -p ./storage/index/log \ +//! && mkdir -p ./storage/index/etc \ +//! && sqlite3 "./storage/index/lib/database/sqlite3.db" "VACUUM;" \ //! && export USER_ID=1000 \ //! && docker run -it \ -//! --user="$USER_ID" \ +//! --env USER_ID="$USER_ID" \ //! --publish 3001:3001/tcp \ -//! --volume "$(pwd)/storage":"/app/storage" \ -//! torrust/index +//! --volume "$(pwd)/storage/index/lib":"/var/lib/torrust/index" \ +//! --volume "$(pwd)/storage/index/log":"/var/log/torrust/index" \ +//! --volume "$(pwd)/storage/index/etc":"/etc/torrust/index" \ +//! torrust/index:develop //! ``` //! //! For more information about using docker visit the [tracker docker documentation](https://github.com/torrust/torrust-index/tree/develop/docker). diff --git a/src/services/authorization.rs b/src/services/authorization.rs index 2861ddd9..e6678ac1 100644 --- a/src/services/authorization.rs +++ b/src/services/authorization.rs @@ -74,7 +74,6 @@ impl Service { /// /// Will return an error if: /// - The user is not authorized to perform the action. - pub async fn authorize(&self, action: ACTION, maybe_user_id: Option) -> std::result::Result<(), ServiceError> { let role = self.get_role(maybe_user_id).await; diff --git a/tests/e2e/web/api/v1/contexts/torrent/contract.rs b/tests/e2e/web/api/v1/contexts/torrent/contract.rs index ed3b4f33..909ec230 100644 --- a/tests/e2e/web/api/v1/contexts/torrent/contract.rs +++ b/tests/e2e/web/api/v1/contexts/torrent/contract.rs @@ -23,8 +23,7 @@ mod for_guests { use crate::common::client::Client; use crate::common::contexts::category::fixtures::software_predefined_category_id; use crate::common::contexts::torrent::asserts::assert_expected_torrent_details; - use crate::common::contexts::torrent::fixtures::{random_torrent, TestTorrent}; - use crate::common::contexts::torrent::forms::UploadTorrentMultipartForm; + use crate::common::contexts::torrent::fixtures::TestTorrent; use crate::common::contexts::torrent::requests::InfoHash; use crate::common::contexts::torrent::responses::{ Category, File, TorrentDetails, TorrentDetailsResponse, TorrentListResponse, @@ -34,29 +33,6 @@ mod for_guests { use crate::e2e::web::api::v1::contexts::torrent::steps::{upload_random_torrent_to_index, upload_test_torrent}; use crate::e2e::web::api::v1::contexts::user::steps::new_logged_in_user; - #[tokio::test] - async fn it_should_allow_guests_to_get_torrents() { - let mut env = TestEnv::new(); - env.start(api::Version::V1).await; - - if !env.provides_a_tracker() { - println!("test skipped. It requires a tracker to be running."); - return; - } - - let client = Client::unauthenticated(&env.server_socket_addr().unwrap()); - - let uploader = new_logged_in_user(&env).await; - let (_test_torrent, _indexed_torrent) = upload_random_torrent_to_index(&uploader, &env).await; - - let response = client.get_torrents(Query::empty()).await; - - let torrent_list_response: TorrentListResponse = serde_json::from_str(&response.body).unwrap(); - - assert!(torrent_list_response.data.total > 0); - assert!(response.is_json_and_ok()); - } - #[tokio::test] async fn it_should_allow_to_get_torrents_with_pagination() { let mut env = TestEnv::new(); @@ -429,40 +405,98 @@ mod for_guests { assert_eq!(response.status, 404); } - #[tokio::test] - async fn it_should_not_allow_guests_to_upload_torrents() { - let mut env = TestEnv::new(); - env.start(api::Version::V1).await; + mod authorization { + use torrust_index::web::api; - let client = Client::unauthenticated(&env.server_socket_addr().unwrap()); + use crate::common::client::Client; + use crate::common::contexts::torrent::fixtures::random_torrent; + use crate::common::contexts::torrent::forms::UploadTorrentMultipartForm; + use crate::common::contexts::torrent::responses::TorrentListResponse; + use crate::common::http::Query; + use crate::e2e::environment::TestEnv; + use crate::e2e::web::api::v1::contexts::torrent::steps::upload_random_torrent_to_index; + use crate::e2e::web::api::v1::contexts::user::steps::new_logged_in_user; - let test_torrent = random_torrent(); + #[tokio::test] + async fn it_should_not_allow_guests_to_upload_torrents() { + let mut env = TestEnv::new(); + env.start(api::Version::V1).await; - let form: UploadTorrentMultipartForm = test_torrent.index_info.into(); + let client = Client::unauthenticated(&env.server_socket_addr().unwrap()); - let response = client.upload_torrent(form.into()).await; + let test_torrent = random_torrent(); - assert_eq!(response.status, 401); - } + let form: UploadTorrentMultipartForm = test_torrent.index_info.into(); - #[tokio::test] - async fn it_should_not_allow_guests_to_delete_torrents() { - let mut env = TestEnv::new(); - env.start(api::Version::V1).await; + let response = client.upload_torrent(form.into()).await; - if !env.provides_a_tracker() { - println!("test skipped. It requires a tracker to be running."); - return; + assert_eq!(response.status, 401); } - let client = Client::unauthenticated(&env.server_socket_addr().unwrap()); + #[tokio::test] + async fn it_should_not_allow_guests_to_delete_torrents() { + let mut env = TestEnv::new(); + env.start(api::Version::V1).await; - let uploader = new_logged_in_user(&env).await; - let (test_torrent, _uploaded_torrent) = upload_random_torrent_to_index(&uploader, &env).await; + if !env.provides_a_tracker() { + println!("test skipped. It requires a tracker to be running."); + return; + } + + let client = Client::unauthenticated(&env.server_socket_addr().unwrap()); + + let uploader = new_logged_in_user(&env).await; + let (test_torrent, _uploaded_torrent) = upload_random_torrent_to_index(&uploader, &env).await; + + let response = client.delete_torrent(&test_torrent.file_info_hash()).await; + + assert_eq!(response.status, 401); + } + + #[tokio::test] + async fn it_should_allow_guests_to_download_a_torrent_file_searching_by_info_hash() { + let mut env = TestEnv::new(); + env.start(api::Version::V1).await; + + if !env.provides_a_tracker() { + println!("test skipped. It requires a tracker to be running."); + return; + } + + let client = Client::unauthenticated(&env.server_socket_addr().unwrap()); + let uploader = new_logged_in_user(&env).await; - let response = client.delete_torrent(&test_torrent.file_info_hash()).await; + // Upload + let (test_torrent, _torrent_listed_in_index) = upload_random_torrent_to_index(&uploader, &env).await; + + // Download + let response = client.download_torrent(&test_torrent.file_info_hash()).await; + + assert_eq!(response.status, 200); + } - assert_eq!(response.status, 401); + #[tokio::test] + async fn it_should_allow_guests_to_get_torrents() { + let mut env = TestEnv::new(); + env.start(api::Version::V1).await; + + if !env.provides_a_tracker() { + println!("test skipped. It requires a tracker to be running."); + return; + } + + let client = Client::unauthenticated(&env.server_socket_addr().unwrap()); + + let uploader = new_logged_in_user(&env).await; + let (_test_torrent, _indexed_torrent) = upload_random_torrent_to_index(&uploader, &env).await; + + let response = client.get_torrents(Query::empty()).await; + + let torrent_list_response: TorrentListResponse = serde_json::from_str(&response.body).unwrap(); + + assert!(torrent_list_response.data.total > 0); + assert!(response.is_json_and_ok()); + } } }