#![allow(dead_code)]
use crate::login::config::Config;
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
use serde::Serialize;
#[derive(Debug, Default, Clone, Serialize)]
pub struct LoginUrlParameters {
facebook_oath_url: String,
client_id: String,
redirect_uri: String,
state: String,
response_type: String,
scope: Vec<&'static str>,
scope_as_string: String,
full_url: String,
}
impl LoginUrlParameters {
pub fn new(config: Config) -> LoginUrlParameters {
LoginUrlParameters::default()
.add_facebook_oath_url(&config.facebook_oath_url())
.add_client_id(&config.client_id())
.add_redirect_uri(&config.redirect_uri())
.add_random_state()
.add_response_type(LoginResponseType::CODE)
.add_scope([""].to_vec())
}
pub fn add_client_id(mut self, client_id: &str) -> Self {
self.client_id = client_id.to_string();
self
}
pub fn add_facebook_oath_url(mut self, url: &str) -> Self {
self.facebook_oath_url = url.to_string();
self
}
pub fn add_redirect_uri(mut self, redirect_uri: &str) -> Self {
self.redirect_uri = redirect_uri.to_string();
self
}
pub fn add_state(mut self, state: &str) -> Self {
self.state = state.to_string();
self
}
pub fn add_response_type(mut self, response_type: LoginResponseType) -> Self {
let resp_type = match response_type {
LoginResponseType::CODE20TOKEN => "code%20token".to_string(),
LoginResponseType::TOKEN => "token".to_string(),
LoginResponseType::CODE => "code".to_string(),
LoginResponseType::GRANTEDSCOPE => "granted_scopes".to_string(),
};
self.response_type = resp_type;
self
}
pub fn add_scope(mut self, scopes: Vec<&'static str>) -> Self {
let scope_count = scopes.len();
self.scope = scopes;
let mut loop_count = 1;
let mut scopes_string = "".to_owned();
for scope_ in &self.scope {
if scope_count == loop_count {
scopes_string += &*format!("{scope_}")
} else {
scopes_string += &*format!("{scope_},")
}
loop_count += 1;
}
self.scope_as_string = scopes_string;
self
}
pub fn add_random_state(mut self) -> Self {
let rand_string: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(10)
.map(char::from)
.collect();
self.state = rand_string;
self
}
fn build_login_url_as_string(&mut self) -> String {
let full_url = "".to_string()
+ &self.facebook_oath_url
+ "client_id="
+ &self.client_id
+ "&redirect_uri="
+ &self.redirect_uri
+ "&response_type="
+ &self.response_type
+ "&state="
+ &*self.state
+ "&scope="
+ &self.scope_as_string;
self.full_url = full_url.clone();
full_url
}
fn build_re_request_permission_url(&mut self) -> String {
let full_url = "".to_string()
+ &self.facebook_oath_url
+ "client_id="
+ &self.client_id
+ "&redirect_uri="
+ &self.redirect_uri
+ "&response_type="
+ &self.response_type
+ "&state="
+ &*self.state
+ "&auth_type=rerequest"
+ "&scope="
+ &self.scope_as_string;
self.full_url = full_url.clone();
full_url
}
fn build_enabling_re_authentication_url(&mut self) -> String {
let full_url = "".to_string()
+ &self.facebook_oath_url
+ "client_id="
+ &self.client_id
+ "&redirect_uri="
+ &self.redirect_uri
+ "&response_type="
+ &self.response_type
+ "&state="
+ &*self.state
+ "&auth_type=reauthenticate"
+ "&scope="
+ &self.scope_as_string;
self.full_url = full_url.clone();
full_url
}
pub fn full_login_url(mut self) -> String {
self.full_url = self.build_login_url_as_string();
self.full_url
}
pub fn re_request_permission_url(mut self) -> String {
self.full_url = self.build_re_request_permission_url();
self.full_url
}
pub fn re_authentication_url(mut self) -> String {
self.full_url = self.build_enabling_re_authentication_url();
self.full_url
}
pub fn facebook_oath_url(&self) -> &String {
&self.facebook_oath_url
}
pub fn client_id(&self) -> &String {
&self.client_id
}
pub fn redirect_uri(&self) -> &String {
&self.redirect_uri
}
pub fn state(&self) -> &String {
&self.state
}
pub fn response_type(&self) -> &String {
&self.response_type
}
pub fn scope(&self) -> &Vec<&'static str> {
&self.scope
}
}
pub enum LoginResponseType {
CODE,
TOKEN,
CODE20TOKEN,
GRANTEDSCOPE,
}
#[cfg(test)]
mod tests {
use crate::login::config::Config;
use crate::login::login::LoginUrlParameters;
use crate::prelude::{LoginResponseType, ResponseType};
#[test]
fn test_build_url() {
let redirect_url = LoginUrlParameters::new(Config {
facebook_oath_url: "https://www.facebook.com/v23.0/dialog/oauth?".to_string(),
client_id: "1234567890".to_string(),
redirect_uri: "http://localhost:8001".to_string(),
})
.add_response_type(LoginResponseType::TOKEN)
.add_state("0987654321")
.add_scope(vec!["test"].to_vec());
assert_eq!(
redirect_url.facebook_oath_url(),
"https://www.facebook.com/v23.0/dialog/oauth?"
);
assert_eq!(redirect_url.client_id(), "1234567890");
assert_eq!(redirect_url.redirect_uri(), "http://localhost:8001");
assert_eq!(redirect_url.state(), "0987654321");
assert_eq!(redirect_url.response_type(), "token");
let scope = ["test".to_string()].to_vec();
assert_eq!(redirect_url.scope(), &scope);
let full_url = redirect_url.full_login_url();
assert_eq!(full_url, "https://www.facebook.com/v23.0/dialog/oauth?client_id=1234567890&redirect_uri=http://localhost:8001&response_type=token&state=0987654321&scope=test")
}
}