app registering support

This commit is contained in:
tastytea 2018-02-09 22:19:25 +01:00
parent 071ebdc607
commit fec50bc146
Signed by: tastytea
GPG Key ID: 59346E0EA35C67E5
5 changed files with 170 additions and 25 deletions

View File

@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.7)
include(GNUInstallDirs)
project (mastodon-cpp
VERSION 0.2.11
VERSION 0.2.12
LANGUAGES CXX
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")

View File

@ -93,12 +93,11 @@ If you use a debug build, you get more verbose error messages.
* [x] Implement all PUT calls
* [x] Implement all DELETE calls
* Version 0.3.0
* [ ] Handle HTTP statuses 301 & 302
* [ ] Support registering as an application
* [x] Handle HTTP statuses 301 & 302
* [x] Support registering as an application
* Later
* [ ] Asynchronous I/O
* [ ] Handle X-RateLimit header
* [ ] Find out why the "short read" error occurs with PATCH and POST
## Status of implementation

View File

@ -0,0 +1,70 @@
/* This file is part of mastodon-cpp.
*/
#include <iostream>
#include <vector>
#include <string>
#include <cstdint>
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include "../mastodon-cpp.hpp"
using Mastodon::API;
int main(int argc, char *argv[])
{
if (argc < 2)
{
std::cerr << "usage: " << argv[0] << " <instance>\n";
return 1;
}
Mastodon::API masto(argv[1], "");
masto.set_useragent("mastodon-cpp-example/1.3.3.7");
std::string answer;
std::uint16_t ret;
std::string client_id, client_secret, url;
ret = masto.register_app1(argv[1],
"test123",
"urn:ietf:wg:oauth:2.0:oob",
"read follow",
"",
client_id,
client_secret,
url);
if (ret == 0)
{
std::cout << "Visit " << url << " to get the code.\n";
std::string code;
std::cout << "Insert code: ";
std::cin >> code;
std::string access_token;
masto.register_app2(argv[1],
client_id,
client_secret,
"urn:ietf:wg:oauth:2.0:oob",
code,
access_token);
if (ret == 0)
{
std::cout << "Success!\nAccess-token: " << access_token << '\n';
}
else
{
std::cerr << "Error code: " << ret << '\n';
return ret;
}
}
else
{
std::cerr << "Error code: " << ret << '\n';
return ret;
}
return 0;
}

View File

@ -18,6 +18,7 @@
#include <map>
#include <vector>
#include <sstream>
#include <regex>
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include "version.hpp"
@ -149,21 +150,87 @@ const curlpp::Forms API::maptoformdata(const parametermap &map)
return formdata;
}
// const string API::register_app(const std::string &instance,
// const std::string &client_name,
// const std::string &redirect_uris,
// const std::string &scopes,
// const std::string &website)
// {
// API::parametermap parameters =
// {
// { "client_name", { client_name } },
// { "redirect_uris", { redirect_uris } },
// { "scopes", { scopes } },
// { "website", { website } }
// };
const std::uint16_t API::register_app1(const string &instance,
const string &client_name,
const string &redirect_uri,
const string &scopes,
const string &website,
string &client_id,
string &client_secret,
string &url)
{
API::parametermap parameters =
{
{ "client_name", { client_name } },
{ "redirect_uris", { redirect_uri } },
{ "scopes", { scopes } },
{ "website", { website } }
};
// string answer;
// std::uint16_t ret = post(API::v1::apps, parameters, answer);
string answer;
std::uint16_t ret = post(API::v1::apps, parameters, answer);
if (ret == 0)
{
std::smatch match;
std::regex reid("client_id\":\"([0-9a-fA-F]+)\"");
std::regex resecret("client_secret\":\"([0-9a-fA-F]+)\"");
std::regex_search(answer, match, reid);
client_id = match[1].str();
std::regex_search(answer, match, resecret);
client_secret = match[1].str();
url = "https://" + instance + "/oauth/authorize" +
"?scope=" + urlencode(scopes) + "&response_type=code" +
"&redirect_uri=" + urlencode(redirect_uri) +
"&client_id=" + client_id;
if (!website.empty())
{
url += "&website=" + website;
}
return 0;
}
else
{
std::cerr << "Error code: " << ret << '\n';
return ret;
}
// }
}
const std::uint16_t API::register_app2(const string &instance,
const string &client_id,
const string &client_secret,
const string &redirect_uri,
const string &code,
string &access_token)
{
API::parametermap parameters =
{
{ "client_id", { client_id } },
{ "client_secret", { client_secret } },
{ "grant_type", { "authorization_code" } },
{ "redirect_uri", { redirect_uri } },
{ "code", { code } },
};
std::string answer;
std::uint16_t ret = post("/oauth/token", parameters, answer);
if (ret == 0)
{
std::smatch match;
std::regex retoken("access_token\":\"([0-9a-fA-F]+)\"");
std::regex_search(answer, match, retoken);
access_token = match[1].str();
return 0;
}
else
{
std::cerr << "Error code: " << ret << '\n';
return ret;
}
}

View File

@ -169,11 +169,20 @@ public:
*/
const std::string urlencode(const std::string &str) const;
// const std::string register_app(const std::string &instance,
// const std::string &client_name,
// const std::string &redirect_uris,
// const std::string &scopes,
// const std::string &website = "");
const std::uint16_t register_app1(const std::string &instance,
const std::string &client_name,
const std::string &redirect_uri,
const std::string &scopes,
const std::string &website,
std::string &client_id,
std::string &client_secret,
std::string &url);
const std::uint16_t register_app2(const std::string &instance,
const std::string &client_id,
const std::string &client_secret,
const std::string &redirect_uri,
const std::string &code,
std::string &access_token);
/*!
* @brief Make a GET request which doesn't require an argument.