More appropriately separate client and session. Also simplifies some of the session implementation

This commit is contained in:
rexy712 2019-12-21 08:35:52 -08:00
parent 0051760884
commit 3041895a97
21 changed files with 290 additions and 180 deletions

View File

@ -27,6 +27,7 @@
#include "matrix/connection.hpp" #include "matrix/connection.hpp"
#include "matrix/roomcxn.hpp" #include "matrix/roomcxn.hpp"
#include "matrix/netreturn.hpp" #include "matrix/netreturn.hpp"
#include "matrix/rest/client_url_list.hpp"
#include <vector> //vector #include <vector> //vector
#include <memory> //shared_ptr #include <memory> //shared_ptr
#include <cstdlib> //size_t #include <cstdlib> //size_t
@ -36,8 +37,10 @@ namespace matrix{
//Shares state with the spawning session. //Shares state with the spawning session.
class client : public connection class client : public connection
{ {
private:
std::shared_ptr<matrix::rest::client_url_list> m_urls;
public: public:
client(const std::shared_ptr<internal::session_info>&); client(const std::shared_ptr<session_info>&);
//Copy and move ctor //Copy and move ctor
client(const client& b) = default; client(const client& b) = default;
@ -137,7 +140,7 @@ namespace matrix{
raii::binary download_file(const raii::string_base& url); raii::binary download_file(const raii::string_base& url);
template<class DLHandler> template<class DLHandler>
bool download_file(const raii::string_base& url, DLHandler&& dl){ bool download_file(const raii::string_base& url, DLHandler&& dl){
_get_curl_setup(m_ses->urls.file_download(m_ses->homeserver, url)); _get_curl_setup(m_urls->file_download(m_ses->homeserver, url));
m_curl.setwritefun(_download_dispatch<DLHandler>); m_curl.setwritefun(_download_dispatch<DLHandler>);
m_curl.setwritedata(&dl); m_curl.setwritedata(&dl);
if(!_perform_curl()) if(!_perform_curl())

View File

@ -26,7 +26,6 @@
#include "raii/rjp_ptr.hpp" #include "raii/rjp_ptr.hpp"
#include "matrix/session_info.hpp" #include "matrix/session_info.hpp"
#include "matrix/netreturn.hpp" #include "matrix/netreturn.hpp"
#include <memory> //shared_ptr
namespace matrix{ namespace matrix{
@ -35,9 +34,9 @@ namespace matrix{
{ {
protected: protected:
mutable raii::curler m_curl = {}; mutable raii::curler m_curl = {};
std::shared_ptr<internal::session_info> m_ses = {}; std::shared_ptr<session_info> m_ses = {};
protected: protected:
connection(const std::shared_ptr<internal::session_info>&); connection(const std::shared_ptr<session_info>&);
connection(const connection&) = default; connection(const connection&) = default;
connection(connection&&) = default; connection(connection&&) = default;
connection& operator=(const connection&) = default; connection& operator=(const connection&) = default;

View File

@ -16,12 +16,14 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef MATRIX_URL_LIST_HPP #ifndef MATRIX_REST_CLIENT_URL_LIST_HPP
#define MATRIX_URL_LIST_HPP #define MATRIX_REST_CLIENT_URL_LIST_HPP
#include "matrix/session_info.hpp"
#include "raii/string.hpp" #include "raii/string.hpp"
#include "matrix/rest/urls_common.hpp"
namespace matrix{ namespace matrix::rest{
class client_url_list class client_url_list
{ {
private: private:
@ -29,48 +31,34 @@ namespace matrix{
raii::string m_file_upload; raii::string m_file_upload;
raii::string m_room_list; raii::string m_room_list;
raii::string m_alias_lookup; raii::string m_alias_lookup;
raii::string m_whoami;
raii::string m_displayname; raii::string m_displayname;
raii::string m_profile_picture; raii::string m_profile_picture;
public: public:
client_url_list(void) = default; client_url_list(void) = default;
client_url_list(const raii::string_base& homeserver); client_url_list(const session_info&);
client_url_list(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid);
client_url_list(const client_url_list&) = default; client_url_list(const client_url_list&) = default;
client_url_list(client_url_list&&) = default; client_url_list(client_url_list&&) = default;
client_url_list& operator=(const client_url_list&) = default; client_url_list& operator=(const client_url_list&) = default;
client_url_list& operator=(client_url_list&&) = default; client_url_list& operator=(client_url_list&&) = default;
static raii::string stat_whoami(const raii::string_base& homeserver, const raii::string_base& access_token);
static raii::string login(const raii::string_base& homeserver);
const raii::string& create_room(void)const; const raii::string& create_room(void)const;
const raii::string& file_upload(void)const; const raii::string& file_upload(void)const;
const raii::string& room_list(void)const; const raii::string& room_list(void)const;
const raii::string& alias_lookup(void)const; const raii::string& alias_lookup(void)const;
const raii::string& whoami(void)const;
const raii::string& displayname(void)const; const raii::string& displayname(void)const;
const raii::string& profile_picture(void)const; const raii::string& profile_picture(void)const;
raii::string file_download(const raii::string_base& homeserver, const raii::string_base& mediaid); raii::string file_download(const raii::string_base& homeserver, const raii::string_base& mediaid);
raii::string file_thumbnail(const raii::string_base& homeserver, const raii::string_base& fileurl, int width, int height, const raii::string_base& method)const; raii::string file_thumbnail(const raii::string_base& homeserver, const raii::string_base& fileurl, int width, int height, const raii::string_base& method)const;
raii::string logout(const raii::string_base& homeserver, const raii::string_base& access_token)const;
raii::string sync(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& next_batch, const raii::string_base& timeout)const;
raii::string power_level(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid)const; raii::string power_level(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& roomid)const;
raii::string presence(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid)const; raii::string presence(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid)const;
raii::string password(const raii::string_base& homeserver, const raii::string_base& access_token)const;
void repopulate_accesstoken(const raii::string_base& homeserver, const raii::string_base& access_token); void repopulate(const session_info&);
void repopulate_userid(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid); void invalidate(void);
void repopulate(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid);
void invalidate_accesstoken(void);
private: private:
void _initial_populate(const raii::string_base& homeserver);
static raii::string get_server_media_string(const raii::string_base& url); static raii::string get_server_media_string(const raii::string_base& url);
static constexpr const char* s_proto = "https://";
static constexpr const char* s_revision = "r0";
}; };
} }

View File

@ -0,0 +1,33 @@
/**
This file is a part of rexy's matrix client
Copyright (C) 2019 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MATRIX_REST_SESSION_URLS_HPP
#define MATRIX_REST_SESSION_URLS_HPP
#include "matrix/rest/urls_common.hpp"
#include "matrix/session_info.hpp"
#include "raii/string.hpp"
namespace matrix::rest::session_urls{
raii::string login(const session_info&);
raii::string logout(const session_info&);
raii::string password(const session_info&);
raii::string whoami(const session_info&);
}
#endif

View File

@ -0,0 +1,29 @@
/**
This file is a part of rexy's matrix client
Copyright (C) 2019 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MATRIX_REST_SYNC_URLS_HPP
#define MATRIX_REST_SYNC_URLS_HPP
#include "matrix/rest/urls_common.hpp"
#include "raii/string.hpp"
namespace matrix::rest::sync_urls{
raii::string sync(const session_info&, const raii::rjp_string& batch, const raii::string& timeout);
}
#endif

View File

@ -0,0 +1,33 @@
/**
This file is a part of rexy's matrix client
Copyright (C) 2019 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MATRIX_REST_URLS_COMMON_HPP
#define MATRIX_REST_URLS_COMMON_HPP
#include "raii/string_base.hpp"
namespace matrix::rest{
constexpr raii::static_string proto(void){
return "https://"_ss;
}
constexpr raii::static_string revision(void){
return "r0"_ss;
}
}
#endif

View File

@ -23,7 +23,7 @@
#include "matrix/upload_info.hpp" #include "matrix/upload_info.hpp"
#include "raii/string.hpp" #include "raii/string.hpp"
#include "raii/rjp_string.hpp" #include "raii/rjp_string.hpp"
#include "matrix/room_url_list.hpp" #include "matrix/rest/room_url_list.hpp"
#include "matrix/iterable.hpp" #include "matrix/iterable.hpp"
#include "matrix/netreturn.hpp" #include "matrix/netreturn.hpp"
@ -38,8 +38,8 @@ namespace matrix{
room_url_list m_urls; room_url_list m_urls;
public: public:
roomcxn(const std::shared_ptr<internal::session_info>&, const raii::string_base& roomid); roomcxn(const std::shared_ptr<session_info>&, const raii::string_base& roomid);
roomcxn(const std::shared_ptr<internal::session_info>& ses, raii::string&& roomid); roomcxn(const std::shared_ptr<session_info>& ses, raii::string&& roomid);
roomcxn(const roomcxn&) = default; roomcxn(const roomcxn&) = default;
roomcxn(roomcxn&&) = default; roomcxn(roomcxn&&) = default;

View File

@ -21,16 +21,14 @@
#include "raii/string.hpp" #include "raii/string.hpp"
#include "raii/rjp_string.hpp" #include "raii/rjp_string.hpp"
#include "matrix/client_url_list.hpp"
namespace matrix::internal{ namespace matrix{
struct session_info{ struct session_info{
raii::string useragent; //useragent to identify our application raii::string useragent; //useragent to identify our application
raii::string homeserver; //name of our homeserver raii::string homeserver; //name of our homeserver
raii::rjp_string access_token; //authentication raii::rjp_string access_token; //authentication
raii::string auth_header; raii::string auth_header;
raii::rjp_string userid; //userid including homeserver raii::rjp_string userid; //userid including homeserver
client_url_list urls;
}; };
} }

View File

@ -40,7 +40,7 @@ namespace matrix{
raii::rjp_string m_next_batch; //string which tracks where we are in the server history raii::rjp_string m_next_batch; //string which tracks where we are in the server history
public: public:
syncer(const std::shared_ptr<internal::session_info>&); syncer(const std::shared_ptr<session_info>&);
//Copy and move ctor //Copy and move ctor
syncer(const syncer& b) = default; syncer(const syncer& b) = default;

View File

@ -18,7 +18,7 @@ ifeq ($(OS),Windows_NT)
WINDOWS::=1 WINDOWS::=1
endif endif
SOURCE_DIRS::=src/raii src/matrix SOURCE_DIRS::=src/raii src/matrix src/matrix/rest
OBJDIR::=obj OBJDIR::=obj
DEPDIR::=$(OBJDIR)/dep DEPDIR::=$(OBJDIR)/dep
LIBDIR::=lib LIBDIR::=lib

View File

@ -27,39 +27,40 @@
namespace matrix{ namespace matrix{
//Ctor //Ctor
client::client(const std::shared_ptr<internal::session_info>& ses): client::client(const std::shared_ptr<session_info>& ses):
connection(ses){} connection(ses),
m_urls(std::make_shared<matrix::rest::client_url_list>(*ses)){}
//networked setter //networked setter
netreturn<void> client::set_display_name(const raii::string_base& newname){ netreturn<void> client::set_display_name(const raii::string_base& newname){
_put_curl(json::_displayname_set(newname), m_ses->urls.displayname(), raii::curl_llist()); _put_curl(json::_displayname_set(newname), m_urls->displayname(), raii::curl_llist());
return netreturn<void>(raii::string(), raii::string(), http_status()); return netreturn<void>(raii::string(), raii::string(), http_status());
} }
netreturn<void> client::set_profile_picture(const raii::string_base& media_url){ netreturn<void> client::set_profile_picture(const raii::string_base& media_url){
_put_curl(json::_avatar_set(media_url), m_ses->urls.profile_picture(), raii::curl_llist()); _put_curl(json::_avatar_set(media_url), m_urls->profile_picture(), raii::curl_llist());
return netreturn<void>(raii::string(), raii::string(), http_status()); return netreturn<void>(raii::string(), raii::string(), http_status());
} }
netreturn<void> client::set_presence(const raii::string_base& status){ netreturn<void> client::set_presence(const raii::string_base& status){
_put_curl(json::_presence_set(status), m_ses->urls.presence(m_ses->homeserver, m_ses->access_token, m_ses->userid), raii::curl_llist()); _put_curl(json::_presence_set(status), m_urls->presence(m_ses->homeserver, m_ses->access_token, m_ses->userid), raii::curl_llist());
return netreturn<void>(raii::string(), raii::string(), http_status()); return netreturn<void>(raii::string(), raii::string(), http_status());
} }
netreturn<raii::rjp_string> client::get_presence(const raii::string_base& userid){ netreturn<raii::rjp_string> client::get_presence(const raii::string_base& userid){
return _get_and_find(m_ses->urls.presence(m_ses->homeserver, m_ses->access_token, userid), json::client::presence()); return _get_and_find(m_urls->presence(m_ses->homeserver, m_ses->access_token, userid), json::client::presence());
} }
//networked getter //networked getter
netreturn<raii::rjp_string> client::get_display_name(void)const{ netreturn<raii::rjp_string> client::get_display_name(void)const{
return _get_and_find(m_ses->urls.displayname(), json::client::displayname()); return _get_and_find(m_urls->displayname(), json::client::displayname());
} }
netreturn<raii::rjp_string> client::get_profile_picture(void)const{ netreturn<raii::rjp_string> client::get_profile_picture(void)const{
return _get_and_find(m_ses->urls.profile_picture(), json::client::avatarurl()); return _get_and_find(m_urls->profile_picture(), json::client::avatarurl());
} }
netreturn<raii::rjp_string> client::room_alias_to_id(const raii::string_base& alias)const{ netreturn<raii::rjp_string> client::room_alias_to_id(const raii::string_base& alias)const{
auto tmp = m_curl.encode(alias, alias.length()); auto tmp = m_curl.encode(alias, alias.length());
return _get_and_find(raii::string(m_ses->urls.alias_lookup() + tmp), json::client::roomid()); return _get_and_find(raii::string(m_urls->alias_lookup() + tmp), json::client::roomid());
} }
netreturn<std::vector<raii::rjp_string>> client::list_rooms(void)const{ netreturn<std::vector<raii::rjp_string>> client::list_rooms(void)const{
raii::string reply = _get_curl(m_ses->urls.room_list()); raii::string reply = _get_curl(m_urls->room_list());
if(!reply) if(!reply)
return _create_netreturn(reply, http_status()); return _create_netreturn(reply, http_status());
@ -80,7 +81,7 @@ namespace matrix{
//room membership //room membership
netreturn<raii::rjp_string> client::create_room(const raii::string_base& name, const raii::string_base& alias)const{ netreturn<raii::rjp_string> client::create_room(const raii::string_base& name, const raii::string_base& alias)const{
return _post_and_find(json::_create_room(name, alias), m_ses->urls.create_room(), raii::curl_llist(), json::client::roomid()); return _post_and_find(json::_create_room(name, alias), m_urls->create_room(), raii::curl_llist(), json::client::roomid());
} }
roomcxn client::spawn_room(const raii::string_base& roomid)const{ roomcxn client::spawn_room(const raii::string_base& roomid)const{
return roomcxn(m_ses, roomid); return roomcxn(m_ses, roomid);
@ -138,7 +139,7 @@ namespace matrix{
} }
m_curl.setopt(CURLOPT_HEADERFUNCTION, _thumbnail_header_callback); m_curl.setopt(CURLOPT_HEADERFUNCTION, _thumbnail_header_callback);
m_curl.setopt(CURLOPT_HEADERDATA, &reply_header); m_curl.setopt(CURLOPT_HEADERDATA, &reply_header);
i.data = _get_curl_binary(m_ses->urls.file_thumbnail(m_ses->homeserver, info.m_fileurl, info.m_thumb.m_width, info.m_thumb.m_height, "crop"_ss)); i.data = _get_curl_binary(m_urls->file_thumbnail(m_ses->homeserver, info.m_fileurl, info.m_thumb.m_width, info.m_thumb.m_height, "crop"_ss));
m_curl.setopt(CURLOPT_HEADERFUNCTION, NULL); m_curl.setopt(CURLOPT_HEADERFUNCTION, NULL);
m_curl.setopt(CURLOPT_HEADERDATA, NULL); m_curl.setopt(CURLOPT_HEADERDATA, NULL);
if(!i.data) if(!i.data)
@ -159,7 +160,7 @@ namespace matrix{
return create_thumbnail(static_cast<uploaded_image&>(info)); return create_thumbnail(static_cast<uploaded_image&>(info));
} }
raii::binary client::download_file(const raii::string_base& url){ raii::binary client::download_file(const raii::string_base& url){
return _get_curl_binary(m_ses->urls.file_download(m_ses->homeserver, url)); return _get_curl_binary(m_urls->file_download(m_ses->homeserver, url));
} }
/******************************* /*******************************
@ -189,7 +190,7 @@ namespace matrix{
m_curl.setreaddata(&upload_data); m_curl.setreaddata(&upload_data);
m_curl.setopt(CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)upload_data.len); m_curl.setopt(CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)upload_data.len);
m_curl.setopt(CURLOPT_INFILESIZE_LARGE, (curl_off_t)upload_data.len); m_curl.setopt(CURLOPT_INFILESIZE_LARGE, (curl_off_t)upload_data.len);
m_curl.seturl(m_ses->urls.file_upload()); m_curl.seturl(m_urls->file_upload());
m_curl.setheader(header); m_curl.setheader(header);
m_curl.setwritefun(_reply_curl_callback); m_curl.setwritefun(_reply_curl_callback);
m_curl.setwritedata(&fileurl); m_curl.setwritedata(&fileurl);

View File

@ -1,115 +0,0 @@
/**
This file is a part of rexy's matrix client
Copyright (C) 2019 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "matrix/client_url_list.hpp"
#include "raii/string.hpp"
#include "raii/util.hpp"
namespace matrix{
client_url_list::client_url_list(const raii::string_base& homeserver){
_initial_populate(homeserver);
}
client_url_list::client_url_list(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid){
repopulate(homeserver, access_token, userid);
}
void client_url_list::repopulate_accesstoken(const raii::string_base& homeserver, const raii::string_base& access_token){
m_create_room = s_proto + homeserver + "/_matrix/client/r0/createRoom?access_token=" + access_token;
m_file_upload = s_proto + homeserver + "/_matrix/media/r0/upload?access_token=" + access_token;
m_room_list = s_proto + homeserver + "/_matrix/client/r0/joined_rooms?access_token=" + access_token;
m_whoami = stat_whoami(homeserver, access_token);
}
void client_url_list::repopulate_userid(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid){
m_displayname = s_proto + homeserver + "/_matrix/client/r0/profile/" + userid + "/displayname?access_token=" + access_token;
m_profile_picture = s_proto + homeserver + "/_matrix/client/r0/profile/" + userid + "/avatar_url?access_token=" + access_token;
}
void client_url_list::repopulate(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid){
_initial_populate(homeserver);
repopulate_accesstoken(homeserver, access_token);
repopulate_userid(homeserver, access_token, userid);
}
void client_url_list::invalidate_accesstoken(void){
m_create_room.reset();
m_file_upload.reset();
m_room_list.reset();
m_whoami.reset();
m_displayname.reset();
m_profile_picture.reset();
}
const raii::string& client_url_list::create_room(void)const{
return m_create_room;
}
const raii::string& client_url_list::file_upload(void)const{
return m_file_upload;
}
const raii::string& client_url_list::room_list(void)const{
return m_room_list;
}
raii::string client_url_list::login(const raii::string_base& homeserver){
return raii::string(s_proto + homeserver + "/_matrix/client/r0/login");
}
raii::string client_url_list::stat_whoami(const raii::string_base& homeserver, const raii::string_base& access_token){
return raii::string(s_proto + homeserver + "/_matrix/client/r0/account/whoami?access_token=" + access_token);
}
const raii::string& client_url_list::alias_lookup(void)const{
return m_alias_lookup;
}
const raii::string& client_url_list::whoami(void)const{
return m_whoami;
}
const raii::string& client_url_list::displayname(void)const{
return m_displayname;
}
const raii::string& client_url_list::profile_picture(void)const{
return m_profile_picture;
}
raii::string client_url_list::file_download(const raii::string_base& homeserver, const raii::string_base& fileurl){
raii::string media = get_server_media_string(fileurl);
if(!media) return {};
return raii::string(s_proto + homeserver + "/_matrix/media/r0/download/" + media);
}
raii::string client_url_list::file_thumbnail(const raii::string_base& homeserver, const raii::string_base& fileurl, int width, int height, const raii::string_base& method)const{
raii::string media = get_server_media_string(fileurl);
if(!media) return {};
return raii::string(s_proto + homeserver + "/_matrix/media/r0/thumbnail/" + media + "?width=" + raii::itostr(width) + "&height=" + raii::itostr(height) + "&method=" + method);
}
raii::string client_url_list::logout(const raii::string_base& homeserver, const raii::string_base& access_token)const{
return raii::string(s_proto + homeserver + "/_matrix/client/r0/logout?access_token=" + access_token);
}
raii::string client_url_list::sync(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& next_batch, const raii::string_base& timeout)const{
if(!next_batch)
return raii::string(s_proto + homeserver + "/_matrix/client/r0/sync?access_token=" + access_token + "&timeout=" + timeout);
return raii::string(s_proto + homeserver + "/_matrix/client/r0/sync?access_token=" + access_token + "&timeout=" + timeout + "&since=" + next_batch);
}
raii::string client_url_list::presence(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid)const{
return raii::string(s_proto + homeserver + "/_matrix/client/r0/presence/" + userid + "/status?access_token=" + access_token);
}
raii::string client_url_list::password(const raii::string_base& homeserver, const raii::string_base& access_token)const{
return raii::string(s_proto + homeserver + "/_matrix/client/r0/account/password?access_token=" + access_token);
}
void client_url_list::_initial_populate(const raii::string_base& homeserver){
m_alias_lookup = s_proto + homeserver + "/_matrix/client/r0/directory/room/";
}
raii::string client_url_list::get_server_media_string(const raii::string_base& url){
if(!url || strncmp(url.get(), "mxc://", 6))
return {};
return raii::string(url.get()+6, url.length()-6);
}
}

View File

@ -24,7 +24,7 @@
namespace matrix{ namespace matrix{
connection::connection(const std::shared_ptr<internal::session_info>& ses): connection::connection(const std::shared_ptr<session_info>& ses):
m_curl(), m_curl(),
m_ses(ses) m_ses(ses)
{ {

View File

@ -0,0 +1,82 @@
/**
This file is a part of rexy's matrix client
Copyright (C) 2019 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "matrix/rest/client_url_list.hpp"
#include "raii/string.hpp"
#include "raii/util.hpp"
namespace matrix::rest{
client_url_list::client_url_list(const session_info& session){
repopulate(session);
}
void client_url_list::repopulate(const session_info& session){
m_create_room = matrix::rest::proto() + session.homeserver + "/_matrix/client/r0/createRoom?access_token=" + session.access_token;
m_file_upload = matrix::rest::proto() + session.homeserver + "/_matrix/media/r0/upload?access_token=" + session.access_token;
m_room_list = matrix::rest::proto() + session.homeserver + "/_matrix/client/r0/joined_rooms?access_token=" + session.access_token;
m_displayname = matrix::rest::proto() + session.homeserver + "/_matrix/client/r0/profile/" + session.userid + "/displayname?access_token=" + session.access_token;
m_profile_picture = matrix::rest::proto() + session.homeserver + "/_matrix/client/r0/profile/" + session.userid + "/avatar_url?access_token=" + session.access_token;
m_alias_lookup = matrix::rest::proto() + session.homeserver + "/_matrix/client/r0/directory/room/";
}
void client_url_list::invalidate(void){
m_create_room.reset();
m_file_upload.reset();
m_room_list.reset();
m_displayname.reset();
m_profile_picture.reset();
m_alias_lookup.reset();
}
const raii::string& client_url_list::create_room(void)const{
return m_create_room;
}
const raii::string& client_url_list::file_upload(void)const{
return m_file_upload;
}
const raii::string& client_url_list::room_list(void)const{
return m_room_list;
}
const raii::string& client_url_list::alias_lookup(void)const{
return m_alias_lookup;
}
const raii::string& client_url_list::displayname(void)const{
return m_displayname;
}
const raii::string& client_url_list::profile_picture(void)const{
return m_profile_picture;
}
raii::string client_url_list::file_download(const raii::string_base& homeserver, const raii::string_base& fileurl){
raii::string media = get_server_media_string(fileurl);
if(!media) return {};
return raii::string(matrix::rest::proto() + homeserver + "/_matrix/media/r0/download/" + media);
}
raii::string client_url_list::file_thumbnail(const raii::string_base& homeserver, const raii::string_base& fileurl, int width, int height, const raii::string_base& method)const{
raii::string media = get_server_media_string(fileurl);
if(!media) return {};
return raii::string(matrix::rest::proto() + homeserver + "/_matrix/media/r0/thumbnail/" + media + "?width=" + raii::itostr(width) + "&height=" + raii::itostr(height) + "&method=" + method);
}
raii::string client_url_list::presence(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid)const{
return raii::string(matrix::rest::proto() + homeserver + "/_matrix/client/r0/presence/" + userid + "/status?access_token=" + access_token);
}
raii::string client_url_list::get_server_media_string(const raii::string_base& url){
if(!url || strncmp(url.get(), "mxc://", 6))
return {};
return raii::string(url.get()+6, url.length()-6);
}
}

View File

@ -16,7 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "matrix/room_url_list.hpp" #include "matrix/rest/room_url_list.hpp"
#include "raii/util.hpp" #include "raii/util.hpp"
namespace matrix{ namespace matrix{

View File

@ -0,0 +1,34 @@
/**
This file is a part of rexy's matrix client
Copyright (C) 2019 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "matrix/rest/session_urls.hpp"
namespace matrix::rest::session_urls{
raii::string login(const session_info& session){
return raii::string(matrix::rest::proto() + session.homeserver + "/_matrix/client/r0/login");
}
raii::string logout(const session_info& session){
return raii::string(matrix::rest::proto() + session.homeserver + "/_matrix/client/r0/logout?access_token=" + session.access_token);
}
raii::string password(const session_info& session){
return raii::string(matrix::rest::proto() + session.homeserver + "/_matrix/client/r0/account/password?access_token=" + session.access_token);
}
raii::string whoami(const session_info& session){
return raii::string(matrix::rest::proto() + session.homeserver + "/_matrix/client/r0/account/whoami?access_token=" + session.access_token);
}
}

View File

@ -0,0 +1,27 @@
/**
This file is a part of rexy's matrix client
Copyright (C) 2019 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "matrix/rest/session_urls.hpp"
namespace matrix::rest::sync_urls{
raii::string sync(const session_info& session, const raii::rjp_string& next_batch, const raii::string& timeout){
if(!next_batch)
return raii::string(matrix::rest::proto() + session.homeserver + "/_matrix/client/r0/sync?access_token=" + session.access_token + "&timeout=" + timeout);
return raii::string(matrix::rest::proto() + session.homeserver + "/_matrix/client/r0/sync?access_token=" + session.access_token + "&timeout=" + timeout + "&since=" + next_batch);
}
}

View File

@ -26,9 +26,9 @@
namespace matrix{ namespace matrix{
roomcxn::roomcxn(const std::shared_ptr<internal::session_info>& ses, const raii::string_base& roomid): roomcxn::roomcxn(const std::shared_ptr<session_info>& ses, const raii::string_base& roomid):
roomcxn(ses, raii::string(roomid)){} roomcxn(ses, raii::string(roomid)){}
roomcxn::roomcxn(const std::shared_ptr<internal::session_info>& ses, raii::string&& roomid): roomcxn::roomcxn(const std::shared_ptr<session_info>& ses, raii::string&& roomid):
connection(ses), connection(ses),
m_roomid(std::move(roomid)), m_roomid(std::move(roomid)),
m_urls(ses->homeserver, ses->access_token, m_curl.encode(m_roomid), ses->userid){} m_urls(ses->homeserver, ses->access_token, m_curl.encode(m_roomid), ses->userid){}

View File

@ -23,6 +23,7 @@
#include "raii/string_base.hpp" #include "raii/string_base.hpp"
#include "matrix/fat_strings.hpp" #include "matrix/fat_strings.hpp"
#include "matrix/json_targets.hpp" #include "matrix/json_targets.hpp"
#include "matrix/rest/session_urls.hpp"
namespace matrix{ namespace matrix{
@ -31,9 +32,9 @@ namespace matrix{
} }
session::session(void): session::session(void):
connection(std::make_shared<internal::session_info>()){} connection(std::make_shared<session_info>()){}
session::session(const auth_data& auth): session::session(const auth_data& auth):
connection(std::make_shared<internal::session_info>()) connection(std::make_shared<session_info>())
{ {
_populate_session_info(auth); _populate_session_info(auth);
_set_curl_defaults(m_ses->useragent); _set_curl_defaults(m_ses->useragent);
@ -70,7 +71,7 @@ namespace matrix{
return _do_login(username, pass); return _do_login(username, pass);
} }
netreturn<void> session::logout(void){ netreturn<void> session::logout(void){
raii::string reply = _post_curl(raii::string(), m_ses->urls.logout(m_ses->homeserver, m_ses->access_token), raii::curl_llist()); raii::string reply = _post_curl(raii::string(), rest::session_urls::logout(*m_ses), raii::curl_llist());
return _create_netreturn(reply, http_status()); return _create_netreturn(reply, http_status());
} }
@ -78,7 +79,7 @@ namespace matrix{
return m_valid; return m_valid;
} }
netreturn<void> session::change_password(const raii::string_base& oldpass, const raii::string_base& newpass){ netreturn<void> session::change_password(const raii::string_base& oldpass, const raii::string_base& newpass){
raii::string reply = _post_curl(json::_empty(), m_ses->urls.password(m_ses->homeserver, m_ses->access_token), raii::curl_llist()); raii::string reply = _post_curl(json::_empty(), rest::session_urls::password(*m_ses), raii::curl_llist());
if(!reply) if(!reply)
return _create_netreturn(reply, http_status()); return _create_netreturn(reply, http_status());
raii::rjp_ptr root(rjp_parse(reply)); raii::rjp_ptr root(rjp_parse(reply));
@ -89,7 +90,7 @@ namespace matrix{
//attempt to change password via username/password login //attempt to change password via username/password login
RJP_search_res res = rjp_search_member(root.get(), json::session::session(), 0); RJP_search_res res = rjp_search_member(root.get(), json::session::session(), 0);
raii::string request = json::_change_psk_password(m_ses->userid, newpass, oldpass, raii::rjp_string(res.value)); raii::string request = json::_change_psk_password(m_ses->userid, newpass, oldpass, raii::rjp_string(res.value));
reply = _post_curl(request, m_ses->urls.password(m_ses->homeserver, m_ses->access_token), raii::curl_llist()); reply = _post_curl(request, rest::session_urls::password(*m_ses), raii::curl_llist());
return _create_netreturn(reply, http_status()); return _create_netreturn(reply, http_status());
} }
client session::spawn_client(void)const{ client session::spawn_client(void)const{
@ -104,39 +105,35 @@ namespace matrix{
m_ses->homeserver.reset(); m_ses->homeserver.reset();
m_ses->access_token.reset(); m_ses->access_token.reset();
m_ses->userid.reset(); m_ses->userid.reset();
m_ses->urls.invalidate_accesstoken();
} }
netreturn<void> session::_do_login(const raii::string_base& username, const raii::string_base& pass){ netreturn<void> session::_do_login(const raii::string_base& username, const raii::string_base& pass){
auto reply = _get_curl(client_url_list::stat_whoami(m_ses->homeserver, m_ses->access_token)); auto reply = _get_curl(rest::session_urls::whoami(*m_ses));
netreturn<void> retval = _create_netreturn(reply, http_status()); netreturn<void> retval = _create_netreturn(reply, http_status());
if(!retval.ok()){ if(!retval.ok()){
if(!username || !pass){ if(!username || !pass){
m_valid = false; m_valid = false;
return retval; return retval;
} }
auto newtoken = _get_new_access_token(username, pass, client_url_list::login(m_ses->homeserver)); auto newtoken = _get_new_access_token(username, pass, rest::session_urls::login(*m_ses));
auto& token = newtoken.value().first; auto& token = newtoken.value().first;
auto& id = newtoken.value().second; auto& id = newtoken.value().second;
if(token && id){ if(token && id){
m_ses->access_token = std::move(token); m_ses->access_token = std::move(token);
m_ses->auth_header = create_auth_header(m_ses->access_token); m_ses->auth_header = create_auth_header(m_ses->access_token);
m_ses->userid = std::move(id); m_ses->userid = std::move(id);
m_ses->urls.repopulate(m_ses->homeserver, m_ses->access_token, m_ses->userid);
m_valid = true; m_valid = true;
}else{ }else{
m_valid = false; m_valid = false;
} }
return netreturn<void>(std::move(newtoken.mxerror()), std::move(newtoken.mxerrorcode()), newtoken.httpstatus()); return netreturn<void>(std::move(newtoken.mxerror()), std::move(newtoken.mxerrorcode()), newtoken.httpstatus());
}else{ }else{
m_ses->urls.repopulate_accesstoken(m_ses->homeserver, m_ses->access_token);
netreturn<raii::rjp_string> uid = _get_userid(); netreturn<raii::rjp_string> uid = _get_userid();
if(!uid.ok()){ if(!uid.ok()){
invalidate(); invalidate();
return netreturn<void>(std::move(uid.mxerror()), std::move(uid.mxerrorcode()), uid.httpstatus()); return netreturn<void>(std::move(uid.mxerror()), std::move(uid.mxerrorcode()), uid.httpstatus());
} }
m_ses->userid = std::move(uid.value()); m_ses->userid = std::move(uid.value());
m_ses->urls.repopulate_userid(m_ses->homeserver, m_ses->access_token, m_ses->userid);
m_valid = true; m_valid = true;
return retval; return retval;
} }
@ -155,7 +152,7 @@ namespace matrix{
return reply; return reply;
} }
netreturn<raii::rjp_string> session::_get_userid(void){ netreturn<raii::rjp_string> session::_get_userid(void){
return _get_and_find(client_url_list::stat_whoami(m_ses->homeserver, m_ses->access_token), json::session::userid()); return _get_and_find(rest::session_urls::whoami(*m_ses), json::session::userid());
} }
netreturn<std::pair<raii::rjp_string,raii::rjp_string>> session::_get_new_access_token(const raii::string_base& name, const raii::string_base& pass, const raii::string_base& loginurl){ netreturn<std::pair<raii::rjp_string,raii::rjp_string>> session::_get_new_access_token(const raii::string_base& name, const raii::string_base& pass, const raii::string_base& loginurl){
raii::string reply = _request_access_token(name, pass, loginurl); raii::string reply = _request_access_token(name, pass, loginurl);

View File

@ -20,13 +20,14 @@
#include "raii/string_base.hpp" #include "raii/string_base.hpp"
#include "raii/rjp_ptr.hpp" #include "raii/rjp_ptr.hpp"
#include "raii/util.hpp" #include "raii/util.hpp"
#include "matrix/rest/sync_urls.hpp"
namespace matrix{ namespace matrix{
syncer::syncer(const std::shared_ptr<internal::session_info>& ses): syncer::syncer(const std::shared_ptr<session_info>& ses):
connection(ses){} connection(ses){}
netreturn<sync::response> syncer::sync(size_t timeout){ netreturn<sync::response> syncer::sync(size_t timeout){
raii::string reply = _get_curl(m_ses->urls.sync(m_ses->homeserver, m_ses->access_token, m_next_batch, raii::itostr(timeout))); raii::string reply = _get_curl(rest::sync_urls::sync(*m_ses, m_next_batch, raii::itostr(timeout)));
if(!reply) if(!reply)
return netreturn<sync::response>(raii::string(), raii::string(), http_status(), {nullptr}); return netreturn<sync::response>(raii::string(), raii::string(), http_status(), {nullptr});