Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //globaldb пока типа есть.
- std::string globaldb = "cloud.trassir.com";
- boost::shared_ptr<Client> http_client;
- boost::shared_ptr<CommandQueue> command_queue;
- boost::shared_ptr<Logger> logger;
- class Session : public boost::enable_shared_from_this<Session> {
- void make_shared_session_callback(const std::string share_node,
- const std::string share_owner, const boost::shared_ptr<Response> &response);
- public:
- struct AccountInfo {
- bool status_ok;
- std::string node;
- std::string sid;
- };
- struct UserInfo {
- std::string main_name;
- AccountInfo main;
- std::string region;
- std::map<std::string, AccountInfo> shares;
- };
- void check_shares();
- Session(const std::string &username, const std::string &node, const std::string &sid)
- {
- user_info.main_name = username;
- user_info.main.node = node;
- user_info.main.sid = sid;
- user_info.main.status_ok = true;
- }
- void login_shares(const std::string &guest_key, const std::vector<std::pair<std::string, std::string> > &shares_list);
- ~Session();
- boost::mutex account_mutex;
- UserInfo user_info;
- private:
- };
- Session::~Session() {
- std::string url = stdprintf("https://%s/logout?sid=%s", user_info.main.node.c_str(),
- user_info.main.sid.c_str());
- boost::shared_ptr<Request> request_provider = http_client->prepare_request();
- request_provider->get_async(url, NULL);
- }
- const unsigned long long check_shares_period_usec = 10000000ULL;
- void Session::check_shares()
- {
- {
- boost::mutex::scoped_lock lock(account_mutex);
- if (!user_info.main.status_ok) {
- return;
- }
- }
- try {
- Json::Value sid(Json::objectValue);
- std::string node;
- {
- boost::mutex::scoped_lock lock(account_mutex);
- node = user_info.main.node;
- sid["sid"] = user_info.main.sid;
- }
- std::string url = stdprintf("https://%s/shares", node.c_str());
- std::string data = sid.toStyledString();
- boost::shared_ptr<Request> request_provider = http_client->prepare_request();
- boost::shared_ptr<Response> response;
- response = request_provider->post(url, data);
- Json::Value v = json_parse_or_die(response->data, false);
- std::map<std::string, std::string> available_shares_nodes;
- Json::Value guest_key_json = v["guest_key"];
- for(Json::Value::iterator shr = v["shares"].begin(); shr != v["shares"].end(); ++shr) {
- const Json::Value &share = *shr;
- const bool share_have_owner = share.isMember("owner") && share["owner"].isString();
- const bool share_have_home = share.isMember("home_node") && share["home_node"].isString()
- && !share["home_node"].asString().empty();
- if (!share_have_owner || !share_have_home) {
- continue;
- }
- available_shares_nodes[share["owner"].asString()] = share["home_node"].asString();
- }
- UserInfo user_info_copy;
- {
- boost::mutex::scoped_lock lock(account_mutex);
- user_info_copy = user_info;
- }
- std::list<std::string> to_erase;
- std::map<std::string, AccountInfo>::iterator it = user_info_copy.shares.begin();
- for (; it != user_info_copy.shares.end(); ++it) {
- const AccountInfo &cabinet_info = it->second;
- const std::string &cabinet_name = it->first;
- if (available_shares_nodes.find(cabinet_name) == available_shares_nodes.end()) {
- to_erase.push_back(cabinet_name);
- } else {
- if (!cabinet_info.status_ok) {
- available_shares_nodes[cabinet_name] = cabinet_info.node;
- } else {
- available_shares_nodes.erase(cabinet_name);
- }
- }
- }
- for (std::list<std::string>::iterator it = to_erase.begin(); it != to_erase.end(); ++it) {
- user_info_copy.shares.erase(*it);
- }
- {
- boost::mutex::scoped_lock lock(account_mutex);
- boost::swap(user_info, user_info_copy);
- }
- std::map<std::string, std::string>::iterator iterator_available_shares_nodes = available_shares_nodes.begin();
- for (; iterator_available_shares_nodes != available_shares_nodes.end(); ++iterator_available_shares_nodes) {
- const std::string &share_node = iterator_available_shares_nodes->second;
- const std::string &share_username = iterator_available_shares_nodes->first;
- std::string url = stdprintf("https://%s/authorize", share_node.c_str());
- std::string data = "password=&login=" + share_username + "&recaptcha=&guest_key=" + guest_key_json.toStyledString();
- request_provider->post_async(url, data, boost::bind(&Session::make_shared_session_callback, shared_from_this(),
- share_node, share_username, _1));
- }
- } catch (std::exception &e) {
- std::string err("Cloudlib: check shares error: ");
- err.append(e.what());
- logger->message(err.c_str());
- }
- command_queue->enqueue(boost::bind(&Session::check_shares, shared_from_this()), check_shares_period_usec);
- }
- Json::Value search_for_home_or_region(const std::string &host, const std::string &username)
- {
- boost::shared_ptr<Response> response;
- try {
- boost::shared_ptr<Request> request_provider = http_client->prepare_request();
- std::string url = stdprintf("https://%s/home-find", host.c_str());
- Json::Value json_to_post;
- json_to_post["user"] = username;
- response = request_provider->post(url, json_to_post.toStyledString());
- } catch (std::exception &e) {
- std::string err("Cloudlib: send request error: ");
- err.append(e.what());
- logger->message(err.c_str());
- throw std::logic_error("cloudlib communication error");
- }
- const Json::Value& response_json = json_parse_or_die(response->data, true);
- if (response_json.isMember("success") && response_json["success"].isInt() && response_json["success"].asInt() == 0) {
- if (response_json.isMember("description") && response_json["description"].isString()) {
- const std::string &desc = response_json["description"].asString();
- if (desc == "bad username or password")
- throw std::runtime_error("cloudlib bad username or password");
- }
- throw std::runtime_error("request failed");
- }
- if (response_json.isMember("error")) {
- if (!response_json["error"].isString())
- throw std::logic_error("unexpected response_jsononse from cloud");
- const std::string &desc = response_json["error"].asString();
- if (desc == "bad username or password")
- throw std::logic_error("bad username or password");
- throw std::runtime_error(desc);
- }
- if (!response_json.isMember("homes") || !response_json["homes"].isArray())
- throw std::logic_error("Bad response: no array 'homes' in response");
- if (response_json["homes"].size() != 1)
- throw std::logic_error("Bad response: no homes or more than one home in response");
- return response_json["homes"][0];
- }
- void Session::make_shared_session_callback(const std::string share_node,
- const std::string share_owner, const boost::shared_ptr<Response> &response)
- {
- if (response->code != 200) {
- logger->message(
- stdprintf("CloudClient: getting shares error with code %d\n", response->code).c_str()
- );
- } else if (!response->error.empty()) {
- logger->message(
- stdprintf("CloudClient: getting shares error with error %s\n", response->error.c_str()).c_str()
- );
- } else {
- Json::Value response_json = json_parse_or_die(response->data, false);
- if (!response_json.isMember("sid") || !response_json["sid"].isString()) {
- logger->message("CloudClient: sid isn't valid\n");
- } else {
- const std::string share_sid = response_json["sid"].asString();
- if (share_sid.empty()) {
- logger->message("CloudClient: share_sid is empty\n");
- }
- AccountInfo share_info = { true, share_node, share_sid };
- boost::mutex::scoped_lock lock(account_mutex);
- user_info.shares[share_owner] = share_info;
- }
- }
- }
- std::pair<std::string, std::string> home_find(const std::string &username) {
- std::string region_to_search;
- Json::Value response_json = search_for_home_or_region(globaldb, username);
- Json::Value ®ion_found = response_json;
- if (region_found.isMember("region") && !region_found["region"].asString().empty()) {
- region_to_search = region_found["region"].asString();
- } else {
- throw std::runtime_error("unexpected home find response contents");
- }
- response_json = search_for_home_or_region(region_to_search, username);
- Json::Value &home_found = response_json;
- if (!home_found.isMember("node") || home_found["node"].asString().empty()) {
- throw std::runtime_error("unexpected home find response contents");
- }
- std::pair<std::string, std::string> user_info;
- user_info.first = region_to_search;
- user_info.second = home_found["node"].asString();
- return user_info;
- }
- boost::shared_ptr<Session> login_main(const std::string &username, const std::string &password, const std::string &client_type)
- {
- if (username.empty()) {
- throw std::runtime_error("cloudlib empty username");
- }
- if (password.empty()) {
- throw std::runtime_error("cloudlib empty password");
- }
- std::pair<std::string, std::string> user_info = home_find(username);
- std::string &node = user_info.second;
- if (node.empty())
- throw std::runtime_error("cloudlib primary node is not found");
- std::string url = stdprintf("https://%s/authorize", node.c_str());
- std::string data = "login=" + username + "&client=" + client_type + "&password=" + password + "&recaptcha=";
- boost::shared_ptr<Request> request_provider = http_client->prepare_request();
- boost::shared_ptr<Response> response;
- response = request_provider->post(url, data);
- const Json::Value& response_json = json_parse_or_die(response->data, true);
- if (response_json.isMember("not_a_home"))
- throw std::logic_error("CloudLib: not_a_home");
- if (response_json.isMember("erase"))
- throw std::logic_error("CloudLib: erase");
- if (!response_json.isMember("success") || !response_json["success"].isInt() || response_json["success"].asInt()!=1)
- throw std::logic_error("CloudLib: bad username or password");
- if (!response_json["login"].isString())
- throw std::logic_error("login field error");
- if (!response_json["base_rights"].isInt())
- throw std::logic_error("CloudLib: not_a_home");
- if (!response_json.isMember("sid"))
- throw std::logic_error("CloudLib: not_a_home");
- boost::shared_ptr<Session> session = boost::make_shared<Session>(username,
- node, response_json["sid"].asString());
- std::string guest_key;
- std::vector<std::pair<std::string, std::string> > shares_list;
- if (response_json.isMember("shares_shortcut")) {
- const Json::Value &v = response_json["shares_shortcut"];
- if (v.isMember("guest_key")) {
- guest_key = v["guest_key"].toStyledString();
- for(Json::Value::iterator shr = v["shares"].begin(); shr != v["shares"].end(); ++shr) {
- const Json::Value &share = *shr;
- const bool share_have_owner = share.isMember("owner") && share["owner"].isString();
- const bool share_have_home = share.isMember("home_node") && share["home_node"].isString()
- && !share["home_node"].asString().empty();
- if (!share_have_owner || !share_have_home) {
- continue;
- }
- const std::string &share_owner = share["owner"].asString();
- const std::string &share_home_node = share["home_node"].asString();
- shares_list.push_back(std::pair<std::string, std::string>(share_owner, share_home_node));
- }
- }
- }
- session->login_shares(guest_key, shares_list);
- return session;
- }
- void Session::login_shares(const std::string &guest_key, const std::vector<std::pair<std::string, std::string> > &shares_list)
- {
- const std::string &node = user_info.main.node;
- for(std::vector<std::pair<std::string, std::string> >::const_iterator it = shares_list.begin(); it != shares_list.end(); ++it) {
- const std::string &share_owner = it->first;
- const std::string &share_home_node = it->second;
- std::string url = stdprintf("https://%s/authorize", share_home_node.c_str());
- std::string data = stdprintf("password=&login=%s&recaptcha=&guest_key=%s", + share_owner.c_str(), guest_key.c_str());
- boost::shared_ptr<Request> request_provider = http_client->prepare_request();
- request_provider->post_async(url, data, boost::bind(&Session::make_shared_session_callback,
- shared_from_this(), share_home_node, share_owner, _1));
- }
- }
- boost::shared_ptr<Session> login(const std::string &username, const std::string &password, const std::string &client_type) {
- logger = boost::make_shared<Logger>(".", ".", "cloudlib.log");
- http_client = boost::make_shared<Client>();
- command_queue = boost::make_shared<CommandQueue>("CloudLib_command_queue");
- try {
- boost::shared_ptr<Session> session = login_main(username, password, client_type);
- sleep(3);
- std::map<std::string, Session::AccountInfo>::iterator it = session->user_info.shares.begin();
- int size = session->user_info.shares.size();
- for(; it != session->user_info.shares.end(); ++it) {
- std::cout << "owner = " << it->first << " sid = " << it->second.sid << std::endl;
- }
- command_queue->enqueue(boost::bind(&Session::check_shares, session));
- return session;
- } catch (std::exception &e) {
- logger->message(e.what());
- }
- return NULL;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement