Swagger-UI resources

This commit is contained in:
lganzzzo 2018-08-01 02:48:47 +03:00
parent ce772ca800
commit 786cdb42f5
15 changed files with 429 additions and 10 deletions

View File

@ -25,6 +25,7 @@
#ifndef oatpp_swagger_Controller_hpp
#define oatpp_swagger_Controller_hpp
#include "oatpp-swagger/Resources.hpp"
#include "oatpp-swagger/oas3/Generator.hpp"
#include "oatpp/web/server/api/ApiController.hpp"
@ -39,16 +40,20 @@ namespace oatpp { namespace swagger {
class Controller : public oatpp::web::server::api::ApiController {
private:
oas3::Document::ObjectWrapper m_document;
std::shared_ptr<oatpp::swagger::Resources> m_resources;
protected:
Controller(const std::shared_ptr<ObjectMapper>& objectMapper,
const oas3::Document::ObjectWrapper& document)
const oas3::Document::ObjectWrapper& document,
const std::shared_ptr<oatpp::swagger::Resources>& resources)
: oatpp::web::server::api::ApiController(objectMapper)
, m_document(document)
, m_resources(resources)
{}
public:
static std::shared_ptr<Controller> createShared(const std::shared_ptr<Endpoints>& endpointsList,
OATPP_COMPONENT(std::shared_ptr<oatpp::swagger::DocumentInfo>, documentInfo)){
OATPP_COMPONENT(std::shared_ptr<oatpp::swagger::DocumentInfo>, documentInfo),
OATPP_COMPONENT(std::shared_ptr<oatpp::swagger::Resources>, resources)){
auto serializerConfig = oatpp::parser::json::mapping::Serializer::Config::createShared();
serializerConfig->includeNullFields = false;
@ -60,23 +65,23 @@ public:
auto document = oas3::Generator::generateDocument(documentInfo, endpointsList);
return std::shared_ptr<Controller>(new Controller(objectMapper, document));
return std::shared_ptr<Controller>(new Controller(objectMapper, document, resources));
}
/**
* Begin ENDPOINTs generation ('ApiController' codegen)
*/
#include OATPP_CODEGEN_BEGIN(ApiController)
ENDPOINT("GET", "/api-docs/oas-3.0.0.json", api) {
return createDtoResponse(Status::CODE_200, m_document);
}
// TODO Insert Your endpoints here !!!
ENDPOINT("GET", "/swagger/ui", getUIRoot) {
return createResponse(Status::CODE_200, m_resources->getResource("index.html"));
}
ENDPOINT("GET", "/swagger/{filename}", getUIResource, PATH(String, filename)) {
return createResponse(Status::CODE_200, m_resources->getResource(filename->c_str()));
}
/**
* Finish ENDPOINTs generation ('ApiController' codegen)
*/
#include OATPP_CODEGEN_END(ApiController)
};

83
Resources.cpp Normal file
View File

@ -0,0 +1,83 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "Resources.hpp"
#include <fstream>
namespace oatpp { namespace swagger {
Resources::Resources(const oatpp::String& resDir) {
if(!resDir || resDir->getSize() == 0) {
throw std::runtime_error("[oatpp::swagger::Resources::Resources()]: Invalid resDir path. Please specify full path to oatpp-swagger/res folder");
}
m_resDir = resDir;
if(m_resDir->getData()[m_resDir->getSize() - 1] != '/') {
m_resDir = m_resDir + "/";
}
}
void Resources::cacheResource(const char* fileName) {
m_resources[fileName] = loadFromFile(fileName);
}
oatpp::String Resources::loadFromFile(const char* fileName) {
auto fullFilename = m_resDir + fileName;
std::ifstream file (fullFilename->c_str(), std::ios::in|std::ios::binary|std::ios::ate);
if (file.is_open()) {
auto result = oatpp::String((v_int32) file.tellg());
file.seekg(0, std::ios::beg);
file.read((char*)result->getData(), result->getSize());
file.close();
return result;
}
OATPP_LOGE("oatpp::swagger::Resources::loadFromFile()", "Can't load file '%s'", fullFilename->c_str());
throw std::runtime_error("[oatpp::swagger::Resources::loadFromFile(...)]: Can't load file. Please make sure you specified full path to oatpp-swagger/res folder");
}
oatpp::String Resources::getResource(const oatpp::String& filename) {
auto it = m_resources.find(filename);
if(it != m_resources.end()) {
return it->second;
}
throw std::runtime_error(
"[oatpp::swagger::Resources::getResource(...)]: Resource file not found. "
"Please make sure: "
"1. You are using correct version of oatpp-swagger. "
"2. oatpp-swagger/res is not empty. "
"3. You specified correct full path to oatpp-swagger/res folder"
);
}
}}

70
Resources.hpp Normal file
View File

@ -0,0 +1,70 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef oatpp_swagger_Resources_hpp
#define oatpp_swagger_Resources_hpp
#include "oatpp/core/Types.hpp"
#include <unordered_map>
namespace oatpp { namespace swagger {
class Resources {
private:
oatpp::String m_resDir;
std::unordered_map<oatpp::String, oatpp::String> m_resources;
private:
oatpp::String loadFromFile(const char* fileName);
void cacheResource(const char* fileName);
public:
Resources(const oatpp::String& resDir);
public:
static std::shared_ptr<Resources> loadResources(const oatpp::String& resDir) {
auto res = std::make_shared<Resources>(resDir);
res->cacheResource("favicon-16x16.png");
res->cacheResource("favicon-32x32.png");
res->cacheResource("index.html");
res->cacheResource("oauth2-redirect.html");
res->cacheResource("swagger-ui-bundle.js");
res->cacheResource("swagger-ui-bundle.js.map");
res->cacheResource("swagger-ui-standalone-preset.js");
res->cacheResource("swagger-ui-standalone-preset.js.map");
res->cacheResource("swagger-ui.css");
res->cacheResource("swagger-ui.css.map");
res->cacheResource("swagger-ui.js");
res->cacheResource("swagger-ui.js.map");
return res;
}
oatpp::String getResource(const oatpp::String& filename);
};
}}
#endif /* oatpp_swagger_Resources_hpp */

BIN
res/favicon-16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

BIN
res/favicon-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

60
res/index.html Normal file
View File

@ -0,0 +1,60 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js"> </script>
<script src="./swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
// Build a system
const ui = SwaggerUIBundle({
url: "http://localhost:8000/api-docs/oas-3.0.0.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
window.ui = ui
}
</script>
</body>
</html>

67
res/oauth2-redirect.html Normal file
View File

@ -0,0 +1,67 @@
<!doctype html>
<html lang="en-US">
<body onload="run()">
</body>
</html>
<script>
'use strict';
function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state;
var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;
if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1);
} else {
qp = location.search.substring(1);
}
arr = qp.split("&")
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) {
return key === "" ? value : decodeURIComponent(value)
}
) : {}
isValid = qp.state === sentState
if ((
oauth2.auth.schema.get("flow") === "accessCode"||
oauth2.auth.schema.get("flow") === "authorizationCode"
) && !oauth2.auth.code) {
if (!isValid) {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "warning",
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
});
}
if (qp.code) {
delete oauth2.state;
oauth2.auth.code = qp.code;
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else {
let oauthErrorMsg
if (qp.error) {
oauthErrorMsg = "["+qp.error+"]: " +
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
(qp.error_uri ? "More info: "+qp.error_uri : "");
}
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
});
}
} else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close();
}
</script>

104
res/swagger-ui-bundle.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

3
res/swagger-ui.css Normal file

File diff suppressed because one or more lines are too long

1
res/swagger-ui.css.map Normal file
View File

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}

9
res/swagger-ui.js Normal file

File diff suppressed because one or more lines are too long

1
res/swagger-ui.js.map Normal file

File diff suppressed because one or more lines are too long