diff --git a/Cargo.toml b/Cargo.toml index 73cc0f3..13b3930 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ chrono = "0.4.38" regex = "1.10.5" futures = "0.3.30" headers = "0.4.0" -reqwest = { version = "0.12.5", default-features = false, features = ["blocking", "rustls-tls"] } +reqwest = { version = "0.12.5", default-features = false, features = ["blocking", "rustls-tls", "cookies", "json"] } lettre = "0.11.7" rand = "0.9.0-alpha.1" rusqlite = "0.31.0" diff --git a/src/main.rs b/src/main.rs index 3df0886..5722b02 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,6 +31,10 @@ future improvements: (that's an incomplete list, but tag things as you notice them…) */ +use std::borrow::Cow; +use std::env; +use std::error::Error; + use chrono::{Local, NaiveDate}; use clap::{Arg, Command}; use colored::Colorize; @@ -195,6 +199,8 @@ fn main() -> Result<(), Box> { &config["wiki-server-url"], &config["wiki-http-user"], &config["wiki-http-password"], + &config["wiki-api-user"], + &config["wiki-api-secret"], is_dry_run(), ); trace_var_!(wiki); diff --git a/src/mediawiki.rs b/src/mediawiki.rs index 628a9fa..6d3b26b 100644 --- a/src/mediawiki.rs +++ b/src/mediawiki.rs @@ -2,6 +2,7 @@ use std::error::Error; use std::fs::File; use std::io::Read; +use colored::Colorize; use pandoc::{PandocError, PandocOutput}; use reqwest::blocking::Client; use serde::Deserialize; @@ -22,10 +23,13 @@ pub const CONFIG: CfgGroup<'static> = CfgGroup { default: "cccb-wiki", description: "HTTP basic auth user name.", }, - CfgField::Password { key: "http-password", description: "HTTP basic auth password." }, + CfgField::Password { + key: "http-password", + description: "HTTP basic auth password." + }, CfgField::Default { key: "api-user", - default: "PlenumBot@PlenumBot-PW1", + default: "PlenumBot@PlenumBot-PW2", description: "API Username associated with the bot account used for edits.", }, CfgField::Password { @@ -39,7 +43,11 @@ pub struct Mediawiki { server_url: String, http_user: String, http_password: String, + api_user: String, + api_secret: String, is_dry_run: bool, + login_token: String, + csrf_token: String, client: Client, } @@ -57,30 +65,69 @@ impl std::fmt::Debug for Mediawiki { impl Mediawiki { pub fn new( - server_url: &str, http_auth_user: &str, http_auth_password: &str, is_dry_run: bool, + server_url: &str, http_auth_user: &str, http_auth_password: &str, api_user: &str, api_secret: &str, is_dry_run: bool, ) -> Self { Self { server_url: server_url.to_string(), http_user: http_auth_user.to_string(), http_password: http_auth_password.to_string(), + api_user: api_user.to_string(), + api_secret: api_secret.to_string(), is_dry_run, - client: Client::new(), + login_token: String::new(), + csrf_token: String::new(), + client: Client::builder().cookie_store(true).build().unwrap(), } } - - /// Authenticate with username and password on http basic auth pub fn get_login_token(&self) -> Result> { let url = format!("{}/api.php?action=query&meta=tokens&type=login&format=json", self.server_url); let resp = self .client .get(url) - .basic_auth(&self.http_user, Some(&self.http_password)) + //.basic_auth(&self.http_user, Some(&self.http_password)) ZU TESTZWECKEN ENTFERNT .send()? .text()?; let response_deserialized: QueryResponse = serde_json::from_str(&resp)?; Ok(response_deserialized.query.tokens.logintoken) } + pub fn login (&self) -> Result> { + let url = format!("{}/api.php?action=login", self.server_url); + let params = [ + ("lgname", &self.api_user), + ("lgpassword", &self.api_secret), + ("lgtoken", &self.login_token) + ]; + let resp = self + .client + .post(url) + .form(¶ms) + .send()? + .text()?; + Ok(resp) + } + pub fn get_csrf_token(&self) -> Result> { // HAS TO BE FIXED + // action=query&meta=tokens + let url = + format!("{}/api.php?", self.server_url); + let params = [ + ("format", "json"), + ("meta", "tokens"), + ("formatversion", "2"), + ("lgtoken", &self.login_token) + ]; + let resp = self + .client + .get(url) + //.basic_auth(&self.http_user, Some(&self.http_password)) ZU TESTZWECKEN ENTFERNT + .query(¶ms) + .send()? + .text()?; + println!(" --- \n{}\n ---", resp.green()); + let response_deserialized: QueryResponse = serde_json::from_str(&resp)?; + Ok(response_deserialized.query.tokens.logintoken) + } + } #[derive(Deserialize)] @@ -99,8 +146,19 @@ struct Tokens { logintoken: String, } -pub fn pad_ins_wiki(old_pad_content: String) { +pub fn pad_ins_wiki(old_pad_content: String, wiki: &mut Mediawiki) -> Result<(), Box> { convert_md_to_mediawiki(old_pad_content); + + let auth_result = wiki.get_login_token().unwrap(); + wiki.login_token = auth_result.clone(); + println!("AUTH Success"); + let login_result = wiki.login()?; + println!("LOGIN Success"); + let csrf_token = wiki.get_csrf_token(); + println!("CSRF Success"); + //wiki.csrf_token.clone_from(&csrf_token); HAS TO BE FIXED + println!("---AUTH RESULT:---\n{}\n---LOGIN RESULT:---\n{:?}\n---CSRF RESULT:---\n\n-----------", auth_result, login_result,/* csrf_token*/); + // Textdatei wieder einlesen // Passwörter aus Datenbank lesen (ToBeDone) @@ -112,6 +170,7 @@ pub fn pad_ins_wiki(old_pad_content: String) { println!("plenum_bot_user: {plenum_bot_user}, plenum_bot_pw: {plenum_bot_pw}, login_token: {login_token}") */ + Ok(()) } /// Converts one file type into another using pandoc and saves the result as a txt file @@ -129,6 +188,7 @@ fn pandoc_convert( p.execute() } + /// Reads a text file from a specified path and returns it as a String fn read_txt_file(filepath: &str) -> String { let mut file = File::open(filepath)