Authorized endpoints and updated README
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Icarus
|
# 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
|
### 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)
|
* [Mear](https://github.com/amazing-username/mear) - Partially implemented (under development)
|
||||||
* [IcarusDownloadManager](https://github.com/amazing-username/IcarusDownloadManager)
|
* [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)
|
* [json](https://www.github.com/nlohmann/json)
|
||||||
* [cpr](https://www.github.com/whoshuu/cpr)
|
* [cpr](https://www.github.com/whoshuu/cpr)
|
||||||
* [TagLib](https://github.com/taglib/taglib)
|
* [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)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -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
|
* server - The address or domain name of the MySQL server
|
||||||
* database - The database name
|
* database - The database name
|
||||||
* user - Username
|
* username - Username
|
||||||
* password - Self-explanatory
|
* 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.
|
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:
|
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
|
```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.
|
From this point the database has been successfully created. Metadata and song filesystem locations can be saved.
|
||||||
|
|||||||
@@ -6,22 +6,21 @@
|
|||||||
#include "oatpp/core/data/stream/FileStream.hpp"
|
#include "oatpp/core/data/stream/FileStream.hpp"
|
||||||
#include "oatpp/web/protocol/http/outgoing/ChunkedBody.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:
|
||||||
{
|
StreamCallback();
|
||||||
public:
|
StreamCallback(const std::string&);
|
||||||
StreamCallback();
|
|
||||||
StreamCallback(const std::string&);
|
|
||||||
|
|
||||||
oatpp::data::v_io_size read(void*, oatpp::data::v_io_size);
|
oatpp::data::v_io_size read(void*, oatpp::data::v_io_size);
|
||||||
private:
|
private:
|
||||||
std::string m_songPath;
|
std::string m_songPath;
|
||||||
|
|
||||||
long m_bytesRead;
|
long m_bytesRead;
|
||||||
long m_counter;
|
long m_counter;
|
||||||
long m_fileSize;
|
long m_fileSize;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,31 +8,30 @@
|
|||||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||||
#include "oatpp/web/server/HttpConnectionHandler.hpp"
|
#include "oatpp/web/server/HttpConnectionHandler.hpp"
|
||||||
|
|
||||||
namespace component
|
namespace component {
|
||||||
|
|
||||||
|
class AppComponent
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
|
||||||
|
return oatpp::network::server::SimpleTCPConnectionProvider::createShared(5002);
|
||||||
|
}());
|
||||||
|
|
||||||
class AppComponent
|
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, httpRouter)([] {
|
||||||
{
|
return oatpp::web::server::HttpRouter::createShared();
|
||||||
public:
|
}());
|
||||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
|
|
||||||
return oatpp::network::server::SimpleTCPConnectionProvider::createShared(5002);
|
|
||||||
}());
|
|
||||||
|
|
||||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, httpRouter)([] {
|
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::server::ConnectionHandler>, serverConnectionHandler)([] {
|
||||||
return oatpp::web::server::HttpRouter::createShared();
|
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
|
||||||
}());
|
|
||||||
|
|
||||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::server::ConnectionHandler>, serverConnectionHandler)([] {
|
return oatpp::web::server::HttpConnectionHandler::createShared(router);
|
||||||
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
|
}());
|
||||||
|
|
||||||
return oatpp::web::server::HttpConnectionHandler::createShared(router);
|
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
|
||||||
}());
|
return oatpp::parser::json::mapping::ObjectMapper::createShared();
|
||||||
|
}());
|
||||||
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
|
private:
|
||||||
return oatpp::parser::json::mapping::ObjectMapper::createShared();
|
};
|
||||||
}());
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,73 +20,83 @@
|
|||||||
#include "database/AlbumRepository.h"
|
#include "database/AlbumRepository.h"
|
||||||
#include "dto/AlbumDto.hpp"
|
#include "dto/AlbumDto.hpp"
|
||||||
#include "manager/AlbumManager.h"
|
#include "manager/AlbumManager.h"
|
||||||
|
#include "manager/TokenManager.h"
|
||||||
#include "model/Models.h"
|
#include "model/Models.h"
|
||||||
#include "type/Scopes.h"
|
#include "type/Scopes.h"
|
||||||
#include "type/AlbumFilter.h"
|
#include "type/AlbumFilter.h"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
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:
|
||||||
|
AlbumController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
AlbumController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||||
|
|
||||||
|
// endpoint for retrieving all album records in json format
|
||||||
|
ENDPOINT("GET", "/api/v1/album", albumRecords,
|
||||||
|
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
||||||
{
|
{
|
||||||
public:
|
auto authHeader = request->getHeader("Authorization");
|
||||||
AlbumController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
auto auth = authHeader->std_str();
|
||||||
{ }
|
manager::TokenManager tok;
|
||||||
|
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveAlbum), Status::CODE_403, "Not allowed");
|
||||||
|
|
||||||
AlbumController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
std::cout << "starting process of retrieving album" << std::endl;
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
database::AlbumRepository albRepo(m_bConf);
|
||||||
{ }
|
auto albsDb = albRepo.retrieveRecords();
|
||||||
|
auto albums = oatpp::data::mapping::type::List<dto::AlbumDto::ObjectWrapper>::createShared();
|
||||||
|
|
||||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
for (auto& albDb : albsDb) {
|
||||||
|
auto alb = dto::AlbumDto::createShared();
|
||||||
|
alb->id = albDb.id;
|
||||||
|
alb->title = albDb.title.c_str();
|
||||||
|
alb->year = albDb.year;
|
||||||
|
|
||||||
// endpoint for retrieving all album records in json format
|
albums->pushBack(alb);
|
||||||
ENDPOINT("GET", "/api/v1/album", albumRecords,
|
|
||||||
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
|
||||||
{
|
|
||||||
std::cout << "starting process of retrieving album" << std::endl;
|
|
||||||
database::AlbumRepository albRepo(m_bConf);
|
|
||||||
auto albsDb = albRepo.retrieveRecords();
|
|
||||||
auto albums = oatpp::data::mapping::type::List<dto::AlbumDto::ObjectWrapper>::createShared();
|
|
||||||
|
|
||||||
for (auto& albDb : albsDb) {
|
|
||||||
auto alb = dto::AlbumDto::createShared();
|
|
||||||
alb->id = albDb.id;
|
|
||||||
alb->title = albDb.title.c_str();
|
|
||||||
alb->year = albDb.year;
|
|
||||||
|
|
||||||
albums->pushBack(alb);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, albums);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// endpoint for retrieving single album record by the album id in json format
|
return createDtoResponse(Status::CODE_200, albums);
|
||||||
ENDPOINT("GET", "/api/v1/album/{id}", albumRecord,
|
}
|
||||||
PATH(Int32, id)) {
|
|
||||||
|
|
||||||
database::AlbumRepository albRepo(m_bConf);
|
// endpoint for retrieving single album record by the album id in json format
|
||||||
model::Album albDb(id);
|
ENDPOINT("GET", "/api/v1/album/{id}", albumRecord,
|
||||||
|
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");
|
||||||
|
|
||||||
OATPP_ASSERT_HTTP(albRepo.doesAlbumExists(albDb, type::AlbumFilter::id) , Status::CODE_403, "album does not exist");
|
database::AlbumRepository albRepo(m_bConf);
|
||||||
|
model::Album albDb(id);
|
||||||
|
|
||||||
std::cout << "album exists" << std::endl;
|
OATPP_ASSERT_HTTP(albRepo.doesAlbumExists(albDb, type::AlbumFilter::id) , Status::CODE_403, "album does not exist");
|
||||||
albDb = albRepo.retrieveRecord(albDb, type::AlbumFilter::id);
|
|
||||||
|
|
||||||
auto album = dto::AlbumDto::createShared();
|
std::cout << "album exists" << std::endl;
|
||||||
album->id = albDb.id;
|
albDb = albRepo.retrieveRecord(albDb, type::AlbumFilter::id);
|
||||||
album->title = albDb.title.c_str();
|
|
||||||
album->year = albDb.year;
|
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, album);
|
auto album = dto::AlbumDto::createShared();
|
||||||
}
|
album->id = albDb.id;
|
||||||
|
album->title = albDb.title.c_str();
|
||||||
|
album->year = albDb.year;
|
||||||
|
|
||||||
#include OATPP_CODEGEN_END(ApiController)
|
return createDtoResponse(Status::CODE_200, album);
|
||||||
private:
|
}
|
||||||
std::string m_exe_path;
|
|
||||||
model::BinaryPath m_bConf;
|
#include OATPP_CODEGEN_END(ApiController)
|
||||||
const long m_dataSize = std::numeric_limits<long long int>::max();
|
private:
|
||||||
};
|
std::string m_exe_path;
|
||||||
|
model::BinaryPath m_bConf;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,71 +20,81 @@
|
|||||||
#include "database/ArtistRepository.h"
|
#include "database/ArtistRepository.h"
|
||||||
#include "dto/ArtistDto.hpp"
|
#include "dto/ArtistDto.hpp"
|
||||||
#include "manager/ArtistManager.h"
|
#include "manager/ArtistManager.h"
|
||||||
|
#include "manager/TokenManager.h"
|
||||||
#include "model/Models.h"
|
#include "model/Models.h"
|
||||||
#include "type/Scopes.h"
|
#include "type/Scopes.h"
|
||||||
#include "type/ArtistFilter.h"
|
#include "type/ArtistFilter.h"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
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:
|
||||||
|
ArtistController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
ArtistController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||||
|
|
||||||
|
// endpoint for retrieving all artist records in json format
|
||||||
|
ENDPOINT("GET", "/api/v1/artist", artistRecords,
|
||||||
|
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
||||||
{
|
{
|
||||||
public:
|
auto authHeader = request->getHeader("Authorization");
|
||||||
ArtistController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
auto auth = authHeader->std_str();
|
||||||
{ }
|
manager::TokenManager tok;
|
||||||
|
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveArtist), Status::CODE_403, "Not allowed");
|
||||||
|
|
||||||
ArtistController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
std::cout << "starting process of retrieving artist" << std::endl;
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
database::ArtistRepository artRepo(m_bConf);
|
||||||
{ }
|
auto artsDb = artRepo.retrieveRecords();
|
||||||
|
auto artists = oatpp::data::mapping::type::List<dto::ArtistDto::ObjectWrapper>::createShared();
|
||||||
|
|
||||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
for (auto& artDb : artsDb) {
|
||||||
|
auto art = dto::ArtistDto::createShared();
|
||||||
|
art->id = artDb.id;
|
||||||
|
art->artist = artDb.artist.c_str();
|
||||||
|
|
||||||
// endpoint for retrieving all artist records in json format
|
artists->pushBack(art);
|
||||||
ENDPOINT("GET", "/api/v1/artist", artistRecords,
|
|
||||||
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
|
||||||
{
|
|
||||||
std::cout << "starting process of retrieving artist" << std::endl;
|
|
||||||
database::ArtistRepository artRepo(m_bConf);
|
|
||||||
auto artsDb = artRepo.retrieveRecords();
|
|
||||||
auto artists = oatpp::data::mapping::type::List<dto::ArtistDto::ObjectWrapper>::createShared();
|
|
||||||
|
|
||||||
for (auto& artDb : artsDb) {
|
|
||||||
auto art = dto::ArtistDto::createShared();
|
|
||||||
art->id = artDb.id;
|
|
||||||
art->artist = artDb.artist.c_str();
|
|
||||||
|
|
||||||
artists->pushBack(art);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, artists);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// endpoint for retrieving single artist record by the artist id in json format
|
return createDtoResponse(Status::CODE_200, artists);
|
||||||
ENDPOINT("GET", "/api/v1/artist/{id}", artistRecord,
|
}
|
||||||
PATH(Int32, id)) {
|
|
||||||
|
|
||||||
database::ArtistRepository artRepo(m_bConf);
|
// endpoint for retrieving single artist record by the artist id in json format
|
||||||
model::Artist artDb(id);
|
ENDPOINT("GET", "/api/v1/artist/{id}", artistRecord,
|
||||||
|
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");
|
||||||
|
|
||||||
OATPP_ASSERT_HTTP(artRepo.doesArtistExist(artDb, type::ArtistFilter::id) , Status::CODE_403, "artist does not exist");
|
database::ArtistRepository artRepo(m_bConf);
|
||||||
|
model::Artist artDb(id);
|
||||||
|
|
||||||
std::cout << "artist exist" << std::endl;
|
OATPP_ASSERT_HTTP(artRepo.doesArtistExist(artDb, type::ArtistFilter::id) , Status::CODE_403, "artist does not exist");
|
||||||
artDb = artRepo.retrieveRecord(artDb, type::ArtistFilter::id);
|
|
||||||
|
|
||||||
auto artist = dto::ArtistDto::createShared();
|
std::cout << "artist exist" << std::endl;
|
||||||
artist->id = artDb.id;
|
artDb = artRepo.retrieveRecord(artDb, type::ArtistFilter::id);
|
||||||
artist->artist = artDb.artist.c_str();
|
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, artist);
|
auto artist = dto::ArtistDto::createShared();
|
||||||
}
|
artist->id = artDb.id;
|
||||||
|
artist->artist = artDb.artist.c_str();
|
||||||
|
|
||||||
#include OATPP_CODEGEN_END(ApiController)
|
return createDtoResponse(Status::CODE_200, artist);
|
||||||
private:
|
}
|
||||||
std::string m_exe_path;
|
|
||||||
model::BinaryPath m_bConf;
|
#include OATPP_CODEGEN_END(ApiController)
|
||||||
const long m_dataSize = std::numeric_limits<long long int>::max();
|
private:
|
||||||
};
|
std::string m_exe_path;
|
||||||
|
model::BinaryPath m_bConf;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,94 +26,96 @@
|
|||||||
|
|
||||||
namespace fs = std::filesystem;
|
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:
|
||||||
|
CoverArtController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
CoverArtController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||||
|
|
||||||
|
// endpoint for retrieving all cover art records in json format
|
||||||
|
ENDPOINT("GET", "/api/v1/coverart", coverArtRecords,
|
||||||
|
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
||||||
{
|
{
|
||||||
public:
|
auto authHeader = request->getHeader("Authorization");
|
||||||
CoverArtController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
auto auth = authHeader->std_str();
|
||||||
{ }
|
manager::TokenManager tok;
|
||||||
|
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::downloadCoverArt), Status::CODE_403, "Not allowed");
|
||||||
|
|
||||||
CoverArtController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
std::cout << "starting process of retrieving cover art" << std::endl;
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
database::CoverArtRepository covRepo(m_bConf);
|
||||||
{ }
|
auto covsDb = covRepo.retrieveRecords();
|
||||||
|
auto coverArts = oatpp::data::mapping::type::List<dto::CoverArtDto::ObjectWrapper>::createShared();
|
||||||
|
|
||||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
for (auto& covDb : covsDb) {
|
||||||
|
auto cov = dto::CoverArtDto::createShared();
|
||||||
|
cov->id = covDb.id;
|
||||||
|
cov->songTitle = covDb.songTitle.c_str();
|
||||||
|
|
||||||
// endpoint for retrieving all cover art records in json format
|
coverArts->pushBack(cov);
|
||||||
ENDPOINT("GET", "/api/v1/coverart", coverArtRecords,
|
|
||||||
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
|
||||||
{
|
|
||||||
std::cout << "starting process of retrieving cover art" << std::endl;
|
|
||||||
database::CoverArtRepository covRepo(m_bConf);
|
|
||||||
auto covsDb = covRepo.retrieveRecords();
|
|
||||||
auto coverArts = oatpp::data::mapping::type::List<dto::CoverArtDto::ObjectWrapper>::createShared();
|
|
||||||
|
|
||||||
for (auto& covDb : covsDb) {
|
|
||||||
auto cov = dto::CoverArtDto::createShared();
|
|
||||||
cov->id = covDb.id;
|
|
||||||
cov->songTitle = covDb.songTitle.c_str();
|
|
||||||
|
|
||||||
coverArts->pushBack(cov);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, coverArts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// endpoint for retrieving single cover art record by the cover art id in json format
|
return createDtoResponse(Status::CODE_200, coverArts);
|
||||||
ENDPOINT("GET", "/api/v1/coverart/{id}", coverArtRecord,
|
}
|
||||||
PATH(Int32, id)) {
|
|
||||||
|
|
||||||
database::CoverArtRepository covRepo(m_bConf);
|
// endpoint for retrieving single cover art record by the cover art id in json format
|
||||||
model::Cover covDb;
|
ENDPOINT("GET", "/api/v1/coverart/{id}", coverArtRecord,
|
||||||
covDb.id = 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");
|
||||||
|
|
||||||
OATPP_ASSERT_HTTP(covRepo.doesCoverArtExist(covDb, type::CoverFilter::id) , Status::CODE_403, "song does not exist");
|
database::CoverArtRepository covRepo(m_bConf);
|
||||||
|
model::Cover covDb;
|
||||||
|
covDb.id = id;
|
||||||
|
|
||||||
std::cout << "cover art exists" << std::endl;
|
OATPP_ASSERT_HTTP(covRepo.doesCoverArtExist(covDb, type::CoverFilter::id) , Status::CODE_403, "song does not exist");
|
||||||
covDb = covRepo.retrieveRecord(covDb, type::CoverFilter::id);
|
|
||||||
|
|
||||||
auto coverArt = dto::CoverArtDto::createShared();
|
std::cout << "cover art exists" << std::endl;
|
||||||
coverArt->id = covDb.id;
|
covDb = covRepo.retrieveRecord(covDb, type::CoverFilter::id);
|
||||||
coverArt->songTitle = covDb.songTitle.c_str();
|
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, coverArt);
|
auto coverArt = dto::CoverArtDto::createShared();
|
||||||
}
|
coverArt->id = covDb.id;
|
||||||
|
coverArt->songTitle = covDb.songTitle.c_str();
|
||||||
|
|
||||||
ENDPOINT("GET", "/api/v1/coverart/download/{id}", downloadCoverArt,
|
return createDtoResponse(Status::CODE_200, coverArt);
|
||||||
PATH(Int32, id)) {
|
}
|
||||||
|
|
||||||
database::CoverArtRepository covRepo(m_bConf);
|
ENDPOINT("GET", "/api/v1/coverart/download/{id}", downloadCoverArt,
|
||||||
model::Cover covDb;
|
REQUEST(std::shared_ptr<IncomingRequest>, request), PATH(Int32, id)) {
|
||||||
covDb.id = id;
|
auto authHeader = request->getHeader("Authorization");
|
||||||
covDb = covRepo.retrieveRecord(covDb, type::CoverFilter::id);
|
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);
|
||||||
std::ifstream fl(covDb.imagePath.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
|
model::Cover covDb;
|
||||||
fl.seekg(0);
|
covDb.id = id;
|
||||||
|
covDb = covRepo.retrieveRecord(covDb, type::CoverFilter::id);
|
||||||
|
|
||||||
std::stringstream buf;
|
auto rawCover = oatpp::base::StrBuffer::loadFromFile(covDb.imagePath.c_str());
|
||||||
std::copy(std::istreambuf_iterator<char>(fl),
|
auto response = createResponse(Status::CODE_200, rawCover);
|
||||||
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);
|
|
||||||
|
|
||||||
response->putHeader(Header::CONTENT_TYPE, "image/*");
|
response->putHeader(Header::CONTENT_TYPE, "image/*");
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include OATPP_CODEGEN_END(ApiController)
|
#include OATPP_CODEGEN_END(ApiController)
|
||||||
private:
|
private:
|
||||||
std::string m_exe_path;
|
std::string m_exe_path;
|
||||||
model::BinaryPath m_bConf;
|
model::BinaryPath m_bConf;
|
||||||
const long m_dataSize = std::numeric_limits<long long int>::max();
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,71 +20,81 @@
|
|||||||
#include "database/GenreRepository.h"
|
#include "database/GenreRepository.h"
|
||||||
#include "dto/GenreDto.hpp"
|
#include "dto/GenreDto.hpp"
|
||||||
#include "manager/GenreManager.h"
|
#include "manager/GenreManager.h"
|
||||||
|
#include "manager/YearManager.h"
|
||||||
#include "model/Models.h"
|
#include "model/Models.h"
|
||||||
#include "type/Scopes.h"
|
#include "type/Scopes.h"
|
||||||
#include "type/GenreFilter.h"
|
#include "type/GenreFilter.h"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
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:
|
||||||
|
GenreController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
GenreController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||||
|
|
||||||
|
// endpoint for retrieving all genre records in json format
|
||||||
|
ENDPOINT("GET", "/api/v1/genre", genreRecords,
|
||||||
|
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
||||||
{
|
{
|
||||||
public:
|
auto authHeader = request->getHeader("Authorization");
|
||||||
GenreController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
auto auth = authHeader->std_str();
|
||||||
{ }
|
manager::TokenManager tok;
|
||||||
|
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveGenre), Status::CODE_403, "Not allowed");
|
||||||
|
|
||||||
GenreController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
std::cout << "starting process of retrieving genre" << std::endl;
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
database::GenreRepository gnrRepo(m_bConf);
|
||||||
{ }
|
auto gnrsDb = gnrRepo.retrieveRecords();
|
||||||
|
auto genres = oatpp::data::mapping::type::List<dto::GenreDto::ObjectWrapper>::createShared();
|
||||||
|
|
||||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
for (auto& gnrDb : gnrsDb) {
|
||||||
|
auto gnr = dto::GenreDto::createShared();
|
||||||
|
gnr->id = gnrDb.id;
|
||||||
|
gnr->category = gnrDb.category.c_str();
|
||||||
|
|
||||||
// endpoint for retrieving all genre records in json format
|
genres->pushBack(gnr);
|
||||||
ENDPOINT("GET", "/api/v1/genre", genreRecords,
|
|
||||||
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
|
||||||
{
|
|
||||||
std::cout << "starting process of retrieving genre" << std::endl;
|
|
||||||
database::GenreRepository gnrRepo(m_bConf);
|
|
||||||
auto gnrsDb = gnrRepo.retrieveRecords();
|
|
||||||
auto genres = oatpp::data::mapping::type::List<dto::GenreDto::ObjectWrapper>::createShared();
|
|
||||||
|
|
||||||
for (auto& gnrDb : gnrsDb) {
|
|
||||||
auto gnr = dto::GenreDto::createShared();
|
|
||||||
gnr->id = gnrDb.id;
|
|
||||||
gnr->category = gnrDb.category.c_str();
|
|
||||||
|
|
||||||
genres->pushBack(gnr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, genres);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// endpoint for retrieving single genre record by the genre id in json format
|
return createDtoResponse(Status::CODE_200, genres);
|
||||||
ENDPOINT("GET", "/api/v1/genre/{id}", genreRecord,
|
}
|
||||||
PATH(Int32, id)) {
|
|
||||||
|
|
||||||
database::GenreRepository gnrRepo(m_bConf);
|
// endpoint for retrieving single genre record by the genre id in json format
|
||||||
model::Genre gnrDb(id);
|
ENDPOINT("GET", "/api/v1/genre/{id}", genreRecord,
|
||||||
|
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");
|
||||||
|
|
||||||
OATPP_ASSERT_HTTP(gnrRepo.doesGenreExist(gnrDb, type::GenreFilter::id) , Status::CODE_403, "genre does not exist");
|
database::GenreRepository gnrRepo(m_bConf);
|
||||||
|
model::Genre gnrDb(id);
|
||||||
|
|
||||||
std::cout << "genre exist" << std::endl;
|
OATPP_ASSERT_HTTP(gnrRepo.doesGenreExist(gnrDb, type::GenreFilter::id) , Status::CODE_403, "genre does not exist");
|
||||||
gnrDb = gnrRepo.retrieveRecord(gnrDb, type::GenreFilter::id);
|
|
||||||
|
|
||||||
auto genre = dto::GenreDto::createShared();
|
std::cout << "genre exist" << std::endl;
|
||||||
genre->id = gnrDb.id;
|
gnrDb = gnrRepo.retrieveRecord(gnrDb, type::GenreFilter::id);
|
||||||
genre->category= gnrDb.category.c_str();
|
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, genre);
|
auto genre = dto::GenreDto::createShared();
|
||||||
}
|
genre->id = gnrDb.id;
|
||||||
|
genre->category= gnrDb.category.c_str();
|
||||||
|
|
||||||
#include OATPP_CODEGEN_END(ApiController)
|
return createDtoResponse(Status::CODE_200, genre);
|
||||||
private:
|
}
|
||||||
std::string m_exe_path;
|
|
||||||
model::BinaryPath m_bConf;
|
#include OATPP_CODEGEN_END(ApiController)
|
||||||
const long m_dataSize = std::numeric_limits<long long int>::max();
|
private:
|
||||||
};
|
std::string m_exe_path;
|
||||||
|
model::BinaryPath m_bConf;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -29,100 +29,73 @@
|
|||||||
|
|
||||||
namespace fs = std::filesystem;
|
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:
|
||||||
|
SongController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
SongController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||||
|
|
||||||
|
// endpoint for uploading a song
|
||||||
|
ENDPOINT("POST", "/api/v1/song/data", songUpload,
|
||||||
|
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
||||||
{
|
{
|
||||||
public:
|
auto authHeader = request->getHeader("Authorization");
|
||||||
SongController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
auto auth = authHeader->std_str();
|
||||||
{ }
|
manager::TokenManager tok;
|
||||||
|
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::upload), Status::CODE_403, "Not allowed");
|
||||||
|
|
||||||
SongController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
auto mp = std::make_shared<oatpp::web::mime::multipart::Multipart>(request->getHeaders());
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
oatpp::web::mime::multipart::Reader mp_reader(mp.get());
|
||||||
|
|
||||||
// endpoint for uploading a song
|
mp_reader.setPartReader("file", oatpp::web::mime::multipart::createInMemoryPartReader(m_dataSize));
|
||||||
ENDPOINT("POST", "/api/v1/song/data", songUpload,
|
|
||||||
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
|
||||||
{
|
|
||||||
auto authHeader = request->getHeader("Authorization");
|
|
||||||
|
|
||||||
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
|
request->transferBody(&mp_reader);
|
||||||
|
|
||||||
auto auth = authHeader->std_str();
|
auto file = mp->getNamedPart("file");
|
||||||
|
|
||||||
manager::TokenManager tok;
|
|
||||||
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::upload), Status::CODE_403, "Not allowed");
|
|
||||||
|
|
||||||
auto mp = std::make_shared<oatpp::web::mime::multipart::Multipart>(request->getHeaders());
|
OATPP_ASSERT_HTTP(file, Status::CODE_400, "file is null");
|
||||||
|
|
||||||
oatpp::web::mime::multipart::Reader mp_reader(mp.get());
|
auto buff = std::unique_ptr<char>(new char[file->getKnownSize()]);
|
||||||
|
auto buffSize = file->getInputStream()->read(buff.get(), file->getKnownSize());
|
||||||
|
|
||||||
mp_reader.setPartReader("file", oatpp::web::mime::multipart::createInMemoryPartReader(m_dataSize));
|
std::vector<unsigned char> data(buff.get(), buff.get() + buffSize);
|
||||||
|
|
||||||
request->transferBody(&mp_reader);
|
model::Song sng;
|
||||||
|
sng.data = std::move(data);
|
||||||
|
|
||||||
|
manager::SongManager songMgr(m_bConf);
|
||||||
|
songMgr.saveSong(sng);
|
||||||
|
|
||||||
auto file = mp->getNamedPart("file");
|
return createResponse(Status::CODE_200, "OK");
|
||||||
|
}
|
||||||
|
|
||||||
OATPP_ASSERT_HTTP(file, Status::CODE_400, "file is null");
|
// endpoint for retrieving all song records in json format
|
||||||
|
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");
|
||||||
|
|
||||||
auto buff = std::unique_ptr<char>(new char[file->getKnownSize()]);
|
std::cout << "starting process of retrieving songs" << std::endl;
|
||||||
auto buffSize = file->getInputStream()->read(buff.get(), file->getKnownSize());
|
database::SongRepository songRepo(m_bConf);
|
||||||
|
auto songsDb = songRepo.retrieveRecords();
|
||||||
std::vector<unsigned char> data(buff.get(), buff.get() + buffSize);
|
auto songs = oatpp::data::mapping::type::List<dto::SongDto::ObjectWrapper>::createShared();
|
||||||
|
|
||||||
model::Song sng;
|
|
||||||
sng.data = std::move(data);
|
|
||||||
|
|
||||||
manager::SongManager songMgr(m_bConf);
|
|
||||||
songMgr.saveSong(sng);
|
|
||||||
|
|
||||||
return createResponse(Status::CODE_200, "OK");
|
|
||||||
}
|
|
||||||
|
|
||||||
// endpoint for retrieving all song records in json format
|
|
||||||
ENDPOINT("GET", "/api/v1/song", songRecords,
|
|
||||||
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
|
||||||
{
|
|
||||||
std::cout << "starting process of retrieving songs" << std::endl;
|
|
||||||
database::SongRepository songRepo(m_bConf);
|
|
||||||
auto songsDb = songRepo.retrieveRecords();
|
|
||||||
auto songs = oatpp::data::mapping::type::List<dto::SongDto::ObjectWrapper>::createShared();
|
|
||||||
|
|
||||||
std::cout << "creating object to send" << std::endl;
|
|
||||||
for (auto& songDb : songsDb) {
|
|
||||||
auto song = dto::SongDto::createShared();
|
|
||||||
song->id = songDb.id;
|
|
||||||
song->title = songDb.title.c_str();
|
|
||||||
song->artist = songDb.artist.c_str();
|
|
||||||
song->album = songDb.album.c_str();
|
|
||||||
song->genre = songDb.genre.c_str();
|
|
||||||
song->year = songDb.year;
|
|
||||||
song->duration = songDb.duration;
|
|
||||||
song->track = songDb.track;
|
|
||||||
song->disc = songDb.disc;
|
|
||||||
|
|
||||||
songs->pushBack(song);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, songs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// endpoint for retrieving song record by the song id in json format
|
|
||||||
ENDPOINT("GET", "/api/v1/song/{id}", songRecord,
|
|
||||||
PATH(Int32, id)) {
|
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
std::cout << "song exists" << std::endl;
|
|
||||||
songDb = songRepo.retrieveRecord(songDb, type::SongFilter::id);
|
|
||||||
|
|
||||||
|
std::cout << "creating object to send" << std::endl;
|
||||||
|
for (auto& songDb : songsDb) {
|
||||||
auto song = dto::SongDto::createShared();
|
auto song = dto::SongDto::createShared();
|
||||||
song->id = songDb.id;
|
song->id = songDb.id;
|
||||||
song->title = songDb.title.c_str();
|
song->title = songDb.title.c_str();
|
||||||
@@ -134,72 +107,130 @@ namespace controller
|
|||||||
song->track = songDb.track;
|
song->track = songDb.track;
|
||||||
song->disc = songDb.disc;
|
song->disc = songDb.disc;
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, song);
|
songs->pushBack(song);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENDPOINT("GET", "/api/v1/song/data/{id}", downloadSong,
|
return createDtoResponse(Status::CODE_200, songs);
|
||||||
PATH(Int32, id)) {
|
}
|
||||||
|
|
||||||
database::SongRepository songRepo(m_bConf);
|
// endpoint for retrieving song record by the song id in json format
|
||||||
model::Song songDb(id);
|
ENDPOINT("GET", "/api/v1/song/{id}", songRecord,
|
||||||
songDb = songRepo.retrieveRecord(songDb, type::SongFilter::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");
|
||||||
|
|
||||||
auto rawSong = oatpp::base::StrBuffer::loadFromFile(songDb.songPath.c_str());
|
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");
|
||||||
|
|
||||||
|
std::cout << "song exists" << std::endl;
|
||||||
|
songDb = songRepo.retrieveRecord(songDb, type::SongFilter::id);
|
||||||
|
|
||||||
|
auto song = dto::SongDto::createShared();
|
||||||
|
song->id = songDb.id;
|
||||||
|
song->title = songDb.title.c_str();
|
||||||
|
song->artist = songDb.artist.c_str();
|
||||||
|
song->album = songDb.album.c_str();
|
||||||
|
song->genre = songDb.genre.c_str();
|
||||||
|
song->year = songDb.year;
|
||||||
|
song->duration = songDb.duration;
|
||||||
|
song->track = songDb.track;
|
||||||
|
song->disc = songDb.disc;
|
||||||
|
|
||||||
|
return createDtoResponse(Status::CODE_200, song);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENDPOINT("GET", "/api/v1/song/data/{id}", downloadSong,
|
||||||
|
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);
|
||||||
|
songDb = songRepo.retrieveRecord(songDb, type::SongFilter::id);
|
||||||
|
|
||||||
|
auto rawSong = oatpp::base::StrBuffer::loadFromFile(songDb.songPath.c_str());
|
||||||
|
|
||||||
auto response = createResponse(Status::CODE_200, rawSong);
|
auto response = createResponse(Status::CODE_200, rawSong);
|
||||||
response->putHeader(Header::CONTENT_TYPE, "audio/mpeg");
|
response->putHeader(Header::CONTENT_TYPE, "audio/mpeg");
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: create endpoint for updating songs
|
ENDPOINT("UPDATE", "/api/v1/song/{id}", songUpdate,
|
||||||
ENDPOINT("UPDATE", "/api/v1/song/{id}", songUpdate,
|
REQUEST(std::shared_ptr<IncomingRequest>, request),
|
||||||
BODY_DTO(dto::SongDto::ObjectWrapper, songDto), PATH(Int32, id)) {
|
BODY_DTO(dto::SongDto::ObjectWrapper, songDto), PATH(Int32, id)) {
|
||||||
songDto->id = 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);
|
auto updatedSong = manager::SongManager::songDtoConv(songDto);
|
||||||
manager::SongManager songMgr(m_bConf);
|
manager::SongManager songMgr(m_bConf);
|
||||||
songMgr.updateSong(updatedSong);
|
songMgr.updateSong(updatedSong);
|
||||||
|
|
||||||
return createResponse(Status::CODE_200, "OK");
|
return createResponse(Status::CODE_200, "OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
// endpoint to delete a song
|
// endpoint to delete a song
|
||||||
ENDPOINT("DELETE", "api/v1/song/data/{id}", songDelete, PATH(Int32, id)) {
|
ENDPOINT("DELETE", "api/v1/song/data/{id}", songDelete,
|
||||||
model::Song song(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::deleteSong), Status::CODE_403, "Not allowed");
|
||||||
|
|
||||||
manager::SongManager sngMgr(m_bConf);
|
model::Song song(id);
|
||||||
sngMgr.deleteSong(song);
|
|
||||||
|
|
||||||
return createResponse(Status::CODE_200, "OK");
|
manager::SongManager sngMgr(m_bConf);
|
||||||
}
|
sngMgr.deleteSong(song);
|
||||||
|
|
||||||
// endpoint for streaming a song
|
return createResponse(Status::CODE_200, "OK");
|
||||||
ENDPOINT("GET", "/api/v1/song/stream/{id}", streamSong,
|
}
|
||||||
PATH(Int32, id)) {
|
|
||||||
database::SongRepository songRepo(m_bConf);
|
|
||||||
model::Song songDb(id);
|
|
||||||
songDb = songRepo.retrieveRecord(songDb, type::SongFilter::id);
|
|
||||||
|
|
||||||
oatpp::data::v_io_size dSize = 1024;
|
// endpoint for streaming a song
|
||||||
|
ENDPOINT("GET", "/api/v1/song/stream/{id}", streamSong,
|
||||||
|
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");
|
||||||
|
|
||||||
auto db = std::make_shared<oatpp::web::protocol::http::outgoing::ChunkedBody>(
|
database::SongRepository songRepo(m_bConf);
|
||||||
std::make_shared<callback::StreamCallback>(songDb.songPath), nullptr, dSize);
|
model::Song songDb(id);
|
||||||
|
songDb = songRepo.retrieveRecord(songDb, type::SongFilter::id);
|
||||||
|
|
||||||
auto response = OutgoingResponse::createShared(Status::CODE_200, db);
|
oatpp::data::v_io_size dSize = 1024;
|
||||||
response->putHeader(Header::CONNECTION, Header::Value::CONNECTION_KEEP_ALIVE);
|
|
||||||
response->putHeader(Header::CONTENT_TYPE, "audio/mpeg");
|
|
||||||
|
|
||||||
return response;
|
auto db = std::make_shared<oatpp::web::protocol::http::outgoing::ChunkedBody>(
|
||||||
}
|
std::make_shared<callback::StreamCallback>(songDb.songPath), nullptr, dSize);
|
||||||
|
|
||||||
#include OATPP_CODEGEN_END(ApiController)
|
auto response = OutgoingResponse::createShared(Status::CODE_200, db);
|
||||||
private:
|
response->putHeader(Header::CONNECTION, Header::Value::CONNECTION_KEEP_ALIVE);
|
||||||
std::string m_exe_path;
|
response->putHeader(Header::CONTENT_TYPE, "audio/mpeg");
|
||||||
|
|
||||||
model::BinaryPath m_bConf;
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
const long m_dataSize = std::numeric_limits<long long int>::max();
|
#include OATPP_CODEGEN_END(ApiController)
|
||||||
};
|
private:
|
||||||
|
std::string m_exe_path;
|
||||||
|
|
||||||
|
model::BinaryPath m_bConf;
|
||||||
|
|
||||||
|
const long m_dataSize = std::numeric_limits<long long int>::max();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,65 +26,74 @@
|
|||||||
|
|
||||||
namespace fs = std::filesystem;
|
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:
|
||||||
|
YearController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
YearController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||||
|
|
||||||
|
// endpoint for retrieving all year records in json format
|
||||||
|
ENDPOINT("GET", "/api/v1/year", yearRecords,
|
||||||
|
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
||||||
{
|
{
|
||||||
public:
|
auto authHeader = request->getHeader("Authorization");
|
||||||
YearController(std::string p, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
OATPP_ASSERT_HTTP(authHeader, Status::CODE_403, "Nope");
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_exe_path(p)
|
auto auth = authHeader->std_str();
|
||||||
{ }
|
manager::TokenManager tok;
|
||||||
|
OATPP_ASSERT_HTTP(tok.isTokenValid(auth, type::Scope::retrieveYear), Status::CODE_403, "Not allowed");
|
||||||
|
|
||||||
YearController(const model::BinaryPath& bConf, OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
|
std::cout << "starting process of retrieving year" << std::endl;
|
||||||
: oatpp::web::server::api::ApiController(objectMapper), m_bConf(bConf)
|
database::YearRepository yrRepo(m_bConf);
|
||||||
{ }
|
auto yrsDb = yrRepo.retrieveRecords();
|
||||||
|
auto yearRecs = oatpp::data::mapping::type::List<dto::YearDto::ObjectWrapper>::createShared();
|
||||||
|
|
||||||
#include OATPP_CODEGEN_BEGIN(ApiController)
|
for (auto& yrDb : yrsDb) {
|
||||||
|
auto yr = dto::YearDto::createShared();
|
||||||
|
yr->id = yrDb.id;
|
||||||
|
yr->year = yrDb.year;
|
||||||
|
|
||||||
// endpoint for retrieving all year records in json format
|
yearRecs->pushBack(yr);
|
||||||
ENDPOINT("GET", "/api/v1/year", yearRecords,
|
|
||||||
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
|
||||||
{
|
|
||||||
std::cout << "starting process of retrieving year" << std::endl;
|
|
||||||
database::YearRepository yrRepo(m_bConf);
|
|
||||||
auto yrsDb = yrRepo.retrieveRecords();
|
|
||||||
auto yearRecs = oatpp::data::mapping::type::List<dto::YearDto::ObjectWrapper>::createShared();
|
|
||||||
|
|
||||||
for (auto& yrDb : yrsDb) {
|
|
||||||
auto yr = dto::YearDto::createShared();
|
|
||||||
yr->id = yrDb.id;
|
|
||||||
yr->year = yrDb.year;
|
|
||||||
|
|
||||||
yearRecs->pushBack(yr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, yearRecs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// endpoint for retrieving single year record by the year id in json format
|
return createDtoResponse(Status::CODE_200, yearRecs);
|
||||||
ENDPOINT("GET", "/api/v1/year/{id}", yearRecord,
|
}
|
||||||
PATH(Int32, id)) {
|
|
||||||
|
|
||||||
database::YearRepository yrRepo(m_bConf);
|
// endpoint for retrieving single year record by the year id in json format
|
||||||
model::Year yrDb(id);
|
ENDPOINT("GET", "/api/v1/year/{id}", yearRecord,
|
||||||
|
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");
|
||||||
|
|
||||||
OATPP_ASSERT_HTTP(yrRepo.doesYearExist(yrDb, type::YearFilter::id) , Status::CODE_403, "year does not exist");
|
database::YearRepository yrRepo(m_bConf);
|
||||||
|
model::Year yrDb(id);
|
||||||
|
|
||||||
std::cout << "year exist" << std::endl;
|
OATPP_ASSERT_HTTP(yrRepo.doesYearExist(yrDb, type::YearFilter::id) , Status::CODE_403, "year does not exist");
|
||||||
yrDb = yrRepo.retrieveRecord(yrDb, type::YearFilter::id);
|
|
||||||
|
|
||||||
auto year = dto::YearDto::createShared();
|
std::cout << "year exist" << std::endl;
|
||||||
year->id = yrDb.id;
|
yrDb = yrRepo.retrieveRecord(yrDb, type::YearFilter::id);
|
||||||
year->year= yrDb.year;
|
|
||||||
|
|
||||||
return createDtoResponse(Status::CODE_200, year);
|
auto year = dto::YearDto::createShared();
|
||||||
}
|
year->id = yrDb.id;
|
||||||
|
year->year= yrDb.year;
|
||||||
|
|
||||||
#include OATPP_CODEGEN_END(ApiController)
|
return createDtoResponse(Status::CODE_200, year);
|
||||||
private:
|
}
|
||||||
std::string m_exe_path;
|
|
||||||
model::BinaryPath m_bConf;
|
#include OATPP_CODEGEN_END(ApiController)
|
||||||
const long m_dataSize = std::numeric_limits<long long int>::max();
|
private:
|
||||||
};
|
std::string m_exe_path;
|
||||||
|
model::BinaryPath m_bConf;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,30 +13,29 @@
|
|||||||
#include "model/Models.h"
|
#include "model/Models.h"
|
||||||
#include "type/Scopes.h"
|
#include "type/Scopes.h"
|
||||||
|
|
||||||
namespace manager
|
namespace manager {
|
||||||
|
class TokenManager
|
||||||
{
|
{
|
||||||
class TokenManager
|
public:
|
||||||
{
|
TokenManager();
|
||||||
public:
|
|
||||||
TokenManager();
|
|
||||||
|
|
||||||
model::LoginResult retrieveToken(const model::BinaryPath&);
|
model::LoginResult retrieveToken(const model::BinaryPath&);
|
||||||
|
|
||||||
bool isTokenValid(std::string&, type::Scope);
|
bool isTokenValid(std::string&, type::Scope);
|
||||||
bool testAuth(const model::BinaryPath&);
|
bool testAuth(const model::BinaryPath&);
|
||||||
private:
|
private:
|
||||||
cpr::Response sendRequest(std::string_view, nlohmann::json&);
|
cpr::Response sendRequest(std::string_view, nlohmann::json&);
|
||||||
|
|
||||||
nlohmann::json createTokenBody(const model::AuthCredentials&);
|
nlohmann::json createTokenBody(const model::AuthCredentials&);
|
||||||
|
|
||||||
model::AuthCredentials parseAuthCredentials(std::string_view);
|
model::AuthCredentials parseAuthCredentials(std::string_view);
|
||||||
model::AuthCredentials parseAuthCredentials(const model::BinaryPath&);
|
model::AuthCredentials parseAuthCredentials(const model::BinaryPath&);
|
||||||
|
|
||||||
std::vector<std::string> extractScopes(const jwt::decoded_jwt&&);
|
std::vector<std::string> extractScopes(const jwt::decoded_jwt&&);
|
||||||
std::pair<bool, std::vector<std::string>> fetchAuthHeader(const std::string&);
|
std::pair<bool, std::vector<std::string>> fetchAuthHeader(const std::string&);
|
||||||
|
|
||||||
bool tokenSupportsScope(const std::vector<std::string>, const std::string&&);
|
bool tokenSupportsScope(const std::vector<std::string>, const std::string&&);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+11
-1
@@ -6,7 +6,17 @@ namespace type
|
|||||||
enum class Scope
|
enum class Scope
|
||||||
{
|
{
|
||||||
upload = 0,
|
upload = 0,
|
||||||
download
|
download,
|
||||||
|
stream,
|
||||||
|
retrieveSong,
|
||||||
|
updateSong,
|
||||||
|
deleteSong,
|
||||||
|
retrieveAlbum,
|
||||||
|
retrieveArtist,
|
||||||
|
retrieveGenre,
|
||||||
|
retrieveYear,
|
||||||
|
downloadCoverArt
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,11 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
callback::StreamCallback::StreamCallback() :
|
namespace callback {
|
||||||
|
StreamCallback::StreamCallback() :
|
||||||
m_counter(0) { }
|
m_counter(0) { }
|
||||||
|
|
||||||
callback::StreamCallback::StreamCallback(const std::string& songPath) :
|
StreamCallback::StreamCallback(const std::string& songPath) :
|
||||||
m_songPath(songPath),
|
m_songPath(songPath),
|
||||||
m_counter(0),
|
m_counter(0),
|
||||||
m_bytesRead(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) {
|
if (m_counter >= m_fileSize) {
|
||||||
std::cout << "done streaming song" << std::endl;
|
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;
|
return count;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,13 +13,13 @@
|
|||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
namespace manager {
|
||||||
manager::TokenManager::TokenManager()
|
TokenManager::TokenManager()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
model::LoginResult manager::TokenManager::retrieveToken(const model::BinaryPath& bConf)
|
model::LoginResult TokenManager::retrieveToken(const model::BinaryPath& bConf)
|
||||||
{
|
{
|
||||||
auto cred = parseAuthCredentials(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);
|
auto authPair = fetchAuthHeader(auth);
|
||||||
|
|
||||||
@@ -65,9 +65,26 @@ bool manager::TokenManager::isTokenValid(std::string& auth, type::Scope scope)
|
|||||||
switch (scope) {
|
switch (scope) {
|
||||||
case type::Scope::upload:
|
case type::Scope::upload:
|
||||||
return tokenSupportsScope(scopes, "upload:songs");
|
return tokenSupportsScope(scopes, "upload:songs");
|
||||||
break;
|
|
||||||
case type::Scope::download:
|
case type::Scope::download:
|
||||||
return tokenSupportsScope(scopes, "download:songs");
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -75,7 +92,7 @@ bool manager::TokenManager::isTokenValid(std::string& auth, type::Scope scope)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool manager::TokenManager::testAuth(const model::BinaryPath& bConf)
|
bool TokenManager::testAuth(const model::BinaryPath& bConf)
|
||||||
{
|
{
|
||||||
auto cred = parseAuthCredentials(bConf);
|
auto cred = parseAuthCredentials(bConf);
|
||||||
auto reqObj = createTokenBody(cred);
|
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()},
|
auto resp = cpr::Post(cpr::Url{uri}, cpr::Body{obj.dump()},
|
||||||
cpr::Header{{"Content-type", "application/json"},
|
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;
|
nlohmann::json obj;
|
||||||
obj["client_id"] = auth.clientId;
|
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");
|
exe_path.append("/authcredentials.json");
|
||||||
|
|
||||||
auto con = manager::DirectoryManager::credentialConfigContent(exe_path);
|
auto con = DirectoryManager::credentialConfigContent(exe_path);
|
||||||
|
|
||||||
model::AuthCredentials auth;
|
model::AuthCredentials auth;
|
||||||
auth.uri = "https://";
|
auth.uri = "https://";
|
||||||
@@ -129,9 +146,9 @@ model::AuthCredentials manager::TokenManager::parseAuthCredentials(std::string_v
|
|||||||
|
|
||||||
return auth;
|
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;
|
model::AuthCredentials auth;
|
||||||
auth.uri = "https://";
|
auth.uri = "https://";
|
||||||
@@ -144,7 +161,7 @@ model::AuthCredentials manager::TokenManager::parseAuthCredentials(const model::
|
|||||||
return auth;
|
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;
|
std::vector<std::string> scopes;
|
||||||
|
|
||||||
@@ -162,7 +179,7 @@ std::vector<std::string> manager::TokenManager::extractScopes(const jwt::decoded
|
|||||||
return scopes;
|
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::istringstream iss(auth);
|
||||||
std::vector<std::string> authHeader{std::istream_iterator<std::string>(iss),
|
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(),
|
return std::any_of(scopes.begin(), scopes.end(),
|
||||||
[&](std::string foundScope) {
|
[&](std::string foundScope) {
|
||||||
return (foundScope.compare(scope) == 0);
|
return (foundScope.compare(scope) == 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user