Replaced ClientToken with pair<string, string> for ease of use.

This commit is contained in:
Alex Zolotarev 2016-01-11 09:40:44 +03:00 committed by Sergey Yershov
parent 1bfcfd2f88
commit 72a9f6e0d8
5 changed files with 51 additions and 52 deletions

View file

@ -3,7 +3,6 @@
#include "editor/osm_auth.hpp"
using osm::OsmOAuth;
using osm::ClientToken;
namespace
{

View file

@ -21,6 +21,11 @@ constexpr char const * kApiVersion = "/api/0.6";
namespace
{
inline bool IsKeySecretValid(TKeySecret const & t)
{
return !(t.first.empty() || t.second.empty());
}
string findAuthenticityToken(string const & body)
{
auto pos = body.find("name=\"authenticity_token\"");
@ -54,10 +59,8 @@ bool isLoggedIn(string const & contents)
}
} // namespace
OsmOAuth::OsmOAuth(string const & consumerKey, string const & consumerSecret,
string const & baseUrl, string const & apiUrl):
m_consumerKey(consumerKey), m_consumerSecret(consumerSecret),
m_baseUrl(baseUrl), m_apiUrl(apiUrl)
OsmOAuth::OsmOAuth(string const & consumerKey, string const & consumerSecret, string const & baseUrl, string const & apiUrl)
: m_consumerKeySecret(consumerKey, consumerSecret), m_baseUrl(baseUrl), m_apiUrl(apiUrl)
{
}
@ -175,10 +178,10 @@ string OsmOAuth::SendAuthRequest(string const & requestTokenKey, SessionID const
}
// Given a web session id, fetches an OAuth access token.
OsmOAuth::AuthResult OsmOAuth::FetchAccessToken(SessionID const & sid, ClientToken & token) const
OsmOAuth::AuthResult OsmOAuth::FetchAccessToken(SessionID const & sid, TKeySecret & outKeySecret) const
{
// Aquire a request token.
OAuth::Consumer consumer(m_consumerKey, m_consumerSecret);
OAuth::Consumer const consumer(m_consumerKeySecret.first, m_consumerKeySecret.second);
OAuth::Client oauth(&consumer);
string const requestTokenUrl = m_baseUrl + "/oauth/request_token";
string const requestTokenQuery = oauth.getURLQueryString(OAuth::Http::Get, requestTokenUrl + "?oauth_callback=oob");
@ -203,15 +206,15 @@ OsmOAuth::AuthResult OsmOAuth::FetchAccessToken(SessionID const & sid, ClientTok
OAuth::KeyValuePairs responseData = OAuth::ParseKeyValuePairs(request2.server_response());
OAuth::Token accessToken = OAuth::Token::extract(responseData);
token.m_key = accessToken.key();
token.m_secret = accessToken.secret();
outKeySecret.first = accessToken.key();
outKeySecret.second = accessToken.secret();
LogoutUser(sid);
return AuthResult::OK;
}
OsmOAuth::AuthResult OsmOAuth::AuthorizePassword(string const & login, string const & password, ClientToken & token) const
OsmOAuth::AuthResult OsmOAuth::AuthorizePassword(string const & login, string const & password, TKeySecret & outKeySecret) const
{
SessionID sid;
AuthResult result = FetchSessionId(sid);
@ -222,10 +225,10 @@ OsmOAuth::AuthResult OsmOAuth::AuthorizePassword(string const & login, string co
if (result != AuthResult::OK)
return result;
return FetchAccessToken(sid, token);
return FetchAccessToken(sid, outKeySecret);
}
OsmOAuth::AuthResult OsmOAuth::AuthorizeFacebook(string const & facebookToken, ClientToken & token) const
OsmOAuth::AuthResult OsmOAuth::AuthorizeFacebook(string const & facebookToken, TKeySecret & outKeySecret) const
{
SessionID sid;
AuthResult result = FetchSessionId(sid);
@ -236,14 +239,14 @@ OsmOAuth::AuthResult OsmOAuth::AuthorizeFacebook(string const & facebookToken, C
if (result != AuthResult::OK)
return result;
return FetchAccessToken(sid, token);
return FetchAccessToken(sid, outKeySecret);
}
OsmOAuth::Response OsmOAuth::Request(ClientToken const & token, string const & method, string const & httpMethod, string const & body) const
OsmOAuth::Response OsmOAuth::Request(TKeySecret const & keySecret, string const & method, string const & httpMethod, string const & body) const
{
CHECK(token.IsValid(), ("Empty request token"));
OAuth::Consumer const consumer(m_consumerKey, m_consumerSecret);
OAuth::Token const oatoken(token.m_key, token.m_secret);
CHECK(IsKeySecretValid(keySecret), ("Empty request token"));
OAuth::Consumer const consumer(m_consumerKeySecret.first, m_consumerKeySecret.second);
OAuth::Token const oatoken(keySecret.first, keySecret.second);
OAuth::Client oauth(&consumer, &oatoken);
OAuth::Http::RequestType reqType;
@ -282,31 +285,34 @@ OsmOAuth::Response OsmOAuth::DirectRequest(string const & method, bool api) cons
return Response(static_cast<ResponseCode>(request.error_code()), request.server_response());
}
OsmOAuth & OsmOAuth::SetToken(ClientToken const & token)
OsmOAuth & OsmOAuth::SetToken(TKeySecret const & keySecret)
{
m_token.m_key = token.m_key;
m_token.m_secret = token.m_secret;
m_tokenKeySecret = keySecret;
return *this;
}
TKeySecret const & OsmOAuth::GetToken() const { return m_tokenKeySecret; }
bool OsmOAuth::IsAuthorized() const { return IsKeySecretValid(m_tokenKeySecret); }
OsmOAuth::AuthResult OsmOAuth::FetchAccessToken(SessionID const & sid)
{
return FetchAccessToken(sid, m_token);
return FetchAccessToken(sid, m_tokenKeySecret);
}
OsmOAuth::AuthResult OsmOAuth::AuthorizePassword(string const & login, string const & password)
{
return AuthorizePassword(login, password, m_token);
return AuthorizePassword(login, password, m_tokenKeySecret);
}
OsmOAuth::AuthResult OsmOAuth::AuthorizeFacebook(string const & facebookToken)
{
return AuthorizeFacebook(facebookToken, m_token);
return AuthorizeFacebook(facebookToken, m_tokenKeySecret);
}
OsmOAuth::Response OsmOAuth::Request(string const & method, string const & httpMethod, string const & body) const
{
return Request(m_token, method, httpMethod, body);
return Request(m_tokenKeySecret, method, httpMethod, body);
}
string DebugPrint(OsmOAuth::AuthResult const res)

View file

@ -1,17 +1,12 @@
#pragma once
#include "std/string.hpp"
#include "std/utility.hpp"
namespace osm
{
/// A structure that holds request token pair.
struct ClientToken
{
string m_key;
string m_secret;
inline bool IsValid() const { return !m_key.empty() && !m_secret.empty(); }
};
using TKeySecret = pair<string /*key*/, string /*secret*/>;
class OsmOAuth
{
@ -51,8 +46,7 @@ public:
/// The constructor. Simply stores a lot of strings in fields.
/// @param[apiUrl] The OSM API URL defaults to baseUrl, or kDefaultApiURL if not specified.
OsmOAuth(string const & consumerKey, string const & consumerSecret,
string const & baseUrl, string const & apiUrl);
OsmOAuth(string const & consumerKey, string const & consumerSecret, string const & baseUrl, string const & apiUrl);
/// Ilya Zverev's test server.
static OsmOAuth IZServerAuth();
@ -63,17 +57,17 @@ public:
/// @name Stateless methods.
//@{
AuthResult AuthorizePassword(string const & login, string const & password, ClientToken & token) const;
AuthResult AuthorizeFacebook(string const & facebookToken, ClientToken & token) const;
AuthResult AuthorizePassword(string const & login, string const & password, TKeySecret & outKeySecret) const;
AuthResult AuthorizeFacebook(string const & facebookToken, TKeySecret & outKeySecret) const;
/// @param[method] The API method, must start with a forward slash.
Response Request(ClientToken const & token, string const & method, string const & httpMethod = "GET", string const & body = "") const;
Response Request(TKeySecret const & keySecret, string const & method, string const & httpMethod = "GET", string const & body = "") const;
//@}
/// @name Methods for using a token stored in this class. Obviously not thread-safe.
//@{
OsmOAuth & SetToken(ClientToken const & token);
ClientToken const & GetToken() const { return m_token; }
bool IsAuthorized() const { return m_token.IsValid(); }
OsmOAuth & SetToken(TKeySecret const & keySecret);
TKeySecret const & GetToken() const;
bool IsAuthorized() const;
AuthResult AuthorizePassword(string const & login, string const & password);
AuthResult AuthorizeFacebook(string const & facebookToken);
/// @param[method] The API method, must start with a forward slash.
@ -91,18 +85,19 @@ private:
string m_token;
};
string m_consumerKey;
string m_consumerSecret;
/// Key and secret for application.
TKeySecret m_consumerKeySecret;
string m_baseUrl;
string m_apiUrl;
ClientToken m_token;
/// Key and secret to sign every OAuth request.
TKeySecret m_tokenKeySecret;
AuthResult FetchSessionId(SessionID & sid) const;
AuthResult LogoutUser(SessionID const & sid) const;
AuthResult LoginUserPassword(string const & login, string const & password, SessionID const & sid) const;
AuthResult LoginFacebook(string const & facebookToken, SessionID const & sid) const;
string SendAuthRequest(string const & requestTokenKey, SessionID const & sid) const;
AuthResult FetchAccessToken(SessionID const & sid, ClientToken & token) const;
AuthResult FetchAccessToken(SessionID const & sid, TKeySecret & outKeySecret) const;
AuthResult FetchAccessToken(SessionID const & sid);
};

View file

@ -99,10 +99,10 @@ typedef NS_OPTIONS(NSUInteger, MWMFieldCorrect)
return YES;
}
- (void)storeCredentials:(osm::ClientToken)token
- (void)storeCredentials:(osm::TKeySecret)keySecret
{
NSString * requestToken = @(token.m_key.c_str());
NSString * requestSecret = @(token.m_secret.c_str());
NSString * requestToken = @(keySecret.first.c_str());
NSString * requestSecret = @(keySecret.second.c_str());
NSUserDefaults * ud = [NSUserDefaults standardUserDefaults];
[ud setObject:requestToken forKey:kOSMRequestToken];
[ud setObject:requestSecret forKey:kOSMRequestSecret];
@ -170,14 +170,13 @@ typedef NS_OPTIONS(NSUInteger, MWMFieldCorrect)
string const username = self.loginTextField.text.UTF8String;
string const password = self.passwordTextField.text.UTF8String;
// TODO(AlexZ): Change to production.
osm::OsmOAuth const auth = osm::OsmOAuth::DevServerAuth();
osm::ClientToken token;
osm::OsmOAuth::AuthResult const result = auth.AuthorizePassword(username, password, token);
osm::OsmOAuth auth = osm::OsmOAuth::DevServerAuth();
osm::OsmOAuth::AuthResult const result = auth.AuthorizePassword(username, password);
dispatch_async(dispatch_get_main_queue(), ^
{
[self stopSpinner];
if (result == osm::OsmOAuth::AuthResult::OK)
[self storeCredentials:token];
[self storeCredentials:auth.GetToken()];
else
[self showInvalidCredentialsAlert];
});

View file

@ -112,8 +112,8 @@ void OsmAuthDialog::OnAction()
}
auto const token = auth.GetToken();
Settings::Set(kTokenKeySetting, token.m_key);
Settings::Set(kTokenSecretSetting, token.m_secret);
Settings::Set(kTokenKeySetting, token.first);
Settings::Set(kTokenSecretSetting, token.second);
SwitchToLogout(this);
}