Changeset - c9cd2218b172
[Not reviewed]
0 3 0
Jan Kaluza - 9 years ago 2016-01-24 13:04:32
jkaluza@redhat.com
Slack: get the bot_access_token when requesting the token and use it to connect RTM
3 files changed with 21 insertions and 3 deletions:
0 comments (0 inline, 0 general)
include/transport/OAuth2.h
Show inline comments
 
@@ -30,25 +30,25 @@ class OAuth2 {
 
		OAuth2(const std::string &clientId, const std::string &clientSecret,
 
			   const std::string &authURL, const std::string &tokenURL,
 
			   const std::string &redirectURL = "", const std::string &scope = "");
 

	
 
		virtual ~OAuth2();
 

	
 
		std::string generateAuthURL();
 

	
 
		const std::string &getState() {
 
			return m_state;
 
		}
 

	
 
		std::string requestToken(const std::string &code, std::string &error);
 
		std::string requestToken(const std::string &code, std::string &token, std::string &bot_token);
 

	
 
	private:
 
		std::string m_clientId;
 
		std::string m_clientSecret;
 
		std::string m_authURL;
 
		std::string m_tokenURL;
 
		std::string m_redirectURL;
 
		std::string m_scope;
 
		std::string m_state;
 
};
 

	
 
}
libtransport/OAuth2.cpp
Show inline comments
 
@@ -62,25 +62,25 @@ std::string OAuth2::generateAuthURL() {
 

	
 
	if (!m_redirectURL.empty()) {
 
		url += "&redirect_uri=" + Util::urlencode(m_redirectURL);
 
	}
 

	
 
	boost::uuids::uuid uuid = boost::uuids::random_generator()();
 
	m_state = boost::lexical_cast<std::string>(uuid);
 
	url += "&state=" + Util::urlencode(m_state);
 

	
 
	return url;
 
}
 

	
 
std::string OAuth2::requestToken(const std::string &code, std::string &token) {
 
std::string OAuth2::requestToken(const std::string &code, std::string &token, std::string &bot_token) {
 
	std::string url = m_tokenURL + "?";
 
	url += "client_id=" + Util::urlencode(m_clientId);
 
	url += "&client_secret=" + Util::urlencode(m_clientSecret);
 
	url += "&code=" + Util::urlencode(code);
 

	
 
	if (!m_redirectURL.empty()) {
 
		url += "&redirect_uri=" + Util::urlencode(m_redirectURL);
 
	}
 

	
 
	rapidjson::Document resp;
 
	HTTPRequest req(HTTPRequest::Get, url);
 
	if (!req.execute(resp)) {
 
@@ -96,16 +96,24 @@ std::string OAuth2::requestToken(const std::string &code, std::string &token) {
 
		LOG4CXX_ERROR(logger, req.getRawData());
 
		return "No 'access_token' object in the reply.";
 
	}
 

	
 
	token = access_token.GetString();
 
	if (token.empty()) {
 
		LOG4CXX_ERROR(logger, "Empty 'access_token' object in the reply.");
 
		LOG4CXX_ERROR(logger, url);
 
		LOG4CXX_ERROR(logger, req.getRawData());
 
		return "Empty 'access_token' object in the reply.";
 
	}
 

	
 
	rapidjson::Value& bot = resp["bot"];
 
	if (bot.IsObject()) {
 
		rapidjson::Value& bot_access_token = resp["bot_access_token"];
 
		if (!bot_access_token.IsString()) {
 
			bot_token = bot_access_token.GetString();
 
		}
 
	}
 

	
 
	return "";
 
}
 

	
 
}
spectrum/src/frontends/slack/SlackUserRegistration.cpp
Show inline comments
 
@@ -101,42 +101,49 @@ std::string SlackUserRegistration::getTeamDomain(const std::string &token) {
 
		LOG4CXX_ERROR(logger, "No 'domain' string in the reply.");
 
		LOG4CXX_ERROR(logger, url);
 
		LOG4CXX_ERROR(logger, req.getRawData());
 
		return "";
 
	}
 

	
 
	return domain.GetString();
 
}
 

	
 
std::string SlackUserRegistration::handleOAuth2Code(const std::string &code, const std::string &state) {
 
	OAuth2 *oauth2 = NULL;
 
	std::string token;
 
	std::string access_token;
 
	std::vector<std::string> data;
 

	
 
	if (state == "use_bot_token") {
 
		token = code;
 
		access_token = code;
 
	}
 
	else {
 
		if (m_auths.find(state) != m_auths.end()) {
 
			oauth2 = m_auths[state];
 
			data = m_authsData[state];
 
		}
 
		else {
 
			return "Received state code '" + state + "' not found in state codes list.";
 
		}
 

	
 
		std::string error = oauth2->requestToken(code, token);
 
		std::string error = oauth2->requestToken(code, access_token, token);
 
		if (!error.empty())  {
 
			return error;
 
		}
 

	
 
		if (token.empty()) {
 
			LOG4CXX_INFO(logger, "Using 'token' as 'bot_access_token'");
 
			token = access_token;
 
		}
 
	}
 

	
 
	std::string domain = getTeamDomain(token);
 
	if (domain.empty()) {
 
		return "The token you have provided is invalid";
 
	}
 

	
 
	UserInfo user;
 
	user.uin = "";
 
	user.password = "";
 
	user.id = 0;
 
	m_storageBackend->getUser(domain, user);
 
@@ -145,24 +152,27 @@ std::string SlackUserRegistration::handleOAuth2Code(const std::string &code, con
 
	user.language = "en";
 
	user.encoding = "";
 
	user.vip = 0;
 

	
 
	registerUser(user, true);
 

	
 
	m_storageBackend->getUser(user.jid, user);
 

	
 
	std::string value = token;
 
	int type = (int) TYPE_STRING;
 
	m_storageBackend->getUserSetting(user.id, "bot_token", type, value);
 

	
 
	value = access_token;
 
	m_storageBackend->getUserSetting(user.id, "access_token", type, value);
 

	
 
	LOG4CXX_INFO(logger, "Registered Slack user " << user.jid);
 

	
 
	if (oauth2) {
 
		m_auths.erase(state);
 
		delete oauth2;
 

	
 
		m_authsData.erase(state);
 
	}
 

	
 
	m_component->getFrontend()->reconnectUser(user.jid);
 

	
 
	return "";
0 comments (0 inline, 0 general)