Advertisement
Guest User

Untitled

a guest
Sep 7th, 2017
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.75 KB | None | 0 0
  1. //globaldb пока типа есть.
  2. std::string globaldb = "cloud.trassir.com";
  3. boost::shared_ptr<Client> http_client;
  4.  
  5. boost::shared_ptr<CommandQueue> command_queue;
  6. boost::shared_ptr<Logger> logger;
  7.  
  8. class Session : public boost::enable_shared_from_this<Session> {
  9.  
  10. void make_shared_session_callback(const std::string share_node,
  11. const std::string share_owner, const boost::shared_ptr<Response> &response);
  12.  
  13.  
  14. public:
  15. struct AccountInfo {
  16. bool status_ok;
  17. std::string node;
  18. std::string sid;
  19. };
  20. struct UserInfo {
  21. std::string main_name;
  22. AccountInfo main;
  23. std::string region;
  24. std::map<std::string, AccountInfo> shares;
  25. };
  26. void check_shares();
  27. Session(const std::string &username, const std::string &node, const std::string &sid)
  28. {
  29. user_info.main_name = username;
  30. user_info.main.node = node;
  31. user_info.main.sid = sid;
  32. user_info.main.status_ok = true;
  33. }
  34.  
  35. void login_shares(const std::string &guest_key, const std::vector<std::pair<std::string, std::string> > &shares_list);
  36. ~Session();
  37. boost::mutex account_mutex;
  38. UserInfo user_info;
  39. private:
  40.  
  41. };
  42.  
  43. Session::~Session() {
  44. std::string url = stdprintf("https://%s/logout?sid=%s", user_info.main.node.c_str(),
  45. user_info.main.sid.c_str());
  46. boost::shared_ptr<Request> request_provider = http_client->prepare_request();
  47. request_provider->get_async(url, NULL);
  48. }
  49.  
  50. const unsigned long long check_shares_period_usec = 10000000ULL;
  51.  
  52. void Session::check_shares()
  53. {
  54. {
  55. boost::mutex::scoped_lock lock(account_mutex);
  56. if (!user_info.main.status_ok) {
  57. return;
  58. }
  59. }
  60. try {
  61. Json::Value sid(Json::objectValue);
  62. std::string node;
  63. {
  64. boost::mutex::scoped_lock lock(account_mutex);
  65. node = user_info.main.node;
  66. sid["sid"] = user_info.main.sid;
  67. }
  68.  
  69. std::string url = stdprintf("https://%s/shares", node.c_str());
  70. std::string data = sid.toStyledString();
  71. boost::shared_ptr<Request> request_provider = http_client->prepare_request();
  72. boost::shared_ptr<Response> response;
  73. response = request_provider->post(url, data);
  74.  
  75. Json::Value v = json_parse_or_die(response->data, false);
  76. std::map<std::string, std::string> available_shares_nodes;
  77. Json::Value guest_key_json = v["guest_key"];
  78.  
  79. for(Json::Value::iterator shr = v["shares"].begin(); shr != v["shares"].end(); ++shr) {
  80. const Json::Value &share = *shr;
  81. const bool share_have_owner = share.isMember("owner") && share["owner"].isString();
  82. const bool share_have_home = share.isMember("home_node") && share["home_node"].isString()
  83. && !share["home_node"].asString().empty();
  84. if (!share_have_owner || !share_have_home) {
  85. continue;
  86. }
  87. available_shares_nodes[share["owner"].asString()] = share["home_node"].asString();
  88. }
  89.  
  90. UserInfo user_info_copy;
  91. {
  92. boost::mutex::scoped_lock lock(account_mutex);
  93. user_info_copy = user_info;
  94. }
  95. std::list<std::string> to_erase;
  96. std::map<std::string, AccountInfo>::iterator it = user_info_copy.shares.begin();
  97. for (; it != user_info_copy.shares.end(); ++it) {
  98. const AccountInfo &cabinet_info = it->second;
  99. const std::string &cabinet_name = it->first;
  100. if (available_shares_nodes.find(cabinet_name) == available_shares_nodes.end()) {
  101. to_erase.push_back(cabinet_name);
  102. } else {
  103. if (!cabinet_info.status_ok) {
  104. available_shares_nodes[cabinet_name] = cabinet_info.node;
  105. } else {
  106. available_shares_nodes.erase(cabinet_name);
  107. }
  108. }
  109. }
  110. for (std::list<std::string>::iterator it = to_erase.begin(); it != to_erase.end(); ++it) {
  111. user_info_copy.shares.erase(*it);
  112. }
  113.  
  114. {
  115. boost::mutex::scoped_lock lock(account_mutex);
  116. boost::swap(user_info, user_info_copy);
  117. }
  118.  
  119. std::map<std::string, std::string>::iterator iterator_available_shares_nodes = available_shares_nodes.begin();
  120. for (; iterator_available_shares_nodes != available_shares_nodes.end(); ++iterator_available_shares_nodes) {
  121. const std::string &share_node = iterator_available_shares_nodes->second;
  122. const std::string &share_username = iterator_available_shares_nodes->first;
  123. std::string url = stdprintf("https://%s/authorize", share_node.c_str());
  124. std::string data = "password=&login=" + share_username + "&recaptcha=&guest_key=" + guest_key_json.toStyledString();
  125. request_provider->post_async(url, data, boost::bind(&Session::make_shared_session_callback, shared_from_this(),
  126. share_node, share_username, _1));
  127. }
  128. } catch (std::exception &e) {
  129. std::string err("Cloudlib: check shares error: ");
  130. err.append(e.what());
  131. logger->message(err.c_str());
  132. }
  133.  
  134. command_queue->enqueue(boost::bind(&Session::check_shares, shared_from_this()), check_shares_period_usec);
  135. }
  136.  
  137. Json::Value search_for_home_or_region(const std::string &host, const std::string &username)
  138. {
  139. boost::shared_ptr<Response> response;
  140. try {
  141. boost::shared_ptr<Request> request_provider = http_client->prepare_request();
  142.  
  143. std::string url = stdprintf("https://%s/home-find", host.c_str());
  144.  
  145. Json::Value json_to_post;
  146. json_to_post["user"] = username;
  147.  
  148. response = request_provider->post(url, json_to_post.toStyledString());
  149. } catch (std::exception &e) {
  150. std::string err("Cloudlib: send request error: ");
  151. err.append(e.what());
  152. logger->message(err.c_str());
  153. throw std::logic_error("cloudlib communication error");
  154. }
  155.  
  156. const Json::Value& response_json = json_parse_or_die(response->data, true);
  157.  
  158. if (response_json.isMember("success") && response_json["success"].isInt() && response_json["success"].asInt() == 0) {
  159. if (response_json.isMember("description") && response_json["description"].isString()) {
  160. const std::string &desc = response_json["description"].asString();
  161. if (desc == "bad username or password")
  162. throw std::runtime_error("cloudlib bad username or password");
  163. }
  164. throw std::runtime_error("request failed");
  165. }
  166. if (response_json.isMember("error")) {
  167. if (!response_json["error"].isString())
  168. throw std::logic_error("unexpected response_jsononse from cloud");
  169. const std::string &desc = response_json["error"].asString();
  170. if (desc == "bad username or password")
  171. throw std::logic_error("bad username or password");
  172. throw std::runtime_error(desc);
  173. }
  174.  
  175. if (!response_json.isMember("homes") || !response_json["homes"].isArray())
  176. throw std::logic_error("Bad response: no array 'homes' in response");
  177. if (response_json["homes"].size() != 1)
  178. throw std::logic_error("Bad response: no homes or more than one home in response");
  179.  
  180. return response_json["homes"][0];
  181. }
  182.  
  183. void Session::make_shared_session_callback(const std::string share_node,
  184. const std::string share_owner, const boost::shared_ptr<Response> &response)
  185. {
  186. if (response->code != 200) {
  187. logger->message(
  188. stdprintf("CloudClient: getting shares error with code %d\n", response->code).c_str()
  189. );
  190.  
  191. } else if (!response->error.empty()) {
  192. logger->message(
  193. stdprintf("CloudClient: getting shares error with error %s\n", response->error.c_str()).c_str()
  194. );
  195. } else {
  196. Json::Value response_json = json_parse_or_die(response->data, false);
  197. if (!response_json.isMember("sid") || !response_json["sid"].isString()) {
  198. logger->message("CloudClient: sid isn't valid\n");
  199. } else {
  200. const std::string share_sid = response_json["sid"].asString();
  201. if (share_sid.empty()) {
  202. logger->message("CloudClient: share_sid is empty\n");
  203. }
  204. AccountInfo share_info = { true, share_node, share_sid };
  205. boost::mutex::scoped_lock lock(account_mutex);
  206. user_info.shares[share_owner] = share_info;
  207. }
  208. }
  209. }
  210.  
  211. std::pair<std::string, std::string> home_find(const std::string &username) {
  212. std::string region_to_search;
  213. Json::Value response_json = search_for_home_or_region(globaldb, username);
  214. Json::Value &region_found = response_json;
  215. if (region_found.isMember("region") && !region_found["region"].asString().empty()) {
  216. region_to_search = region_found["region"].asString();
  217. } else {
  218. throw std::runtime_error("unexpected home find response contents");
  219. }
  220. response_json = search_for_home_or_region(region_to_search, username);
  221.  
  222. Json::Value &home_found = response_json;
  223. if (!home_found.isMember("node") || home_found["node"].asString().empty()) {
  224. throw std::runtime_error("unexpected home find response contents");
  225. }
  226. std::pair<std::string, std::string> user_info;
  227. user_info.first = region_to_search;
  228. user_info.second = home_found["node"].asString();
  229. return user_info;
  230. }
  231.  
  232. boost::shared_ptr<Session> login_main(const std::string &username, const std::string &password, const std::string &client_type)
  233. {
  234. if (username.empty()) {
  235. throw std::runtime_error("cloudlib empty username");
  236. }
  237. if (password.empty()) {
  238. throw std::runtime_error("cloudlib empty password");
  239. }
  240. std::pair<std::string, std::string> user_info = home_find(username);
  241. std::string &node = user_info.second;
  242. if (node.empty())
  243. throw std::runtime_error("cloudlib primary node is not found");
  244.  
  245. std::string url = stdprintf("https://%s/authorize", node.c_str());
  246. std::string data = "login=" + username + "&client=" + client_type + "&password=" + password + "&recaptcha=";
  247. boost::shared_ptr<Request> request_provider = http_client->prepare_request();
  248. boost::shared_ptr<Response> response;
  249.  
  250. response = request_provider->post(url, data);
  251. const Json::Value& response_json = json_parse_or_die(response->data, true);
  252.  
  253. if (response_json.isMember("not_a_home"))
  254. throw std::logic_error("CloudLib: not_a_home");
  255. if (response_json.isMember("erase"))
  256. throw std::logic_error("CloudLib: erase");
  257. if (!response_json.isMember("success") || !response_json["success"].isInt() || response_json["success"].asInt()!=1)
  258. throw std::logic_error("CloudLib: bad username or password");
  259. if (!response_json["login"].isString())
  260. throw std::logic_error("login field error");
  261. if (!response_json["base_rights"].isInt())
  262. throw std::logic_error("CloudLib: not_a_home");
  263. if (!response_json.isMember("sid"))
  264. throw std::logic_error("CloudLib: not_a_home");
  265.  
  266. boost::shared_ptr<Session> session = boost::make_shared<Session>(username,
  267. node, response_json["sid"].asString());
  268. std::string guest_key;
  269. std::vector<std::pair<std::string, std::string> > shares_list;
  270.  
  271. if (response_json.isMember("shares_shortcut")) {
  272. const Json::Value &v = response_json["shares_shortcut"];
  273. if (v.isMember("guest_key")) {
  274. guest_key = v["guest_key"].toStyledString();
  275.  
  276. for(Json::Value::iterator shr = v["shares"].begin(); shr != v["shares"].end(); ++shr) {
  277. const Json::Value &share = *shr;
  278. const bool share_have_owner = share.isMember("owner") && share["owner"].isString();
  279. const bool share_have_home = share.isMember("home_node") && share["home_node"].isString()
  280. && !share["home_node"].asString().empty();
  281. if (!share_have_owner || !share_have_home) {
  282. continue;
  283. }
  284. const std::string &share_owner = share["owner"].asString();
  285. const std::string &share_home_node = share["home_node"].asString();
  286. shares_list.push_back(std::pair<std::string, std::string>(share_owner, share_home_node));
  287. }
  288. }
  289. }
  290. session->login_shares(guest_key, shares_list);
  291. return session;
  292. }
  293.  
  294. void Session::login_shares(const std::string &guest_key, const std::vector<std::pair<std::string, std::string> > &shares_list)
  295. {
  296. const std::string &node = user_info.main.node;
  297.  
  298. for(std::vector<std::pair<std::string, std::string> >::const_iterator it = shares_list.begin(); it != shares_list.end(); ++it) {
  299.  
  300. const std::string &share_owner = it->first;
  301. const std::string &share_home_node = it->second;
  302.  
  303. std::string url = stdprintf("https://%s/authorize", share_home_node.c_str());
  304. std::string data = stdprintf("password=&login=%s&recaptcha=&guest_key=%s", + share_owner.c_str(), guest_key.c_str());
  305.  
  306. boost::shared_ptr<Request> request_provider = http_client->prepare_request();
  307.  
  308. request_provider->post_async(url, data, boost::bind(&Session::make_shared_session_callback,
  309. shared_from_this(), share_home_node, share_owner, _1));
  310. }
  311. }
  312.  
  313. boost::shared_ptr<Session> login(const std::string &username, const std::string &password, const std::string &client_type) {
  314. logger = boost::make_shared<Logger>(".", ".", "cloudlib.log");
  315. http_client = boost::make_shared<Client>();
  316. command_queue = boost::make_shared<CommandQueue>("CloudLib_command_queue");
  317. try {
  318.  
  319. boost::shared_ptr<Session> session = login_main(username, password, client_type);
  320.  
  321. sleep(3);
  322. std::map<std::string, Session::AccountInfo>::iterator it = session->user_info.shares.begin();
  323. int size = session->user_info.shares.size();
  324. for(; it != session->user_info.shares.end(); ++it) {
  325. std::cout << "owner = " << it->first << " sid = " << it->second.sid << std::endl;
  326. }
  327. command_queue->enqueue(boost::bind(&Session::check_shares, session));
  328.  
  329. return session;
  330. } catch (std::exception &e) {
  331. logger->message(e.what());
  332. }
  333. return NULL;
  334. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement