Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions src/authentication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,7 @@ pub fn verify_and_store_token(
}

fn verify_token(token: &str, api_url: &str) -> anyhow::Result<(), AuthenticationError> {
// Using uuid of non existing playlist. If we get 404 it means we authenticated successfully.
let url = format!("{api_url}/v3/groups/11CF9Z3GZR0005XXKH00F8V20R/");
let url = format!("{api_url}/v4/screens?limit=1");
let secret = format!("Token {token}");
let client = reqwest::blocking::Client::builder().build()?;

Expand All @@ -140,8 +139,8 @@ fn verify_token(token: &str, api_url: &str) -> anyhow::Result<(), Authentication
.send()?;

match res.status() {
StatusCode::OK => Ok(()),
StatusCode::UNAUTHORIZED => Err(AuthenticationError::WrongCredentials),
StatusCode::NOT_FOUND => Ok(()),
_ => Err(AuthenticationError::Unknown),
}
}
Expand Down Expand Up @@ -173,9 +172,9 @@ mod tests {
let mock_server = MockServer::start();
mock_server.mock(|when, then| {
when.method(GET)
.path("/v3/groups/11CF9Z3GZR0005XXKH00F8V20R/")
.header("Authorization", "Token token");
then.status(404);
.path("/v4/screens")
.header("Authorization", "Token correct_token");
then.status(200).body("[]");
});

let config = Config::new(mock_server.base_url());
Expand All @@ -196,8 +195,7 @@ mod tests {

let mock_server = MockServer::start();
mock_server.mock(|when, then| {
when.method(GET)
.path("/v3/groups/11CF9Z3GZR0005XXKH00F8V20R/");
when.method(GET).path("/v4/screens");
then.status(401);
});

Expand Down Expand Up @@ -248,11 +246,11 @@ mod tests {
let _test = set_env(OsString::from("HOME"), tmp_dir.path().to_str().unwrap());

let mock_server = MockServer::start();
let group_call_mock = mock_server.mock(|when, then| {
let screens_call_mock = mock_server.mock(|when, then| {
when.method(GET)
.path("/v3/groups/11CF9Z3GZR0005XXKH00F8V20R/")
.path("/v4/screens")
.header("Authorization", "Token correct_token");
then.status(404);
then.status(200).body("[]");
});

let config = Config::new(mock_server.base_url());
Expand All @@ -261,7 +259,7 @@ mod tests {
let path = tmp_dir.path().join(".screenly");
assert!(path.exists());
let contents = fs::read_to_string(path).unwrap();
group_call_mock.assert();
screens_call_mock.assert();
assert!(contents.eq("correct_token"));
}
}
43 changes: 20 additions & 23 deletions src/commands/screen.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::collections::HashMap;

use reqwest::StatusCode;

use crate::authentication::Authentication;
use crate::commands;
use crate::commands::{CommandError, Screens};
Expand Down Expand Up @@ -36,32 +34,20 @@ impl ScreenCommand {
pin: &str,
maybe_name: Option<String>,
) -> anyhow::Result<Screens, CommandError> {
let url = format!("{}/v3/screens/", &self.authentication.config.url);
let mut payload = HashMap::new();
payload.insert("pin".to_string(), pin.to_string());
if let Some(name) = maybe_name {
payload.insert("name".to_string(), name);
}
let response = self
.authentication
.build_client()?
.post(url)
.json(&payload)
.send()?;
if response.status() != StatusCode::CREATED {
return Err(CommandError::WrongResponseStatus(
response.status().as_u16(),
));
}

// Our newer endpoints all return arrays so let's just convert the output from v3 to be the same
let mut array: Vec<serde_json::Value> = Vec::new();
array.insert(0, serde_json::from_str(&response.text()?)?);
Ok(Screens::new(serde_json::Value::Array(array)))
let created = commands::post(&self.authentication, "v4.1/screens", &payload)?;
let id = created["id"].as_str().ok_or(CommandError::MissingField)?;

self.get(id)
}

pub fn delete(&self, id: &str) -> anyhow::Result<(), CommandError> {
let endpoint = format!("v3/screens/{id}/");
let endpoint = format!("v4.1/screens?id=eq.{id}");
commands::delete(&self.authentication, &endpoint)
}
}
Expand Down Expand Up @@ -104,26 +90,36 @@ mod tests {

#[test]
fn test_add_screen_should_send_correct_request() {
let new_screen = serde_json::from_str::<Value>("{\"id\":\"017a5104-524b-33d8-8026-9087b59e7eb5\",\"team_id\":\"016343c2-82b8-0000-a121-e30f1035875e\",\"created_at\":\"2021-06-28T05:07:55+00:00\",\"name\":\"Test\",\"is_enabled\":true,\"coords\":[55.22931, 48.90429],\"last_ping\":\"2021-08-25T06:17:20.728+00:00\",\"last_ip\":null,\"local_ip\":\"192.168.1.146\",\"mac\":\"b8:27:eb:d6:83:6f\",\"last_screenshot_time\":\"2021-08-25T06:09:04.399+00:00\",\"uptime\":\"230728.38\",\"load_avg\":\"0.14\",\"signal_strength\":null,\"interface\":\"eth0\",\"debug\":false,\"location\":\"Kamsko-Ust'inskiy rayon, Russia\",\"team\":\"016343c2-82b8-0000-a121-e30f1035875e\",\"timezone\":\"Europe/Moscow\",\"type\":\"hardware\",\"hostname\":\"srly-4shnfrdc5cd2p0p\",\"ws_open\":false,\"status\":\"Offline\",\"last_screenshot\":\"https://us-assets.screenlyapp.com/01CD1W50NR000A28F31W83B1TY/screenshots/01F98G8MJB6FC809MGGYTSWZNN/5267668e6db35498e61b83d4c702dbe8\",\"in_sync\":false,\"software_version\":\"Screenly 2 Player\",\"hardware_version\":\"Raspberry Pi 3B\",\"config\":{\"hdmi_mode\": 34, \"hdmi_boost\": 2, \"hdmi_drive\": 0, \"hdmi_group\": 0, \"verify_ssl\": true, \"audio_output\": \"hdmi\", \"hdmi_timings\": \"\", \"overscan_top\": 0, \"overscan_left\": 0, \"use_composite\": false, \"display_rotate\": 0, \"overscan_right\": 0, \"overscan_scale\": 0, \"overscan_bottom\": 0, \"disable_overscan\": 0, \"shuffle_playlist\": false, \"framebuffer_width\": 0, \"use_composite_pal\": false, \"framebuffer_height\": 0, \"hdmi_force_hotplug\": true, \"use_composite_ntsc\": false, \"hdmi_pixel_encoding\": 0, \"play_history_enabled\": false}}").unwrap();
let new_screen = serde_json::from_str::<Value>("{\"id\":\"01HBDXC6ZRGC2PKDZC7X5ZFGE0\",\"team_id\":\"016343c2-82b8-0000-a121-e30f1035875e\",\"created_at\":\"2021-06-28T05:07:55+00:00\",\"name\":\"Test\",\"is_enabled\":true,\"coords\":[55.22931, 48.90429],\"last_ping\":\"2021-08-25T06:17:20.728+00:00\",\"last_ip\":null,\"local_ip\":\"192.168.1.146\",\"mac\":\"b8:27:eb:d6:83:6f\",\"last_screenshot_time\":\"2021-08-25T06:09:04.399+00:00\",\"uptime\":\"230728.38\",\"load_avg\":\"0.14\",\"signal_strength\":null,\"interface\":\"eth0\",\"debug\":false,\"location\":\"Kamsko-Ust'inskiy rayon, Russia\",\"team\":\"016343c2-82b8-0000-a121-e30f1035875e\",\"timezone\":\"Europe/Moscow\",\"type\":\"hardware\",\"hostname\":\"srly-4shnfrdc5cd2p0p\",\"ws_open\":false,\"status\":\"Offline\",\"last_screenshot\":\"https://us-assets.screenlyapp.com/01CD1W50NR000A28F31W83B1TY/screenshots/01F98G8MJB6FC809MGGYTSWZNN/5267668e6db35498e61b83d4c702dbe8\",\"in_sync\":false,\"software_version\":\"Screenly 2 Player\",\"hardware_version\":\"Raspberry Pi 3B\",\"config\":{\"hdmi_mode\": 34, \"hdmi_boost\": 2, \"hdmi_drive\": 0, \"hdmi_group\": 0, \"verify_ssl\": true, \"audio_output\": \"hdmi\", \"hdmi_timings\": \"\", \"overscan_top\": 0, \"overscan_left\": 0, \"use_composite\": false, \"display_rotate\": 0, \"overscan_right\": 0, \"overscan_scale\": 0, \"overscan_bottom\": 0, \"disable_overscan\": 0, \"shuffle_playlist\": false, \"framebuffer_width\": 0, \"use_composite_pal\": false, \"framebuffer_height\": 0, \"hdmi_force_hotplug\": true, \"use_composite_ntsc\": false, \"hdmi_pixel_encoding\": 0, \"play_history_enabled\": false}}").unwrap();
let mock_server = MockServer::start();
let post_mock = mock_server.mock(|when, then| {
when.method(POST)
.path("/v3/screens/")
.path("/v4.1/screens")
.header("Authorization", "Token token")
.header("content-type", "application/json")
.header(
"user-agent",
format!("screenly-cli {}", env!("CARGO_PKG_VERSION")),
)
.json_body(json!({"pin": "test-pin", "name": "test"}));
then.status(201).json_body(new_screen.clone());
then.status(200)
.json_body(json!({"id": "01HBDXC6ZRGC2PKDZC7X5ZFGE0"}));
});

let get_mock = mock_server.mock(|when, then| {
when.method(GET)
.path("/v4/screens")
.query_param("id", "eq.01HBDXC6ZRGC2PKDZC7X5ZFGE0")
.header("Authorization", "Token token");
then.status(200).json_body(json!([new_screen.clone()]));
});

let config = Config::new(mock_server.base_url());
let authentication = Authentication::new_with_config(config, "token");
let screen_command = ScreenCommand::new(authentication);
let v = screen_command.add("test-pin", Some("test".to_string()));
post_mock.assert();
get_mock.assert();
assert!(v.is_ok());
assert_eq!(v.unwrap().value.as_array().unwrap()[0], new_screen);
}
Expand Down Expand Up @@ -157,7 +153,8 @@ mod tests {
let mock_server = MockServer::start();
mock_server.mock(|when, then| {
when.method(DELETE)
.path("/v3/screens/test-id/")
.path("/v4.1/screens")
.query_param("id", "eq.test-id")
.header(
"user-agent",
format!("screenly-cli {}", env!("CARGO_PKG_VERSION")),
Expand Down
Loading