Changeset - 008827e06d6d
[Not reviewed]
0 1 0
Jan Kaluza - 10 years ago 2016-01-31 10:19:30
jkaluza@redhat.com
Set 30 seconds timeout for oauth2 code
1 file changed with 1 insertions and 1 deletions:
0 comments (0 inline, 0 general)
spectrum_manager/src/server.cpp
Show inline comments
 
@@ -207,267 +207,267 @@ void Server::authorize(struct mg_connection *conn, struct http_message *hm) {
 
		std::cout << "User authorized\n";
 
		mg_printf(conn, "HTTP/1.1 302 Found\r\n"
 
			"Set-Cookie: session=%s; max-age=3600; http-only\r\n"  // Session ID
 
			"Set-Cookie: user=%s\r\n"  // Set user, needed by Javascript code
 
			"Set-Cookie: admin=%s\r\n"  // Set user, needed by Javascript code
 
			"Set-Cookie: base_location=%s\r\n"  // Set user, needed by Javascript code
 
			"Set-Cookie: original_url=/; max-age=0\r\n"  // Delete original_url
 
			"Location: %s%sinstances\r\n\r\n",
 
			session->session_id, session->user, session->admin ? "1" : "0", CONFIG_STRING(m_config, "service.base_location").c_str(), host.c_str(), CONFIG_STRING(m_config, "service.base_location").c_str());
 
	} else {
 
		// Authentication failure, redirect to login.
 
		redirect_to(conn, hm, "/login");
 
	}
 
}
 

	
 
bool Server::is_authorized(const struct mg_connection *conn, struct http_message *hm) {
 
	Server::session *session;
 
	char valid_id[33];
 
	bool authorized = false;
 

	
 
	// Always authorize accesses to login page and to authorize URI
 
	if (!mg_vcmp(&hm->uri, "/login") ||
 
		!mg_vcmp(&hm->uri, "/login/") ||
 
		!mg_vcmp(&hm->uri, "/form.css") ||
 
		!mg_vcmp(&hm->uri, "/style.css") ||
 
		!mg_vcmp(&hm->uri, "/logo.png") ||
 
		!mg_vcmp(&hm->uri, "/users/register.shtml") ||
 
		!mg_vcmp(&hm->uri, "/api/v1/users/add") ||
 
		!mg_vcmp(&hm->uri, "/authorize")) {
 
		return true;
 
	}
 

	
 
	if ((session = get_session(hm)) != NULL) {
 
		generate_session_id(valid_id, session->random, session->user);
 
		if (strcmp(valid_id, session->session_id) == 0) {
 
			session->expire = time(0) + SESSION_TTL;
 
			authorized = true;
 
		}
 
	}
 

	
 
	return authorized;
 
}
 

	
 
void Server::redirect_to(struct mg_connection *conn, struct http_message *hm, const char *where) {
 
	std::string host;
 
	mg_str *host_hdr = mg_get_http_header(hm, "Host");
 
	if (host_hdr) {
 
		if (!CONFIG_STRING(m_config, "service.cert").empty()) {
 
			host += "https://";
 
		}
 
		else {
 
			host += "http://";
 
		}
 
		host += std::string(host_hdr->p, host_hdr->len);
 
	}
 

	
 
	where = where + 1;
 

	
 
	mg_printf(conn, "HTTP/1.1 302 Found\r\n"
 
		"Set-Cookie: original_url=/\r\n"
 
		"Location: %s%s%s\r\n\r\n", host.c_str(), CONFIG_STRING(m_config, "service.base_location").c_str(), where);
 
}
 

	
 
void Server::print_html(struct mg_connection *conn, struct http_message *hm, const std::string &html) {
 
	mg_printf(conn,
 
			"HTTP/1.1 200 OK\r\n"
 
			"Content-Type: text/html\r\n"
 
			"Content-Length: %d\r\n"        // Always set Content-Length
 
			"\r\n"
 
			"%s%s%s",
 
			(int) html.size() + m_header.size() + m_footer.size(), m_header.c_str(), html.c_str(), m_footer.c_str());
 
}
 

	
 
std::string Server::send_command(const std::string &jid, const std::string &cmd, int timeout) {
 
	Swift::SimpleEventLoop eventLoop;
 
	Swift::BoostNetworkFactories networkFactories(&eventLoop);
 

	
 
	ask_local_server(m_config, networkFactories, jid, cmd);
 
	struct timeval td_start,td_end;
 
	float elapsed = 0; 
 
	gettimeofday(&td_start, NULL);
 
	gettimeofday(&td_end, NULL);
 

	
 
	time_t started = time(NULL);
 
	while(get_response().empty() && td_end.tv_sec - td_start.tv_sec < timeout) {
 
		gettimeofday(&td_end, NULL);
 
		eventLoop.runOnce();
 
	}
 

	
 
	std::string response = get_response();
 
	if (response == "Empty response") {
 
		return "";
 
	}
 

	
 
	return response;
 
}
 

	
 
// void Server::serve_onlineusers(struct mg_connection *conn, struct http_message *hm) {
 
// 	Server:session *session = get_session(hm);
 
// 	if (!session->admin) {
 
// 		redirect_to(conn, hm, "/");
 
// 		return;
 
// 	}
 
// 
 
// 	std::string html;
 
// 	std::string jid = get_http_var(hm, "jid");
 
// 
 
// 	html += std::string("<h2>") + jid + " online users</h2><table><tr><th>JID<th>Command</th></tr>";
 
// 
 
// 	Swift::SimpleEventLoop eventLoop;
 
// 	Swift::BoostNetworkFactories networkFactories(&eventLoop);
 
// 
 
// 	ask_local_server(m_config, networkFactories, jid, "online_users");
 
// 	eventLoop.runUntilEvents();
 
// 	while(get_response().empty()) {
 
// 		eventLoop.runUntilEvents();
 
// 	}
 
// 
 
// 	std::string response = get_response();
 
// 	std::vector<std::string> users;
 
// 	boost::split(users, response, boost::is_any_of("\n"));
 
// 
 
// 	BOOST_FOREACH(std::string &user, users) {
 
// 		html += "<tr><td>" + user + "</td><td></td></tr>";
 
// 	}
 
// 
 
// 	html += "</table><a href=\"/\">Back to main page</a>";
 
// 	html += "</body></html>";
 
// 	print_html(conn, hm, html);
 
// }
 
// 
 
// void Server::serve_cmd(struct mg_connection *conn, struct http_message *hm) {
 
// 	Server:session *session = get_session(hm);
 
// 	if (!session->admin) {
 
// 		redirect_to(conn, hm, "/");
 
// 		return;
 
// 	}
 
// 
 
// 	std::string html;
 
// 	std::string jid = get_http_var(hm, "jid");
 
// 	std::string cmd = get_http_var(hm, "cmd");
 
// 
 
// 	html += std::string("<h2>") + jid + " command result</h2>";
 
// 
 
// 	Swift::SimpleEventLoop eventLoop;
 
// 	Swift::BoostNetworkFactories networkFactories(&eventLoop);
 
// 
 
// 	ask_local_server(m_config, networkFactories, jid, cmd);
 
// 	while(get_response().empty()) {
 
// 		eventLoop.runUntilEvents();
 
// 	}
 
// 
 
// 	std::string response = get_response();
 
// 	
 
// 	html += "<pre>" + response + "</pre>";
 
// 
 
// 	html += "<a href=\"/\">Back to main page</a>";
 
// 	html += "</body></html>";
 
// 	print_html(conn, hm, html);
 
// }
 

	
 
void Server::serve_logout(struct mg_connection *conn, struct http_message *hm) {
 
	std::string host;
 
	mg_str *host_hdr = mg_get_http_header(hm, "Host");
 
	if (host_hdr) {
 
		if (!CONFIG_STRING(m_config, "service.cert").empty()) {
 
			host += "https://";
 
		}
 
		else {
 
			host += "http://";
 
		}
 
		host += std::string(host_hdr->p, host_hdr->len);
 
	}
 

	
 
	Server:session *session = get_session(hm);
 
	mg_printf(conn, "HTTP/1.1 302 Found\r\n"
 
		"Set-Cookie: session=%s; max-age=0\r\n"
 
		"Set-Cookie: admin=%s; max-age=0\r\n"
 
		"Location: %s%s\r\n\r\n",
 
		session->session_id, session->admin ? "1" : "0", host.c_str(), CONFIG_STRING(m_config, "service.base_location").c_str());
 

	
 
	sessions.erase(session->session_id);
 
	delete session;
 
}
 

	
 
void Server::serve_oauth2(struct mg_connection *conn, struct http_message *hm) {
 
// 	http://slack.spectrum.im/oauth2/localhostxmpp?code=14830663267.19140123492.e7f78a836d&state=534ab3b6-8bf1-4974-8274-847df8490bc5
 
	std::string uri(hm->uri.p, hm->uri.len);
 
	std::string instance = uri.substr(uri.rfind("/") + 1);
 
	std::string code = get_http_var(hm, "code");
 
	std::string state = get_http_var(hm, "state");
 

	
 
	std::string response = send_command(instance, "set_oauth2_code " + code + " " + state, 10);
 
	std::string response = send_command(instance, "set_oauth2_code " + code + " " + state, 30);
 
	std::cerr << "set_oauth2_code response: '" << response << "'\n";
 
	if (response.find("Registered as ") == 0) {
 
		std::vector<std::string> args;
 
		boost::split(args, response, boost::is_any_of(" "));
 
		std::cerr << "set_oauth2_code response size " << args.size() << "\n";
 
		if (args.size() == 3) {
 
			Server:session *session = get_session(hm);
 
			UserInfo info;
 
			m_storage->getUser(session->user, info);
 
			std::string username = "";
 
			int type = (int) TYPE_STRING;
 
			m_storage->getUserSetting(info.id, instance, type, username);
 
			m_storage->updateUserSetting(info.id, instance, args[2]);
 
		}
 
	}
 
	redirect_to(conn, hm, "/instances/");
 
}
 

	
 
void Server::event_handler(struct mg_connection *conn, int ev, void *p) {
 
	struct http_message *hm = (struct http_message *) p;
 

	
 
	if (ev == MG_EV_SSI_CALL) {
 
		mbuf_resize(&conn->send_mbuf, conn->send_mbuf.size * 2);
 
		std::string resp(conn->send_mbuf.buf, conn->send_mbuf.len);
 
		boost::replace_all(resp, "href=\"/", std::string("href=\"") + CONFIG_STRING(m_config, "service.base_location"));
 
		boost::replace_all(resp, "src=\"/", std::string("src=\"") + CONFIG_STRING(m_config, "service.base_location"));
 
		boost::replace_all(resp, "action=\"/", std::string("action=\"") + CONFIG_STRING(m_config, "service.base_location"));
 
		strcpy(conn->send_mbuf.buf, resp.c_str());
 
		mbuf_trim(&conn->send_mbuf);
 
		return;
 
	}
 

	
 
	if (ev != MG_EV_HTTP_REQUEST) {
 
		return;
 
	}
 

	
 
	hm->uri.p += CONFIG_STRING(m_config, "service.base_location").size() - 1;
 
	hm->uri.len -= CONFIG_STRING(m_config, "service.base_location").size() - 1;
 

	
 
	if (!is_authorized(conn, hm)) {
 
		redirect_to(conn, hm, "/login");
 
	} else if (mg_vcmp(&hm->uri, "/authorize") == 0) {
 
		authorize(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/logout") == 0) {
 
		serve_logout(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/users") == 0) {
 
// 		serve_users(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/users/add") == 0) {
 
// 		serve_users_add(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/users/remove") == 0) {
 
// 		serve_users_remove(conn, hm);
 
	} else if (has_prefix(&hm->uri, "/oauth2")) {
 
		serve_oauth2(conn, hm);
 
	} else if (has_prefix(&hm->uri, "/api/v1/")) {
 
		m_apiServer->handleRequest(this, get_session(hm), conn, hm);
 
	} else {
 
		if (hm->uri.p[hm->uri.len - 1] != '/') {
 
			std::string url(hm->uri.p, hm->uri.len);
 
			if (url.find(".") == std::string::npos) {
 
				url += "/";
 
				redirect_to(conn, hm, url.c_str());
 
				conn->flags |= MG_F_SEND_AND_CLOSE;
 
				return;
 
			}
 
		}
 
		mg_serve_http(conn, hm, s_http_server_opts);
 
	}
 

	
 
	conn->flags |= MG_F_SEND_AND_CLOSE;
 
}
 

	
 

	
 

	
 

	
0 comments (0 inline, 0 general)