use std::io::Read;
use hyper::method::Method;
use hyper::header::{Headers, Authorization};
use rustc_serialize::json;
use chrono::NaiveDate;
use utils::Address;
use dto::{FromDTO, UserDTO, ProfileDTO, AuthenticationCodeDTO, ResponseDTO, UpdateUserDTO,
SearchUserDTO};
use super::{Client, VoidDTO};
use error::{Result, Error};
use super::types::{User, Profile};
use super::oauth::AccessToken;
impl Client {
pub fn resend_email_confirmation(&self, access_token: &AccessToken) -> Result<()> {
if access_token.get_user_id().is_some() && !access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let _ = self.send_request(Method::Get,
format!("{}resend_email_confirmation", self.url),
headers,
None::<&VoidDTO>)?;
Ok(())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired user token")))
}
}
pub fn get_user(&self, access_token: &AccessToken, user_id: u64) -> Result<User> {
if (access_token.is_user(user_id) || access_token.is_admin()) &&
!access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let mut response = self.send_request(Method::Get,
format!("{}user/{}", self.url, user_id),
headers,
None::<&VoidDTO>)?;
let mut response_str = String::new();
let _ = response.read_to_string(&mut response_str)?;
Ok(User::from_dto(json::decode::<UserDTO>(&response_str)?)?)
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired admin or user \
token, and in the case of a user token, the ID \
in the token must match the given ID")))
}
}
pub fn get_me(&self, access_token: &AccessToken) -> Result<User> {
let user_id = access_token.get_user_id();
if user_id.is_some() && !access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let mut response = self.send_request(Method::Get,
format!("{}user/{}", self.url, user_id.unwrap()),
headers,
None::<&VoidDTO>)?;
let mut response_str = String::new();
let _ = response.read_to_string(&mut response_str)?;
Ok(User::from_dto(json::decode::<UserDTO>(&response_str)?)?)
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired user token")))
}
}
pub fn get_all_users(&self, access_token: &AccessToken) -> Result<Vec<User>> {
if access_token.is_admin() && !access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let mut response = self.send_request(Method::Get,
format!("{}all_users", self.url),
headers,
None::<&VoidDTO>)?;
let mut response_str = String::new();
let _ = response.read_to_string(&mut response_str)?;
let dto_users: Vec<UserDTO> = json::decode(&response_str)?;
Ok(dto_users.into_iter()
.filter_map(|u| match User::from_dto(u) {
Ok(u) => Some(u),
Err(_) => None,
})
.collect())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired admin token")))
}
}
pub fn delete_user(&self, access_token: &AccessToken, user_id: u64) -> Result<()> {
if access_token.is_admin() && !access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let _ = self.send_request(Method::Delete,
format!("{}user/{}", self.url, user_id),
headers,
None::<&VoidDTO>)?;
Ok(())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired admin token")))
}
}
pub fn generate_authenticator_code(&self, access_token: &AccessToken) -> Result<String> {
if access_token.get_user_id().is_some() && !access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let mut response = self.send_request(Method::Get,
format!("{}generate_authenticator_code", self.url),
headers,
None::<&VoidDTO>)?;
let mut response_str = String::new();
let _ = response.read_to_string(&mut response_str)?;
Ok(json::decode::<ResponseDTO>(&response_str)?.message)
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired user token")))
}
}
pub fn authenticate(&self, access_token: &AccessToken, code: u32) -> Result<()> {
if access_token.get_user_id().is_some() && !access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let dto = AuthenticationCodeDTO { code: code };
let _ = self.send_request(Method::Post,
format!("{}authenticate", self.url),
headers,
Some(&dto))?;
Ok(())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired user token")))
}
}
pub fn set_username<U: Into<String>>(&self,
access_token: &AccessToken,
user_id: u64,
username: U)
-> Result<()> {
if (access_token.is_user(user_id) || access_token.is_admin()) &&
!access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let dto = UpdateUserDTO {
new_username: Some(username.into()),
new_email: None,
new_first: None,
new_last: None,
old_password: None,
new_password: None,
new_phone: None,
new_birthday: None,
new_image: None,
new_address: None,
};
let _ = self.send_request(Method::Post,
format!("{}update_user/{}", self.url, user_id),
headers,
Some(&dto))?;
Ok(())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired admin or user \
token, and in the case of a user token, the ID \
in the token must match the given ID")))
}
}
pub fn set_phone<P: Into<String>>(&self,
access_token: &AccessToken,
user_id: u64,
phone: P)
-> Result<()> {
if (access_token.is_user(user_id) || access_token.is_admin()) &&
!access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let dto = UpdateUserDTO {
new_username: None,
new_email: None,
new_first: None,
new_last: None,
old_password: None,
new_password: None,
new_phone: Some(phone.into()),
new_birthday: None,
new_image: None,
new_address: None,
};
let _ = self.send_request(Method::Post,
format!("{}update_user/{}", self.url, user_id),
headers,
Some(&dto))?;
Ok(())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired admin or user \
token, and in the case of a user token, the ID \
in the token must match the given ID")))
}
}
pub fn set_birthday(&self,
access_token: &AccessToken,
user_id: u64,
birthday: NaiveDate)
-> Result<()> {
if (access_token.is_user(user_id) || access_token.is_admin()) &&
!access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let dto = UpdateUserDTO {
new_username: None,
new_email: None,
new_first: None,
new_last: None,
old_password: None,
new_password: None,
new_phone: None,
new_birthday: Some(birthday),
new_image: None,
new_address: None,
};
let _ = self.send_request(Method::Post,
format!("{}update_user/{}", self.url, user_id),
headers,
Some(&dto))?;
Ok(())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired admin or user \
token, and in the case of a user token, the ID \
in the token must match the given ID")))
}
}
pub fn set_name<F: Into<String>, L: Into<String>>(&self,
access_token: &AccessToken,
user_id: u64,
first: F,
last: L)
-> Result<()> {
if (access_token.is_user(user_id) || access_token.is_admin()) &&
!access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let dto = UpdateUserDTO {
new_username: None,
new_email: None,
new_first: Some(first.into()),
new_last: Some(last.into()),
old_password: None,
new_password: None,
new_phone: None,
new_birthday: None,
new_image: None,
new_address: None,
};
let _ = self.send_request(Method::Post,
format!("{}update_user/{}", self.url, user_id),
headers,
Some(&dto))?;
Ok(())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired admin or user \
token, and in the case of a user token, the ID \
in the token must match the given ID")))
}
}
pub fn set_email<E: Into<String>>(&self,
access_token: &AccessToken,
user_id: u64,
email: E)
-> Result<()> {
if (access_token.is_user(user_id) || access_token.is_admin()) &&
!access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let dto = UpdateUserDTO {
new_username: None,
new_email: Some(email.into()),
new_first: None,
new_last: None,
old_password: None,
new_password: None,
new_phone: None,
new_birthday: None,
new_image: None,
new_address: None,
};
let _ = self.send_request(Method::Post,
format!("{}update_user/{}", self.url, user_id),
headers,
Some(&dto))?;
Ok(())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired admin or user \
token, and in the case of a user token, the ID \
in the token must match the given ID")))
}
}
pub fn set_image<I: Into<String>>(&self,
access_token: &AccessToken,
user_id: u64,
image_url: I)
-> Result<()> {
if (access_token.is_user(user_id) || access_token.is_admin()) &&
!access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let dto = UpdateUserDTO {
new_username: None,
new_email: None,
new_first: None,
new_last: None,
old_password: None,
new_password: None,
new_phone: None,
new_birthday: None,
new_image: Some(image_url.into()),
new_address: None,
};
let _ = self.send_request(Method::Post,
format!("{}update_user/{}", self.url, user_id),
headers,
Some(&dto))?;
Ok(())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired admin or user \
token, and in the case of a user token, the ID \
in the token must match the given ID")))
}
}
pub fn set_address(&self,
access_token: &AccessToken,
user_id: u64,
address: Address)
-> Result<()> {
if (access_token.is_user(user_id) || access_token.is_admin()) &&
!access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let dto = UpdateUserDTO {
new_username: None,
new_email: None,
new_first: None,
new_last: None,
old_password: None,
new_password: None,
new_phone: None,
new_birthday: None,
new_image: None,
new_address: Some(address),
};
let _ = self.send_request(Method::Post,
format!("{}update_user/{}", self.url, user_id),
headers,
Some(&dto))?;
Ok(())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired admin or user \
token, and in the case of a user token, the ID \
in the token must match the given ID")))
}
}
pub fn set_password<O: Into<String>, N: Into<String>>(&self,
access_token: &AccessToken,
old_password: O,
new_password: N)
-> Result<()> {
let user_id = access_token.get_user_id();
if user_id.is_some() && !access_token.has_expired() {
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let dto = UpdateUserDTO {
new_username: None,
new_email: None,
new_first: None,
new_last: None,
old_password: Some(old_password.into()),
new_password: Some(new_password.into()),
new_phone: None,
new_birthday: None,
new_image: None,
new_address: None,
};
let _ = self.send_request(Method::Post,
format!("{}update_user/{}", self.url, user_id.unwrap()),
headers,
Some(&dto))?;
Ok(())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired user token")))
}
}
pub fn search_user_random<R: Into<String>>(&self,
access_token: &AccessToken,
random: R,
include_me: bool,
include_friends: bool)
-> Result<Vec<Profile>> {
let user_id = access_token.get_user_id();
if (access_token.is_public() || user_id.is_some()) && !access_token.has_expired() {
if (include_me || include_friends) && user_id.is_none() {
panic!("to include the current user or friends the token must be a user scoped \
token");
}
let mut headers = Headers::new();
headers.set(Authorization(access_token.get_token()));
let dto = SearchUserDTO {
random: Some(random.into()),
username: None,
email: None,
first_name: None,
last_name: None,
age: None,
country: None,
state: None,
city: None,
phone: None,
all: false,
include_me: include_me,
include_friends: include_friends,
};
let mut response = self.send_request(Method::Post,
format!("{}search_user", self.url),
headers,
Some(&dto))?;
let mut response_str = String::new();
let _ = response.read_to_string(&mut response_str)?;
let dto_users: Vec<ProfileDTO> = json::decode(&response_str)?;
Ok(dto_users.into_iter()
.filter_map(|u| match Profile::from_dto(u) {
Ok(u) => Some(u),
Err(_) => None,
})
.collect())
} else {
Err(Error::Forbidden(String::from("the token must be an unexpired public or user \
token")))
}
}
}