Authorized endpoints and updated README

This commit is contained in:
kdeng00
2019-09-25 23:03:38 -04:00
parent 698ccf9099
commit 32ed611112
13 changed files with 563 additions and 459 deletions
+7 -3
View File
@@ -1,6 +1,6 @@
# Icarus
Icarus is a music streaming API Server that interacts with [Mear](https://github.com/amazing-username/mear).
Icarus is a music streaming API Server, allowing access to stream your personal music collection
### Interfacing With Icarus
@@ -8,6 +8,7 @@ One can interface with Icarus the music server either by:
* [Mear](https://github.com/amazing-username/mear) - Partially implemented (under development)
* [IcarusDownloadManager](https://github.com/amazing-username/IcarusDownloadManager)
* Create your own client to interact with the API
@@ -19,6 +20,9 @@ One can interface with Icarus the music server either by:
* [json](https://www.github.com/nlohmann/json)
* [cpr](https://www.github.com/whoshuu/cpr)
* [TagLib](https://github.com/taglib/taglib)
* [jwt-cpp](https://github.com/Thalhammer/jwt-cpp)
* [libbcrypt](https://github.com/rg3/libbcrypt)
* [oatpp](https://github.com/oatpp/oatpp)
![image](https://user-images.githubusercontent.com/14333136/56252069-28532d00-6084-11e9-896d-1a3c378014ef.png)
@@ -117,7 +121,7 @@ In order for Database functionality to be operable, there must be a valid connec
```
* server - The address or domain name of the MySQL server
* database - The database name
* user - Username
* username - Username
* password - Self-explanatory
The only requirement of the User is that the user should have full permissions to the database as well as permissions to create a database. Other than that, that is all that is required.
@@ -135,7 +139,7 @@ Prior to starting the API, the database must be created. The following tables ar
There is a MySQL script to create these tables, it can be found in the [Scripts/MySQL/](https://github.com/amazing-username/Icarus/blob/master/Scripts/MySQL/create_database.sql) directory. Just merely execute:
```shell
mysql -u *dblikedecibel* -p < Scripts/MySQL/create_database.sql
mysql -u dblikedecibel -p < Scripts/MySQL/create_database.sql
```
From this point the database has been successfully created. Metadata and song filesystem locations can be saved.
+5 -6
View File
@@ -6,22 +6,21 @@
#include "oatpp/core/data/stream/FileStream.hpp"
#include "oatpp/web/protocol/http/outgoing/ChunkedBody.hpp"
namespace callback
namespace callback {
class StreamCallback : public oatpp::data::stream::ReadCallback
{
class StreamCallback : public oatpp::data::stream::ReadCallback
{
public:
public:
StreamCallback();
StreamCallback(const std::string&);
oatpp::data::v_io_size read(void*, oatpp::data::v_io_size);
private:
private:
std::string m_songPath;
long m_bytesRead;
long m_counter;
long m_fileSize;
};
};
}
#endif
+6 -7
View File
@@ -8,12 +8,11 @@
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/web/server/HttpConnectionHandler.hpp"
namespace component
{
namespace component {
class AppComponent
{
public:
class AppComponent
{
public:
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
return oatpp::network::server::SimpleTCPConnectionProvider::createShared(5002);
}());
@@ -31,8 +30,8 @@ namespace component
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
return oatpp::parser::json::mapping::ObjectMapper::createShared();
}());
private:
};
private:
};
}
#endif
+18 -8
View File
@@ -20,17 +20,17 @@
#include "database/AlbumRepository.h"
#include "dto/AlbumDto.hpp"
#include "manager/AlbumManager.h"
#include "manager/TokenManager.h"
#include "model/Models.h"
#include "type/Scopes.h"
#include "type/AlbumFilter.h"
namespace fs = std::filesystem;
namespace controller
namespace controller {
class AlbumController : public oatpp::web::server::api::ApiController
{
class AlbumController : public oatpp::web::server::api::ApiController
{
public:
public:
AlbumController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
{ }
@@ -45,6 +45,12 @@ namespace controller
ENDPOINT("GET", "/api/v1/album", albumRecords,
REQUEST(std::shared_ptr<IncomingRequest>, request))
{
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveAlbum), Status::CODE_403, "Not allowed");
std::cout << "starting process of retrieving album" << std::endl;
database::AlbumRepository albRepo(m_bConf);
auto albsDb = albRepo.retrieveRecords();
@@ -64,7 +70,12 @@ namespace controller
// endpoint for retrieving single album record by the album id in json format
ENDPOINT("GET", "/api/v1/album/{id}", albumRecord,
PATH(Int32, id)) {
REQUEST(std::shared_ptr<IncomingRequest>, request), PATH(Int32, id)) {
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveAlbum), Status::CODE_403, "Not allowed");
database::AlbumRepository albRepo(m_bConf);
model::Album albDb(id);
@@ -83,10 +94,9 @@ namespace controller
}
#include OATPP_CODEGEN_END(ApiController)
private:
private:
std::string m_exe_path;
model::BinaryPath m_bConf;
const long m_dataSize = std::numeric_limits<long long int>::max();
};
};
}
#endif
+18 -8
View File
@@ -20,17 +20,17 @@
#include "database/ArtistRepository.h"
#include "dto/ArtistDto.hpp"
#include "manager/ArtistManager.h"
#include "manager/TokenManager.h"
#include "model/Models.h"
#include "type/Scopes.h"
#include "type/ArtistFilter.h"
namespace fs = std::filesystem;
namespace controller
namespace controller {
class ArtistController : public oatpp::web::server::api::ApiController
{
class ArtistController : public oatpp::web::server::api::ApiController
{
public:
public:
ArtistController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
{ }
@@ -45,6 +45,12 @@ namespace controller
ENDPOINT("GET", "/api/v1/artist", artistRecords,
REQUEST(std::shared_ptr<IncomingRequest>, request))
{
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveArtist), Status::CODE_403, "Not allowed");
std::cout << "starting process of retrieving artist" << std::endl;
database::ArtistRepository artRepo(m_bConf);
auto artsDb = artRepo.retrieveRecords();
@@ -63,7 +69,12 @@ namespace controller
// endpoint for retrieving single artist record by the artist id in json format
ENDPOINT("GET", "/api/v1/artist/{id}", artistRecord,
PATH(Int32, id)) {
REQUEST(std::shared_ptr<IncomingRequest>, request), PATH(Int32, id)) {
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveArtist), Status::CODE_403, "Not allowed");
database::ArtistRepository artRepo(m_bConf);
model::Artist artDb(id);
@@ -81,10 +92,9 @@ namespace controller
}
#include OATPP_CODEGEN_END(ApiController)
private:
private:
std::string m_exe_path;
model::BinaryPath m_bConf;
const long m_dataSize = std::numeric_limits<long long int>::max();
};
};
}
#endif
+23 -21
View File
@@ -26,11 +26,10 @@
namespace fs = std::filesystem;
namespace controller
namespace controller {
class CoverArtController : public oatpp::web::server::api::ApiController
{
class CoverArtController : public oatpp::web::server::api::ApiController
{
public:
public:
CoverArtController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
{ }
@@ -45,6 +44,12 @@ namespace controller
ENDPOINT("GET", "/api/v1/coverart", coverArtRecords,
REQUEST(std::shared_ptr<IncomingRequest>, request))
{
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::downloadCoverArt), Status::CODE_403, "Not allowed");
std::cout << "starting process of retrieving cover art" << std::endl;
database::CoverArtRepository covRepo(m_bConf);
auto covsDb = covRepo.retrieveRecords();
@@ -63,7 +68,12 @@ namespace controller
// endpoint for retrieving single cover art record by the cover art id in json format
ENDPOINT("GET", "/api/v1/coverart/{id}", coverArtRecord,
PATH(Int32, id)) {
REQUEST(std::shared_ptr<IncomingRequest>, request), PATH(Int32, id)) {
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::downloadCoverArt), Status::CODE_403, "Not allowed");
database::CoverArtRepository covRepo(m_bConf);
model::Cover covDb;
@@ -82,25 +92,18 @@ namespace controller
}
ENDPOINT("GET", "/api/v1/coverart/download/{id}", downloadCoverArt,
PATH(Int32, id)) {
REQUEST(std::shared_ptr<IncomingRequest>, request), PATH(Int32, id)) {
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::downloadCoverArt), Status::CODE_403, "Not allowed");
database::CoverArtRepository covRepo(m_bConf);
model::Cover covDb;
covDb.id = id;
covDb = covRepo.retrieveRecord(covDb, type::CoverFilter::id);
/**
std::ifstream fl(covDb.imagePath.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
fl.seekg(0);
std::stringstream buf;
std::copy(std::istreambuf_iterator<char>(fl),
std::istreambuf_iterator<char>(),
std::ostreambuf_iterator<char>(buf));
fl.close();
*/
//auto rawCover = oatpp::String(buf.str().data(), (v_int32)buf.str().size(), true);
auto rawCover = oatpp::base::StrBuffer::loadFromFile(covDb.imagePath.c_str());
auto response = createResponse(Status::CODE_200, rawCover);
@@ -110,10 +113,9 @@ namespace controller
}
#include OATPP_CODEGEN_END(ApiController)
private:
private:
std::string m_exe_path;
model::BinaryPath m_bConf;
const long m_dataSize = std::numeric_limits<long long int>::max();
};
};
}
#endif
+18 -8
View File
@@ -20,17 +20,17 @@
#include "database/GenreRepository.h"
#include "dto/GenreDto.hpp"
#include "manager/GenreManager.h"
#include "manager/YearManager.h"
#include "model/Models.h"
#include "type/Scopes.h"
#include "type/GenreFilter.h"
namespace fs = std::filesystem;
namespace controller
namespace controller {
class GenreController : public oatpp::web::server::api::ApiController
{
class GenreController : public oatpp::web::server::api::ApiController
{
public:
public:
GenreController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
{ }
@@ -45,6 +45,12 @@ namespace controller
ENDPOINT("GET", "/api/v1/genre", genreRecords,
REQUEST(std::shared_ptr<IncomingRequest>, request))
{
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveGenre), Status::CODE_403, "Not allowed");
std::cout << "starting process of retrieving genre" << std::endl;
database::GenreRepository gnrRepo(m_bConf);
auto gnrsDb = gnrRepo.retrieveRecords();
@@ -63,7 +69,12 @@ namespace controller
// endpoint for retrieving single genre record by the genre id in json format
ENDPOINT("GET", "/api/v1/genre/{id}", genreRecord,
PATH(Int32, id)) {
REQUEST(std::shared_ptr<IncomingRequest>, request), PATH(Int32, id)) {
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveGenre), Status::CODE_403, "Not allowed");
database::GenreRepository gnrRepo(m_bConf);
model::Genre gnrDb(id);
@@ -81,10 +92,9 @@ namespace controller
}
#include OATPP_CODEGEN_END(ApiController)
private:
private:
std::string m_exe_path;
model::BinaryPath m_bConf;
const long m_dataSize = std::numeric_limits<long long int>::max();
};
};
}
#endif
+46 -15
View File
@@ -29,11 +29,10 @@
namespace fs = std::filesystem;
namespace controller
namespace controller {
class SongController : public oatpp::web::server::api::ApiController
{
class SongController : public oatpp::web::server::api::ApiController
{
public:
public:
SongController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
{ }
@@ -49,11 +48,8 @@ namespace controller
REQUEST(std::shared_ptr<IncomingRequest>, request))
{
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::upload), Status::CODE_403, "Not allowed");
@@ -87,6 +83,12 @@ namespace controller
ENDPOINT("GET", "/api/v1/song", songRecords,
REQUEST(std::shared_ptr<IncomingRequest>, request))
{
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveSong), Status::CODE_403, "Not allowed");
std::cout << "starting process of retrieving songs" << std::endl;
database::SongRepository songRepo(m_bConf);
auto songsDb = songRepo.retrieveRecords();
@@ -113,12 +115,18 @@ namespace controller
// endpoint for retrieving song record by the song id in json format
ENDPOINT("GET", "/api/v1/song/{id}", songRecord,
PATH(Int32, id)) {
REQUEST(std::shared_ptr<IncomingRequest>, request), PATH(Int32, id)) {
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveSong), Status::CODE_403, "Not allowed");
database::SongRepository songRepo(m_bConf);
model::Song songDb(id);
OATPP_ASSERT_HTTP(songRepo.doesSongExist(songDb, type::SongFilter::id) , Status::CODE_403, "song does not exist");
OATPP_ASSERT_HTTP(songRepo.doesSongExist(songDb, type::SongFilter::id) , Status::CODE_403,
"song does not exist");
std::cout << "song exists" << std::endl;
songDb = songRepo.retrieveRecord(songDb, type::SongFilter::id);
@@ -138,7 +146,12 @@ namespace controller
}
ENDPOINT("GET", "/api/v1/song/data/{id}", downloadSong,
PATH(Int32, id)) {
REQUEST(std::shared_ptr<IncomingRequest>, request), PATH(Int32, id)) {
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::download), Status::CODE_403, "Not allowed");
database::SongRepository songRepo(m_bConf);
model::Song songDb(id);
@@ -152,10 +165,15 @@ namespace controller
return response;
}
// TODO: create endpoint for updating songs
ENDPOINT("UPDATE", "/api/v1/song/{id}", songUpdate,
REQUEST(std::shared_ptr<IncomingRequest>, request),
BODY_DTO(dto::SongDto::ObjectWrapper, songDto), PATH(Int32, id)) {
songDto->id = id;
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::updateSong), Status::CODE_403, "Not allowed");
auto updatedSong = manager::SongManager::songDtoConv(songDto);
manager::SongManager songMgr(m_bConf);
@@ -165,7 +183,14 @@ namespace controller
}
// endpoint to delete a song
ENDPOINT("DELETE", "api/v1/song/data/{id}", songDelete, PATH(Int32, id)) {
ENDPOINT("DELETE", "api/v1/song/data/{id}", songDelete,
REQUEST(std::shared_ptr<IncomingRequest>, request), PATH(Int32, id)) {
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::deleteSong), Status::CODE_403, "Not allowed");
model::Song song(id);
manager::SongManager sngMgr(m_bConf);
@@ -176,7 +201,13 @@ namespace controller
// endpoint for streaming a song
ENDPOINT("GET", "/api/v1/song/stream/{id}", streamSong,
PATH(Int32, id)) {
REQUEST(std::shared_ptr<IncomingRequest>, request), PATH(Int32, id)) {
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::stream), Status::CODE_403, "Not allowed");
database::SongRepository songRepo(m_bConf);
model::Song songDb(id);
songDb = songRepo.retrieveRecord(songDb, type::SongFilter::id);
@@ -194,12 +225,12 @@ namespace controller
}
#include OATPP_CODEGEN_END(ApiController)
private:
private:
std::string m_exe_path;
model::BinaryPath m_bConf;
const long m_dataSize = std::numeric_limits<long long int>::max();
};
};
}
#endif
+17 -8
View File
@@ -26,11 +26,10 @@
namespace fs = std::filesystem;
namespace controller
namespace controller {
class YearController : public oatpp::web::server::api::ApiController
{
class YearController : public oatpp::web::server::api::ApiController
{
public:
public:
YearController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
{ }
@@ -45,6 +44,12 @@ namespace controller
ENDPOINT("GET", "/api/v1/year", yearRecords,
REQUEST(std::shared_ptr<IncomingRequest>, request))
{
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveYear), Status::CODE_403, "Not allowed");
std::cout << "starting process of retrieving year" << std::endl;
database::YearRepository yrRepo(m_bConf);
auto yrsDb = yrRepo.retrieveRecords();
@@ -63,7 +68,12 @@ namespace controller
// endpoint for retrieving single year record by the year id in json format
ENDPOINT("GET", "/api/v1/year/{id}", yearRecord,
PATH(Int32, id)) {
REQUEST(std::shared_ptr<IncomingRequest>, request), PATH(Int32, id)) {
auto authHeader = request->getHeader("Authorization");
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
auto auth = authHeader->std_str();
manager::TokenManager tok;
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveYear), Status::CODE_403, "Not allowed");
database::YearRepository yrRepo(m_bConf);
model::Year yrDb(id);
@@ -81,10 +91,9 @@ namespace controller
}
#include OATPP_CODEGEN_END(ApiController)
private:
private:
std::string m_exe_path;
model::BinaryPath m_bConf;
const long m_dataSize = std::numeric_limits<long long int>::max();
};
};
}
#endif
+5 -6
View File
@@ -13,18 +13,17 @@
#include "model/Models.h"
#include "type/Scopes.h"
namespace manager
namespace manager {
class TokenManager
{
class TokenManager
{
public:
public:
TokenManager();
model::LoginResult retrieveToken(const model::BinaryPath&);
bool isTokenValid(std::string&, type::Scope);
bool testAuth(const model::BinaryPath&);
private:
private:
cpr::Response sendRequest(std::string_view, nlohmann::json&);
nlohmann::json createTokenBody(const model::AuthCredentials&);
@@ -36,7 +35,7 @@ namespace manager
std::pair<bool, std::vector<std::string>> fetchAuthHeader(const std::string&);
bool tokenSupportsScope(const std::vector<std::string>, const std::string&&);
};
};
}
#endif
+11 -1
View File
@@ -6,7 +6,17 @@ namespace type
enum class Scope
{
upload = 0,
download
download,
stream,
retrieveSong,
updateSong,
deleteSong,
retrieveAlbum,
retrieveArtist,
retrieveGenre,
retrieveYear,
downloadCoverArt
};
}
+5 -3
View File
@@ -4,10 +4,11 @@
#include <fstream>
#include <memory>
callback::StreamCallback::StreamCallback() :
namespace callback {
StreamCallback::StreamCallback() :
m_counter(0) { }
callback::StreamCallback::StreamCallback(const std::string& songPath) :
StreamCallback::StreamCallback(const std::string& songPath) :
m_songPath(songPath),
m_counter(0),
m_bytesRead(0)
@@ -19,7 +20,7 @@ callback::StreamCallback::StreamCallback(const std::string& songPath) :
}
oatpp::data::v_io_size callback::StreamCallback::read(void *buff, oatpp::data::v_io_size count)
oatpp::data::v_io_size StreamCallback::read(void *buff, oatpp::data::v_io_size count)
{
if (m_counter >= m_fileSize) {
std::cout << "done streaming song" << std::endl;
@@ -40,3 +41,4 @@ oatpp::data::v_io_size callback::StreamCallback::read(void *buff, oatpp::data::v
return count;
}
}
+35 -16
View File
@@ -13,13 +13,13 @@
namespace fs = std::filesystem;
manager::TokenManager::TokenManager()
namespace manager {
TokenManager::TokenManager()
{
}
model::LoginResult manager::TokenManager::retrieveToken(const model::BinaryPath& bConf)
model::LoginResult TokenManager::retrieveToken(const model::BinaryPath& bConf)
{
auto cred = parseAuthCredentials(bConf);
@@ -46,7 +46,7 @@ model::LoginResult manager::TokenManager::retrieveToken(const model::BinaryPath&
}
bool manager::TokenManager::isTokenValid(std::string& auth, type::Scope scope)
bool TokenManager::isTokenValid(std::string& auth, type::Scope scope)
{
auto authPair = fetchAuthHeader(auth);
@@ -65,9 +65,26 @@ bool manager::TokenManager::isTokenValid(std::string& auth, type::Scope scope)
switch (scope) {
case type::Scope::upload:
return tokenSupportsScope(scopes, "upload:songs");
break;
case type::Scope::download:
return tokenSupportsScope(scopes, "download:songs");
case type::Scope::stream:
return tokenSupportsScope(scopes, "stream:songs");
case type::Scope::deleteSong:
return tokenSupportsScope(scopes, "delete:songs");
case type::Scope::updateSong:
return tokenSupportsScope(scopes, "update:songs");
case type::Scope::retrieveSong:
return tokenSupportsScope(scopes, "read:song_details");
case type::Scope::retrieveAlbum:
return tokenSupportsScope(scopes, "read:albums");
case type::Scope::retrieveArtist:
return tokenSupportsScope(scopes, "read:artists");
case type::Scope::retrieveGenre:
return tokenSupportsScope(scopes, "read:genre");
case type::Scope::retrieveYear:
return tokenSupportsScope(scopes, "read:year");
case type::Scope::downloadCoverArt:
return tokenSupportsScope(scopes, "download:cover_art");
default:
break;
}
@@ -75,7 +92,7 @@ bool manager::TokenManager::isTokenValid(std::string& auth, type::Scope scope)
return false;
}
bool manager::TokenManager::testAuth(const model::BinaryPath& bConf)
bool TokenManager::testAuth(const model::BinaryPath& bConf)
{
auto cred = parseAuthCredentials(bConf);
auto reqObj = createTokenBody(cred);
@@ -90,7 +107,7 @@ bool manager::TokenManager::testAuth(const model::BinaryPath& bConf)
}
cpr::Response manager::TokenManager::sendRequest(std::string_view uri, nlohmann::json& obj)
cpr::Response TokenManager::sendRequest(std::string_view uri, nlohmann::json& obj)
{
auto resp = cpr::Post(cpr::Url{uri}, cpr::Body{obj.dump()},
cpr::Header{{"Content-type", "application/json"},
@@ -100,7 +117,7 @@ cpr::Response manager::TokenManager::sendRequest(std::string_view uri, nlohmann:
}
nlohmann::json manager::TokenManager::createTokenBody(const model::AuthCredentials& auth)
nlohmann::json TokenManager::createTokenBody(const model::AuthCredentials& auth)
{
nlohmann::json obj;
obj["client_id"] = auth.clientId;
@@ -112,12 +129,12 @@ nlohmann::json manager::TokenManager::createTokenBody(const model::AuthCredentia
}
model::AuthCredentials manager::TokenManager::parseAuthCredentials(std::string_view path)
model::AuthCredentials TokenManager::parseAuthCredentials(std::string_view path)
{
auto exe_path = manager::DirectoryManager::configPath(path);
auto exe_path = DirectoryManager::configPath(path);
exe_path.append("/authcredentials.json");
auto con = manager::DirectoryManager::credentialConfigContent(exe_path);
auto con = DirectoryManager::credentialConfigContent(exe_path);
model::AuthCredentials auth;
auth.uri = "https://";
@@ -129,9 +146,9 @@ model::AuthCredentials manager::TokenManager::parseAuthCredentials(std::string_v
return auth;
}
model::AuthCredentials manager::TokenManager::parseAuthCredentials(const model::BinaryPath& bConf)
model::AuthCredentials TokenManager::parseAuthCredentials(const model::BinaryPath& bConf)
{
auto con = manager::DirectoryManager::credentialConfigContent(bConf);
auto con = DirectoryManager::credentialConfigContent(bConf);
model::AuthCredentials auth;
auth.uri = "https://";
@@ -144,7 +161,7 @@ model::AuthCredentials manager::TokenManager::parseAuthCredentials(const model::
return auth;
}
std::vector<std::string> manager::TokenManager::extractScopes(const jwt::decoded_jwt&& decoded)
std::vector<std::string> TokenManager::extractScopes(const jwt::decoded_jwt&& decoded)
{
std::vector<std::string> scopes;
@@ -162,7 +179,7 @@ std::vector<std::string> manager::TokenManager::extractScopes(const jwt::decoded
return scopes;
}
std::pair<bool, std::vector<std::string>> manager::TokenManager::fetchAuthHeader(const std::string& auth)
std::pair<bool, std::vector<std::string>> TokenManager::fetchAuthHeader(const std::string& auth)
{
std::istringstream iss(auth);
std::vector<std::string> authHeader{std::istream_iterator<std::string>(iss),
@@ -182,10 +199,12 @@ std::pair<bool, std::vector<std::string>> manager::TokenManager::fetchAuthHeader
}
bool manager::TokenManager::tokenSupportsScope(const std::vector<std::string> scopes, const std::string&& scope)
bool TokenManager::tokenSupportsScope(const std::vector<std::string> scopes,
const std::string&& scope)
{
return std::any_of(scopes.begin(), scopes.end(),
[&](std::string foundScope) {
return (foundScope.compare(scope) == 0);
});
}
}