Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for self signed certificates (#85) #86

Merged
merged 5 commits into from
Nov 19, 2023
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: 3 additions & 19 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions example.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"display": "genres",
"separator": "-"
},
"self_signed_cert": false,
"_comment": "the 4 lines below and this line arent needed and should be removed, by default nothing will display if these are present",
"blacklist": {
"media_types": ["music", "movie", "episode", "livetv"],
Expand Down
6 changes: 3 additions & 3 deletions jellyfin-rpc-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jellyfin-rpc-cli"
version = "0.15.4"
version = "0.15.5"
edition = "2021"
description = "Displays the content you're currently watching on Discord!"
license = "GPL-3.0-or-later"
Expand All @@ -27,8 +27,8 @@ retry = "2.0"

[dependencies.jellyfin-rpc]
features = ["imgur", "cli"]
version = "0.1.4"
#path = "../jellyfin-rpc"
#version = "0.1.4"
path = "../jellyfin-rpc"

[dependencies.clap]
features = ["derive"]
Expand Down
34 changes: 27 additions & 7 deletions jellyfin-rpc-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use clap::Parser;
use colored::Colorize;
use discord_rich_presence::{activity, DiscordIpc, DiscordIpcClient};
pub use jellyfin_rpc::services::imgur::*;
pub use jellyfin_rpc::prelude::*;
pub use jellyfin_rpc::services::imgur::*;
use retry::retry_with_index;
#[cfg(feature = "updates")]
mod updates;
Expand All @@ -26,6 +26,13 @@ struct Args {
help = "Path to image urls file for imgur"
)]
image_urls: Option<String>,
#[arg(
short = 's',
long = "suppress-warnings",
help = "Stops warnings from showing on startup",
default_value_t = false
)]
suppress_warnings: bool,
}

#[tokio::main]
Expand Down Expand Up @@ -68,11 +75,22 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
"Jellyfin-RPC".bright_blue()
);

if config
.clone()
.images
.and_then(|images| images.enable_images)
.unwrap_or(false)
if !args.suppress_warnings && config.jellyfin.self_signed_cert.is_some_and(|val| val) {
eprintln!(
"{}\n{}",
"------------------------------------------------------------------".bold(),
"WARNING: Self-signed certificates are enabled!"
.bold()
.red()
);
}

if !args.suppress_warnings
&& config
.clone()
.images
.and_then(|images| images.enable_images)
.unwrap_or(false)
&& !config
.clone()
.images
Expand All @@ -82,7 +100,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
eprintln!(
"{}\n{}",
"------------------------------------------------------------------".bold(),
"Images without Imgur requires port forwarding!"
"WARNING: Images without Imgur requires port forwarding!"
.bold()
.red()
)
Expand Down Expand Up @@ -174,6 +192,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
&config.jellyfin.api_key,
&content.item_id,
library,
config.jellyfin.self_signed_cert.unwrap_or(false),
)
.await?;
}
Expand Down Expand Up @@ -207,6 +226,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.and_then(|imgur| imgur.client_id)
.expect("Imgur client ID cant be loaded."),
args.image_urls.clone(),
config.jellyfin.self_signed_cert.unwrap_or(false),
)
.await
.unwrap_or_else(|e| {
Expand Down
2 changes: 1 addition & 1 deletion jellyfin-rpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "jellyfin-rpc"
version = "0.1.4"
version = "0.1.5"
edition = "2021"
description = "Backend for the Jellyfin-RPC-cli and Jellyfin-RPC-Iced projects"
license = "GPL-3.0-or-later"
Expand Down
1 change: 1 addition & 0 deletions jellyfin-rpc/example.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"display": "genres",
"separator": "-"
},
"self_signed_cert": false,
"_comment": "the 4 lines below and this line arent needed and should be removed, by default nothing will display if these are present",
"blacklist": {
"media_types": ["music", "movie", "episode", "livetv"],
Expand Down
17 changes: 10 additions & 7 deletions jellyfin-rpc/src/core/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ use serde_json;
use std::env;

/// Main struct containing every other struct in the file.
///
///
/// The config file is parsed into this struct.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "lowercase")]
pub struct Config {
/// Jellyfin configuration.
///
///
/// Has every required part of the config, hence why its not an `Option<Jellyfin>`.
pub jellyfin: Jellyfin,
/// Discord configuration.
Expand All @@ -35,6 +35,8 @@ pub struct Jellyfin {
pub music: Option<Music>,
/// Blacklist configuration.
pub blacklist: Option<Blacklist>,
/// Self signed certificate option
pub self_signed_cert: Option<bool>,
}

/// Username of the person that info should be gathered from.
Expand All @@ -51,15 +53,15 @@ pub enum Username {
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct Music {
/// Display is where you tell the program what should be displayed.
///
///
/// Example: `vec![String::from("genres"), String::from("year")]`
pub display: Option<Display>,
/// Separator is what should be between the artist(s) and the `display` options.
pub separator: Option<char>,
}

/// Display is where you tell the program what should be displayed.
///
///
/// Example: `vec![String::from("genres"), String::from("year")]`
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
Expand Down Expand Up @@ -89,7 +91,7 @@ pub struct Discord {
}

/// Button struct
///
///
/// Contains information about buttons
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct Button {
Expand All @@ -116,9 +118,9 @@ pub struct Images {
}

/// Find config.json in filesystem.
///
///
/// This is to avoid the user having to specify a filepath on launch.
///
///
/// Default config path depends on OS
/// Windows: `%appdata%\jellyfin-rpc\config.json`
/// Linux/macOS: `~/.config/jellyfin-rpc/config.json`
Expand Down Expand Up @@ -154,6 +156,7 @@ impl Default for Config {
api_key: "".to_string(),
music: None,
blacklist: None,
self_signed_cert: None,
},
discord: None,
imgur: None,
Expand Down
2 changes: 1 addition & 1 deletion jellyfin-rpc/src/core/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::prelude::MediaType;
use discord_rich_presence::activity;

/// Used to set the activity on Discord.
///
///
/// This has checks to do different things for different mediatypes and replaces images with default ones if they are needed.
pub fn setactivity<'a>(
state_message: &'a str,
Expand Down
17 changes: 15 additions & 2 deletions jellyfin-rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
/// Main module
pub mod core;
/// Useful imports
///
///
/// Contains imports that most programs will be using.
pub mod prelude;
/// External connections
pub mod services;
pub use crate::core::error;
pub use core::rpc::setactivity;
use discord_rich_presence::DiscordIpc;
use discord_rich_presence::DiscordIpcClient;
use retry::retry_with_index;
pub use core::rpc::setactivity;
#[cfg(test)]
mod tests;

Expand Down Expand Up @@ -61,3 +61,16 @@ pub fn connect(rich_presence_client: &mut DiscordIpcClient) {
)
.unwrap();
}

/// Built in reqwest::get() function, has an extra field to specify if the self signed cert should be accepted.
pub async fn get<U: reqwest::IntoUrl>(
url: U,
self_signed_cert: bool,
) -> Result<reqwest::Response, reqwest::Error> {
reqwest::Client::builder()
.danger_accept_invalid_certs(self_signed_cert)
.build()?
.get(url)
.send()
.await
}
31 changes: 24 additions & 7 deletions jellyfin-rpc/src/services/imgur.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ pub struct Imgur {
}

/// Find urls.json in filesystem, used to store images that were already previously uploaded to imgur.
///
///
/// This is to avoid the user having to specify a filepath on launch.
///
///
/// Default urls.json path depends on OS
/// Windows: `%appdata%\jellyfin-rpc\urls.json`
/// Linux/macOS: `~/.config/jellyfin-rpc/urls.json`
Expand All @@ -32,13 +32,14 @@ pub fn get_urls_path() -> Result<String, ImgurError> {

impl Imgur {
/// Queries the urls.json file for an imgur url with the same item ID attached.
///
///
/// If there's no imgur URL in the file, it will upload the image to imgur, store it in the file and then hand the URL over in a result.
pub async fn get(
image_url: &str,
item_id: &str,
client_id: &str,
image_urls_file: Option<String>,
self_signed_cert: bool,
) -> Result<Self, ImgurError> {
let file = match image_urls_file {
Some(file) => file,
Expand All @@ -53,7 +54,15 @@ impl Imgur {
}

Ok(Self {
url: Imgur::write_file(file, image_url, item_id, client_id, &mut json).await?,
url: Imgur::write_file(
file,
image_url,
item_id,
client_id,
self_signed_cert,
&mut json,
)
.await?,
})
}

Expand Down Expand Up @@ -87,12 +96,13 @@ impl Imgur {
image_url: &str,
item_id: &str,
client_id: &str,
self_signed_cert: bool,
json: &mut Value,
) -> Result<String, ImgurError> {
// Create a new map that's used for adding data to the "urls.json" file
let mut new_data = serde_json::Map::new();
// Upload the content's image to imgur
let imgur_url = Imgur::upload(image_url, client_id).await?;
let imgur_url = Imgur::upload(image_url, client_id, self_signed_cert).await?;
// Insert the item_id and the new image url into the map we created earlier
new_data.insert(item_id.to_string(), json!(imgur_url));

Expand All @@ -105,8 +115,15 @@ impl Imgur {
Ok(imgur_url)
}

async fn upload(image_url: &str, client_id: &str) -> Result<String, ImgurError> {
let img = reqwest::get(image_url).await?.bytes().await?;
async fn upload(
image_url: &str,
client_id: &str,
self_signed_cert: bool,
) -> Result<String, ImgurError> {
let img = crate::get(image_url, self_signed_cert)
.await?
.bytes()
.await?;
let client = reqwest::Client::new();
let response = client
.post("https://api.imgur.com/3/image")
Expand Down
Loading
Loading