commit 79a0d08b130fa6773baa4a178d576a96aaac318c
parent b54e35f960f78cd09030f573f3f6c06ae98c60b2
Author: MTRNord <mtrnord1@gmail.com>
Date: Thu, 20 Apr 2017 10:40:36 +0200
prepare llogin and update hyper (not working yet), add sendMessage (in itself working)
Diffstat:
| M | Cargo.toml | | | 11 | ++++++++--- |
| A | log.txt | | | 72 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | src/hangups/mod.rs | | | 149 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- |
| M | src/lib.rs | | | 345 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- |
4 files changed, 485 insertions(+), 92 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
@@ -4,8 +4,13 @@ version = "0.0.1"
authors = ["MTRNord"]
[dependencies]
-yup-oauth2 = "1.0.5"
-hyper = "0.10.2"
-hyper-native-tls = "0.2.2"
+hyper = { git = "https://github.com/hyperium/hyper" }
protobuf = "1.2.2"
rand = "0.3"
+sha1 = "0.2.0"
+rustc-serialize = "0.3.23"
+jconfig = "0.1.0"
+regex = "0.2"
+url = "1.4.0"
+tokio-core = "0.1.6"
+futures = "0.1.13"
diff --git a/log.txt b/log.txt
@@ -0,0 +1,72 @@
+ Compiling hangups v0.0.1 (file:///source)
+error[E0382]: use of moved value: `core`
+ --> src/lib.rs:257:9
+ |
+233 | let req_raw = client.get(auth_uri).and_then(|res| {
+ | ----- value moved (into closure) here
+...
+257 | core.run(req).unwrap();
+ | ^^^^ value used here after move
+ |
+ = note: move occurs because `core` has type `tokio_core::reactor::Core`, which does not implement the `Copy` trait
+
+error: cannot borrow immutable borrowed content as mutable
+ --> src/lib.rs:247:115
+ |
+247 | do_auth_step(&mut core, &client, email_uri, &res, &body.as_str(), client_email, client_email, &mut headers);
+ | ^^^^^^^^^^^^ cannot borrow as mutable
+
+error[E0505]: cannot move out of `res` because it is borrowed
+ --> src/lib.rs:240:18
+ |
+236 | &res.headers()
+ | --- borrow of `res` occurs here
+...
+240 | &res.body().for_each(|chunk| {
+ | ^^^ move out of `res` occurs here
+
+error[E0382]: use of moved value: `core`
+ --> src/lib.rs:247:39
+ |
+246 | let core_raw = core;
+ | -------- value moved here
+247 | do_auth_step(&mut core, &client, email_uri, &res, &body.as_str(), client_email, client_email, &mut headers);
+ | ^^^^ value used here after move
+ |
+ = note: move occurs because `core` has type `tokio_core::reactor::Core`, which does not implement the `Copy` trait
+
+error[E0382]: use of moved value: `res`
+ --> src/lib.rs:247:66
+ |
+240 | &res.body().for_each(|chunk| {
+ | --- value moved here
+...
+247 | do_auth_step(&mut core, &client, email_uri, &res, &body.as_str(), client_email, client_email, &mut headers);
+ | ^^^ value used here after move
+ |
+ = note: move occurs because `res` has type `hyper::client::Response`, which does not implement the `Copy` trait
+
+error[E0382]: use of moved value: `client_email`
+ --> src/lib.rs:247:101
+ |
+247 | do_auth_step(&mut core, &client, email_uri, &res, &body.as_str(), client_email, client_email, &mut headers);
+ | ------------ ^^^^^^^^^^^^ value used here after move
+ | |
+ | value moved here
+ |
+ = note: move occurs because `client_email` has type `std::string::String`, which does not implement the `Copy` trait
+
+error[E0505]: cannot move out of `body` because it is borrowed
+ --> src/hangups/mod.rs:125:12
+ |
+109 | let post_req = client.request(fresh_request).map_err(|_| ()).and_then(|res| {
+ | ----- borrow of `body` occurs here
+...
+125 | Ok(body)
+ | ^^^^ move out of `body` occurs here
+
+error: aborting due to 7 previous errors
+
+error: Could not compile `hangups`.
+
+To learn more, run the command again with --verbose.
diff --git a/src/hangups/mod.rs b/src/hangups/mod.rs
@@ -1,44 +1,148 @@
#[path = "proto/hangouts.rs"] mod hangouts;
pub mod hangups {
- use hangups::hangouts::{MessageContent, Segment, SegmentType, RequestHeader, EventRequestHeader,
- SendChatMessageRequest, DeliveryMediumType, OffTheRecordStatus,
- EventType, SendChatMessageResponse, DeliveryMedium, ConversationId};
+ use hangups::hangouts::{MessageContent, Segment, SegmentType, RequestHeader,
+ EventRequestHeader, SendChatMessageRequest, DeliveryMediumType,
+ OffTheRecordStatus, EventType, SendChatMessageResponse,
+ DeliveryMedium, ConversationId};
use protobuf::RepeatedField;
use rand::random;
- use hyper::header::Headers;
use hyper::header::Cookie;
- use hyper::client::Client;
+ use hyper::client::Request;
+ use hyper::{Method, Uri};
+ use std::io::{Read, Write};
+ use hyper::error::Error;
+ use protobuf::Message;
+ use std::collections::HashMap;
+ use std::time::*;
+ use sha1::Sha1;
+ use rustc_serialize::hex::ToHex;
+ use rustc_serialize::base64::FromBase64;
+ use protobuf::core::parse_from_bytes;
+ use auth::get_auth;
+ use helper::get_configs;
+ use std::str::FromStr;
+ use std;
+
header! { (ContentType, "content-type") => [String] }
header! {
(XGoogEncodeResponseIfExecutable, "X-Goog-Encode-Response-If-Executable") => [String]
}
- fn get_auth_headers() {}
+ fn get_cookies() -> Result<HashMap<String, String>, Error> {
+ let config = get_configs().unwrap();
+ if (config.get_raw("SAPISID") == None) || (config.get_raw("HSID") == None) || (config.get_raw("SSID") == None) || (config.get_raw("APISID") == None) || (config.get_raw("SID") == None) {
+ get_auth(String::from(""), String::from(""));
+ }
+
+ let sapisid_cookie = String::from(config.get_raw("SAPISID").unwrap().as_string().unwrap());
+ let hsid_cookie = String::from(config.get_raw("HSID").unwrap().as_string().unwrap());
+ let ssid_cookie = String::from(config.get_raw("SSID").unwrap().as_string().unwrap());
+ let apisid_cookie = String::from(config.get_raw("APISID").unwrap().as_string().unwrap());
+ let sid_cookie = String::from(config.get_raw("SID").unwrap().as_string().unwrap());
+
+ let mut cookies = HashMap::new();
+ cookies.insert(String::from("SAPISID"), sapisid_cookie);
+ cookies.insert(String::from("HSID"), hsid_cookie);
+ cookies.insert(String::from("SSID"), ssid_cookie);
+ cookies.insert(String::from("APISID"), apisid_cookie);
+ cookies.insert(String::from("SID"), sid_cookie);
+ Ok(cookies)
+ }
+
+ fn get_auth_headers(sapisid: String) -> Result<HashMap<String, String>, Error> {
+ let origin_url = String::from("https://talkgadget.google.com");
+ let now = SystemTime::now();
+ let dur = now.duration_since(UNIX_EPOCH).unwrap();
+ let timestamp_msec = dur.as_secs();
+
+
+ let auth_string = String::from(format!("{} {} {}", timestamp_msec, sapisid, origin_url));
+ let mut hash = Sha1::new();
+ hash.update(auth_string.as_bytes());
+ let hash_bytes = hash.digest().bytes();
+ let hex_sha1 = hash_bytes.to_hex();
+ let sapisid_hash = format!("SAPISIDHASH {}_{}", timestamp_msec, hex_sha1);
+ let mut auth_cookies = HashMap::new();
+ auth_cookies.insert(String::from("authorization"), sapisid_hash);
+ auth_cookies.insert(String::from("x-origin"), origin_url);
+ auth_cookies.insert(String::from("x-goog-authuser"), String::from("0"));
+ Ok(auth_cookies)
+ }
fn api_request(endpoint_url: String,
content_type: String,
- cookies: String,
- payload: SendChatMessageRequest) {
- let mut headers = Headers::new();
- headers.set(Cookie(vec![String::from(cookies.to_owned())]));
- headers.set(ContentType(String::from(content_type.to_owned())));
- headers.set(XGoogEncodeResponseIfExecutable(String::from("base64".to_owned())));
- let client = Client::new();
- let post_request = client.post(&*endpoint_url).headers(headers);
+ response_type: String,
+ payload: std::vec::Vec<u8>)
+ -> Result<String, Error> {
+ use hyper::Client;
+ use tokio_core::reactor::Core;
+ use std::str::FromStr;
+ use futures::{Future, Stream};
+
+ let mut core = Core::new().unwrap();
+ let handle = core.handle();
+ let client = Client::configure()
+ .keep_alive(true)
+ .build(&handle);
+ let url = format!("{}?key=AIzaSyAfFJCeph-euFSwtmqFZi0kaKk-cZ5wufM&alt={}",
+ endpoint_url,
+ response_type).parse::<Uri>().unwrap();;
+ let auth_header = get_auth_headers(String::from("PLACEHOLDER"))
+ .unwrap();
+ let mut fresh_request = Request::new(Method::Post, url);
+ let cookies = get_cookies().unwrap();
+ let mut cookie_vec = Vec::new();
+ for (key, val) in cookies {
+ cookie_vec.push(format!("{}={}", key, val))
+ }
+ fresh_request.headers_mut().set(Cookie(cookie_vec));
+ fresh_request.headers_mut().set(ContentType(String::from(content_type.to_owned())));
+ fresh_request.headers_mut().set(XGoogEncodeResponseIfExecutable(String::from("base64".to_owned())));
+ fresh_request.set_body(payload);
+ for (key, val) in auth_header {
+ fresh_request.headers_mut().append_raw(key, val.as_bytes().to_vec());
+ }
+ let mut body = String::new();
+
+ let mut post = {
+ let post_req = client.request(fresh_request).map_err(|_| ()).and_then(|res| {
+ res.body().for_each(|chunk| {
+ let body_chunk = String::from_utf8(chunk.to_vec()).unwrap();
+ body.push_str(body_chunk.as_str());
+ Ok(())
+ });
+ Ok(())
+ })
+ .map(|_| {
+ println!("\n\nDone.");
+ });
+ post_req
+ };
+
+ core.run(post).unwrap();
+
+ Ok(body)
}
fn protobuf_api_request(api_endpoint: String,
- request_struct: SendChatMessageRequest,
- response_struct: SendChatMessageResponse) {
+ request_struct: SendChatMessageRequest)
+ -> Result<SendChatMessageResponse, Error> {
let url = format!("https://clients6.google.com/chat/v1/{}", api_endpoint);
+ let payload = request_struct.write_to_bytes().unwrap();
let output = api_request(url,
String::from("application/x-protobuf"),
String::from("proto"),
- request_struct);
+ payload);
+ let decoded_output = output.unwrap().as_str().from_base64().unwrap();
+ let response_proto = parse_from_bytes::<SendChatMessageResponse>(&decoded_output[..])
+ .unwrap();
+ Ok(response_proto)
}
- pub fn send_message(message: String, conv_id_raw: String) {
+ pub fn send_message(message: String,
+ conv_id_raw: String)
+ -> Result<SendChatMessageResponse, Error> {
//Prepare message
let segment_type = SegmentType::SEGMENT_TYPE_TEXT;
let mut segment_raw = Segment::new();
@@ -73,10 +177,9 @@ pub mod hangups {
request.set_message_content(message_content);
request.set_event_request_header(event_request_header);
- //Prepare response
- let response = SendChatMessageResponse::new();
-
- let err = protobuf_api_request(String::from("conversations/sendchatmessage"), request, response);
+ let output = protobuf_api_request(String::from("conversations/sendchatmessage"), request)
+ .unwrap();
+ Ok(output)
}
}
@@ -86,7 +189,7 @@ mod tests {
fn test_send_message() {
use super::hangups::send_message;
- let test_message = String::from("TEST!");
+ let test_message = String::from("Diese Nachricht sendet der Bot!");
let test_conv = String::from("Ugxu9JRlbNPSqk5Ye1V4AaABAQ");
send_message(test_message, test_conv);
}
diff --git a/src/lib.rs b/src/lib.rs
@@ -1,31 +1,204 @@
-#![allow(unused_variables)]
#[macro_use]
extern crate hyper;
-extern crate hyper_native_tls;
-extern crate yup_oauth2 as oauth2;
extern crate protobuf;
extern crate rand;
+extern crate sha1;
+extern crate rustc_serialize;
+extern crate jconfig;
+extern crate regex;
+extern crate url;
+extern crate tokio_core;
+extern crate futures;
pub mod auth {
- pub fn get_auth(client_email: String) {
+ use hyper::{Client, Body, Uri};
+ use hyper::client::{Response, HttpConnector};
+ use tokio_core::reactor::Core;
+ use hyper::header::Headers;
+ fn do_auth_step(mut core: &mut Core, client: &Client<HttpConnector, Body>, url: Uri, resp: &Response, resp_body: &str, email: String, password: String, mut resp_headers_raw: &mut Headers) {
+ use hyper::header::{Headers, SetCookie, UserAgent};
+ use hyper::client::Request;
+ use hyper::{Method, Uri};
+ use regex::Regex;
+ use std::str;
+ use url::form_urlencoded;
+ use std::str::FromStr;
+ use futures::Future;
+ use futures::Stream;
+
+ header! { (ContentType, "content-type") => [String] }
+ header! { (GAPS, "GAPS") => [String] }
+ header! { (GALX, "GALX") => [String] }
+
+ let mut req_headers = Headers::new();
+ if resp_headers_raw.has::<SetCookie>() {
+ let resp_headers = resp_headers_raw.get_raw("Set-Cookie").unwrap();
+ let mut resp_headers_string = String::new();
+ for elem in resp_headers.iter() {
+ let s = match str::from_utf8(elem) {
+ Ok(v) => v,
+ Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
+ };
+ resp_headers_string.push_str(s);
+ }
+ let resp_cookie_gaps_re = Regex::new("(?:GAPS=)(.*?)(?:;)").unwrap();
+ let resp_cookie_gaps_captures = resp_cookie_gaps_re.captures(resp_headers_string.as_str()).unwrap();
+ let resp_cookie_gaps = resp_cookie_gaps_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp_cookie_galx_re = Regex::new("(?:GALX=)(.*?)(?:;)").unwrap();
+ let resp_cookie_galx_captures = resp_cookie_galx_re.captures(resp_headers_string.as_str()).unwrap();
+ let resp_cookie_galx = resp_cookie_galx_captures.get(1).map_or("", |m| m.as_str());
+
+ if resp_cookie_gaps != "" {
+ req_headers.set(GAPS(resp_cookie_gaps.to_owned()));
+ }
+ if resp_cookie_galx != "" {
+ req_headers.set(GALX(resp_cookie_galx.to_owned()));
+ }
+ }
+
+ let resp_page_re = Regex::new("(?:<input.*name=\"Page\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp_page_captures = resp_page_re.captures(resp_body).unwrap();
+ let resp_page = resp_page_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp_galx_re = Regex::new("(?:<input.*name=\"GALX\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp_galx_captures = resp_galx_re.captures(resp_body).unwrap();
+ let resp_galx = resp_galx_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp_gxf_re = Regex::new("(?:<input.*name=\"gxf\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp_gxf_captures = resp_gxf_re.captures(resp_body).unwrap();
+ let resp_gxf = resp_gxf_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp_continue_re = Regex::new("(?:<input.*name=\"continue\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp_continue_captures = resp_continue_re.captures(resp_body).unwrap();
+ let resp_gcontinue = resp_continue_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp_ltmpl_re = Regex::new("(?:<input.*name=\"ltmpl\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp_ltmpl_captures = resp_ltmpl_re.captures(resp_body).unwrap();
+ let resp_ltmpl = resp_ltmpl_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp_scc_re = Regex::new("(?:<input.*name=\"scc\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp_scc_captures = resp_scc_re.captures(resp_body).unwrap();
+ let resp_scc = resp_scc_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp_sarp_re = Regex::new("(?:<input.*name=\"sarp\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp_sarp_captures = resp_sarp_re.captures(resp_body).unwrap();
+ let resp_sarp = resp_sarp_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp_oauth_re = Regex::new("(?:<input.*name=\"oresp\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp_oauth_captures = resp_oauth_re.captures(resp_body).unwrap();
+ let resp_oauth = resp_oauth_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp_profile_information_re = Regex::new("(?:<input.*name=\"ProfileInformation\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp_profile_information_captures = resp_profile_information_re.captures(resp_body).unwrap();
+ let resp_profile_information = resp_profile_information_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp_session_state_re = Regex::new("(?:<input.*name=\"SessionState\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp_session_state_captures = resp_session_state_re.captures(resp_body).unwrap();
+ let resp_session_state = resp_session_state_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp__utf8_re = Regex::new("(?:<input.*name=\"_utf8\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp__utf8_captures = resp__utf8_re.captures(resp_body).unwrap();
+ let resp__utf8 = resp__utf8_captures.get(1).map_or("", |m| m.as_str());
+
+ let resp_bgresponse_re = Regex::new("(?:<input.*name=\"bgresponse\".*)(?:value=\"([^\"]*))").unwrap();
+ let resp_bgresponse_captures = resp_bgresponse_re.captures(resp_body).unwrap();
+ let resp_bgresponse = resp_bgresponse_captures.get(1).map_or("", |m| m.as_str());
+
+ let body_send: String = form_urlencoded::Serializer::new(String::new())
+ .append_pair("Page", resp_page)
+ .append_pair("GALX", resp_galx)
+ .append_pair("gxf", resp_gxf)
+ .append_pair("continue", resp_gcontinue.replace("&", "&").as_str())
+ .append_pair("ltmpl", resp_ltmpl)
+ .append_pair("scc", resp_scc)
+ .append_pair("sarp", resp_sarp)
+ .append_pair("oauth", resp_oauth)
+ .append_pair("ProfileInformation", resp_profile_information)
+ .append_pair("SessionState", resp_session_state)
+ .append_pair("_utf8", resp__utf8)
+ .append_pair("bgresponse", resp_bgresponse)
+ .append_pair("Email", email.as_str())
+ .append_pair("Passwd", password.as_str())
+ .append_pair("pstMsg", "0")
+ .append_pair("checkConnection", "")
+ .append_pair("checkedDomains", "youtube")
+ .append_pair("signIn", "Anmelden")
+ .append_pair("PersistentCookie", "no")
+ .finish();
+
+ // Do Email Login
+ let mut body = String::new();
+
+ let mut fresh_request = Request::new(Method::Post, url);
+ fresh_request.headers_mut().set(ContentType(String::from("application/x-www-form-urlencoded".to_owned())));
+ fresh_request.headers_mut().set(UserAgent::new("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36".to_owned()));
+ fresh_request.set_body(body_send);
+ let mut post = client.request(fresh_request).map_err(|_| ()).and_then(|res| {
+ println!("Response: {}", &res.status());
+ println!("Headers: \n{}", &res.headers());
+
+ &res.body().for_each(|chunk| {
+ let body_chunk = String::from_utf8(chunk.to_vec()).unwrap();
+ body.push_str(&body_chunk.as_str());
+ Ok(())
+ });
+ Ok(())
+ })
+ .map(|_| {
+ println!("\n\nDone.");
+ });
+ &core.run(post).unwrap();
+ // let mut email_post = client.post(url)
+ // .body(email_body_send.as_str())
+ // .headers(req_headers)
+ // .unwrap();
+
+ // email_post.read_to_string(&mut email_body)
+ // .unwrap();
+ }
+
+ fn write_cookie_config() {
+ // let mut config = get_configs().unwrap();
+ //
+ // config.set::<SAPISID>().unwrap();
+ // config.set::<HSID>().unwrap();
+ // config.set::<SSID>().unwrap();
+ // config.set::<SAPISID>().unwrap();
+ // config.set::<SAPISID>().unwrap();
+ // config.set_raw("SAPISID", )
+ // config.set_raw("HSID", )
+ // config.set_raw("SSID", )
+ // config.set_raw("APISID", )
+ // config.set_raw("SID", )
+ }
+
+ pub fn get_auth(mut client_email: String, mut client_passwd: String) {
use hyper::Client;
- use hyper::net::HttpsConnector;
- use hyper_native_tls::NativeTlsClient;
- use oauth2::{Authenticator, DefaultAuthenticatorDelegate, MemoryStorage, GetToken,
- ApplicationSecret, FlowType};
- use std::io::{stdin, stdout, Write};
-
- let ssl = NativeTlsClient::new().unwrap();
- let connector = HttpsConnector::new(ssl);
- let client = Client::with_connector(connector);
-
- let client_id = String::from("936475272427.apps.googleusercontent.com");
- let client_secret = String::from("KWsJlkaMn1jGLxQpWxMnOox-");
- let token_uri = String::from("https://accounts.google.com/o/oauth2/token");
- let auth_uri = String::from("https://accounts.google.com/o/oauth2/programmatic_auth");
- let redirect_uri = String::from("urn:ietf:wg:oauth:2.0:oob");
+ use hyper::header::{Headers, SetCookie, UserAgent};
+ use hyper::client::Request;
+ use hyper::{Method, Uri};
+ use std::io::{stdin, stdout, Write, Read};
+ use std::str;
+ use url::form_urlencoded;
+ use regex::Regex;
+ use tokio_core::reactor::Core;
+ use std::str::FromStr;
+ use futures::Future;
+ use futures::Stream;
+
+ let mut core = Core::new().unwrap();
+ let handle = core.handle();
+ let client = Client::configure()
+ .keep_alive(true)
+ .build(&handle);
+
+ let auth_uri = "https://accounts.google.com/o/oauth2/programmatic_auth?scope=https://www.google.com/accounts/OAuthLogin+https://www.googleapis.com/auth/userinfo.email&client_id=936475272427.apps.googleusercontent.com".parse::<Uri>().unwrap();
+ let email_uri = "https://accounts.google.com/signin/v1/lookup".parse::<Uri>().unwrap();
+ let passwd_uri = "https://accounts.google.com/signin/challenge/sl/password".parse::<Uri>().unwrap();
+
if client_email == String::from("") {
- let mut client_email = String::new();
+ println!("");
println!("Please enter Google Email: ");
let _ = stdout().flush();
stdin()
@@ -40,61 +213,101 @@ pub mod auth {
}
println!("You typed: {}", client_email);
- let secret = ApplicationSecret {
- client_id: client_id,
- client_secret: client_secret,
- token_uri: token_uri,
- auth_uri: auth_uri,
- redirect_uris: vec![redirect_uri],
- project_id: None,
- client_email: Some(client_email),
- auth_provider_x509_cert_url: None,
- client_x509_cert_url: None,
- };
- let res = Authenticator::new(&secret,
- DefaultAuthenticatorDelegate,
- client,
- <MemoryStorage as Default>::default(),
- Some(FlowType::InstalledInteractive))
- .token(&["https://www.google.com/accounts/OAuthLogin", "https://www.googleapis.com/auth/userinfo.email"]);
- match res {
- Ok(t) => {
- println!("Acquired access_token: {}", t.access_token);
- println!("Acquired refresh_token: {}", t.refresh_token);
+ if client_passwd == String::from("") {
+ println!("Please enter Google Password: ");
+ let _ = stdout().flush();
+ stdin()
+ .read_line(&mut client_passwd)
+ .expect("Did not enter a correct Password");
+ if let Some('\n') = client_passwd.chars().next_back() {
+ client_passwd.pop();
+ }
+ if let Some('\r') = client_passwd.chars().next_back() {
+ client_passwd.pop();
}
- Err(err) => println!("Failed to acquire token: {}", err),
}
+ println!("You typed: {}", client_passwd);
+
+ // Login Step1
+ let req = {
+ let req_raw = client.get(auth_uri).and_then(|res| {
+ println!("Response: {}", &res.status());
+ let mut headers = {
+ &res.headers()
+ };
+ let mut body = String::new();
+
+ &res.body().for_each(|chunk| {
+ let body_chunk = String::from_utf8(chunk.to_vec()).unwrap();
+ body.push_str(body_chunk.as_str());
+ Ok(())
+ });
+ {
+ let core_raw = core;
+ do_auth_step(&mut core, &client, email_uri, &res, &body.as_str(), client_email, client_email, &mut headers);
+ }
+ Ok(())
+ })
+ .map(|_| {
+ println!("\n\nDone.");
+ });
+ req_raw
+ };
+ core.run(req).unwrap();
}
}
pub mod hangups;
-#[cfg(test)]
-mod tests {
- #[test]
- fn test_get_auth_token() {
- use super::auth::get_auth;
- use std::io::{stdin, stdout, Write};
+pub mod helper{
+ use jconfig::config::Config;
+ use jconfig::error::Error;
+
+ fn check_generate_configs() {
+ use std::fs::{File, create_dir_all};
use std::env;
+ use std::io::Write;
+ // TODO Add handling if there is no home dir.
+ // match std::env::home_dir() {
+ // Some(dir) => {
+ // //There is a home directory, do something with the dir variable
+ // },
+ // None => {
+ // //There is no home directory, do something else
+ // }
+ // }
- match env::var_os("CI") {
- Some(env) => println!("CI's currently not supported at this test"),
- None => {
- let mut client_email = String::new();
- println!("Please enter Google Email: ");
- let _ = stdout().flush();
- stdin()
- .read_line(&mut client_email)
- .expect("Did not enter a correct Email");
- if let Some('\n') = client_email.chars().next_back() {
- client_email.pop();
- }
- if let Some('\r') = client_email.chars().next_back() {
- client_email.pop();
- }
- get_auth(client_email);
- }
- }
+ //Memory File
+ let mut memory_path = env::home_dir().unwrap();
+ memory_path.push(".local/share/hangups/");
+ create_dir_all(memory_path.as_path()).unwrap();
+ memory_path.push("memory.json");
+ let mut f = File::create(memory_path.as_path()).unwrap();
+ f.write_all(b"{}").unwrap();
+ f.sync_all().unwrap();
+
+ //Config File
+ let mut config_path = env::home_dir().unwrap();
+ config_path.push(".local/share/hangups/");
+ create_dir_all(config_path.as_path()).unwrap();
+ config_path.push("config.json");
+ let mut f = File::create(config_path.as_path()).unwrap();
+ f.write_all(b"{}").unwrap();
+ f.sync_all().unwrap();
+ }
+ pub fn get_configs() -> Result<Config, Error>{
+ use std::env;
+
+ check_generate_configs();
+
+ let mut memory_path = env::home_dir().unwrap();
+ memory_path.push(".local/share/hangups/");
+ memory_path.push("memory.json");
+
+ // Load the memory
+ let config = Config::load(memory_path.as_path()).unwrap();
+
+ Ok(config)
}
}