diff --git a/samples/client/petstore-security-test/cpp-qt5/.openapi-generator-ignore b/samples/client/petstore-security-test/cpp-qt5/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/cpp-qt5/.openapi-generator/VERSION b/samples/client/petstore-security-test/cpp-qt5/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/cpp-qt5/client/OAIFakeApi.cpp b/samples/client/petstore-security-test/cpp-qt5/client/OAIFakeApi.cpp new file mode 100644 index 00000000000..82ee2542975 --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/client/OAIFakeApi.cpp @@ -0,0 +1,82 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +#include "OAIFakeApi.h" +#include "OAIHelpers.h" + +#include +#include + +namespace OpenAPI { + +OAIFakeApi::OAIFakeApi() { + +} + +OAIFakeApi::~OAIFakeApi() { + +} + +OAIFakeApi::OAIFakeApi(QString host, QString basePath) { + this->host = host; + this->basePath = basePath; +} + +void +OAIFakeApi::testCodeInject____end__rn_n_r(const QString& test_code_inject____end____rn_n_r) { + QString fullPath; + fullPath.append(this->host).append(this->basePath).append("/fake"); + + OAIHttpRequestWorker *worker = new OAIHttpRequestWorker(); + OAIHttpRequestInput input(fullPath, "PUT"); + if (test_code_inject____end____rn_n_r != nullptr) { + input.add_var("test code inject */ ' " =end -- \r\n \n \r", test_code_inject____end____rn_n_r); + } + + + foreach(QString key, this->defaultHeaders.keys()) { + input.headers.insert(key, this->defaultHeaders.value(key)); + } + + connect(worker, + &OAIHttpRequestWorker::on_execution_finished, + this, + &OAIFakeApi::testCodeInject____end__rn_n_rCallback); + + worker->execute(&input); +} + +void +OAIFakeApi::testCodeInject____end__rn_n_rCallback(OAIHttpRequestWorker * worker) { + QString msg; + QString error_str = worker->error_str; + QNetworkReply::NetworkError error_type = worker->error_type; + + if (worker->error_type == QNetworkReply::NoError) { + msg = QString("Success! %1 bytes").arg(worker->response.length()); + } + else { + msg = "Error: " + worker->error_str; + } + worker->deleteLater(); + + if (worker->error_type == QNetworkReply::NoError) { + emit testCodeInject____end__rn_n_rSignal(); + emit testCodeInject____end__rn_n_rSignalFull(worker); + } else { + emit testCodeInject____end__rn_n_rSignalE(error_type, error_str); + emit testCodeInject____end__rn_n_rSignalEFull(worker, error_type, error_str); + } +} + + +} diff --git a/samples/client/petstore-security-test/cpp-qt5/client/OAIFakeApi.h b/samples/client/petstore-security-test/cpp-qt5/client/OAIFakeApi.h new file mode 100644 index 00000000000..471de8e8404 --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/client/OAIFakeApi.h @@ -0,0 +1,53 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +#ifndef OAI_OAIFakeApi_H +#define OAI_OAIFakeApi_H + +#include "OAIHttpRequest.h" + +#include + +#include + +namespace OpenAPI { + +class OAIFakeApi: public QObject { + Q_OBJECT + +public: + OAIFakeApi(); + OAIFakeApi(QString host, QString basePath); + ~OAIFakeApi(); + + QString host; + QString basePath; + QMap defaultHeaders; + + void testCodeInject____end__rn_n_r(const QString& test_code_inject____end____rn_n_r); + +private: + void testCodeInject____end__rn_n_rCallback (OAIHttpRequestWorker * worker); + +signals: + void testCodeInject____end__rn_n_rSignal(); + + void testCodeInject____end__rn_n_rSignalFull(OAIHttpRequestWorker* worker); + + void testCodeInject____end__rn_n_rSignalE(QNetworkReply::NetworkError error_type, QString& error_str); + + void testCodeInject____end__rn_n_rSignalEFull(OAIHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); + +}; + +} +#endif diff --git a/samples/client/petstore-security-test/cpp-qt5/client/OAIHelpers.cpp b/samples/client/petstore-security-test/cpp-qt5/client/OAIHelpers.cpp new file mode 100644 index 00000000000..136664af629 --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/client/OAIHelpers.cpp @@ -0,0 +1,327 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +#include +#include "OAIHelpers.h" +#include "OAIObject.h" + +namespace OpenAPI { + + +QString +toStringValue(const QString &value) { + return value; +} + +QString +toStringValue(const QDateTime &value){ + // ISO 8601 + return value.toString("yyyy-MM-ddTHH:mm:ss[Z|[+|-]HH:mm]"); +} + +QString +toStringValue(const QByteArray &value){ + return QString(value); +} + +QString +toStringValue(const QDate &value){ + // ISO 8601 + return value.toString(Qt::DateFormat::ISODate); +} + +QString +toStringValue(const qint32 &value) { + return QString::number(value); +} + +QString +toStringValue(const qint64 &value) { + return QString::number(value); +} + +QString +toStringValue(const bool &value) { + return QString(value ? "true" : "false"); +} + +QString +toStringValue(const float &value){ + return QString::number(static_cast(value)); +} + +QString +toStringValue(const double &value){ + return QString::number(value); +} + +QJsonValue +toJsonValue(const QString &value){ + return QJsonValue(value); +} + +QJsonValue +toJsonValue(const QDateTime &value){ + return QJsonValue(value.toString(Qt::ISODate)); +} + +QJsonValue +toJsonValue(const QByteArray &value){ + return QJsonValue(QString(value.toBase64())); +} + +QJsonValue +toJsonValue(const QDate &value){ + return QJsonValue(value.toString(Qt::ISODate)); +} + +QJsonValue +toJsonValue(const qint32 &value){ + return QJsonValue(value); +} + +QJsonValue +toJsonValue(const qint64 &value){ + return QJsonValue(value); +} + +QJsonValue +toJsonValue(const bool &value){ + return QJsonValue(value); +} + +QJsonValue +toJsonValue(const float &value){ + return QJsonValue(static_cast(value)); +} + +QJsonValue +toJsonValue(const double &value){ + return QJsonValue(value); +} + +QJsonValue +toJsonValue(const OAIObject &value){ + return value.asJsonObject(); +} + +bool +fromStringValue(const QString &inStr, QString &value){ + value.clear(); + value.append(inStr); + return !inStr.isEmpty(); +} + +bool +fromStringValue(const QString &inStr, QDateTime &value){ + if(inStr.isEmpty()){ + return false; + } + else{ + auto dateTime = QDateTime::fromString(inStr, "yyyy-MM-ddTHH:mm:ss[Z|[+|-]HH:mm]"); + if(dateTime.isValid()){ + value.setDate(dateTime.date()); + value.setTime(dateTime.time()); + } + else{ + qDebug() << "DateTime is invalid"; + } + return dateTime.isValid(); + } +} + +bool +fromStringValue(const QString &inStr, QByteArray &value){ + if(inStr.isEmpty()){ + return false; + } + else{ + value.clear(); + value.append(inStr.toUtf8()); + return value.count() > 0; + } +} + +bool +fromStringValue(const QString &inStr, QDate &value){ + if(inStr.isEmpty()){ + return false; + } + else{ + auto date = QDate::fromString(inStr, Qt::DateFormat::ISODate); + if(date.isValid()){ + value.setDate(date.year(), date.month(), date.day()); + } + else{ + qDebug() << "Date is invalid"; + } + return date.isValid(); + } +} + +bool +fromStringValue(const QString &inStr, qint32 &value){ + bool ok = false; + value = QVariant(inStr).toInt(&ok); + return ok; +} + +bool +fromStringValue(const QString &inStr, qint64 &value){ + bool ok = false; + value = QVariant(inStr).toLongLong(&ok); + return ok; +} + +bool +fromStringValue(const QString &inStr, bool &value){ + value = QVariant(inStr).toBool(); + return ((inStr == "true") || (inStr == "false")); +} + +bool +fromStringValue(const QString &inStr, float &value){ + bool ok = false; + value = QVariant(inStr).toFloat(&ok); + return ok; +} + +bool +fromStringValue(const QString &inStr, double &value){ + bool ok = false; + value = QVariant(inStr).toDouble(&ok); + return ok; +} + +bool +fromJsonValue(QString &value, const QJsonValue &jval){ + bool ok = true; + if(!jval.isUndefined() && !jval.isNull()){ + if(jval.isString()){ + value = jval.toString(); + } else if(jval.isBool()) { + value = jval.toBool() ? "true" : "false"; + } else if(jval.isDouble()){ + value = QString::number(jval.toDouble()); + } else { + ok = false; + } + } else { + ok = false; + } + return ok; +} + +bool +fromJsonValue(QDateTime &value, const QJsonValue &jval){ + bool ok = true; + if(!jval.isUndefined() && !jval.isNull() && jval.isString()){ + value = QDateTime::fromString(jval.toString(), Qt::ISODate); + ok = value.isValid(); + } else { + ok = false; + } + return ok; +} + +bool +fromJsonValue(QByteArray &value, const QJsonValue &jval){ + bool ok = true; + if(!jval.isUndefined() && !jval.isNull() && jval.isString()) { + value = QByteArray::fromBase64(QByteArray::fromStdString(jval.toString().toStdString())); + ok = value.size() > 0 ; + } else { + ok = false; + } + return ok; +} + +bool +fromJsonValue(QDate &value, const QJsonValue &jval){ + bool ok = true; + if(!jval.isUndefined() && !jval.isNull() && jval.isString()){ + value = QDate::fromString(jval.toString(), Qt::ISODate); + ok = value.isValid(); + } else { + ok = false; + } + return ok; +} + +bool +fromJsonValue(qint32 &value, const QJsonValue &jval){ + bool ok = true; + if(!jval.isUndefined() && !jval.isNull() && !jval.isObject() && !jval.isArray()){ + value = jval.toInt(); + } else { + ok = false; + } + return ok; +} + +bool +fromJsonValue(qint64 &value, const QJsonValue &jval){ + bool ok = true; + if(!jval.isUndefined() && !jval.isNull() && !jval.isObject() && !jval.isArray()){ + value = jval.toVariant().toLongLong(); + } else { + ok = false; + } + return ok; +} + +bool +fromJsonValue(bool &value, const QJsonValue &jval){ + bool ok = true; + if(jval.isBool()){ + value = jval.toBool(); + } else { + ok = false; + } + return ok; +} + +bool +fromJsonValue(float &value, const QJsonValue &jval){ + bool ok = true; + if(jval.isDouble()){ + value = static_cast(jval.toDouble()); + } else { + ok = false; + } + return ok; +} + +bool +fromJsonValue(double &value, const QJsonValue &jval){ + bool ok = true; + if(jval.isDouble()){ + value = jval.toDouble(); + } else { + ok = false; + } + return ok; +} + +bool +fromJsonValue(OAIObject &value, const QJsonValue &jval){ + bool ok = true; + if(jval.isObject()){ + value.fromJsonObject(jval.toObject()); + ok = value.isValid(); + } else { + ok = false; + } + return ok; +} + +} diff --git a/samples/client/petstore-security-test/cpp-qt5/client/OAIHelpers.h b/samples/client/petstore-security-test/cpp-qt5/client/OAIHelpers.h new file mode 100644 index 00000000000..f1ab48190b9 --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/client/OAIHelpers.h @@ -0,0 +1,158 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +#ifndef OAI_HELPERS_H +#define OAI_HELPERS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "OAIObject.h" + +namespace OpenAPI { + + QString toStringValue(const QString &value); + QString toStringValue(const QDateTime &value); + QString toStringValue(const QByteArray &value); + QString toStringValue(const QDate &value); + QString toStringValue(const qint32 &value); + QString toStringValue(const qint64 &value); + QString toStringValue(const bool &value); + QString toStringValue(const float &value); + QString toStringValue(const double &value); + + template + QString toStringValue(const QList &val) { + QString strArray; + for(const auto& item : val) { + strArray.append(toStringValue(item) + ","); + } + if(val.count() > 0) { + strArray.chop(1); + } + return strArray; + } + + QJsonValue toJsonValue(const QString &value); + QJsonValue toJsonValue(const QDateTime &value); + QJsonValue toJsonValue(const QByteArray &value); + QJsonValue toJsonValue(const QDate &value); + QJsonValue toJsonValue(const qint32 &value); + QJsonValue toJsonValue(const qint64 &value); + QJsonValue toJsonValue(const bool &value); + QJsonValue toJsonValue(const float &value); + QJsonValue toJsonValue(const double &value); + QJsonValue toJsonValue(const OAIObject &value); + + template + QJsonValue toJsonValue(const QList &val) { + QJsonArray jArray; + for(const auto& item : val) { + jArray.append(toJsonValue(item)); + } + return jArray; + } + + template + QJsonValue toJsonValue(const QMap &val) { + QJsonObject jObject; + for(const auto& itemkey : val.keys()) { + jObject.insert(itemkey, toJsonValue(val.value(itemkey))); + } + return jObject; + } + + bool fromStringValue(const QString &inStr, QString &value); + bool fromStringValue(const QString &inStr, QDateTime &value); + bool fromStringValue(const QString &inStr, QByteArray &value); + bool fromStringValue(const QString &inStr, QDate &value); + bool fromStringValue(const QString &inStr, qint32 &value); + bool fromStringValue(const QString &inStr, qint64 &value); + bool fromStringValue(const QString &inStr, bool &value); + bool fromStringValue(const QString &inStr, float &value); + bool fromStringValue(const QString &inStr, double &value); + + template + bool fromStringValue(const QList &inStr, QList &val) { + bool ok = (inStr.count() > 0); + for(const auto& item: inStr){ + T itemVal; + ok &= fromStringValue(item, itemVal); + val.push_back(itemVal); + } + return ok; + } + + template + bool fromStringValue(const QMap &inStr, QMap &val) { + bool ok = (inStr.count() > 0); + for(const auto& itemkey : inStr.keys()){ + T itemVal; + ok &= fromStringValue(inStr.value(itemkey), itemVal); + val.insert(itemkey, itemVal); + } + return ok; + } + + bool fromJsonValue(QString &value, const QJsonValue &jval); + bool fromJsonValue(QDateTime &value, const QJsonValue &jval); + bool fromJsonValue(QByteArray &value, const QJsonValue &jval); + bool fromJsonValue(QDate &value, const QJsonValue &jval); + bool fromJsonValue(qint32 &value, const QJsonValue &jval); + bool fromJsonValue(qint64 &value, const QJsonValue &jval); + bool fromJsonValue(bool &value, const QJsonValue &jval); + bool fromJsonValue(float &value, const QJsonValue &jval); + bool fromJsonValue(double &value, const QJsonValue &jval); + bool fromJsonValue(OAIObject &value, const QJsonValue &jval); + + template + bool fromJsonValue(QList &val, const QJsonValue &jval) { + bool ok = true; + if(jval.isArray()){ + for(const auto& jitem : jval.toArray()){ + T item; + ok &= fromJsonValue(item, jitem); + val.push_back(item); + } + } else { + ok = false; + } + return ok; + } + + template + bool fromJsonValue(QMap &val, const QJsonValue &jval) { + bool ok = true; + if(jval.isObject()){ + auto varmap = jval.toObject().toVariantMap(); + if(varmap.count() > 0){ + for(const auto& itemkey : varmap.keys() ){ + T itemVal; + ok &= fromJsonValue(itemVal, QJsonValue::fromVariant(varmap.value(itemkey))); + val.insert(itemkey, itemVal); + } + } + } else { + ok = false; + } + return ok; + } + +} + +#endif // OAI_HELPERS_H diff --git a/samples/client/petstore-security-test/cpp-qt5/client/OAIHttpRequest.cpp b/samples/client/petstore-security-test/cpp-qt5/client/OAIHttpRequest.cpp new file mode 100644 index 00000000000..9854226e134 --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/client/OAIHttpRequest.cpp @@ -0,0 +1,333 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +#include "OAIHttpRequest.h" +#include +#include +#include +#include +#include + + +namespace OpenAPI { + +OAIHttpRequestInput::OAIHttpRequestInput() { + initialize(); +} + +OAIHttpRequestInput::OAIHttpRequestInput(QString v_url_str, QString v_http_method) { + initialize(); + url_str = v_url_str; + http_method = v_http_method; +} + +void OAIHttpRequestInput::initialize() { + var_layout = NOT_SET; + url_str = ""; + http_method = "GET"; +} + +void OAIHttpRequestInput::add_var(QString key, QString value) { + vars[key] = value; +} + +void OAIHttpRequestInput::add_file(QString variable_name, QString local_filename, QString request_filename, QString mime_type) { + OAIHttpRequestInputFileElement file; + file.variable_name = variable_name; + file.local_filename = local_filename; + file.request_filename = request_filename; + file.mime_type = mime_type; + files.append(file); +} + + +OAIHttpRequestWorker::OAIHttpRequestWorker(QObject *parent) + : QObject(parent), manager(nullptr) +{ + qsrand(QDateTime::currentDateTime().toTime_t()); + + manager = new QNetworkAccessManager(this); + connect(manager, &QNetworkAccessManager::finished, this, &OAIHttpRequestWorker::on_manager_finished); +} + +OAIHttpRequestWorker::~OAIHttpRequestWorker() { +} + +QMap OAIHttpRequestWorker::getResponseHeaders() const { + return headers; +} + +QString OAIHttpRequestWorker::http_attribute_encode(QString attribute_name, QString input) { + // result structure follows RFC 5987 + bool need_utf_encoding = false; + QString result = ""; + QByteArray input_c = input.toLocal8Bit(); + char c; + for (int i = 0; i < input_c.length(); i++) { + c = input_c.at(i); + if (c == '\\' || c == '/' || c == '\0' || c < ' ' || c > '~') { + // ignore and request utf-8 version + need_utf_encoding = true; + } + else if (c == '"') { + result += "\\\""; + } + else { + result += c; + } + } + + if (result.length() == 0) { + need_utf_encoding = true; + } + + if (!need_utf_encoding) { + // return simple version + return QString("%1=\"%2\"").arg(attribute_name, result); + } + + QString result_utf8 = ""; + for (int i = 0; i < input_c.length(); i++) { + c = input_c.at(i); + if ( + (c >= '0' && c <= '9') + || (c >= 'A' && c <= 'Z') + || (c >= 'a' && c <= 'z') + ) { + result_utf8 += c; + } + else { + result_utf8 += "%" + QString::number(static_cast(input_c.at(i)), 16).toUpper(); + } + } + + // return enhanced version with UTF-8 support + return QString("%1=\"%2\"; %1*=utf-8''%3").arg(attribute_name, result, result_utf8); +} + +void OAIHttpRequestWorker::execute(OAIHttpRequestInput *input) { + + // reset variables + + QByteArray request_content = ""; + response = ""; + error_type = QNetworkReply::NoError; + error_str = ""; + bool isFormData = false; + + + // decide on the variable layout + + if (input->files.length() > 0) { + input->var_layout = MULTIPART; + } + if (input->var_layout == NOT_SET) { + input->var_layout = input->http_method == "GET" || input->http_method == "HEAD" ? ADDRESS : URL_ENCODED; + } + + + // prepare request content + + QString boundary = ""; + + if (input->var_layout == ADDRESS || input->var_layout == URL_ENCODED) { + // variable layout is ADDRESS or URL_ENCODED + + if (input->vars.count() > 0) { + bool first = true; + isFormData = true; + foreach (QString key, input->vars.keys()) { + if (!first) { + request_content.append("&"); + } + first = false; + + request_content.append(QUrl::toPercentEncoding(key)); + request_content.append("="); + request_content.append(QUrl::toPercentEncoding(input->vars.value(key))); + } + + if (input->var_layout == ADDRESS) { + input->url_str += "?" + request_content; + request_content = ""; + } + } + } + else { + // variable layout is MULTIPART + + boundary = "__-----------------------" + + QString::number(QDateTime::currentDateTime().toTime_t()) + + QString::number(qrand()); + QString boundary_delimiter = "--"; + QString new_line = "\r\n"; + + // add variables + foreach (QString key, input->vars.keys()) { + // add boundary + request_content.append(boundary_delimiter); + request_content.append(boundary); + request_content.append(new_line); + + // add header + request_content.append("Content-Disposition: form-data; "); + request_content.append(http_attribute_encode("name", key)); + request_content.append(new_line); + request_content.append("Content-Type: text/plain"); + request_content.append(new_line); + + // add header to body splitter + request_content.append(new_line); + + // add variable content + request_content.append(input->vars.value(key)); + request_content.append(new_line); + } + + // add files + for (QList::iterator file_info = input->files.begin(); file_info != input->files.end(); file_info++) { + QFileInfo fi(file_info->local_filename); + + // ensure necessary variables are available + if ( + file_info->local_filename == nullptr || file_info->local_filename.isEmpty() + || file_info->variable_name == nullptr || file_info->variable_name.isEmpty() + || !fi.exists() || !fi.isFile() || !fi.isReadable() + ) { + // silent abort for the current file + continue; + } + + QFile file(file_info->local_filename); + if (!file.open(QIODevice::ReadOnly)) { + // silent abort for the current file + continue; + } + + // ensure filename for the request + if (file_info->request_filename == nullptr || file_info->request_filename.isEmpty()) { + file_info->request_filename = fi.fileName(); + if (file_info->request_filename.isEmpty()) { + file_info->request_filename = "file"; + } + } + + // add boundary + request_content.append(boundary_delimiter); + request_content.append(boundary); + request_content.append(new_line); + + // add header + request_content.append(QString("Content-Disposition: form-data; %1; %2").arg( + http_attribute_encode("name", file_info->variable_name), + http_attribute_encode("filename", file_info->request_filename) + )); + request_content.append(new_line); + + if (file_info->mime_type != nullptr && !file_info->mime_type.isEmpty()) { + request_content.append("Content-Type: "); + request_content.append(file_info->mime_type); + request_content.append(new_line); + } + + request_content.append("Content-Transfer-Encoding: binary"); + request_content.append(new_line); + + // add header to body splitter + request_content.append(new_line); + + // add file content + request_content.append(file.readAll()); + request_content.append(new_line); + + file.close(); + } + + // add end of body + request_content.append(boundary_delimiter); + request_content.append(boundary); + request_content.append(boundary_delimiter); + } + + if(input->request_body.size() > 0) { + qDebug() << "got a request body"; + request_content.clear(); + request_content.append(input->request_body); + } + // prepare connection + + QNetworkRequest request = QNetworkRequest(QUrl(input->url_str)); + if (OAIHttpRequestWorker::sslDefaultConfiguration != nullptr) { + request.setSslConfiguration(*OAIHttpRequestWorker::sslDefaultConfiguration); + } + request.setRawHeader("User-Agent", "OpenAPI-Generator/1.0.0/cpp-qt5"); + foreach(QString key, input->headers.keys()) { + request.setRawHeader(key.toStdString().c_str(), input->headers.value(key).toStdString().c_str()); + } + + if (request_content.size() > 0 && !isFormData) { + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + } + else if (input->var_layout == URL_ENCODED) { + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + } + else if (input->var_layout == MULTIPART) { + request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + boundary); + } + + if (input->http_method == "GET") { + manager->get(request); + } + else if (input->http_method == "POST") { + manager->post(request, request_content); + } + else if (input->http_method == "PUT") { + manager->put(request, request_content); + } + else if (input->http_method == "HEAD") { + manager->head(request); + } + else if (input->http_method == "DELETE") { + manager->deleteResource(request); + } + else { +#if (QT_VERSION >= 0x050800) + manager->sendCustomRequest(request, input->http_method.toLatin1(), request_content); +#else + QBuffer *buffer = new QBuffer; + buffer->setData(request_content); + buffer->open(QIODevice::ReadOnly); + + QNetworkReply* reply = manager->sendCustomRequest(request, input->http_method.toLatin1(), buffer); + buffer->setParent(reply); +#endif + } + +} + +void OAIHttpRequestWorker::on_manager_finished(QNetworkReply *reply) { + error_type = reply->error(); + response = reply->readAll(); + error_str = reply->errorString(); + if(reply->rawHeaderPairs().count() > 0){ + for(const auto& item: reply->rawHeaderPairs()){ + headers.insert(item.first, item.second); + } + } + reply->deleteLater(); + + emit on_execution_finished(this); +} +QSslConfiguration* OAIHttpRequestWorker::sslDefaultConfiguration; + + +} diff --git a/samples/client/petstore-security-test/cpp-qt5/client/OAIHttpRequest.h b/samples/client/petstore-security-test/cpp-qt5/client/OAIHttpRequest.h new file mode 100644 index 00000000000..af19b1e06fb --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/client/OAIHttpRequest.h @@ -0,0 +1,94 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +/** + * Based on http://www.creativepulse.gr/en/blog/2014/restful-api-requests-using-qt-cpp-for-linux-mac-osx-ms-windows + * By Alex Stylianos + * + **/ + +#ifndef OAI_HTTPREQUESTWORKER_H +#define OAI_HTTPREQUESTWORKER_H + +#include +#include +#include +#include +#include + + + +namespace OpenAPI { + +enum OAIHttpRequestVarLayout {NOT_SET, ADDRESS, URL_ENCODED, MULTIPART}; + +class OAIHttpRequestInputFileElement { + +public: + QString variable_name; + QString local_filename; + QString request_filename; + QString mime_type; + +}; + + +class OAIHttpRequestInput { + +public: + QString url_str; + QString http_method; + OAIHttpRequestVarLayout var_layout; + QMap vars; + QMap headers; + QList files; + QByteArray request_body; + + OAIHttpRequestInput(); + OAIHttpRequestInput(QString v_url_str, QString v_http_method); + void initialize(); + void add_var(QString key, QString value); + void add_file(QString variable_name, QString local_filename, QString request_filename, QString mime_type); + +}; + + +class OAIHttpRequestWorker : public QObject { + Q_OBJECT + +public: + QByteArray response; + QNetworkReply::NetworkError error_type; + QString error_str; + + explicit OAIHttpRequestWorker(QObject *parent = nullptr); + virtual ~OAIHttpRequestWorker(); + + QMap getResponseHeaders() const; + QString http_attribute_encode(QString attribute_name, QString input); + void execute(OAIHttpRequestInput *input); + static QSslConfiguration* sslDefaultConfiguration; + +signals: + void on_execution_finished(OAIHttpRequestWorker *worker); + +private: + QNetworkAccessManager *manager; + QMap headers; +private slots: + void on_manager_finished(QNetworkReply *reply); + +}; + +} + +#endif // OAI_HTTPREQUESTWORKER_H diff --git a/samples/client/petstore-security-test/cpp-qt5/client/OAIObject.h b/samples/client/petstore-security-test/cpp-qt5/client/OAIObject.h new file mode 100644 index 00000000000..b95ccca62ba --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/client/OAIObject.h @@ -0,0 +1,66 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +#ifndef OAI_OBJECT_H +#define OAI_OBJECT_H + +#include +#include + +namespace OpenAPI { + +class OAIObject { + public: + OAIObject() { + + } + + OAIObject(QString jsonString) { + fromJson(jsonString); + } + + virtual ~OAIObject(){ + + } + + virtual QJsonObject asJsonObject() const { + return jObj; + } + + virtual QString asJson() const { + QJsonDocument doc(jObj); + return doc.toJson(QJsonDocument::Compact); + } + + virtual void fromJson(QString jsonString) { + QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8()); + jObj = doc.object(); + } + + virtual void fromJsonObject(QJsonObject json) { + jObj = json; + } + + virtual bool isSet() const { + return false; + } + + virtual bool isValid() const { + return true; + } +private : + QJsonObject jObj; +}; + +} + +#endif // OAI_OBJECT_H diff --git a/samples/client/petstore-security-test/cpp-qt5/client/OAIReturn.cpp b/samples/client/petstore-security-test/cpp-qt5/client/OAIReturn.cpp new file mode 100644 index 00000000000..29ce188642f --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/client/OAIReturn.cpp @@ -0,0 +1,101 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +#include "OAIReturn.h" + +#include "OAIHelpers.h" + +#include +#include +#include +#include + +namespace OpenAPI { + +OAIReturn::OAIReturn(QString json) { + this->init(); + this->fromJson(json); +} + +OAIReturn::OAIReturn() { + this->init(); +} + +OAIReturn::~OAIReturn() { + +} + +void +OAIReturn::init() { + m__return_isSet = false; + m__return_isValid = false; +} + +void +OAIReturn::fromJson(QString jsonString) { + QByteArray array (jsonString.toStdString().c_str()); + QJsonDocument doc = QJsonDocument::fromJson(array); + QJsonObject jsonObject = doc.object(); + this->fromJsonObject(jsonObject); +} + +void +OAIReturn::fromJsonObject(QJsonObject json) { + m__return_isValid = ::OpenAPI::fromJsonValue(_return, json[QString("return")]); + +} + +QString +OAIReturn::asJson () const { + QJsonObject obj = this->asJsonObject(); + QJsonDocument doc(obj); + QByteArray bytes = doc.toJson(); + return QString(bytes); +} + +QJsonObject +OAIReturn::asJsonObject() const { + QJsonObject obj; + if(m__return_isSet){ + obj.insert(QString("return"), ::OpenAPI::toJsonValue(_return)); + } + return obj; +} + +qint32 +OAIReturn::getReturn() const { + return _return; +} +void +OAIReturn::setReturn(const qint32 &_return) { + this->_return = _return; + this->m__return_isSet = true; +} + +bool +OAIReturn::isSet() const { + bool isObjectUpdated = false; + do{ + if(m__return_isSet){ isObjectUpdated = true; break;} + }while(false); + return isObjectUpdated; +} + +bool +OAIReturn::isValid() const { + // only required properties are required for the object to be considered valid + return true; +} + +} + diff --git a/samples/client/petstore-security-test/cpp-qt5/client/OAIReturn.h b/samples/client/petstore-security-test/cpp-qt5/client/OAIReturn.h new file mode 100644 index 00000000000..c76f5915e12 --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/client/OAIReturn.h @@ -0,0 +1,56 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +/* + * OAIReturn.h + * + * Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r + */ + +#ifndef OAIReturn_H +#define OAIReturn_H + +#include + + + +#include "OAIObject.h" + +namespace OpenAPI { + +class OAIReturn: public OAIObject { +public: + OAIReturn(); + OAIReturn(QString json); + ~OAIReturn() override; + + QString asJson () const override; + QJsonObject asJsonObject() const override; + void fromJsonObject(QJsonObject json) override; + void fromJson(QString jsonString) override; + + qint32 getReturn() const; + void setReturn(const qint32 &_return); + + virtual bool isSet() const override; + virtual bool isValid() const override; + +private: + void init(); + qint32 _return; + bool m__return_isSet; + bool m__return_isValid; +}; + +} + +#endif // OAIReturn_H diff --git a/samples/client/petstore-security-test/cpp-qt5/client/client.pri b/samples/client/petstore-security-test/cpp-qt5/client/client.pri new file mode 100644 index 00000000000..4b400c6372f --- /dev/null +++ b/samples/client/petstore-security-test/cpp-qt5/client/client.pri @@ -0,0 +1,21 @@ +QT += network + +HEADERS += \ +# Models + $${PWD}/OAIReturn.h \ +# APIs + $${PWD}/OAIFakeApi.h \ +# Others + $${PWD}/OAIHelpers.h \ + $${PWD}/OAIHttpRequest.h \ + $${PWD}/OAIObject.h + +SOURCES += \ +# Models + $${PWD}/OAIReturn.cpp \ +# APIs + $${PWD}/OAIFakeApi.cpp \ +# Others + $${PWD}/OAIHelpers.cpp \ + $${PWD}/OAIHttpRequest.cpp + diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/.gitignore b/samples/client/petstore-security-test/csharp/SwaggerClient/.gitignore new file mode 100644 index 00000000000..17302c93bf0 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/.gitignore @@ -0,0 +1,186 @@ +# Ref: https://gist.github.com/kmorcinek/2710267 +# Download this file using PowerShell v3 under Windows with the following comand +# Invoke-WebRequest https://gist.githubusercontent.com/kmorcinek/2710267/raw/ -OutFile .gitignore + +# User-specific files +*.suo +*.user +*.sln.docstates +./nuget + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# OS generated files # +.DS_Store* +ehthumbs.db +Icon? +Thumbs.db + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings +modulesbin/ +tempbin/ + +# EPiServer Site file (VPP) +AppData/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# vim +*.txt~ +*.swp +*.swo + +# svn +.svn + +# SQL Server files +**/App_Data/*.mdf +**/App_Data/*.ldf +**/App_Data/*.sdf + + +#LightSwitch generated files +GeneratedArtifacts/ +_Pvt_Extensions/ +ModelManifest.xml + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac desktop service store files +.DS_Store + +# SASS Compiler cache +.sass-cache + +# Visual Studio 2014 CTP +**/*.sln.ide diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/.openapi-generator-ignore b/samples/client/petstore-security-test/csharp/SwaggerClient/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/.openapi-generator/VERSION b/samples/client/petstore-security-test/csharp/SwaggerClient/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/.travis.yml b/samples/client/petstore-security-test/csharp/SwaggerClient/.travis.yml new file mode 100644 index 00000000000..e4965fc7e5c --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/.travis.yml @@ -0,0 +1,9 @@ +# +# Generated by: https://github.com/openapitools/openapi-generator.git +# +language: csharp +mono: + - latest +solution: Org.OpenAPITools.sln +script: + - /bin/sh ./mono_nunit_test.sh diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/Org.OpenAPITools.sln b/samples/client/petstore-security-test/csharp/SwaggerClient/Org.OpenAPITools.sln new file mode 100644 index 00000000000..bbfdbfc85f2 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/Org.OpenAPITools.sln @@ -0,0 +1,27 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +VisualStudioVersion = 12.0.0.0 +MinimumVisualStudioVersion = 10.0.0.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Org.OpenAPITools", "src\Org.OpenAPITools\Org.OpenAPITools.csproj", "{8CE139DF-64BC-4591-85F8-8506C2B67514}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Org.OpenAPITools.Test", "src\Org.OpenAPITools.Test\Org.OpenAPITools.Test.csproj", "{19F1DEBC-DE5E-4517-8062-F000CD499087}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8CE139DF-64BC-4591-85F8-8506C2B67514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8CE139DF-64BC-4591-85F8-8506C2B67514}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8CE139DF-64BC-4591-85F8-8506C2B67514}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8CE139DF-64BC-4591-85F8-8506C2B67514}.Release|Any CPU.Build.0 = Release|Any CPU + {19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19F1DEBC-DE5E-4517-8062-F000CD499087}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19F1DEBC-DE5E-4517-8062-F000CD499087}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal \ No newline at end of file diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/README.md b/samples/client/petstore-security-test/csharp/SwaggerClient/README.md new file mode 100644 index 00000000000..dba339f2eb6 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/README.md @@ -0,0 +1,126 @@ +# Org.OpenAPITools - the C# library for the OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + +This C# SDK is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r +- SDK version: 1.0.0 +- Build package: org.openapitools.codegen.languages.CSharpClientCodegen + + +## Frameworks supported +- .NET 4.0 or later +- Windows Phone 7.1 (Mango) + + +## Dependencies +- [RestSharp](https://www.nuget.org/packages/RestSharp) - 105.1.0 or later +- [Json.NET](https://www.nuget.org/packages/Newtonsoft.Json/) - 7.0.0 or later +- [JsonSubTypes](https://www.nuget.org/packages/JsonSubTypes/) - 1.2.0 or later + +The DLLs included in the package may not be the latest version. We recommend using [NuGet](https://docs.nuget.org/consume/installing-nuget) to obtain the latest version of the packages: +``` +Install-Package RestSharp +Install-Package Newtonsoft.Json +Install-Package JsonSubTypes +``` + +NOTE: RestSharp versions greater than 105.1.0 have a bug which causes file uploads to fail. See [RestSharp#742](https://github.com/restsharp/RestSharp/issues/742) + + +## Installation +Run the following command to generate the DLL +- [Mac/Linux] `/bin/sh build.sh` +- [Windows] `build.bat` + +Then include the DLL (under the `bin` folder) in the C# project, and use the namespaces: +```csharp +using Org.OpenAPITools.Api; +using Org.OpenAPITools.Client; +using Org.OpenAPITools.Model; +``` + +## Packaging + +A `.nuspec` is included with the project. You can follow the Nuget quickstart to [create](https://docs.microsoft.com/en-us/nuget/quickstart/create-and-publish-a-package#create-the-package) and [publish](https://docs.microsoft.com/en-us/nuget/quickstart/create-and-publish-a-package#publish-the-package) packages. + +This `.nuspec` uses placeholders from the `.csproj`, so build the `.csproj` directly: + +``` +nuget pack -Build -OutputDirectory out Org.OpenAPITools.csproj +``` + +Then, publish to a [local feed](https://docs.microsoft.com/en-us/nuget/hosting-packages/local-feeds) or [other host](https://docs.microsoft.com/en-us/nuget/hosting-packages/overview) and consume the new package via Nuget as usual. + + +## Getting Started + +```csharp +using System; +using System.Diagnostics; +using Org.OpenAPITools.Api; +using Org.OpenAPITools.Client; +using Org.OpenAPITools.Model; + +namespace Example +{ + public class Example + { + public void main() + { + + var apiInstance = new FakeApi(); + var testCodeInjectEndRnNR = testCodeInjectEndRnNR_example; // string | To test code injection *_/ ' \\\" =end - - \\\\r\\\\n \\\\n \\\\r (optional) + + try + { + // To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + apiInstance.TestCodeInjectEndRnNR(testCodeInjectEndRnNR); + } + catch (Exception e) + { + Debug.Print("Exception when calling FakeApi.TestCodeInjectEndRnNR: " + e.Message ); + } + + } + } +} +``` + + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end - - \\r\\n \\n \\r/v2 *_/ ' \" =end - - \\r\\n \\n \\r* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*FakeApi* | [**TestCodeInjectEndRnNR**](docs/FakeApi.md#testcodeinjectendrnnr) | **PUT** /fake | To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + + + +## Documentation for Models + + - [Model.Return](docs/Return.md) + + + +## Documentation for Authorization + + +### api_key + +- **Type**: API key +- **API key parameter name**: api_key */ ' " =end -- \r\n \n \r +- **Location**: HTTP header + + +### petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - write:pets: modify pets in your account *_/ ' \" =end - - \\r\\n \\n \\r + - read:pets: read your pets *_/ ' \" =end - - \\r\\n \\n \\r + diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/build.bat b/samples/client/petstore-security-test/csharp/SwaggerClient/build.bat new file mode 100644 index 00000000000..88942a71d0f --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/build.bat @@ -0,0 +1,17 @@ +:: Generated by: https://github.com/openapitools/openapi-generator.git +:: + +@echo off + +SET CSCPATH=%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319 + +if not exist ".\nuget.exe" powershell -Command "(new-object System.Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '.\nuget.exe')" +.\nuget.exe install src\Org.OpenAPITools\packages.config -o packages + +if not exist ".\bin" mkdir bin + +copy packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll bin\Newtonsoft.Json.dll +copy packages\JsonSubTypes.1.2.0\lib\net45\JsonSubTypes.dll bin\JsonSubTypes.dll +copy packages\RestSharp.105.1.0\lib\net45\RestSharp.dll bin\RestSharp.dll +%CSCPATH%\csc /reference:bin\Newtonsoft.Json.dll;bin\JsonSubTypes.dll;bin\RestSharp.dll;System.ComponentModel.DataAnnotations.dll /target:library /out:bin\Org.OpenAPITools.dll /recurse:src\Org.OpenAPITools\*.cs /doc:bin\Org.OpenAPITools.xml + diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/build.sh b/samples/client/petstore-security-test/csharp/SwaggerClient/build.sh new file mode 100644 index 00000000000..269c087258e --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/build.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# +# Generated by: https://github.com/openapitools/openapi-generator.git +# + +frameworkVersion=net45 + +# sdk must match installed framworks under PREFIX/lib/mono/[value] +sdk=4.5.2-api + +# langversion refers to C# language features. see man mcs for details. +langversion=${sdk} +nuget_cmd=nuget + +# Match against our known SDK possibilities +case "${sdk}" in + 4) + langversion=4 + ;; + 4.5*) + langversion=5 + ;; + 4.6*) + langversion=6 + ;; + 4.7*) + langversion=7 # ignoring 7.1 for now. + ;; + *) + langversion=6 + ;; +esac + +echo "[INFO] Target framework: ${frameworkVersion}" + +if ! type nuget &>/dev/null; then + echo "[INFO] Download nuget and packages" + wget -nc https://dist.nuget.org/win-x86-commandline/latest/nuget.exe; + nuget_cmd="mono nuget.exe" +fi + +mozroots --import --sync +${nuget_cmd} install src/Org.OpenAPITools/packages.config -o packages; + +echo "[INFO] Copy DLLs to the 'bin' folder" +mkdir -p bin; +cp packages/Newtonsoft.Json.10.0.3/lib/net45/Newtonsoft.Json.dll bin/Newtonsoft.Json.dll; +cp packages/RestSharp.105.1.0/lib/net45/RestSharp.dll bin/RestSharp.dll; +cp packages/JsonSubTypes.1.2.0/lib/net45/JsonSubTypes.dll bin/JsonSubTypes.dll + +echo "[INFO] Run 'mcs' to build bin/Org.OpenAPITools.dll" +mcs -langversion:${langversion} -sdk:${sdk} -r:bin/Newtonsoft.Json.dll,bin/JsonSubTypes.dll,\ +bin/RestSharp.dll,\ +System.ComponentModel.DataAnnotations.dll,\ +System.Runtime.Serialization.dll \ +-target:library \ +-out:bin/Org.OpenAPITools.dll \ +-recurse:'src/Org.OpenAPITools/*.cs' \ +-doc:bin/Org.OpenAPITools.xml \ +-platform:anycpu + +if [ $? -ne 0 ] +then + echo "[ERROR] Compilation failed with exit code $?" + exit 1 +else + echo "[INFO] bin/Org.OpenAPITools.dll was created successfully" +fi diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/docs/FakeApi.md b/samples/client/petstore-security-test/csharp/SwaggerClient/docs/FakeApi.md new file mode 100644 index 00000000000..beb59544e67 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/docs/FakeApi.md @@ -0,0 +1,69 @@ +# Org.OpenAPITools.Api.FakeApi + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end - - \\r\\n \\n \\r/v2 *_/ ' \" =end - - \\r\\n \\n \\r* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**TestCodeInjectEndRnNR**](FakeApi.md#testcodeinjectendrnnr) | **PUT** /fake | To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + + + +# **TestCodeInjectEndRnNR** +> void TestCodeInjectEndRnNR (string testCodeInjectEndRnNR = null) + +To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + +To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + +### Example +```csharp +using System; +using System.Diagnostics; +using Org.OpenAPITools.Api; +using Org.OpenAPITools.Client; +using Org.OpenAPITools.Model; + +namespace Example +{ + public class TestCodeInjectEndRnNRExample + { + public void main() + { + var apiInstance = new FakeApi(); + var testCodeInjectEndRnNR = testCodeInjectEndRnNR_example; // string | To test code injection *_/ ' \\\" =end - - \\\\r\\\\n \\\\n \\\\r (optional) + + try + { + // To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + apiInstance.TestCodeInjectEndRnNR(testCodeInjectEndRnNR); + } + catch (Exception e) + { + Debug.Print("Exception when calling FakeApi.TestCodeInjectEndRnNR: " + e.Message ); + } + } + } +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **testCodeInjectEndRnNR** | **string**| To test code injection *_/ ' \\\" =end - - \\\\r\\\\n \\\\n \\\\r | [optional] + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded, *_/ ' =end - - + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/docs/Return.md b/samples/client/petstore-security-test/csharp/SwaggerClient/docs/Return.md new file mode 100644 index 00000000000..7f8bb567d78 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/docs/Return.md @@ -0,0 +1,9 @@ +# Org.OpenAPITools.Model.Return +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**_Return** | **int?** | property description *_/ ' \" =end - - \\r\\n \\n \\r | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/git_push.sh b/samples/client/petstore-security-test/csharp/SwaggerClient/git_push.sh new file mode 100644 index 00000000000..4d22bfef4d7 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/mono_nunit_test.sh b/samples/client/petstore-security-test/csharp/SwaggerClient/mono_nunit_test.sh new file mode 100644 index 00000000000..039eba8ed42 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/mono_nunit_test.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# +# Generated by: https://github.com/openapitools/openapi-generator.git +# + +wget -nc https://dist.nuget.org/win-x86-commandline/latest/nuget.exe +mozroots --import --sync + +echo "[INFO] remove bin/Debug/Org.OpenAPITools.Test.dll" +rm src/Org.OpenAPITools.Test/bin/Debug/Org.OpenAPITools.Test.dll 2> /dev/null + +echo "[INFO] install NUnit runners via NuGet" +wget -nc https://dist.nuget.org/win-x86-commandline/latest/nuget.exe +mozroots --import --sync +mono nuget.exe install src/Org.OpenAPITools.Test/packages.config -o packages + +echo "[INFO] Install NUnit runners via NuGet" +mono nuget.exe install NUnit.Runners -Version 2.6.4 -OutputDirectory packages + +echo "[INFO] Build the solution and run the unit test" +xbuild Org.OpenAPITools.sln && \ + mono ./packages/NUnit.Runners.2.6.4/tools/nunit-console.exe src/Org.OpenAPITools.Test/bin/Debug/Org.OpenAPITools.Test.dll diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/Api/FakeApiTests.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/Api/FakeApiTests.cs new file mode 100644 index 00000000000..64fbe25bf2b --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/Api/FakeApiTests.cs @@ -0,0 +1,80 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +using System; +using System.IO; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Reflection; +using RestSharp; +using NUnit.Framework; + +using Org.OpenAPITools.Client; +using Org.OpenAPITools.Api; + +namespace Org.OpenAPITools.Test +{ + /// + /// Class for testing FakeApi + /// + /// + /// This file is automatically generated by OpenAPI Generator (https://openapi-generator.tech). + /// Please update the test case below to test the API endpoint. + /// + [TestFixture] + public class FakeApiTests + { + private FakeApi instance; + + /// + /// Setup before each unit test + /// + [SetUp] + public void Init() + { + instance = new FakeApi(); + } + + /// + /// Clean up after each unit test + /// + [TearDown] + public void Cleanup() + { + + } + + /// + /// Test an instance of FakeApi + /// + [Test] + public void InstanceTest() + { + // TODO uncomment below to test 'IsInstanceOfType' FakeApi + //Assert.IsInstanceOfType(typeof(FakeApi), instance, "instance is a FakeApi"); + } + + + /// + /// Test TestCodeInjectEndRnNR + /// + [Test] + public void TestCodeInjectEndRnNRTest() + { + // TODO uncomment below to test the method and replace null with proper value + //string testCodeInjectEndRnNR = null; + //instance.TestCodeInjectEndRnNR(testCodeInjectEndRnNR); + + } + + } + +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/Model/ReturnTests.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/Model/ReturnTests.cs new file mode 100644 index 00000000000..106ab7f5207 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/Model/ReturnTests.cs @@ -0,0 +1,80 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + + +using NUnit.Framework; + +using System; +using System.Linq; +using System.IO; +using System.Collections.Generic; +using Org.OpenAPITools.Api; +using Org.OpenAPITools.Model; +using Org.OpenAPITools.Client; +using System.Reflection; +using Newtonsoft.Json; + +namespace Org.OpenAPITools.Test +{ + /// + /// Class for testing Return + /// + /// + /// This file is automatically generated by OpenAPI Generator (https://openapi-generator.tech). + /// Please update the test case below to test the model. + /// + [TestFixture] + public class ReturnTests + { + // TODO uncomment below to declare an instance variable for Return + //private Return instance; + + /// + /// Setup before each test + /// + [SetUp] + public void Init() + { + // TODO uncomment below to create an instance of Return + //instance = new Return(); + } + + /// + /// Clean up after each test + /// + [TearDown] + public void Cleanup() + { + + } + + /// + /// Test an instance of Return + /// + [Test] + public void ReturnInstanceTest() + { + // TODO uncomment below to test "IsInstanceOfType" Return + //Assert.IsInstanceOfType (instance, "variable 'instance' is a Return"); + } + + + /// + /// Test the property '_Return' + /// + [Test] + public void _ReturnTest() + { + // TODO unit test for the property '_Return' + } + + } + +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj new file mode 100644 index 00000000000..0f26bb33098 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj @@ -0,0 +1,89 @@ + + + + + Debug + AnyCPU + {19F1DEBC-DE5E-4517-8062-F000CD499087} + Library + Properties + Org.OpenAPITools.Test + Org.OpenAPITools.Test + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + $(SolutionDir)\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + ..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + ..\..\vendor\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + $(SolutionDir)\packages\JsonSubTypes.1.2.0\lib\net45\JsonSubTypes.dll + ..\packages\JsonSubTypes.1.2.0\lib\net45\JsonSubTypes.dll + ..\..\packages\JsonSubTypes.1.2.0\lib\net45\JsonSubTypes.dll + ..\..\vendor\JsonSubTypes.1.2.0\lib\net45\JsonSubTypes.dll + + + $(SolutionDir)\packages\RestSharp.105.1.0\lib\net45\RestSharp.dll + ..\packages\RestSharp.105.1.0\lib\net45\RestSharp.dll + ..\..\packages\RestSharp.105.1.0\lib\net45\RestSharp.dll + ..\..\vendor\RestSharp.105.1.0\lib\net45\RestSharp.dll + + + $(SolutionDir)\packages\NUnit.2.6.4\lib\nunit.framework.dll + ..\packages\NUnit.2.6.4\lib\nunit.framework.dll + ..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll + ..\..\vendor\NUnit.2.6.4\lib\nunit.framework.dll + + + + + + + + + + + + {8CE139DF-64BC-4591-85F8-8506C2B67514} + Org.OpenAPITools + + + + diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/packages.config b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/packages.config new file mode 100644 index 00000000000..ac390c1dcb3 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools.Test/packages.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Api/FakeApi.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Api/FakeApi.cs new file mode 100644 index 00000000000..13d99785fc3 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Api/FakeApi.cs @@ -0,0 +1,309 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using RestSharp; +using Org.OpenAPITools.Client; + +namespace Org.OpenAPITools.Api +{ + /// + /// Represents a collection of functions to interact with the API endpoints + /// + public interface IFakeApi : IApiAccessor + { + #region Synchronous Operations + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// Thrown when fails to make API call + /// To test code injection *_/ ' \\\" =end - - \\\\r\\\\n \\\\n \\\\r (optional) + /// + void TestCodeInjectEndRnNR (string testCodeInjectEndRnNR = null); + + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// Thrown when fails to make API call + /// To test code injection *_/ ' \\\" =end - - \\\\r\\\\n \\\\n \\\\r (optional) + /// ApiResponse of Object(void) + ApiResponse TestCodeInjectEndRnNRWithHttpInfo (string testCodeInjectEndRnNR = null); + #endregion Synchronous Operations + #region Asynchronous Operations + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// Thrown when fails to make API call + /// To test code injection *_/ ' \\\" =end - - \\\\r\\\\n \\\\n \\\\r (optional) + /// Task of void + System.Threading.Tasks.Task TestCodeInjectEndRnNRAsync (string testCodeInjectEndRnNR = null); + + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// Thrown when fails to make API call + /// To test code injection *_/ ' \\\" =end - - \\\\r\\\\n \\\\n \\\\r (optional) + /// Task of ApiResponse + System.Threading.Tasks.Task> TestCodeInjectEndRnNRAsyncWithHttpInfo (string testCodeInjectEndRnNR = null); + #endregion Asynchronous Operations + } + + /// + /// Represents a collection of functions to interact with the API endpoints + /// + public partial class FakeApi : IFakeApi + { + private Org.OpenAPITools.Client.ExceptionFactory _exceptionFactory = (name, response) => null; + + /// + /// Initializes a new instance of the class. + /// + /// + public FakeApi(String basePath) + { + this.Configuration = new Org.OpenAPITools.Client.Configuration { BasePath = basePath }; + + ExceptionFactory = Org.OpenAPITools.Client.Configuration.DefaultExceptionFactory; + } + + /// + /// Initializes a new instance of the class + /// + /// + public FakeApi() + { + this.Configuration = Org.OpenAPITools.Client.Configuration.Default; + + ExceptionFactory = Org.OpenAPITools.Client.Configuration.DefaultExceptionFactory; + } + + /// + /// Initializes a new instance of the class + /// using Configuration object + /// + /// An instance of Configuration + /// + public FakeApi(Org.OpenAPITools.Client.Configuration configuration = null) + { + if (configuration == null) // use the default one in Configuration + this.Configuration = Org.OpenAPITools.Client.Configuration.Default; + else + this.Configuration = configuration; + + ExceptionFactory = Org.OpenAPITools.Client.Configuration.DefaultExceptionFactory; + } + + /// + /// Gets the base path of the API client. + /// + /// The base path + public String GetBasePath() + { + return this.Configuration.ApiClient.RestClient.BaseUrl.ToString(); + } + + /// + /// Sets the base path of the API client. + /// + /// The base path + [Obsolete("SetBasePath is deprecated, please do 'Configuration.ApiClient = new ApiClient(\"http://new-path\")' instead.")] + public void SetBasePath(String basePath) + { + // do nothing + } + + /// + /// Gets or sets the configuration object + /// + /// An instance of the Configuration + public Org.OpenAPITools.Client.Configuration Configuration {get; set;} + + /// + /// Provides a factory method hook for the creation of exceptions. + /// + public Org.OpenAPITools.Client.ExceptionFactory ExceptionFactory + { + get + { + if (_exceptionFactory != null && _exceptionFactory.GetInvocationList().Length > 1) + { + throw new InvalidOperationException("Multicast delegate for ExceptionFactory is unsupported."); + } + return _exceptionFactory; + } + set { _exceptionFactory = value; } + } + + /// + /// Gets the default header. + /// + /// Dictionary of HTTP header + [Obsolete("DefaultHeader is deprecated, please use Configuration.DefaultHeader instead.")] + public IDictionary DefaultHeader() + { + return new ReadOnlyDictionary(this.Configuration.DefaultHeader); + } + + /// + /// Add default header. + /// + /// Header field name. + /// Header field value. + /// + [Obsolete("AddDefaultHeader is deprecated, please use Configuration.AddDefaultHeader instead.")] + public void AddDefaultHeader(string key, string value) + { + this.Configuration.AddDefaultHeader(key, value); + } + + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// Thrown when fails to make API call + /// To test code injection *_/ ' \\\" =end - - \\\\r\\\\n \\\\n \\\\r (optional) + /// + public void TestCodeInjectEndRnNR (string testCodeInjectEndRnNR = null) + { + TestCodeInjectEndRnNRWithHttpInfo(testCodeInjectEndRnNR); + } + + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// Thrown when fails to make API call + /// To test code injection *_/ ' \\\" =end - - \\\\r\\\\n \\\\n \\\\r (optional) + /// ApiResponse of Object(void) + public ApiResponse TestCodeInjectEndRnNRWithHttpInfo (string testCodeInjectEndRnNR = null) + { + + var localVarPath = "/fake"; + var localVarPathParams = new Dictionary(); + var localVarQueryParams = new List>(); + var localVarHeaderParams = new Dictionary(this.Configuration.DefaultHeader); + var localVarFormParams = new Dictionary(); + var localVarFileParams = new Dictionary(); + Object localVarPostBody = null; + + // to determine the Content-Type header + String[] localVarHttpContentTypes = new String[] { + "application/x-www-form-urlencoded", + "*_/ ' =end - - " + }; + String localVarHttpContentType = this.Configuration.ApiClient.SelectHeaderContentType(localVarHttpContentTypes); + + // to determine the Accept header + String[] localVarHttpHeaderAccepts = new String[] { + }; + String localVarHttpHeaderAccept = this.Configuration.ApiClient.SelectHeaderAccept(localVarHttpHeaderAccepts); + if (localVarHttpHeaderAccept != null) + localVarHeaderParams.Add("Accept", localVarHttpHeaderAccept); + + if (testCodeInjectEndRnNR != null) localVarFormParams.Add("test code inject */ ' " =end -- \r\n \n \r", this.Configuration.ApiClient.ParameterToString(testCodeInjectEndRnNR)); // form parameter + + + // make the HTTP request + IRestResponse localVarResponse = (IRestResponse) this.Configuration.ApiClient.CallApi(localVarPath, + Method.PUT, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarFileParams, + localVarPathParams, localVarHttpContentType); + + int localVarStatusCode = (int) localVarResponse.StatusCode; + + if (ExceptionFactory != null) + { + Exception exception = ExceptionFactory("TestCodeInjectEndRnNR", localVarResponse); + if (exception != null) throw exception; + } + + return new ApiResponse(localVarStatusCode, + localVarResponse.Headers.ToDictionary(x => x.Name, x => string.Join(",", x.Value)), + null); + } + + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// Thrown when fails to make API call + /// To test code injection *_/ ' \\\" =end - - \\\\r\\\\n \\\\n \\\\r (optional) + /// Task of void + public async System.Threading.Tasks.Task TestCodeInjectEndRnNRAsync (string testCodeInjectEndRnNR = null) + { + await TestCodeInjectEndRnNRAsyncWithHttpInfo(testCodeInjectEndRnNR); + + } + + /// + /// To test code injection *_/ ' \" =end - - \\r\\n \\n \\r To test code injection *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// Thrown when fails to make API call + /// To test code injection *_/ ' \\\" =end - - \\\\r\\\\n \\\\n \\\\r (optional) + /// Task of ApiResponse + public async System.Threading.Tasks.Task> TestCodeInjectEndRnNRAsyncWithHttpInfo (string testCodeInjectEndRnNR = null) + { + + var localVarPath = "/fake"; + var localVarPathParams = new Dictionary(); + var localVarQueryParams = new List>(); + var localVarHeaderParams = new Dictionary(this.Configuration.DefaultHeader); + var localVarFormParams = new Dictionary(); + var localVarFileParams = new Dictionary(); + Object localVarPostBody = null; + + // to determine the Content-Type header + String[] localVarHttpContentTypes = new String[] { + "application/x-www-form-urlencoded", + "*_/ ' =end - - " + }; + String localVarHttpContentType = this.Configuration.ApiClient.SelectHeaderContentType(localVarHttpContentTypes); + + // to determine the Accept header + String[] localVarHttpHeaderAccepts = new String[] { + }; + String localVarHttpHeaderAccept = this.Configuration.ApiClient.SelectHeaderAccept(localVarHttpHeaderAccepts); + if (localVarHttpHeaderAccept != null) + localVarHeaderParams.Add("Accept", localVarHttpHeaderAccept); + + if (testCodeInjectEndRnNR != null) localVarFormParams.Add("test code inject */ ' " =end -- \r\n \n \r", this.Configuration.ApiClient.ParameterToString(testCodeInjectEndRnNR)); // form parameter + + + // make the HTTP request + IRestResponse localVarResponse = (IRestResponse) await this.Configuration.ApiClient.CallApiAsync(localVarPath, + Method.PUT, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarFileParams, + localVarPathParams, localVarHttpContentType); + + int localVarStatusCode = (int) localVarResponse.StatusCode; + + if (ExceptionFactory != null) + { + Exception exception = ExceptionFactory("TestCodeInjectEndRnNR", localVarResponse); + if (exception != null) throw exception; + } + + return new ApiResponse(localVarStatusCode, + localVarResponse.Headers.ToDictionary(x => x.Name, x => string.Join(",", x.Value)), + null); + } + + } +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ApiClient.cs new file mode 100644 index 00000000000..a81780b3b80 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ApiClient.cs @@ -0,0 +1,530 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text.RegularExpressions; +using System.IO; +using System.Web; +using System.Linq; +using System.Net; +using System.Text; +using Newtonsoft.Json; +using RestSharp; + +namespace Org.OpenAPITools.Client +{ + /// + /// API client is mainly responsible for making the HTTP call to the API backend. + /// + public partial class ApiClient + { + private JsonSerializerSettings serializerSettings = new JsonSerializerSettings + { + ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor + }; + + /// + /// Allows for extending request processing for generated code. + /// + /// The RestSharp request object + partial void InterceptRequest(IRestRequest request); + + /// + /// Allows for extending response processing for generated code. + /// + /// The RestSharp request object + /// The RestSharp response object + partial void InterceptResponse(IRestRequest request, IRestResponse response); + + /// + /// Initializes a new instance of the class + /// with default configuration. + /// + public ApiClient() + { + Configuration = Org.OpenAPITools.Client.Configuration.Default; + RestClient = new RestClient("http://petstore.swagger.io *_/ ' \" =end - - \\r\\n \\n \\r/v2 *_/ ' \" =end - - \\r\\n \\n \\r"); + } + + /// + /// Initializes a new instance of the class + /// with default base path (http://petstore.swagger.io *_/ ' \" =end - - \\r\\n \\n \\r/v2 *_/ ' \" =end - - \\r\\n \\n \\r). + /// + /// An instance of Configuration. + public ApiClient(Configuration config) + { + Configuration = config ?? Org.OpenAPITools.Client.Configuration.Default; + + RestClient = new RestClient(Configuration.BasePath); + } + + /// + /// Initializes a new instance of the class + /// with default configuration. + /// + /// The base path. + public ApiClient(String basePath = "http://petstore.swagger.io *_/ ' \" =end - - \\r\\n \\n \\r/v2 *_/ ' \" =end - - \\r\\n \\n \\r") + { + if (String.IsNullOrEmpty(basePath)) + throw new ArgumentException("basePath cannot be empty"); + + RestClient = new RestClient(basePath); + Configuration = Client.Configuration.Default; + } + + /// + /// Gets or sets the default API client for making HTTP calls. + /// + /// The default API client. + [Obsolete("ApiClient.Default is deprecated, please use 'Configuration.Default.ApiClient' instead.")] + public static ApiClient Default; + + /// + /// Gets or sets an instance of the IReadableConfiguration. + /// + /// An instance of the IReadableConfiguration. + /// + /// helps us to avoid modifying possibly global + /// configuration values from within a given client. It does not guarantee thread-safety + /// of the instance in any way. + /// + public IReadableConfiguration Configuration { get; set; } + + /// + /// Gets or sets the RestClient. + /// + /// An instance of the RestClient + public RestClient RestClient { get; set; } + + // Creates and sets up a RestRequest prior to a call. + private RestRequest PrepareRequest( + String path, RestSharp.Method method, List> queryParams, Object postBody, + Dictionary headerParams, Dictionary formParams, + Dictionary fileParams, Dictionary pathParams, + String contentType) + { + var request = new RestRequest(path, method); + + // add path parameter, if any + foreach(var param in pathParams) + request.AddParameter(param.Key, param.Value, ParameterType.UrlSegment); + + // add header parameter, if any + foreach(var param in headerParams) + request.AddHeader(param.Key, param.Value); + + // add query parameter, if any + foreach(var param in queryParams) + request.AddQueryParameter(param.Key, param.Value); + + // add form parameter, if any + foreach(var param in formParams) + request.AddParameter(param.Key, param.Value); + + // add file parameter, if any + foreach(var param in fileParams) + { + request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentType); + } + + if (postBody != null) // http body (model or byte[]) parameter + { + request.AddParameter(contentType, postBody, ParameterType.RequestBody); + } + + return request; + } + + /// + /// Makes the HTTP request (Sync). + /// + /// URL path. + /// HTTP method. + /// Query parameters. + /// HTTP body (POST request). + /// Header parameters. + /// Form parameters. + /// File parameters. + /// Path parameters. + /// Content Type of the request + /// Object + public Object CallApi( + String path, RestSharp.Method method, List> queryParams, Object postBody, + Dictionary headerParams, Dictionary formParams, + Dictionary fileParams, Dictionary pathParams, + String contentType) + { + var request = PrepareRequest( + path, method, queryParams, postBody, headerParams, formParams, fileParams, + pathParams, contentType); + + // set timeout + + RestClient.Timeout = Configuration.Timeout; + // set user agent + RestClient.UserAgent = Configuration.UserAgent; + + InterceptRequest(request); + var response = RestClient.Execute(request); + InterceptResponse(request, response); + + return (Object) response; + } + /// + /// Makes the asynchronous HTTP request. + /// + /// URL path. + /// HTTP method. + /// Query parameters. + /// HTTP body (POST request). + /// Header parameters. + /// Form parameters. + /// File parameters. + /// Path parameters. + /// Content type. + /// The Task instance. + public async System.Threading.Tasks.Task CallApiAsync( + String path, RestSharp.Method method, List> queryParams, Object postBody, + Dictionary headerParams, Dictionary formParams, + Dictionary fileParams, Dictionary pathParams, + String contentType) + { + var request = PrepareRequest( + path, method, queryParams, postBody, headerParams, formParams, fileParams, + pathParams, contentType); + InterceptRequest(request); + var response = await RestClient.ExecuteTaskAsync(request); + InterceptResponse(request, response); + return (Object)response; + } + + /// + /// Escape string (url-encoded). + /// + /// String to be escaped. + /// Escaped string. + public string EscapeString(string str) + { + return UrlEncode(str); + } + + /// + /// Create FileParameter based on Stream. + /// + /// Parameter name. + /// Input stream. + /// FileParameter. + public FileParameter ParameterToFile(string name, Stream stream) + { + if (stream is FileStream) + return FileParameter.Create(name, ReadAsBytes(stream), Path.GetFileName(((FileStream)stream).Name)); + else + return FileParameter.Create(name, ReadAsBytes(stream), "no_file_name_provided"); + } + + /// + /// If parameter is DateTime, output in a formatted string (default ISO 8601), customizable with Configuration.DateTime. + /// If parameter is a list, join the list with ",". + /// Otherwise just return the string. + /// + /// The parameter (header, path, query, form). + /// Formatted string. + public string ParameterToString(object obj) + { + if (obj is DateTime) + // Return a formatted date string - Can be customized with Configuration.DateTimeFormat + // Defaults to an ISO 8601, using the known as a Round-trip date/time pattern ("o") + // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8 + // For example: 2009-06-15T13:45:30.0000000 + return ((DateTime)obj).ToString (Configuration.DateTimeFormat); + else if (obj is DateTimeOffset) + // Return a formatted date string - Can be customized with Configuration.DateTimeFormat + // Defaults to an ISO 8601, using the known as a Round-trip date/time pattern ("o") + // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8 + // For example: 2009-06-15T13:45:30.0000000 + return ((DateTimeOffset)obj).ToString (Configuration.DateTimeFormat); + else if (obj is IList) + { + var flattenedString = new StringBuilder(); + foreach (var param in (IList)obj) + { + if (flattenedString.Length > 0) + flattenedString.Append(","); + flattenedString.Append(param); + } + return flattenedString.ToString(); + } + else + return Convert.ToString (obj); + } + + /// + /// Deserialize the JSON string into a proper object. + /// + /// The HTTP response. + /// Object type. + /// Object representation of the JSON string. + public object Deserialize(IRestResponse response, Type type) + { + IList headers = response.Headers; + if (type == typeof(byte[])) // return byte array + { + return response.RawBytes; + } + + // TODO: ? if (type.IsAssignableFrom(typeof(Stream))) + if (type == typeof(Stream)) + { + if (headers != null) + { + var filePath = String.IsNullOrEmpty(Configuration.TempFolderPath) + ? Path.GetTempPath() + : Configuration.TempFolderPath; + var regex = new Regex(@"Content-Disposition=.*filename=['""]?([^'""\s]+)['""]?$"); + foreach (var header in headers) + { + var match = regex.Match(header.ToString()); + if (match.Success) + { + string fileName = filePath + SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); + File.WriteAllBytes(fileName, response.RawBytes); + return new FileStream(fileName, FileMode.Open); + } + } + } + var stream = new MemoryStream(response.RawBytes); + return stream; + } + + if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object + { + return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + } + + if (type == typeof(String) || type.Name.StartsWith("System.Nullable")) // return primitive type + { + return ConvertType(response.Content, type); + } + + // at this point, it must be a model (json) + try + { + return JsonConvert.DeserializeObject(response.Content, type, serializerSettings); + } + catch (Exception e) + { + throw new ApiException(500, e.Message); + } + } + + /// + /// Serialize an input (model) into JSON string + /// + /// Object. + /// JSON string. + public String Serialize(object obj) + { + try + { + return obj != null ? JsonConvert.SerializeObject(obj) : null; + } + catch (Exception e) + { + throw new ApiException(500, e.Message); + } + } + + /// + ///Check if the given MIME is a JSON MIME. + ///JSON MIME examples: + /// application/json + /// application/json; charset=UTF8 + /// APPLICATION/JSON + /// application/vnd.company+json + /// + /// MIME + /// Returns True if MIME type is json. + public bool IsJsonMime(String mime) + { + var jsonRegex = new Regex("(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$"); + return mime != null && (jsonRegex.IsMatch(mime) || mime.Equals("application/json-patch+json")); + } + + /// + /// Select the Content-Type header's value from the given content-type array: + /// if JSON type exists in the given array, use it; + /// otherwise use the first one defined in 'consumes' + /// + /// The Content-Type array to select from. + /// The Content-Type header to use. + public String SelectHeaderContentType(String[] contentTypes) + { + if (contentTypes.Length == 0) + return "application/json"; + + foreach (var contentType in contentTypes) + { + if (IsJsonMime(contentType.ToLower())) + return contentType; + } + + return contentTypes[0]; // use the first content type specified in 'consumes' + } + + /// + /// Select the Accept header's value from the given accepts array: + /// if JSON exists in the given array, use it; + /// otherwise use all of them (joining into a string) + /// + /// The accepts array to select from. + /// The Accept header to use. + public String SelectHeaderAccept(String[] accepts) + { + if (accepts.Length == 0) + return null; + + if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) + return "application/json"; + + return String.Join(",", accepts); + } + + /// + /// Encode string in base64 format. + /// + /// String to be encoded. + /// Encoded string. + public static string Base64Encode(string text) + { + return System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(text)); + } + + /// + /// Dynamically cast the object into target type. + /// + /// Object to be casted + /// Target type + /// Casted object + public static dynamic ConvertType(dynamic fromObject, Type toObject) + { + return Convert.ChangeType(fromObject, toObject); + } + + /// + /// Convert stream to byte array + /// + /// Input stream to be converted + /// Byte array + public static byte[] ReadAsBytes(Stream inputStream) + { + byte[] buf = new byte[16*1024]; + using (MemoryStream ms = new MemoryStream()) + { + int count; + while ((count = inputStream.Read(buf, 0, buf.Length)) > 0) + { + ms.Write(buf, 0, count); + } + return ms.ToArray(); + } + } + + /// + /// URL encode a string + /// Credit/Ref: https://github.com/restsharp/RestSharp/blob/master/RestSharp/Extensions/StringExtensions.cs#L50 + /// + /// String to be URL encoded + /// Byte array + public static string UrlEncode(string input) + { + const int maxLength = 32766; + + if (input == null) + { + throw new ArgumentNullException("input"); + } + + if (input.Length <= maxLength) + { + return Uri.EscapeDataString(input); + } + + StringBuilder sb = new StringBuilder(input.Length * 2); + int index = 0; + + while (index < input.Length) + { + int length = Math.Min(input.Length - index, maxLength); + string subString = input.Substring(index, length); + + sb.Append(Uri.EscapeDataString(subString)); + index += subString.Length; + } + + return sb.ToString(); + } + + /// + /// Sanitize filename by removing the path + /// + /// Filename + /// Filename + public static string SanitizeFilename(string filename) + { + Match match = Regex.Match(filename, @".*[/\\](.*)$"); + + if (match.Success) + { + return match.Groups[1].Value; + } + else + { + return filename; + } + } + + /// + /// Convert params to key/value pairs. + /// Use collectionFormat to properly format lists and collections. + /// + /// Key name. + /// Value object. + /// A list of KeyValuePairs + public IEnumerable> ParameterToKeyValuePairs(string collectionFormat, string name, object value) + { + var parameters = new List>(); + + if (IsCollection(value) && collectionFormat == "multi") + { + var valueCollection = value as IEnumerable; + parameters.AddRange(from object item in valueCollection select new KeyValuePair(name, ParameterToString(item))); + } + else + { + parameters.Add(new KeyValuePair(name, ParameterToString(value))); + } + + return parameters; + } + + /// + /// Check if generic object is a collection. + /// + /// + /// True if object is a collection type + private static bool IsCollection(object value) + { + return value is IList || value is ICollection; + } + } +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ApiException.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ApiException.cs new file mode 100644 index 00000000000..73c246f2712 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ApiException.cs @@ -0,0 +1,60 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +using System; + +namespace Org.OpenAPITools.Client +{ + /// + /// API Exception + /// + public class ApiException : Exception + { + /// + /// Gets or sets the error code (HTTP status code) + /// + /// The error code (HTTP status code). + public int ErrorCode { get; set; } + + /// + /// Gets or sets the error content (body json object) + /// + /// The error content (Http response body). + public dynamic ErrorContent { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + public ApiException() {} + + /// + /// Initializes a new instance of the class. + /// + /// HTTP status code. + /// Error message. + public ApiException(int errorCode, string message) : base(message) + { + this.ErrorCode = errorCode; + } + + /// + /// Initializes a new instance of the class. + /// + /// HTTP status code. + /// Error message. + /// Error content. + public ApiException(int errorCode, string message, dynamic errorContent = null) : base(message) + { + this.ErrorCode = errorCode; + this.ErrorContent = errorContent; + } + } + +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ApiResponse.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ApiResponse.cs new file mode 100644 index 00000000000..1a28d04811b --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ApiResponse.cs @@ -0,0 +1,54 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +using System; +using System.Collections.Generic; + +namespace Org.OpenAPITools.Client +{ + /// + /// API Response + /// + public class ApiResponse + { + /// + /// Gets or sets the status code (HTTP status code) + /// + /// The status code. + public int StatusCode { get; private set; } + + /// + /// Gets or sets the HTTP headers + /// + /// HTTP headers + public IDictionary Headers { get; private set; } + + /// + /// Gets or sets the data (parsed HTTP body) + /// + /// The data. + public T Data { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// HTTP status code. + /// HTTP headers. + /// Data (parsed HTTP body) + public ApiResponse(int statusCode, IDictionary headers, T data) + { + this.StatusCode= statusCode; + this.Headers = headers; + this.Data = data; + } + + } + +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/Configuration.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/Configuration.cs new file mode 100644 index 00000000000..e7e202cc1a6 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/Configuration.cs @@ -0,0 +1,452 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +using System; +using System.Reflection; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Org.OpenAPITools.Client +{ + /// + /// Represents a set of configuration settings + /// + public class Configuration : IReadableConfiguration + { + #region Constants + + /// + /// Version of the package. + /// + /// Version of the package. + public const string Version = "1.0.0"; + + /// + /// Identifier for ISO 8601 DateTime Format + /// + /// See https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8 for more information. + // ReSharper disable once InconsistentNaming + public const string ISO8601_DATETIME_FORMAT = "o"; + + #endregion Constants + + #region Static Members + + private static readonly object GlobalConfigSync = new { }; + private static Configuration _globalConfiguration; + + /// + /// Default creation of exceptions for a given method name and response object + /// + public static readonly ExceptionFactory DefaultExceptionFactory = (methodName, response) => + { + var status = (int)response.StatusCode; + if (status >= 400) + { + return new ApiException(status, + string.Format("Error calling {0}: {1}", methodName, response.Content), + response.Content); + } + if (status == 0) + { + return new ApiException(status, + string.Format("Error calling {0}: {1}", methodName, response.ErrorMessage), response.ErrorMessage); + } + return null; + }; + + /// + /// Gets or sets the default Configuration. + /// + /// Configuration. + public static Configuration Default + { + get { return _globalConfiguration; } + set + { + lock (GlobalConfigSync) + { + _globalConfiguration = value; + } + } + } + + #endregion Static Members + + #region Private Members + + /// + /// Gets or sets the API key based on the authentication name. + /// + /// The API key. + private IDictionary _apiKey = null; + + /// + /// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name. + /// + /// The prefix of the API key. + private IDictionary _apiKeyPrefix = null; + + private string _dateTimeFormat = ISO8601_DATETIME_FORMAT; + private string _tempFolderPath = Path.GetTempPath(); + + #endregion Private Members + + #region Constructors + + static Configuration() + { + _globalConfiguration = new GlobalConfiguration(); + } + + /// + /// Initializes a new instance of the class + /// + public Configuration() + { + UserAgent = "OpenAPI-Generator/1.0.0/csharp"; + BasePath = "http://petstore.swagger.io *_/ ' \" =end - - \\r\\n \\n \\r/v2 *_/ ' \" =end - - \\r\\n \\n \\r"; + DefaultHeader = new ConcurrentDictionary(); + ApiKey = new ConcurrentDictionary(); + ApiKeyPrefix = new ConcurrentDictionary(); + + // Setting Timeout has side effects (forces ApiClient creation). + Timeout = 100000; + } + + /// + /// Initializes a new instance of the class + /// + public Configuration( + IDictionary defaultHeader, + IDictionary apiKey, + IDictionary apiKeyPrefix, + string basePath = "http://petstore.swagger.io *_/ ' \" =end - - \\r\\n \\n \\r/v2 *_/ ' \" =end - - \\r\\n \\n \\r") : this() + { + if (string.IsNullOrWhiteSpace(basePath)) + throw new ArgumentException("The provided basePath is invalid.", "basePath"); + if (defaultHeader == null) + throw new ArgumentNullException("defaultHeader"); + if (apiKey == null) + throw new ArgumentNullException("apiKey"); + if (apiKeyPrefix == null) + throw new ArgumentNullException("apiKeyPrefix"); + + BasePath = basePath; + + foreach (var keyValuePair in defaultHeader) + { + DefaultHeader.Add(keyValuePair); + } + + foreach (var keyValuePair in apiKey) + { + ApiKey.Add(keyValuePair); + } + + foreach (var keyValuePair in apiKeyPrefix) + { + ApiKeyPrefix.Add(keyValuePair); + } + } + + /// + /// Initializes a new instance of the class with different settings + /// + /// Api client + /// Dictionary of default HTTP header + /// Username + /// Password + /// accessToken + /// Dictionary of API key + /// Dictionary of API key prefix + /// Temp folder path + /// DateTime format string + /// HTTP connection timeout (in milliseconds) + /// HTTP user agent + [Obsolete("Use explicit object construction and setting of properties.", true)] + public Configuration( + // ReSharper disable UnusedParameter.Local + ApiClient apiClient = null, + IDictionary defaultHeader = null, + string username = null, + string password = null, + string accessToken = null, + IDictionary apiKey = null, + IDictionary apiKeyPrefix = null, + string tempFolderPath = null, + string dateTimeFormat = null, + int timeout = 100000, + string userAgent = "OpenAPI-Generator/1.0.0/csharp" + // ReSharper restore UnusedParameter.Local + ) + { + + } + + /// + /// Initializes a new instance of the Configuration class. + /// + /// Api client. + [Obsolete("This constructor caused unexpected sharing of static data. It is no longer supported.", true)] + // ReSharper disable once UnusedParameter.Local + public Configuration(ApiClient apiClient) + { + + } + + #endregion Constructors + + + #region Properties + + private ApiClient _apiClient = null; + /// + /// Gets an instance of an ApiClient for this configuration + /// + public virtual ApiClient ApiClient + { + get + { + if (_apiClient == null) _apiClient = CreateApiClient(); + return _apiClient; + } + } + + private String _basePath = null; + /// + /// Gets or sets the base path for API access. + /// + public virtual string BasePath { + get { return _basePath; } + set { + _basePath = value; + // pass-through to ApiClient if it's set. + if(_apiClient != null) { + _apiClient.RestClient.BaseUrl = new Uri(_basePath); + } + } + } + + /// + /// Gets or sets the default header. + /// + public virtual IDictionary DefaultHeader { get; set; } + + /// + /// Gets or sets the HTTP timeout (milliseconds) of ApiClient. Default to 100000 milliseconds. + /// + public virtual int Timeout + { + + get { return ApiClient.RestClient.Timeout; } + set { ApiClient.RestClient.Timeout = value; } + } + + /// + /// Gets or sets the HTTP user agent. + /// + /// Http user agent. + public virtual string UserAgent { get; set; } + + /// + /// Gets or sets the username (HTTP basic authentication). + /// + /// The username. + public virtual string Username { get; set; } + + /// + /// Gets or sets the password (HTTP basic authentication). + /// + /// The password. + public virtual string Password { get; set; } + + /// + /// Gets the API key with prefix. + /// + /// API key identifier (authentication scheme). + /// API key with prefix. + public string GetApiKeyWithPrefix(string apiKeyIdentifier) + { + var apiKeyValue = ""; + ApiKey.TryGetValue (apiKeyIdentifier, out apiKeyValue); + var apiKeyPrefix = ""; + if (ApiKeyPrefix.TryGetValue (apiKeyIdentifier, out apiKeyPrefix)) + return apiKeyPrefix + " " + apiKeyValue; + else + return apiKeyValue; + } + + /// + /// Gets or sets the access token for OAuth2 authentication. + /// + /// The access token. + public virtual string AccessToken { get; set; } + + /// + /// Gets or sets the temporary folder path to store the files downloaded from the server. + /// + /// Folder path. + public virtual string TempFolderPath + { + get { return _tempFolderPath; } + + set + { + if (string.IsNullOrEmpty(value)) + { + _tempFolderPath = Path.GetTempPath(); + return; + } + + // create the directory if it does not exist + if (!Directory.Exists(value)) + { + Directory.CreateDirectory(value); + } + + // check if the path contains directory separator at the end + if (value[value.Length - 1] == Path.DirectorySeparatorChar) + { + _tempFolderPath = value; + } + else + { + _tempFolderPath = value + Path.DirectorySeparatorChar; + } + } + } + + /// + /// Gets or sets the date time format used when serializing in the ApiClient + /// By default, it's set to ISO 8601 - "o", for others see: + /// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx + /// and https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx + /// No validation is done to ensure that the string you're providing is valid + /// + /// The DateTimeFormat string + public virtual string DateTimeFormat + { + get { return _dateTimeFormat; } + set + { + if (string.IsNullOrEmpty(value)) + { + // Never allow a blank or null string, go back to the default + _dateTimeFormat = ISO8601_DATETIME_FORMAT; + return; + } + + // Caution, no validation when you choose date time format other than ISO 8601 + // Take a look at the above links + _dateTimeFormat = value; + } + } + + /// + /// Gets or sets the prefix (e.g. Token) of the API key based on the authentication name. + /// + /// The prefix of the API key. + public virtual IDictionary ApiKeyPrefix + { + get { return _apiKeyPrefix; } + set + { + if (value == null) + { + throw new InvalidOperationException("ApiKeyPrefix collection may not be null."); + } + _apiKeyPrefix = value; + } + } + + /// + /// Gets or sets the API key based on the authentication name. + /// + /// The API key. + public virtual IDictionary ApiKey + { + get { return _apiKey; } + set + { + if (value == null) + { + throw new InvalidOperationException("ApiKey collection may not be null."); + } + _apiKey = value; + } + } + + #endregion Properties + + #region Methods + + /// + /// Add default header. + /// + /// Header field name. + /// Header field value. + /// + public void AddDefaultHeader(string key, string value) + { + DefaultHeader[key] = value; + } + + /// + /// Creates a new based on this instance. + /// + /// + public ApiClient CreateApiClient() + { + return new ApiClient(BasePath) { Configuration = this }; + } + + + /// + /// Returns a string with essential information for debugging. + /// + public static String ToDebugReport() + { + String report = "C# SDK (Org.OpenAPITools) Debug Report:\n"; + report += " OS: " + System.Environment.OSVersion + "\n"; + report += " .NET Framework Version: " + System.Environment.Version + "\n"; + report += " Version of the API: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r\n"; + report += " SDK Package Version: 1.0.0\n"; + + return report; + } + + /// + /// Add Api Key Header. + /// + /// Api Key name. + /// Api Key value. + /// + public void AddApiKey(string key, string value) + { + ApiKey[key] = value; + } + + /// + /// Sets the API key prefix. + /// + /// Api Key name. + /// Api Key value. + public void AddApiKeyPrefix(string key, string value) + { + ApiKeyPrefix[key] = value; + } + + #endregion Methods + } +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ExceptionFactory.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ExceptionFactory.cs new file mode 100644 index 00000000000..4495d9ea278 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/ExceptionFactory.cs @@ -0,0 +1,24 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + + +using System; +using RestSharp; + +namespace Org.OpenAPITools.Client +{ + /// + /// A delegate to ExceptionFactory method + /// + /// Method name + /// Response + /// Exceptions + public delegate Exception ExceptionFactory(string methodName, IRestResponse response); +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/GlobalConfiguration.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/GlobalConfiguration.cs new file mode 100644 index 00000000000..a6cd8feb57a --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/GlobalConfiguration.cs @@ -0,0 +1,34 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + + +using System; +using System.Reflection; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; + +namespace Org.OpenAPITools.Client +{ + /// + /// provides a compile-time extension point for globally configuring + /// API Clients. + /// + /// + /// A customized implementation via partial class may reside in another file and may + /// be excluded from automatic generation via a .openapi-generator-ignore file. + /// + public partial class GlobalConfiguration : Configuration + { + + } +} \ No newline at end of file diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/IApiAccessor.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/IApiAccessor.cs new file mode 100644 index 00000000000..f483d4e5386 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/IApiAccessor.cs @@ -0,0 +1,42 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using RestSharp; + +namespace Org.OpenAPITools.Client +{ + /// + /// Represents configuration aspects required to interact with the API endpoints. + /// + public interface IApiAccessor + { + /// + /// Gets or sets the configuration object + /// + /// An instance of the Configuration + Configuration Configuration {get; set;} + + /// + /// Gets the base path of the API client. + /// + /// The base path + String GetBasePath(); + + /// + /// Provides a factory method hook for the creation of exceptions. + /// + ExceptionFactory ExceptionFactory { get; set; } + } +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/IReadableConfiguration.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/IReadableConfiguration.cs new file mode 100644 index 00000000000..4676392c5d0 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/IReadableConfiguration.cs @@ -0,0 +1,94 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + + +using System.Collections.Generic; + +namespace Org.OpenAPITools.Client +{ + /// + /// Represents a readable-only configuration contract. + /// + public interface IReadableConfiguration + { + /// + /// Gets the access token. + /// + /// Access token. + string AccessToken { get; } + + /// + /// Gets the API key. + /// + /// API key. + IDictionary ApiKey { get; } + + /// + /// Gets the API key prefix. + /// + /// API key prefix. + IDictionary ApiKeyPrefix { get; } + + /// + /// Gets the base path. + /// + /// Base path. + string BasePath { get; } + + /// + /// Gets the date time format. + /// + /// Date time foramt. + string DateTimeFormat { get; } + + /// + /// Gets the default header. + /// + /// Default header. + IDictionary DefaultHeader { get; } + + /// + /// Gets the temp folder path. + /// + /// Temp folder path. + string TempFolderPath { get; } + + /// + /// Gets the HTTP connection timeout (in milliseconds) + /// + /// HTTP connection timeout. + int Timeout { get; } + + /// + /// Gets the user agent. + /// + /// User agent. + string UserAgent { get; } + + /// + /// Gets the username. + /// + /// Username. + string Username { get; } + + /// + /// Gets the password. + /// + /// Password. + string Password { get; } + + /// + /// Gets the API key with prefix. + /// + /// API key identifier (authentication scheme). + /// API key with prefix. + string GetApiKeyWithPrefix(string apiKeyIdentifier); + } +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/OpenAPIDateConverter.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/OpenAPIDateConverter.cs new file mode 100644 index 00000000000..fa751b344d5 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Client/OpenAPIDateConverter.cs @@ -0,0 +1,30 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +using Newtonsoft.Json.Converters; + +namespace Org.OpenAPITools.Client +{ + /// + /// Formatter for 'date' openapi formats ss defined by full-date - RFC3339 + /// see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#data-types + /// + public class OpenAPIDateConverter : IsoDateTimeConverter + { + /// + /// Initializes a new instance of the class. + /// + public OpenAPIDateConverter() + { + // full-date = date-fullyear "-" date-month "-" date-mday + DateTimeFormat = "yyyy-MM-dd"; + } + } +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Model/Return.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Model/Return.cs new file mode 100644 index 00000000000..c2c7f248c33 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Model/Return.cs @@ -0,0 +1,125 @@ +/* + * OpenAPI Petstore *_/ ' \" =end - - \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end - - + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end - - \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end - - \\r\\n \\n \\r + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; +using OpenAPIDateConverter = Org.OpenAPITools.Client.OpenAPIDateConverter; + +namespace Org.OpenAPITools.Model +{ + /// + /// Model for testing reserved words *_/ ' \" =end - - \\r\\n \\n \\r + /// + [DataContract] + public partial class Return : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + /// property description *_/ ' \" =end - - \\r\\n \\n \\r. + public Return(int? _return = default(int?)) + { + this._Return = _return; + } + + /// + /// property description *_/ ' \" =end - - \\r\\n \\n \\r + /// + /// property description *_/ ' \" =end - - \\r\\n \\n \\r + [DataMember(Name="return", EmitDefaultValue=false)] + public int? _Return { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class Return {\n"); + sb.Append(" _Return: ").Append(_Return).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as Return); + } + + /// + /// Returns true if Return instances are equal + /// + /// Instance of Return to be compared + /// Boolean + public bool Equals(Return input) + { + if (input == null) + return false; + + return + ( + this._Return == input._Return || + (this._Return != null && + this._Return.Equals(input._Return)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this._Return != null) + hashCode = hashCode * 59 + this._Return.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Org.OpenAPITools.csproj b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Org.OpenAPITools.csproj new file mode 100644 index 00000000000..4c53c0850bd --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Org.OpenAPITools.csproj @@ -0,0 +1,78 @@ + + + + + + Debug + AnyCPU + {8CE139DF-64BC-4591-85F8-8506C2B67514} + Library + Properties + Org.OpenAPITools + Org.OpenAPITools + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + $(SolutionDir)\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + ..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + ..\..\vendor\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + $(SolutionDir)\packages\JsonSubTypes.1.2.0\lib\net45\JsonSubTypes.dll + ..\packages\JsonSubTypes.1.2.0\lib\net45\JsonSubTypes.dll + ..\..\packages\JsonSubTypes.1.2.0\lib\net45\JsonSubTypes.dll + ..\..\vendor\JsonSubTypes.1.2.0\lib\net45\JsonSubTypes.dll + + + $(SolutionDir)\packages\RestSharp.105.1.0\lib\net45\RestSharp.dll + ..\packages\RestSharp.105.1.0\lib\net45\RestSharp.dll + ..\..\packages\RestSharp.105.1.0\lib\net45\RestSharp.dll + ..\..\vendor\RestSharp.105.1.0\lib\net45\RestSharp.dll + + + + + + + + + + + diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Org.OpenAPITools.nuspec b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Org.OpenAPITools.nuspec new file mode 100644 index 00000000000..fe2a2ee2af7 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Org.OpenAPITools.nuspec @@ -0,0 +1,42 @@ + + + + + $id$ + OpenAPI Library + + + $version$ + + + $author$ + + + $author$ + false + false + + + A library generated from a OpenAPI doc + http://url.to/terms/ *_/ ' \" =end - - \\r\\n \\n \\r + http://www.apache.org/licenses/LICENSE-2.0.html *_/ ' \" =end - - \\r\\n \\n \\r + + + + + + + + + + + + + + + + + + diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Properties/AssemblyInfo.cs b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..d1abdf7936a --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/Properties/AssemblyInfo.cs @@ -0,0 +1,32 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenAPI Library")] +[assembly: AssemblyDescription("A library generated from a OpenAPI doc")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("OpenAPI")] +[assembly: AssemblyProduct("OpenAPILibrary")] +[assembly: AssemblyCopyright("No Copyright")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0")] +[assembly: AssemblyFileVersion("1.0.0")] diff --git a/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/packages.config b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/packages.config new file mode 100644 index 00000000000..3caf34e0d76 --- /dev/null +++ b/samples/client/petstore-security-test/csharp/SwaggerClient/src/Org.OpenAPITools/packages.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/samples/client/petstore-security-test/go/.gitignore b/samples/client/petstore-security-test/go/.gitignore new file mode 100644 index 00000000000..daf913b1b34 --- /dev/null +++ b/samples/client/petstore-security-test/go/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/samples/client/petstore-security-test/go/.openapi-generator-ignore b/samples/client/petstore-security-test/go/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/go/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/go/.openapi-generator/VERSION b/samples/client/petstore-security-test/go/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/go/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/go/.travis.yml b/samples/client/petstore-security-test/go/.travis.yml new file mode 100644 index 00000000000..f5cb2ce9a5a --- /dev/null +++ b/samples/client/petstore-security-test/go/.travis.yml @@ -0,0 +1,8 @@ +language: go + +install: + - go get -d -v . + +script: + - go build -v ./ + diff --git a/samples/client/petstore-security-test/go/README.md b/samples/client/petstore-security-test/go/README.md new file mode 100644 index 00000000000..f94b342e314 --- /dev/null +++ b/samples/client/petstore-security-test/go/README.md @@ -0,0 +1,82 @@ +# Go API client for openapi + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + +## Overview +This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [OpenAPI-spec](https://www.openapis.org/) from a remote server, you can easily generate an API client. + +- API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +- Package version: 1.0.0 +- Build package: org.openapitools.codegen.languages.GoClientCodegen + +## Installation + +Install the following dependencies: +``` +go get github.com/stretchr/testify/assert +go get golang.org/x/oauth2 +go get golang.org/x/net/context +go get github.com/antihax/optional +``` + +Put the package under your project folder and add the following in import: +```golang +import "./openapi" +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*FakeApi* | [**TestCodeInjectEndRnNR**](docs/FakeApi.md#testcodeinjectendrnnr) | **Put** /fake | To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + +## Documentation For Models + + - [Return](docs/Return.md) + + +## Documentation For Authorization + +## api_key +- **Type**: API key + +Example +```golang +auth := context.WithValue(context.Background(), sw.ContextAPIKey, sw.APIKey{ + Key: "APIKEY", + Prefix: "Bearer", // Omit if not necessary. +}) +r, err := client.Service.Operation(auth, args) +``` +## petstore_auth +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - **write:pets**: modify pets in your account *_/ ' \" =end -- \\r\\n \\n \\r + - **read:pets**: read your pets *_/ ' \" =end -- \\r\\n \\n \\r + +Example +```golang +auth := context.WithValue(context.Background(), sw.ContextAccessToken, "ACCESSTOKENSTRING") +r, err := client.Service.Operation(auth, args) +``` + +Or via OAuth2 module to automatically refresh tokens and perform user authentication. +```golang +import "golang.org/x/oauth2" + +/* Perform OAuth2 round trip request and obtain a token */ + +tokenSource := oauth2cfg.TokenSource(createContext(httpClient), &token) +auth := context.WithValue(oauth2.NoContext, sw.ContextOAuth2, tokenSource) +r, err := client.Service.Operation(auth, args) +``` + +## Author + +something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + diff --git a/samples/client/petstore-security-test/go/api/openapi.yaml b/samples/client/petstore-security-test/go/api/openapi.yaml new file mode 100644 index 00000000000..93d182387f4 --- /dev/null +++ b/samples/client/petstore-security-test/go/api/openapi.yaml @@ -0,0 +1,75 @@ +openapi: 3.0.1 +info: + contact: + email: something@something.abc */ ' " =end -- \r\n \n \r + description: "This spec is mainly for testing Petstore server and contains fake\ + \ endpoints, models. Please do not use this for any other purpose. Special characters:\ + \ \" \\ */ ' \" =end -- \r\n \n \r" + license: + name: Apache-2.0 */ ' " =end -- \r\n \n \r + url: http://www.apache.org/licenses/LICENSE-2.0.html */ ' " =end -- \r\n \n \r + termsOfService: http://url.to/terms/ */ ' " =end -- \r\n \n \r + title: OpenAPI Petstore */ ' " =end -- \r\n \n \r + version: 1.0.0 */ ' " =end -- \r\n \n \r +externalDocs: + description: Find out more about OpenAPI */ ' " =end -- \r\n \n \r + url: https://openapis.org +servers: +- url: //petstore.swagger.io */ ' " =end -- \r\n \n \r/v2 */ ' " =end -- \r\n \n \r +tags: +- description: Everything about your Pets */ ' " =end -- \r\n \n \r + externalDocs: + description: Find out more */ ' " =end -- \r\n \n \r + url: https://openapis.org + name: fake +paths: + /fake: + put: + description: To test code injection */ ' " =end -- \r\n \n \r + operationId: testCodeInject */ ' " =end -- \r\n \n \r + requestBody: + content: + application/x-www-form-urlencoded: + schema: + properties: + test code inject */ ' " =end -- \r\n \n \r: + description: To test code injection */ ' " =end -- \r\n \n \r + type: string + ? "*/ ' \" =end -- \r\n \n \r" + : schema: + properties: + test code inject */ ' " =end -- \r\n \n \r: + description: To test code injection */ ' " =end -- \r\n \n \r + type: string + responses: + 400: + content: {} + description: To test code injection */ ' " =end -- \r\n \n \r + summary: To test code injection */ ' " =end -- \r\n \n \r + tags: + - fake +components: + schemas: + Return: + description: Model for testing reserved words */ ' " =end -- \r\n \n \r + properties: + return: + description: property description */ ' " =end -- \r\n \n \r + format: int32 + type: integer + type: object + xml: + name: Return + securitySchemes: + petstore_auth: + flows: + implicit: + authorizationUrl: http://petstore.swagger.io/api/oauth/dialog + scopes: + write:pets: modify pets in your account */ ' " =end -- \r\n \n \r + read:pets: read your pets */ ' " =end -- \r\n \n \r + type: oauth2 + api_key: + in: header + name: api_key */ ' " =end -- \r\n \n \r + type: apiKey diff --git a/samples/client/petstore-security-test/go/api_fake.go b/samples/client/petstore-security-test/go/api_fake.go new file mode 100644 index 00000000000..a7981c1f3ff --- /dev/null +++ b/samples/client/petstore-security-test/go/api_fake.go @@ -0,0 +1,102 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "context" + "io/ioutil" + "net/http" + "net/url" + "strings" + "github.com/antihax/optional" +) + +// Linger please +var ( + _ context.Context +) + +type FakeApiService service + +/* +FakeApiService To test code injection *_/ ' \" =end -- \\r\\n \\n \\r +To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param optional nil or *TestCodeInjectEndRnNROpts - Optional Parameters: + * @param "TestCodeInjectEndRnNR" (optional.String) - To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r +*/ + +type TestCodeInjectEndRnNROpts struct { + TestCodeInjectEndRnNR optional.String +} + +func (a *FakeApiService) TestCodeInjectEndRnNR(ctx context.Context, localVarOptionals *TestCodeInjectEndRnNROpts) (*http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Put") + localVarPostBody interface{} + localVarFormFileName string + localVarFileName string + localVarFileBytes []byte + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/fake" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{"application/x-www-form-urlencoded", "*_/ ' =end -- "} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.TestCodeInjectEndRnNR.IsSet() { + localVarFormParams.Add("test code inject */ ' " =end -- \r\n \n \r", parameterToString(localVarOptionals.TestCodeInjectEndRnNR.Value(), "")) + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFormFileName, localVarFileName, localVarFileBytes) + if err != nil { + return nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarHttpResponse, err + } + + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body.Close() + if err != nil { + return localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericOpenAPIError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + return localVarHttpResponse, newErr + } + + return localVarHttpResponse, nil +} diff --git a/samples/client/petstore-security-test/go/client.go b/samples/client/petstore-security-test/go/client.go new file mode 100644 index 00000000000..c6fa8699e2e --- /dev/null +++ b/samples/client/petstore-security-test/go/client.go @@ -0,0 +1,484 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "bytes" + "context" + "encoding/json" + "encoding/xml" + "errors" + "fmt" + "io" + "mime/multipart" + "net/http" + "net/url" + "os" + "path/filepath" + "reflect" + "regexp" + "strconv" + "strings" + "time" + "unicode/utf8" + + "golang.org/x/oauth2" +) + +var ( + jsonCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:vnd\.[^;]+\+)?json)`) + xmlCheck = regexp.MustCompile(`(?i:(?:application|text)/xml)`) +) + +// APIClient manages communication with the OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r API v1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +// In most cases there should be only one, shared, APIClient. +type APIClient struct { + cfg *Configuration + common service // Reuse a single struct instead of allocating one for each service on the heap. + + // API Services + + FakeApi *FakeApiService +} + +type service struct { + client *APIClient +} + +// NewAPIClient creates a new API client. Requires a userAgent string describing your application. +// optionally a custom http.Client to allow for advanced features such as caching. +func NewAPIClient(cfg *Configuration) *APIClient { + if cfg.HTTPClient == nil { + cfg.HTTPClient = http.DefaultClient + } + + c := &APIClient{} + c.cfg = cfg + c.common.client = c + + // API Services + c.FakeApi = (*FakeApiService)(&c.common) + + return c +} + +func atoi(in string) (int, error) { + return strconv.Atoi(in) +} + +// selectHeaderContentType select a content type from the available list. +func selectHeaderContentType(contentTypes []string) string { + if len(contentTypes) == 0 { + return "" + } + if contains(contentTypes, "application/json") { + return "application/json" + } + return contentTypes[0] // use the first content type specified in 'consumes' +} + +// selectHeaderAccept join all accept types and return +func selectHeaderAccept(accepts []string) string { + if len(accepts) == 0 { + return "" + } + + if contains(accepts, "application/json") { + return "application/json" + } + + return strings.Join(accepts, ",") +} + +// contains is a case insenstive match, finding needle in a haystack +func contains(haystack []string, needle string) bool { + for _, a := range haystack { + if strings.ToLower(a) == strings.ToLower(needle) { + return true + } + } + return false +} + +// Verify optional parameters are of the correct type. +func typeCheckParameter(obj interface{}, expected string, name string) error { + // Make sure there is an object. + if obj == nil { + return nil + } + + // Check the type is as expected. + if reflect.TypeOf(obj).String() != expected { + return fmt.Errorf("Expected %s to be of type %s but received %s.", name, expected, reflect.TypeOf(obj).String()) + } + return nil +} + +// parameterToString convert interface{} parameters to string, using a delimiter if format is provided. +func parameterToString(obj interface{}, collectionFormat string) string { + var delimiter string + + switch collectionFormat { + case "pipes": + delimiter = "|" + case "ssv": + delimiter = " " + case "tsv": + delimiter = "\t" + case "csv": + delimiter = "," + } + + if reflect.TypeOf(obj).Kind() == reflect.Slice { + return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]") + } else if t, ok := obj.(time.Time); ok { + return t.Format(time.RFC3339) + } + + return fmt.Sprintf("%v", obj) +} + +// callAPI do the request. +func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) { + return c.cfg.HTTPClient.Do(request) +} + +// Change base path to allow switching to mocks +func (c *APIClient) ChangeBasePath(path string) { + c.cfg.BasePath = path +} + +// prepareRequest build the request +func (c *APIClient) prepareRequest( + ctx context.Context, + path string, method string, + postBody interface{}, + headerParams map[string]string, + queryParams url.Values, + formParams url.Values, + formFileName string, + fileName string, + fileBytes []byte) (localVarRequest *http.Request, err error) { + + var body *bytes.Buffer + + // Detect postBody type and post. + if postBody != nil { + contentType := headerParams["Content-Type"] + if contentType == "" { + contentType = detectContentType(postBody) + headerParams["Content-Type"] = contentType + } + + body, err = setBody(postBody, contentType) + if err != nil { + return nil, err + } + } + + // add form parameters and file if available. + if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") { + if body != nil { + return nil, errors.New("Cannot specify postBody and multipart form at the same time.") + } + body = &bytes.Buffer{} + w := multipart.NewWriter(body) + + for k, v := range formParams { + for _, iv := range v { + if strings.HasPrefix(k, "@") { // file + err = addFile(w, k[1:], iv) + if err != nil { + return nil, err + } + } else { // form value + w.WriteField(k, iv) + } + } + } + if len(fileBytes) > 0 && fileName != "" { + w.Boundary() + //_, fileNm := filepath.Split(fileName) + part, err := w.CreateFormFile(formFileName, filepath.Base(fileName)) + if err != nil { + return nil, err + } + _, err = part.Write(fileBytes) + if err != nil { + return nil, err + } + // Set the Boundary in the Content-Type + headerParams["Content-Type"] = w.FormDataContentType() + } + + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + w.Close() + } + + if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 { + if body != nil { + return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.") + } + body = &bytes.Buffer{} + body.WriteString(formParams.Encode()) + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + } + + // Setup path and query parameters + url, err := url.Parse(path) + if err != nil { + return nil, err + } + + // Adding Query Param + query := url.Query() + for k, v := range queryParams { + for _, iv := range v { + query.Add(k, iv) + } + } + + // Encode the parameters. + url.RawQuery = query.Encode() + + // Generate a new request + if body != nil { + localVarRequest, err = http.NewRequest(method, url.String(), body) + } else { + localVarRequest, err = http.NewRequest(method, url.String(), nil) + } + if err != nil { + return nil, err + } + + // add header parameters, if any + if len(headerParams) > 0 { + headers := http.Header{} + for h, v := range headerParams { + headers.Set(h, v) + } + localVarRequest.Header = headers + } + + // Override request host, if applicable + if c.cfg.Host != "" { + localVarRequest.Host = c.cfg.Host + } + + // Add the user agent to the request. + localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent) + + if ctx != nil { + // add context to the request + localVarRequest = localVarRequest.WithContext(ctx) + + // Walk through any authentication. + + // OAuth2 authentication + if tok, ok := ctx.Value(ContextOAuth2).(oauth2.TokenSource); ok { + // We were able to grab an oauth2 token from the context + var latestToken *oauth2.Token + if latestToken, err = tok.Token(); err != nil { + return nil, err + } + + latestToken.SetAuthHeader(localVarRequest) + } + + // Basic HTTP Authentication + if auth, ok := ctx.Value(ContextBasicAuth).(BasicAuth); ok { + localVarRequest.SetBasicAuth(auth.UserName, auth.Password) + } + + // AccessToken Authentication + if auth, ok := ctx.Value(ContextAccessToken).(string); ok { + localVarRequest.Header.Add("Authorization", "Bearer "+auth) + } + } + + for header, value := range c.cfg.DefaultHeader { + localVarRequest.Header.Add(header, value) + } + + return localVarRequest, nil +} + +func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) { + if s, ok := v.(*string); ok { + *s = string(b) + return nil + } + if xmlCheck.MatchString(contentType) { + if err = xml.Unmarshal(b, v); err != nil { + return err + } + return nil + } + if jsonCheck.MatchString(contentType) { + if err = json.Unmarshal(b, v); err != nil { + return err + } + return nil + } + return errors.New("undefined response type") +} + +// Add a file to the multipart request +func addFile(w *multipart.Writer, fieldName, path string) error { + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + + part, err := w.CreateFormFile(fieldName, filepath.Base(path)) + if err != nil { + return err + } + _, err = io.Copy(part, file) + + return err +} + +// Prevent trying to import "fmt" +func reportError(format string, a ...interface{}) error { + return fmt.Errorf(format, a...) +} + +// Set request body from an interface{} +func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) { + if bodyBuf == nil { + bodyBuf = &bytes.Buffer{} + } + + if reader, ok := body.(io.Reader); ok { + _, err = bodyBuf.ReadFrom(reader) + } else if b, ok := body.([]byte); ok { + _, err = bodyBuf.Write(b) + } else if s, ok := body.(string); ok { + _, err = bodyBuf.WriteString(s) + } else if s, ok := body.(*string); ok { + _, err = bodyBuf.WriteString(*s) + } else if jsonCheck.MatchString(contentType) { + err = json.NewEncoder(bodyBuf).Encode(body) + } else if xmlCheck.MatchString(contentType) { + xml.NewEncoder(bodyBuf).Encode(body) + } + + if err != nil { + return nil, err + } + + if bodyBuf.Len() == 0 { + err = fmt.Errorf("Invalid body type %s\n", contentType) + return nil, err + } + return bodyBuf, nil +} + +// detectContentType method is used to figure out `Request.Body` content type for request header +func detectContentType(body interface{}) string { + contentType := "text/plain; charset=utf-8" + kind := reflect.TypeOf(body).Kind() + + switch kind { + case reflect.Struct, reflect.Map, reflect.Ptr: + contentType = "application/json; charset=utf-8" + case reflect.String: + contentType = "text/plain; charset=utf-8" + default: + if b, ok := body.([]byte); ok { + contentType = http.DetectContentType(b) + } else if kind == reflect.Slice { + contentType = "application/json; charset=utf-8" + } + } + + return contentType +} + +// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go +type cacheControl map[string]string + +func parseCacheControl(headers http.Header) cacheControl { + cc := cacheControl{} + ccHeader := headers.Get("Cache-Control") + for _, part := range strings.Split(ccHeader, ",") { + part = strings.Trim(part, " ") + if part == "" { + continue + } + if strings.ContainsRune(part, '=') { + keyval := strings.Split(part, "=") + cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",") + } else { + cc[part] = "" + } + } + return cc +} + +// CacheExpires helper function to determine remaining time before repeating a request. +func CacheExpires(r *http.Response) time.Time { + // Figure out when the cache expires. + var expires time.Time + now, err := time.Parse(time.RFC1123, r.Header.Get("date")) + if err != nil { + return time.Now() + } + respCacheControl := parseCacheControl(r.Header) + + if maxAge, ok := respCacheControl["max-age"]; ok { + lifetime, err := time.ParseDuration(maxAge + "s") + if err != nil { + expires = now + } else { + expires = now.Add(lifetime) + } + } else { + expiresHeader := r.Header.Get("Expires") + if expiresHeader != "" { + expires, err = time.Parse(time.RFC1123, expiresHeader) + if err != nil { + expires = now + } + } + } + return expires +} + +func strlen(s string) int { + return utf8.RuneCountInString(s) +} + +// GenericOpenAPIError Provides access to the body, error and model on returned errors. +type GenericOpenAPIError struct { + body []byte + error string + model interface{} +} + +// Error returns non-empty string if there was an error. +func (e GenericOpenAPIError) Error() string { + return e.error +} + +// Body returns the raw bytes of the response +func (e GenericOpenAPIError) Body() []byte { + return e.body +} + +// Model returns the unpacked model of the error +func (e GenericOpenAPIError) Model() interface{} { + return e.model +} diff --git a/samples/client/petstore-security-test/go/configuration.go b/samples/client/petstore-security-test/go/configuration.go new file mode 100644 index 00000000000..961a31cd517 --- /dev/null +++ b/samples/client/petstore-security-test/go/configuration.go @@ -0,0 +1,73 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "net/http" +) + +// contextKeys are used to identify the type of value in the context. +// Since these are string, it is possible to get a short description of the +// context key for logging and debugging using key.String(). + +type contextKey string + +func (c contextKey) String() string { + return "auth " + string(c) +} + +var ( + // ContextOAuth2 takes an oauth2.TokenSource as authentication for the request. + ContextOAuth2 = contextKey("token") + + // ContextBasicAuth takes BasicAuth as authentication for the request. + ContextBasicAuth = contextKey("basic") + + // ContextAccessToken takes a string oauth2 access token as authentication for the request. + ContextAccessToken = contextKey("accesstoken") + + // ContextAPIKey takes an APIKey as authentication for the request + ContextAPIKey = contextKey("apikey") +) + +// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth +type BasicAuth struct { + UserName string `json:"userName,omitempty"` + Password string `json:"password,omitempty"` +} + +// APIKey provides API key based authentication to a request passed via context using ContextAPIKey +type APIKey struct { + Key string + Prefix string +} + +type Configuration struct { + BasePath string `json:"basePath,omitempty"` + Host string `json:"host,omitempty"` + Scheme string `json:"scheme,omitempty"` + DefaultHeader map[string]string `json:"defaultHeader,omitempty"` + UserAgent string `json:"userAgent,omitempty"` + HTTPClient *http.Client +} + +func NewConfiguration() *Configuration { + cfg := &Configuration{ + BasePath: "http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r", + DefaultHeader: make(map[string]string), + UserAgent: "OpenAPI-Generator/1.0.0/go", + } + return cfg +} + +func (c *Configuration) AddDefaultHeader(key string, value string) { + c.DefaultHeader[key] = value +} diff --git a/samples/client/petstore-security-test/go/docs/FakeApi.md b/samples/client/petstore-security-test/go/docs/FakeApi.md new file mode 100644 index 00000000000..dcb7ad10cbe --- /dev/null +++ b/samples/client/petstore-security-test/go/docs/FakeApi.md @@ -0,0 +1,44 @@ +# \FakeApi + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**TestCodeInjectEndRnNR**](FakeApi.md#TestCodeInjectEndRnNR) | **Put** /fake | To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + +# **TestCodeInjectEndRnNR** +> TestCodeInjectEndRnNR(ctx, optional) +To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + +To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **optional** | ***TestCodeInjectEndRnNROpts** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a pointer to a TestCodeInjectEndRnNROpts struct + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **testCodeInjectEndRnNR** | **optional.String**| To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded, *_/ ' =end -- + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/client/petstore-security-test/go/docs/Return.md b/samples/client/petstore-security-test/go/docs/Return.md new file mode 100644 index 00000000000..3eeaed486cb --- /dev/null +++ b/samples/client/petstore-security-test/go/docs/Return.md @@ -0,0 +1,10 @@ +# Return + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Return** | **int32** | property description *_/ ' \" =end -- \\r\\n \\n \\r | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore-security-test/go/git_push.sh b/samples/client/petstore-security-test/go/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/go/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/go/model_return.go b/samples/client/petstore-security-test/go/model_return.go new file mode 100644 index 00000000000..8aaed985aaf --- /dev/null +++ b/samples/client/petstore-security-test/go/model_return.go @@ -0,0 +1,17 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +// Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r +type Return struct { + // property description *_/ ' \" =end -- \\r\\n \\n \\r + Return int32 `json:"return,omitempty"` +} diff --git a/samples/client/petstore-security-test/go/response.go b/samples/client/petstore-security-test/go/response.go new file mode 100644 index 00000000000..02bfc2cc31a --- /dev/null +++ b/samples/client/petstore-security-test/go/response.go @@ -0,0 +1,44 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "net/http" +) + +type APIResponse struct { + *http.Response `json:"-"` + Message string `json:"message,omitempty"` + // Operation is the name of the OpenAPI operation. + Operation string `json:"operation,omitempty"` + // RequestURL is the request URL. This value is always available, even if the + // embedded *http.Response is nil. + RequestURL string `json:"url,omitempty"` + // Method is the HTTP method used for the request. This value is always + // available, even if the embedded *http.Response is nil. + Method string `json:"method,omitempty"` + // Payload holds the contents of the response body (which may be nil or empty). + // This is provided here as the raw response.Body() reader will have already + // been drained. + Payload []byte `json:"-"` +} + +func NewAPIResponse(r *http.Response) *APIResponse { + + response := &APIResponse{Response: r} + return response +} + +func NewAPIResponseWithError(errorMessage string) *APIResponse { + + response := &APIResponse{Message: errorMessage} + return response +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/.gitignore b/samples/client/petstore-security-test/java/okhttp-gson/.gitignore new file mode 100644 index 00000000000..a530464afa1 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/.gitignore @@ -0,0 +1,21 @@ +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# exclude jar for gradle wrapper +!gradle/wrapper/*.jar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +# build files +**/target +target +.gradle +build diff --git a/samples/client/petstore-security-test/java/okhttp-gson/.openapi-generator-ignore b/samples/client/petstore-security-test/java/okhttp-gson/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/java/okhttp-gson/.openapi-generator/VERSION b/samples/client/petstore-security-test/java/okhttp-gson/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/java/okhttp-gson/.travis.yml b/samples/client/petstore-security-test/java/okhttp-gson/.travis.yml new file mode 100644 index 00000000000..80a7f2fc66c --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/.travis.yml @@ -0,0 +1,17 @@ +# +# Generated by: https://openapi-generator.tech +# +language: java +jdk: + - oraclejdk8 + - oraclejdk7 +before_install: + # ensure gradlew has proper permission + - chmod a+x ./gradlew +script: + # test using maven + - mvn test + # uncomment below to test using gradle + # - gradle test + # uncomment below to test using sbt + # - sbt test diff --git a/samples/client/petstore-security-test/java/okhttp-gson/README.md b/samples/client/petstore-security-test/java/okhttp-gson/README.md new file mode 100644 index 00000000000..b4a27c3b7a0 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/README.md @@ -0,0 +1,139 @@ +# petstore-okhttp-gson + +OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +- API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + + +*Automatically generated by the [OpenAPI Generator](https://openapi-generator.tech)* + + +## Requirements + +Building the API client library requires: +1. Java 1.7+ +2. Maven/Gradle + +## Installation + +To install the API client library to your local Maven repository, simply execute: + +```shell +mvn clean install +``` + +To deploy it to a remote Maven repository instead, configure the settings of the repository and execute: + +```shell +mvn clean deploy +``` + +Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information. + +### Maven users + +Add this dependency to your project's POM: + +```xml + + org.openapitools + petstore-okhttp-gson + 1.0.0 + compile + +``` + +### Gradle users + +Add this dependency to your project's build file: + +```groovy +compile "org.openapitools:petstore-okhttp-gson:1.0.0" +``` + +### Others + +At first generate the JAR by executing: + +```shell +mvn clean package +``` + +Then manually install the following JARs: + +* `target/petstore-okhttp-gson-1.0.0.jar` +* `target/lib/*.jar` + +## Getting Started + +Please follow the [installation](#installation) instruction and execute the following Java code: + +```java + +import org.openapitools.client.*; +import org.openapitools.client.auth.*; +import org.openapitools.client.model.*; +import org.openapitools.client.api.FakeApi; + +import java.io.File; +import java.util.*; + +public class FakeApiExample { + + public static void main(String[] args) { + + FakeApi apiInstance = new FakeApi(); + String testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR = "testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR_example"; // String | To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r + try { + apiInstance.testCodeInjectEndRnNR(testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR); + } catch (ApiException e) { + System.err.println("Exception when calling FakeApi#testCodeInjectEndRnNR"); + e.printStackTrace(); + } + } +} + +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*FakeApi* | [**testCodeInjectEndRnNR**](docs/FakeApi.md#testCodeInjectEndRnNR) | **PUT** /fake | To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + +## Documentation for Models + + - [ModelReturn](docs/ModelReturn.md) + + +## Documentation for Authorization + +Authentication schemes defined for the API: +### api_key + +- **Type**: API key +- **API key parameter name**: api_key */ ' " =end -- \r\n \n \r +- **Location**: HTTP header + +### petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - write:pets: modify pets in your account *_/ ' \" =end -- \\r\\n \\n \\r + - read:pets: read your pets *_/ ' \" =end -- \\r\\n \\n \\r + + +## Recommendation + +It's recommended to create an instance of `ApiClient` per thread in a multithreaded environment to avoid any potential issues. + +## Author + +something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + diff --git a/samples/client/petstore-security-test/java/okhttp-gson/build.gradle b/samples/client/petstore-security-test/java/okhttp-gson/build.gradle new file mode 100644 index 00000000000..6f451be8dfd --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/build.gradle @@ -0,0 +1,110 @@ +apply plugin: 'idea' +apply plugin: 'eclipse' +apply plugin: 'java' + +group = 'org.openapitools' +version = '1.0.0' + +buildscript { + repositories { + mavenCentral() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.+' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' + } +} + +repositories { + jcenter() +} +sourceSets { + main.java.srcDirs = ['src/main/java'] +} + +if(hasProperty('target') && target == 'android') { + + apply plugin: 'com.android.library' + apply plugin: 'com.github.dcendents.android-maven' + + android { + compileSdkVersion 25 + buildToolsVersion '25.0.2' + defaultConfig { + minSdkVersion 14 + targetSdkVersion 25 + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + } + + // Rename the aar correctly + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${project.name}-${variant.baseName}-${version}.aar" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + dependencies { + provided 'javax.annotation:jsr250-api:1.0' + } + } + + afterEvaluate { + android.libraryVariants.all { variant -> + def task = project.tasks.create "jar${variant.name.capitalize()}", Jar + task.description = "Create jar artifact for ${variant.name}" + task.dependsOn variant.javaCompile + task.from variant.javaCompile.destinationDir + task.destinationDir = project.file("${project.buildDir}/outputs/jar") + task.archiveName = "${project.name}-${variant.baseName}-${version}.jar" + artifacts.add('archives', task); + } + } + + task sourcesJar(type: Jar) { + from android.sourceSets.main.java.srcDirs + classifier = 'sources' + } + + artifacts { + archives sourcesJar + } + +} else { + + apply plugin: 'java' + apply plugin: 'maven' + + sourceCompatibility = JavaVersion.VERSION_1_7 + targetCompatibility = JavaVersion.VERSION_1_7 + + install { + repositories.mavenInstaller { + pom.artifactId = 'petstore-okhttp-gson' + } + } + + task execute(type:JavaExec) { + main = System.getProperty('mainClass') + classpath = sourceSets.main.runtimeClasspath + } +} + +dependencies { + compile 'io.swagger:swagger-annotations:1.5.21' + compile 'com.squareup.okhttp3:okhttp:3.13.1' + compile 'com.squareup.okhttp3:logging-interceptor:3.13.1' + compile 'com.google.code.gson:gson:2.8.5' + compile 'io.gsonfire:gson-fire:1.8.3' + compile group: 'org.apache.oltu.oauth2', name: 'org.apache.oltu.oauth2.client', version: '1.0.1' + compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1' + compile 'org.threeten:threetenbp:1.3.5' + testCompile 'junit:junit:4.12' +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/build.sbt b/samples/client/petstore-security-test/java/okhttp-gson/build.sbt new file mode 100644 index 00000000000..c5fea6a50ba --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/build.sbt @@ -0,0 +1,23 @@ +lazy val root = (project in file(".")). + settings( + organization := "org.openapitools", + name := "petstore-okhttp-gson", + version := "1.0.0", + scalaVersion := "2.11.4", + scalacOptions ++= Seq("-feature"), + javacOptions in compile ++= Seq("-Xlint:deprecation"), + publishArtifact in (Compile, packageDoc) := false, + resolvers += Resolver.mavenLocal, + libraryDependencies ++= Seq( + "io.swagger" % "swagger-annotations" % "1.5.21", + "com.squareup.okhttp3" % "okhttp" % "3.13.1", + "com.squareup.okhttp3" % "logging-interceptor" % "3.13.1", + "com.google.code.gson" % "gson" % "2.8.5", + "org.apache.commons" % "commons-lang3" % "3.8.1", + "org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1", + "org.threeten" % "threetenbp" % "1.3.5" % "compile", + "io.gsonfire" % "gson-fire" % "1.8.3" % "compile", + "junit" % "junit" % "4.12" % "test", + "com.novocode" % "junit-interface" % "0.10" % "test" + ) + ) diff --git a/samples/client/petstore-security-test/java/okhttp-gson/docs/FakeApi.md b/samples/client/petstore-security-test/java/okhttp-gson/docs/FakeApi.md new file mode 100644 index 00000000000..7a532020704 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/docs/FakeApi.md @@ -0,0 +1,53 @@ +# FakeApi + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**testCodeInjectEndRnNR**](FakeApi.md#testCodeInjectEndRnNR) | **PUT** /fake | To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + + +# **testCodeInjectEndRnNR** +> testCodeInjectEndRnNR(testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR) + +To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + +To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + +### Example +```java +// Import classes: +//import org.openapitools.client.ApiException; +//import org.openapitools.client.api.FakeApi; + + +FakeApi apiInstance = new FakeApi(); +String testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR = "testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR_example"; // String | To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r +try { + apiInstance.testCodeInjectEndRnNR(testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR); +} catch (ApiException e) { + System.err.println("Exception when calling FakeApi#testCodeInjectEndRnNR"); + e.printStackTrace(); +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR** | **String**| To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r | [optional] + +### Return type + +null (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded, *_/ ' =end -- + - **Accept**: Not defined + diff --git a/samples/client/petstore-security-test/java/okhttp-gson/docs/ModelReturn.md b/samples/client/petstore-security-test/java/okhttp-gson/docs/ModelReturn.md new file mode 100644 index 00000000000..62640f380c1 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/docs/ModelReturn.md @@ -0,0 +1,10 @@ + +# ModelReturn + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**_return** | **Integer** | property description *_/ ' \" =end -- \\r\\n \\n \\r | [optional] + + + diff --git a/samples/client/petstore-security-test/java/okhttp-gson/git_push.sh b/samples/client/petstore-security-test/java/okhttp-gson/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/java/okhttp-gson/gradle.properties b/samples/client/petstore-security-test/java/okhttp-gson/gradle.properties new file mode 100644 index 00000000000..05644f0754a --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/gradle.properties @@ -0,0 +1,2 @@ +# Uncomment to build for Android +#target = android \ No newline at end of file diff --git a/samples/client/petstore-security-test/java/okhttp-gson/gradle/wrapper/gradle-wrapper.jar b/samples/client/petstore-security-test/java/okhttp-gson/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000000..87b738cbd05 Binary files /dev/null and b/samples/client/petstore-security-test/java/okhttp-gson/gradle/wrapper/gradle-wrapper.jar differ diff --git a/samples/client/petstore-security-test/java/okhttp-gson/gradle/wrapper/gradle-wrapper.properties b/samples/client/petstore-security-test/java/okhttp-gson/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000..e496c054f69 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/samples/client/petstore-security-test/java/okhttp-gson/gradlew b/samples/client/petstore-security-test/java/okhttp-gson/gradlew new file mode 100644 index 00000000000..af6708ff229 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/samples/client/petstore-security-test/java/okhttp-gson/gradlew.bat b/samples/client/petstore-security-test/java/okhttp-gson/gradlew.bat new file mode 100644 index 00000000000..f9553162f12 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/samples/client/petstore-security-test/java/okhttp-gson/pom.xml b/samples/client/petstore-security-test/java/okhttp-gson/pom.xml new file mode 100644 index 00000000000..cbabd6637b1 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/pom.xml @@ -0,0 +1,251 @@ + + 4.0.0 + org.openapitools + petstore-okhttp-gson + jar + petstore-okhttp-gson + 1.0.0 + https://github.com/openapitools/openapi-generator + OpenAPI Java + + scm:git:git@github.com:openapitools/openapi-generator.git + scm:git:git@github.com:openapitools/openapi-generator.git + https://github.com/openapitools/openapi-generator + + + + + Unlicense + http://www.apache.org/licenses/LICENSE-2.0.html *_/ ' \" =end -- \\r\\n \\n \\r + repo + + + + + + OpenAPI-Generator Contributors + team@openapitools.org + OpenAPITools.org + http://openapitools.org + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.0.0-M1 + + + enforce-maven + + enforce + + + + + 2.2.0 + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.10 + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + + + sign-artifacts + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + + + io.swagger + swagger-annotations + ${swagger-core-version} + + + com.squareup.okhttp3 + okhttp + ${okhttp-version} + + + com.squareup.okhttp3 + logging-interceptor + ${okhttp-version} + + + com.google.code.gson + gson + ${gson-version} + + + io.gsonfire + gson-fire + ${gson-fire-version} + + + org.apache.oltu.oauth2 + org.apache.oltu.oauth2.client + 1.0.1 + + + org.apache.commons + commons-lang3 + ${commons-lang3-version} + + + org.threeten + threetenbp + ${threetenbp-version} + + + + junit + junit + ${junit-version} + test + + + + 1.7 + ${java.version} + ${java.version} + 1.8.3 + 1.5.21 + 3.13.1 + 2.8.5 + 3.8.1 + 1.3.5 + 1.0.0 + 4.12 + UTF-8 + + diff --git a/samples/client/petstore-security-test/java/okhttp-gson/settings.gradle b/samples/client/petstore-security-test/java/okhttp-gson/settings.gradle new file mode 100644 index 00000000000..3e4b819a481 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/settings.gradle @@ -0,0 +1 @@ +rootProject.name = "petstore-okhttp-gson" \ No newline at end of file diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/AndroidManifest.xml b/samples/client/petstore-security-test/java/okhttp-gson/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..54fbcb3da1e --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiCallback.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiCallback.java new file mode 100644 index 00000000000..b96509ee69a --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiCallback.java @@ -0,0 +1,62 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +import java.io.IOException; + +import java.util.Map; +import java.util.List; + +/** + * Callback for asynchronous API call. + * + * @param The return type + */ +public interface ApiCallback { + /** + * This is called when the API call fails. + * + * @param e The exception causing the failure + * @param statusCode Status code of the response if available, otherwise it would be 0 + * @param responseHeaders Headers of the response if available, otherwise it would be null + */ + void onFailure(ApiException e, int statusCode, Map> responseHeaders); + + /** + * This is called when the API call succeeded. + * + * @param result The result deserialized from response + * @param statusCode Status code of the response + * @param responseHeaders Headers of the response + */ + void onSuccess(T result, int statusCode, Map> responseHeaders); + + /** + * This is called when the API upload processing. + * + * @param bytesWritten bytes Written + * @param contentLength content length of request body + * @param done write end + */ + void onUploadProgress(long bytesWritten, long contentLength, boolean done); + + /** + * This is called when the API downlond processing. + * + * @param bytesRead bytes Read + * @param contentLength content lenngth of the response + * @param done Read end + */ + void onDownloadProgress(long bytesRead, long contentLength, boolean done); +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiClient.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiClient.java new file mode 100644 index 00000000000..a8431f9a3a6 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiClient.java @@ -0,0 +1,1348 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +import okhttp3.*; +import okhttp3.internal.http.HttpMethod; +import okhttp3.logging.HttpLoggingInterceptor; +import okhttp3.logging.HttpLoggingInterceptor.Level; +import okio.BufferedSink; +import okio.Okio; +import org.threeten.bp.LocalDate; +import org.threeten.bp.OffsetDateTime; +import org.threeten.bp.format.DateTimeFormatter; +import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; +import org.apache.oltu.oauth2.common.message.types.GrantType; + +import javax.net.ssl.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Type; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.SecureRandom; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.text.DateFormat; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.openapitools.client.auth.Authentication; +import org.openapitools.client.auth.HttpBasicAuth; +import org.openapitools.client.auth.ApiKeyAuth; +import org.openapitools.client.auth.OAuth; +import org.openapitools.client.auth.RetryingOAuth; +import org.openapitools.client.auth.OAuthFlow; + +public class ApiClient { + + private String basePath = "http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r"; + private boolean debugging = false; + private Map defaultHeaderMap = new HashMap(); + private String tempFolderPath = null; + + private Map authentications; + + private DateFormat dateFormat; + private DateFormat datetimeFormat; + private boolean lenientDatetimeFormat; + private int dateLength; + + private InputStream sslCaCert; + private boolean verifyingSsl; + private KeyManager[] keyManagers; + + private OkHttpClient httpClient; + private JSON json; + + private HttpLoggingInterceptor loggingInterceptor; + + /* + * Basic constructor for ApiClient + */ + public ApiClient() { + init(); + + // Setup authentications (key: authentication name, value: authentication). + authentications.put("api_key", new ApiKeyAuth("header", "api_key */ ' " =end -- \r\n \n \r")); + authentications.put("petstore_auth", new OAuth()); + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); + } + + /* + * Constructor for ApiClient to support access token retry on 401/403 configured with client ID + */ + public ApiClient(String clientId) { + this(clientId, null, null); + } + + /* + * Constructor for ApiClient to support access token retry on 401/403 configured with client ID and additional parameters + */ + public ApiClient(String clientId, Map parameters) { + this(clientId, null, parameters); + } + + /* + * Constructor for ApiClient to support access token retry on 401/403 configured with client ID, secret, and additional parameters + */ + public ApiClient(String clientId, String clientSecret, Map parameters) { + init(); + + RetryingOAuth retryingOAuth = new RetryingOAuth("", clientId, OAuthFlow.implicit, clientSecret, parameters); + authentications.put( + "petstore_auth", + retryingOAuth + ); + httpClient.interceptors().add(retryingOAuth); + + // Prevent the authentications from being modified. + authentications = Collections.unmodifiableMap(authentications); + } + + private void init() { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.addNetworkInterceptor(getProgressInterceptor()); + httpClient = builder.build(); + + + verifyingSsl = true; + + json = new JSON(); + + // Set default User-Agent. + setUserAgent("OpenAPI-Generator/1.0.0/java"); + + authentications = new HashMap(); + } + + /** + * Get base path + * + * @return Base path + */ + public String getBasePath() { + return basePath; + } + + /** + * Set base path + * + * @param basePath Base path of the URL (e.g http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r + * @return An instance of OkHttpClient + */ + public ApiClient setBasePath(String basePath) { + this.basePath = basePath; + return this; + } + + /** + * Get HTTP client + * + * @return An instance of OkHttpClient + */ + public OkHttpClient getHttpClient() { + return httpClient; + } + + /** + * Set HTTP client + * + * @param newHttpClient An instance of OkHttpClient + * @return Api Client + */ + public ApiClient setHttpClient(OkHttpClient newHttpClient) { + if(!httpClient.equals(newHttpClient)) { + OkHttpClient.Builder builder = newHttpClient.newBuilder(); + Iterator networkInterceptorIterator = httpClient.networkInterceptors().iterator(); + while(networkInterceptorIterator.hasNext()) { + builder.addNetworkInterceptor(networkInterceptorIterator.next()); + } + Iterator interceptorIterator = httpClient.interceptors().iterator(); + while(interceptorIterator.hasNext()) { + builder.addInterceptor(interceptorIterator.next()); + } + this.httpClient = builder.build(); + } + return this; + } + + /** + * Get JSON + * + * @return JSON object + */ + public JSON getJSON() { + return json; + } + + /** + * Set JSON + * + * @param json JSON object + * @return Api client + */ + public ApiClient setJSON(JSON json) { + this.json = json; + return this; + } + + /** + * True if isVerifyingSsl flag is on + * + * @return True if isVerifySsl flag is on + */ + public boolean isVerifyingSsl() { + return verifyingSsl; + } + + /** + * Configure whether to verify certificate and hostname when making https requests. + * Default to true. + * NOTE: Do NOT set to false in production code, otherwise you would face multiple types of cryptographic attacks. + * + * @param verifyingSsl True to verify TLS/SSL connection + * @return ApiClient + */ + public ApiClient setVerifyingSsl(boolean verifyingSsl) { + this.verifyingSsl = verifyingSsl; + applySslSettings(); + return this; + } + + /** + * Get SSL CA cert. + * + * @return Input stream to the SSL CA cert + */ + public InputStream getSslCaCert() { + return sslCaCert; + } + + /** + * Configure the CA certificate to be trusted when making https requests. + * Use null to reset to default. + * + * @param sslCaCert input stream for SSL CA cert + * @return ApiClient + */ + public ApiClient setSslCaCert(InputStream sslCaCert) { + this.sslCaCert = sslCaCert; + applySslSettings(); + return this; + } + + public KeyManager[] getKeyManagers() { + return keyManagers; + } + + /** + * Configure client keys to use for authorization in an SSL session. + * Use null to reset to default. + * + * @param managers The KeyManagers to use + * @return ApiClient + */ + public ApiClient setKeyManagers(KeyManager[] managers) { + this.keyManagers = managers; + applySslSettings(); + return this; + } + + public DateFormat getDateFormat() { + return dateFormat; + } + + public ApiClient setDateFormat(DateFormat dateFormat) { + this.json.setDateFormat(dateFormat); + return this; + } + + public ApiClient setSqlDateFormat(DateFormat dateFormat) { + this.json.setSqlDateFormat(dateFormat); + return this; + } + + public ApiClient setOffsetDateTimeFormat(DateTimeFormatter dateFormat) { + this.json.setOffsetDateTimeFormat(dateFormat); + return this; + } + + public ApiClient setLocalDateFormat(DateTimeFormatter dateFormat) { + this.json.setLocalDateFormat(dateFormat); + return this; + } + + public ApiClient setLenientOnJson(boolean lenientOnJson) { + this.json.setLenientOnJson(lenientOnJson); + return this; + } + + /** + * Get authentications (key: authentication name, value: authentication). + * + * @return Map of authentication objects + */ + public Map getAuthentications() { + return authentications; + } + + /** + * Get authentication for the given name. + * + * @param authName The authentication name + * @return The authentication, null if not found + */ + public Authentication getAuthentication(String authName) { + return authentications.get(authName); + } + + /** + * Helper method to set username for the first HTTP basic authentication. + * + * @param username Username + */ + public void setUsername(String username) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setUsername(username); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set password for the first HTTP basic authentication. + * + * @param password Password + */ + public void setPassword(String password) { + for (Authentication auth : authentications.values()) { + if (auth instanceof HttpBasicAuth) { + ((HttpBasicAuth) auth).setPassword(password); + return; + } + } + throw new RuntimeException("No HTTP basic authentication configured!"); + } + + /** + * Helper method to set API key value for the first API key authentication. + * + * @param apiKey API key + */ + public void setApiKey(String apiKey) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKey(apiKey); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set API key prefix for the first API key authentication. + * + * @param apiKeyPrefix API key prefix + */ + public void setApiKeyPrefix(String apiKeyPrefix) { + for (Authentication auth : authentications.values()) { + if (auth instanceof ApiKeyAuth) { + ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix); + return; + } + } + throw new RuntimeException("No API key authentication configured!"); + } + + /** + * Helper method to set access token for the first OAuth2 authentication. + * + * @param accessToken Access token + */ + public void setAccessToken(String accessToken) { + for (Authentication auth : authentications.values()) { + if (auth instanceof OAuth) { + ((OAuth) auth).setAccessToken(accessToken); + return; + } + } + throw new RuntimeException("No OAuth2 authentication configured!"); + } + + /** + * Set the User-Agent header's value (by adding to the default header map). + * + * @param userAgent HTTP request's user agent + * @return ApiClient + */ + public ApiClient setUserAgent(String userAgent) { + addDefaultHeader("User-Agent", userAgent); + return this; + } + + /** + * Add a default header. + * + * @param key The header's key + * @param value The header's value + * @return ApiClient + */ + public ApiClient addDefaultHeader(String key, String value) { + defaultHeaderMap.put(key, value); + return this; + } + + /** + * Check that whether debugging is enabled for this API client. + * + * @return True if debugging is enabled, false otherwise. + */ + public boolean isDebugging() { + return debugging; + } + + /** + * Enable/disable debugging for this API client. + * + * @param debugging To enable (true) or disable (false) debugging + * @return ApiClient + */ + public ApiClient setDebugging(boolean debugging) { + if (debugging != this.debugging) { + if (debugging) { + loggingInterceptor = new HttpLoggingInterceptor(); + loggingInterceptor.setLevel(Level.BODY); + httpClient = httpClient.newBuilder().addInterceptor(loggingInterceptor).build(); + } else { + httpClient.interceptors().remove(loggingInterceptor); + loggingInterceptor = null; + } + } + this.debugging = debugging; + return this; + } + + /** + * The path of temporary folder used to store downloaded files from endpoints + * with file response. The default value is null, i.e. using + * the system's default tempopary folder. + * + * @see createTempFile + * @return Temporary folder path + */ + public String getTempFolderPath() { + return tempFolderPath; + } + + /** + * Set the temporary folder path (for downloading files) + * + * @param tempFolderPath Temporary folder path + * @return ApiClient + */ + public ApiClient setTempFolderPath(String tempFolderPath) { + this.tempFolderPath = tempFolderPath; + return this; + } + + /** + * Get connection timeout (in milliseconds). + * + * @return Timeout in milliseconds + */ + public int getConnectTimeout() { + return httpClient.connectTimeoutMillis(); + } + + /** + * Sets the connect timeout (in milliseconds). + * A value of 0 means no timeout, otherwise values must be between 1 and + * {@link Integer#MAX_VALUE}. + * + * @param connectionTimeout connection timeout in milliseconds + * @return Api client + */ + public ApiClient setConnectTimeout(int connectionTimeout) { + httpClient = httpClient.newBuilder().connectTimeout(connectionTimeout, TimeUnit.MILLISECONDS).build(); + return this; + } + + /** + * Get read timeout (in milliseconds). + * + * @return Timeout in milliseconds + */ + public int getReadTimeout() { + return httpClient.readTimeoutMillis(); + } + + /** + * Sets the read timeout (in milliseconds). + * A value of 0 means no timeout, otherwise values must be between 1 and + * {@link Integer#MAX_VALUE}. + * + * @param readTimeout read timeout in milliseconds + * @return Api client + */ + public ApiClient setReadTimeout(int readTimeout) { + httpClient = httpClient.newBuilder().readTimeout(readTimeout, TimeUnit.MILLISECONDS).build(); + return this; + } + + /** + * Get write timeout (in milliseconds). + * + * @return Timeout in milliseconds + */ + public int getWriteTimeout() { + return httpClient.writeTimeoutMillis(); + } + + /** + * Sets the write timeout (in milliseconds). + * A value of 0 means no timeout, otherwise values must be between 1 and + * {@link Integer#MAX_VALUE}. + * + * @param writeTimeout connection timeout in milliseconds + * @return Api client + */ + public ApiClient setWriteTimeout(int writeTimeout) { + httpClient = httpClient.newBuilder().writeTimeout(writeTimeout, TimeUnit.MILLISECONDS).build(); + return this; + } + + /** + * Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one) + * + * @return Token request builder + */ + public TokenRequestBuilder getTokenEndPoint() { + for (Authentication apiAuth : authentications.values()) { + if (apiAuth instanceof RetryingOAuth) { + RetryingOAuth retryingOAuth = (RetryingOAuth) apiAuth; + return retryingOAuth.getTokenRequestBuilder(); + } + } + return null; + } + + /** + * Format the given parameter object into string. + * + * @param param Parameter + * @return String representation of the parameter + */ + public String parameterToString(Object param) { + if (param == null) { + return ""; + } else if (param instanceof Date || param instanceof OffsetDateTime || param instanceof LocalDate) { + //Serialize to json string and remove the " enclosing characters + String jsonStr = json.serialize(param); + return jsonStr.substring(1, jsonStr.length() - 1); + } else if (param instanceof Collection) { + StringBuilder b = new StringBuilder(); + for (Object o : (Collection) param) { + if (b.length() > 0) { + b.append(","); + } + b.append(String.valueOf(o)); + } + return b.toString(); + } else { + return String.valueOf(param); + } + } + + /** + * Formats the specified query parameter to a list containing a single {@code Pair} object. + * + * Note that {@code value} must not be a collection. + * + * @param name The name of the parameter. + * @param value The value of the parameter. + * @return A list containing a single {@code Pair} object. + */ + public List parameterToPair(String name, Object value) { + List params = new ArrayList(); + + // preconditions + if (name == null || name.isEmpty() || value == null || value instanceof Collection) { + return params; + } + + params.add(new Pair(name, parameterToString(value))); + return params; + } + + /** + * Formats the specified collection query parameters to a list of {@code Pair} objects. + * + * Note that the values of each of the returned Pair objects are percent-encoded. + * + * @param collectionFormat The collection format of the parameter. + * @param name The name of the parameter. + * @param value The value of the parameter. + * @return A list of {@code Pair} objects. + */ + public List parameterToPairs(String collectionFormat, String name, Collection value) { + List params = new ArrayList(); + + // preconditions + if (name == null || name.isEmpty() || value == null || value.isEmpty()) { + return params; + } + + // create the params based on the collection format + if ("multi".equals(collectionFormat)) { + for (Object item : value) { + params.add(new Pair(name, escapeString(parameterToString(item)))); + } + return params; + } + + // collectionFormat is assumed to be "csv" by default + String delimiter = ","; + + // escape all delimiters except commas, which are URI reserved + // characters + if ("ssv".equals(collectionFormat)) { + delimiter = escapeString(" "); + } else if ("tsv".equals(collectionFormat)) { + delimiter = escapeString("\t"); + } else if ("pipes".equals(collectionFormat)) { + delimiter = escapeString("|"); + } + + StringBuilder sb = new StringBuilder(); + for (Object item : value) { + sb.append(delimiter); + sb.append(escapeString(parameterToString(item))); + } + + params.add(new Pair(name, sb.substring(delimiter.length()))); + + return params; + } + + /** + * Formats the specified collection path parameter to a string value. + * + * @param collectionFormat The collection format of the parameter. + * @param value The value of the parameter. + * @return String representation of the parameter + */ + public String collectionPathParameterToString(String collectionFormat, Collection value) { + // create the value based on the collection format + if ("multi".equals(collectionFormat)) { + // not valid for path params + return parameterToString(value); + } + + // collectionFormat is assumed to be "csv" by default + String delimiter = ","; + + if ("ssv".equals(collectionFormat)) { + delimiter = " "; + } else if ("tsv".equals(collectionFormat)) { + delimiter = "\t"; + } else if ("pipes".equals(collectionFormat)) { + delimiter = "|"; + } + + StringBuilder sb = new StringBuilder() ; + for (Object item : value) { + sb.append(delimiter); + sb.append(parameterToString(item)); + } + + return sb.substring(delimiter.length()); + } + + /** + * Sanitize filename by removing path. + * e.g. ../../sun.gif becomes sun.gif + * + * @param filename The filename to be sanitized + * @return The sanitized filename + */ + public String sanitizeFilename(String filename) { + return filename.replaceAll(".*[/\\\\]", ""); + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * "* / *" is also default to JSON + * @param mime MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public boolean isJsonMime(String mime) { + String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$"; + return mime != null && (mime.matches(jsonMime) || mime.equals("*/*")); + } + + /** + * Select the Accept header's value from the given accepts array: + * if JSON exists in the given array, use it; + * otherwise use all of them (joining into a string) + * + * @param accepts The accepts array to select from + * @return The Accept header to use. If the given array is empty, + * null will be returned (not to set the Accept header explicitly). + */ + public String selectHeaderAccept(String[] accepts) { + if (accepts.length == 0) { + return null; + } + for (String accept : accepts) { + if (isJsonMime(accept)) { + return accept; + } + } + return StringUtil.join(accepts, ","); + } + + /** + * Select the Content-Type header's value from the given array: + * if JSON exists in the given array, use it; + * otherwise use the first one of the array. + * + * @param contentTypes The Content-Type array to select from + * @return The Content-Type header to use. If the given array is empty, + * or matches "any", JSON will be used. + */ + public String selectHeaderContentType(String[] contentTypes) { + if (contentTypes.length == 0 || contentTypes[0].equals("*/*")) { + return "application/json"; + } + for (String contentType : contentTypes) { + if (isJsonMime(contentType)) { + return contentType; + } + } + return contentTypes[0]; + } + + /** + * Escape the given string to be used as URL query value. + * + * @param str String to be escaped + * @return Escaped string + */ + public String escapeString(String str) { + try { + return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); + } catch (UnsupportedEncodingException e) { + return str; + } + } + + /** + * Deserialize response body to Java object, according to the return type and + * the Content-Type response header. + * + * @param Type + * @param response HTTP response + * @param returnType The type of the Java object + * @return The deserialized Java object + * @throws ApiException If fail to deserialize response body, i.e. cannot read response body + * or the Content-Type of the response is not supported. + */ + @SuppressWarnings("unchecked") + public T deserialize(Response response, Type returnType) throws ApiException { + if (response == null || returnType == null) { + return null; + } + + if ("byte[]".equals(returnType.toString())) { + // Handle binary response (byte array). + try { + return (T) response.body().bytes(); + } catch (IOException e) { + throw new ApiException(e); + } + } else if (returnType.equals(File.class)) { + // Handle file downloading. + return (T) downloadFileFromResponse(response); + } + + String respBody; + try { + if (response.body() != null) + respBody = response.body().string(); + else + respBody = null; + } catch (IOException e) { + throw new ApiException(e); + } + + if (respBody == null || "".equals(respBody)) { + return null; + } + + String contentType = response.headers().get("Content-Type"); + if (contentType == null) { + // ensuring a default content type + contentType = "application/json"; + } + if (isJsonMime(contentType)) { + return json.deserialize(respBody, returnType); + } else if (returnType.equals(String.class)) { + // Expecting string, return the raw response body. + return (T) respBody; + } else { + throw new ApiException( + "Content type \"" + contentType + "\" is not supported for type: " + returnType, + response.code(), + response.headers().toMultimap(), + respBody); + } + } + + /** + * Serialize the given Java object into request body according to the object's + * class and the request Content-Type. + * + * @param obj The Java object + * @param contentType The request Content-Type + * @return The serialized request body + * @throws ApiException If fail to serialize the given object + */ + public RequestBody serialize(Object obj, String contentType) throws ApiException { + if (obj instanceof byte[]) { + // Binary (byte array) body parameter support. + return RequestBody.create(MediaType.parse(contentType), (byte[]) obj); + } else if (obj instanceof File) { + // File body parameter support. + return RequestBody.create(MediaType.parse(contentType), (File) obj); + } else if (isJsonMime(contentType)) { + String content; + if (obj != null) { + content = json.serialize(obj); + } else { + content = null; + } + return RequestBody.create(MediaType.parse(contentType), content); + } else { + throw new ApiException("Content type \"" + contentType + "\" is not supported"); + } + } + + /** + * Download file from the given response. + * + * @param response An instance of the Response object + * @throws ApiException If fail to read file content from response and write to disk + * @return Downloaded file + */ + public File downloadFileFromResponse(Response response) throws ApiException { + try { + File file = prepareDownloadFile(response); + BufferedSink sink = Okio.buffer(Okio.sink(file)); + sink.writeAll(response.body().source()); + sink.close(); + return file; + } catch (IOException e) { + throw new ApiException(e); + } + } + + /** + * Prepare file for download + * + * @param response An instance of the Response object + * @return Prepared file for the download + * @throws IOException If fail to prepare file for download + */ + public File prepareDownloadFile(Response response) throws IOException { + String filename = null; + String contentDisposition = response.header("Content-Disposition"); + if (contentDisposition != null && !"".equals(contentDisposition)) { + // Get filename from the Content-Disposition header. + Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?"); + Matcher matcher = pattern.matcher(contentDisposition); + if (matcher.find()) { + filename = sanitizeFilename(matcher.group(1)); + } + } + + String prefix = null; + String suffix = null; + if (filename == null) { + prefix = "download-"; + suffix = ""; + } else { + int pos = filename.lastIndexOf("."); + if (pos == -1) { + prefix = filename + "-"; + } else { + prefix = filename.substring(0, pos) + "-"; + suffix = filename.substring(pos); + } + // File.createTempFile requires the prefix to be at least three characters long + if (prefix.length() < 3) + prefix = "download-"; + } + + if (tempFolderPath == null) + return File.createTempFile(prefix, suffix); + else + return File.createTempFile(prefix, suffix, new File(tempFolderPath)); + } + + /** + * {@link #execute(Call, Type)} + * + * @param Type + * @param call An instance of the Call object + * @return ApiResponse<T> + * @throws ApiException If fail to execute the call + */ + public ApiResponse execute(Call call) throws ApiException { + return execute(call, null); + } + + /** + * Execute HTTP call and deserialize the HTTP response body into the given return type. + * + * @param returnType The return type used to deserialize HTTP response body + * @param The return type corresponding to (same with) returnType + * @param call Call + * @return ApiResponse object containing response status, headers and + * data, which is a Java object deserialized from response body and would be null + * when returnType is null. + * @throws ApiException If fail to execute the call + */ + public ApiResponse execute(Call call, Type returnType) throws ApiException { + try { + Response response = call.execute(); + T data = handleResponse(response, returnType); + return new ApiResponse(response.code(), response.headers().toMultimap(), data); + } catch (IOException e) { + throw new ApiException(e); + } + } + + /** + * {@link #executeAsync(Call, Type, ApiCallback)} + * + * @param Type + * @param call An instance of the Call object + * @param callback ApiCallback<T> + */ + public void executeAsync(Call call, ApiCallback callback) { + executeAsync(call, null, callback); + } + + /** + * Execute HTTP call asynchronously. + * + * @param Type + * @param call The callback to be executed when the API call finishes + * @param returnType Return type + * @param callback ApiCallback + * @see #execute(Call, Type) + */ + @SuppressWarnings("unchecked") + public void executeAsync(Call call, final Type returnType, final ApiCallback callback) { + call.enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + callback.onFailure(new ApiException(e), 0, null); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + T result; + try { + result = (T) handleResponse(response, returnType); + } catch (ApiException e) { + callback.onFailure(e, response.code(), response.headers().toMultimap()); + return; + } + callback.onSuccess(result, response.code(), response.headers().toMultimap()); + } + }); + } + + /** + * Handle the given response, return the deserialized object when the response is successful. + * + * @param Type + * @param response Response + * @param returnType Return type + * @return Type + * @throws ApiException If the response has an unsuccessful status code or + * fail to deserialize the response body + */ + public T handleResponse(Response response, Type returnType) throws ApiException { + if (response.isSuccessful()) { + if (returnType == null || response.code() == 204) { + // returning null if the returnType is not defined, + // or the status code is 204 (No Content) + if (response.body() != null) { + try { + response.body().close(); + } catch (Exception e) { + throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap()); + } + } + return null; + } else { + return deserialize(response, returnType); + } + } else { + String respBody = null; + if (response.body() != null) { + try { + respBody = response.body().string(); + } catch (IOException e) { + throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap()); + } + } + throw new ApiException(response.message(), response.code(), response.headers().toMultimap(), respBody); + } + } + + /** + * Build HTTP call with the given options. + * + * @param path The sub-path of the HTTP URL + * @param method The request method, one of "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH" and "DELETE" + * @param queryParams The query parameters + * @param collectionQueryParams The collection query parameters + * @param body The request body object + * @param headerParams The header parameters + * @param formParams The form parameters + * @param authNames The authentications to apply + * @param callback Callback for upload/download progress + * @return The HTTP call + * @throws ApiException If fail to serialize the request body object + */ + public Call buildCall(String path, String method, List queryParams, List collectionQueryParams, Object body, Map headerParams, Map formParams, String[] authNames, ApiCallback callback) throws ApiException { + Request request = buildRequest(path, method, queryParams, collectionQueryParams, body, headerParams, formParams, authNames, callback); + + return httpClient.newCall(request); + } + + /** + * Build an HTTP request with the given options. + * + * @param path The sub-path of the HTTP URL + * @param method The request method, one of "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH" and "DELETE" + * @param queryParams The query parameters + * @param collectionQueryParams The collection query parameters + * @param body The request body object + * @param headerParams The header parameters + * @param formParams The form parameters + * @param authNames The authentications to apply + * @param callback Callback for upload/download progress + * @return The HTTP request + * @throws ApiException If fail to serialize the request body object + */ + public Request buildRequest(String path, String method, List queryParams, List collectionQueryParams, Object body, Map headerParams, Map formParams, String[] authNames, ApiCallback callback) throws ApiException { + updateParamsForAuth(authNames, queryParams, headerParams); + + final String url = buildUrl(path, queryParams, collectionQueryParams); + final Request.Builder reqBuilder = new Request.Builder().url(url); + processHeaderParams(headerParams, reqBuilder); + + String contentType = (String) headerParams.get("Content-Type"); + // ensuring a default content type + if (contentType == null) { + contentType = "application/json"; + } + + RequestBody reqBody; + if (!HttpMethod.permitsRequestBody(method)) { + reqBody = null; + } else if ("application/x-www-form-urlencoded".equals(contentType)) { + reqBody = buildRequestBodyFormEncoding(formParams); + } else if ("multipart/form-data".equals(contentType)) { + reqBody = buildRequestBodyMultipart(formParams); + } else if (body == null) { + if ("DELETE".equals(method)) { + // allow calling DELETE without sending a request body + reqBody = null; + } else { + // use an empty request body (for POST, PUT and PATCH) + reqBody = RequestBody.create(MediaType.parse(contentType), ""); + } + } else { + reqBody = serialize(body, contentType); + } + + // Associate callback with request (if not null) so interceptor can + // access it when creating ProgressResponseBody + reqBuilder.tag(callback); + + Request request = null; + + if (callback != null && reqBody != null) { + ProgressRequestBody progressRequestBody = new ProgressRequestBody(reqBody, callback); + request = reqBuilder.method(method, progressRequestBody).build(); + } else { + request = reqBuilder.method(method, reqBody).build(); + } + + return request; + } + + /** + * Build full URL by concatenating base path, the given sub path and query parameters. + * + * @param path The sub path + * @param queryParams The query parameters + * @param collectionQueryParams The collection query parameters + * @return The full URL + */ + public String buildUrl(String path, List queryParams, List collectionQueryParams) { + final StringBuilder url = new StringBuilder(); + url.append(basePath).append(path); + + if (queryParams != null && !queryParams.isEmpty()) { + // support (constant) query string in `path`, e.g. "/posts?draft=1" + String prefix = path.contains("?") ? "&" : "?"; + for (Pair param : queryParams) { + if (param.getValue() != null) { + if (prefix != null) { + url.append(prefix); + prefix = null; + } else { + url.append("&"); + } + String value = parameterToString(param.getValue()); + url.append(escapeString(param.getName())).append("=").append(escapeString(value)); + } + } + } + + if (collectionQueryParams != null && !collectionQueryParams.isEmpty()) { + String prefix = url.toString().contains("?") ? "&" : "?"; + for (Pair param : collectionQueryParams) { + if (param.getValue() != null) { + if (prefix != null) { + url.append(prefix); + prefix = null; + } else { + url.append("&"); + } + String value = parameterToString(param.getValue()); + // collection query parameter value already escaped as part of parameterToPairs + url.append(escapeString(param.getName())).append("=").append(value); + } + } + } + + return url.toString(); + } + + /** + * Set header parameters to the request builder, including default headers. + * + * @param headerParams Header parameters in the ofrm of Map + * @param reqBuilder Reqeust.Builder + */ + public void processHeaderParams(Map headerParams, Request.Builder reqBuilder) { + for (Entry param : headerParams.entrySet()) { + reqBuilder.header(param.getKey(), parameterToString(param.getValue())); + } + for (Entry header : defaultHeaderMap.entrySet()) { + if (!headerParams.containsKey(header.getKey())) { + reqBuilder.header(header.getKey(), parameterToString(header.getValue())); + } + } + } + + /** + * Update query and header parameters based on authentication settings. + * + * @param authNames The authentications to apply + * @param queryParams List of query parameters + * @param headerParams Map of header parameters + */ + public void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams) { + for (String authName : authNames) { + Authentication auth = authentications.get(authName); + if (auth == null) { + throw new RuntimeException("Authentication undefined: " + authName); + } + auth.applyToParams(queryParams, headerParams); + } + } + + /** + * Build a form-encoding request body with the given form parameters. + * + * @param formParams Form parameters in the form of Map + * @return RequestBody + */ + public RequestBody buildRequestBodyFormEncoding(Map formParams) { + okhttp3.FormBody.Builder formBuilder = new okhttp3.FormBody.Builder(); + for (Entry param : formParams.entrySet()) { + formBuilder.add(param.getKey(), parameterToString(param.getValue())); + } + return formBuilder.build(); + } + + /** + * Build a multipart (file uploading) request body with the given form parameters, + * which could contain text fields and file fields. + * + * @param formParams Form parameters in the form of Map + * @return RequestBody + */ + public RequestBody buildRequestBodyMultipart(Map formParams) { + MultipartBody.Builder mpBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM); + for (Entry param : formParams.entrySet()) { + if (param.getValue() instanceof File) { + File file = (File) param.getValue(); + Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\"; filename=\"" + file.getName() + "\""); + MediaType mediaType = MediaType.parse(guessContentTypeFromFile(file)); + mpBuilder.addPart(partHeaders, RequestBody.create(mediaType, file)); + } else { + Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + param.getKey() + "\""); + mpBuilder.addPart(partHeaders, RequestBody.create(null, parameterToString(param.getValue()))); + } + } + return mpBuilder.build(); + } + + /** + * Guess Content-Type header from the given file (defaults to "application/octet-stream"). + * + * @param file The given file + * @return The guessed Content-Type + */ + public String guessContentTypeFromFile(File file) { + String contentType = URLConnection.guessContentTypeFromName(file.getName()); + if (contentType == null) { + return "application/octet-stream"; + } else { + return contentType; + } + } + + /** + * Get network interceptor to add it to the httpClient to track download progress for + * async requests. + */ + private Interceptor getProgressInterceptor() { + return new Interceptor() { + @Override + public Response intercept(Interceptor.Chain chain) throws IOException { + final Request request = chain.request(); + final Response originalResponse = chain.proceed(request); + if (request.tag() instanceof ApiCallback) { + final ApiCallback callback = (ApiCallback) request.tag(); + return originalResponse.newBuilder() + .body(new ProgressResponseBody(originalResponse.body(), callback)) + .build(); + } + return originalResponse; + } + }; + } + + /** + * Apply SSL related settings to httpClient according to the current values of + * verifyingSsl and sslCaCert. + */ + private void applySslSettings() { + try { + TrustManager[] trustManagers = null; + HostnameVerifier hostnameVerifier = null; + if (!verifyingSsl) { + trustManagers = new TrustManager[]{ + new X509TrustManager() { + @Override + public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[]{}; + } + } + }; + SSLContext sslContext = SSLContext.getInstance("TLS"); + hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + } else if (sslCaCert != null) { + char[] password = null; // Any password will work. + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + Collection certificates = certificateFactory.generateCertificates(sslCaCert); + if (certificates.isEmpty()) { + throw new IllegalArgumentException("expected non-empty set of trusted certificates"); + } + KeyStore caKeyStore = newEmptyKeyStore(password); + int index = 0; + for (Certificate certificate : certificates) { + String certificateAlias = "ca" + Integer.toString(index++); + caKeyStore.setCertificateEntry(certificateAlias, certificate); + } + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(caKeyStore); + trustManagers = trustManagerFactory.getTrustManagers(); + } + + if (keyManagers != null || trustManagers != null) { + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(keyManagers, trustManagers, new SecureRandom()); + httpClient = httpClient.newBuilder().sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0]).build(); + } else { + httpClient = httpClient.newBuilder().sslSocketFactory(null, (X509TrustManager) trustManagers[0]).build(); + } + + httpClient = httpClient.newBuilder().hostnameVerifier(hostnameVerifier).build(); + } catch (GeneralSecurityException e) { + throw new RuntimeException(e); + } + } + + private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException { + try { + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + keyStore.load(null, password); + return keyStore; + } catch (IOException e) { + throw new AssertionError(e); + } + } +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiException.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiException.java new file mode 100644 index 00000000000..c787fca3e66 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiException.java @@ -0,0 +1,91 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +import java.util.Map; +import java.util.List; + + +public class ApiException extends Exception { + private int code = 0; + private Map> responseHeaders = null; + private String responseBody = null; + + public ApiException() {} + + public ApiException(Throwable throwable) { + super(throwable); + } + + public ApiException(String message) { + super(message); + } + + public ApiException(String message, Throwable throwable, int code, Map> responseHeaders, String responseBody) { + super(message, throwable); + this.code = code; + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + + public ApiException(String message, int code, Map> responseHeaders, String responseBody) { + this(message, (Throwable) null, code, responseHeaders, responseBody); + } + + public ApiException(String message, Throwable throwable, int code, Map> responseHeaders) { + this(message, throwable, code, responseHeaders, null); + } + + public ApiException(int code, Map> responseHeaders, String responseBody) { + this((String) null, (Throwable) null, code, responseHeaders, responseBody); + } + + public ApiException(int code, String message) { + super(message); + this.code = code; + } + + public ApiException(int code, String message, Map> responseHeaders, String responseBody) { + this(code, message); + this.responseHeaders = responseHeaders; + this.responseBody = responseBody; + } + + /** + * Get the HTTP status code. + * + * @return HTTP status code + */ + public int getCode() { + return code; + } + + /** + * Get the HTTP response headers. + * + * @return A map of list of string + */ + public Map> getResponseHeaders() { + return responseHeaders; + } + + /** + * Get the HTTP response body. + * + * @return Response body in the form of string + */ + public String getResponseBody() { + return responseBody; + } +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiResponse.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiResponse.java new file mode 100644 index 00000000000..d469147d056 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ApiResponse.java @@ -0,0 +1,59 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +import java.util.List; +import java.util.Map; + +/** + * API response returned by API call. + * + * @param The type of data that is deserialized from response body + */ +public class ApiResponse { + final private int statusCode; + final private Map> headers; + final private T data; + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + */ + public ApiResponse(int statusCode, Map> headers) { + this(statusCode, headers, null); + } + + /** + * @param statusCode The status code of HTTP response + * @param headers The headers of HTTP response + * @param data The object deserialized from response bod + */ + public ApiResponse(int statusCode, Map> headers, T data) { + this.statusCode = statusCode; + this.headers = headers; + this.data = data; + } + + public int getStatusCode() { + return statusCode; + } + + public Map> getHeaders() { + return headers; + } + + public T getData() { + return data; + } +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/Configuration.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/Configuration.java new file mode 100644 index 00000000000..35aa9a1c78c --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/Configuration.java @@ -0,0 +1,39 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + + +public class Configuration { + private static ApiClient defaultApiClient = new ApiClient(); + + /** + * Get the default API client, which would be used when creating API + * instances without providing an API client. + * + * @return Default API client + */ + public static ApiClient getDefaultApiClient() { + return defaultApiClient; + } + + /** + * Set the default API client, which would be used when creating API + * instances without providing an API client. + * + * @param apiClient API client + */ + public static void setDefaultApiClient(ApiClient apiClient) { + defaultApiClient = apiClient; + } +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/GzipRequestInterceptor.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/GzipRequestInterceptor.java new file mode 100644 index 00000000000..49ae0e5769e --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/GzipRequestInterceptor.java @@ -0,0 +1,85 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +import okhttp3.*; +import okio.Buffer; +import okio.BufferedSink; +import okio.GzipSink; +import okio.Okio; + +import java.io.IOException; + +/** + * Encodes request bodies using gzip. + * + * Taken from https://github.com/square/okhttp/issues/350 + */ +class GzipRequestInterceptor implements Interceptor { + @Override + public Response intercept(Chain chain) throws IOException { + Request originalRequest = chain.request(); + if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) { + return chain.proceed(originalRequest); + } + + Request compressedRequest = originalRequest.newBuilder() + .header("Content-Encoding", "gzip") + .method(originalRequest.method(), forceContentLength(gzip(originalRequest.body()))) + .build(); + return chain.proceed(compressedRequest); + } + + private RequestBody forceContentLength(final RequestBody requestBody) throws IOException { + final Buffer buffer = new Buffer(); + requestBody.writeTo(buffer); + return new RequestBody() { + @Override + public MediaType contentType() { + return requestBody.contentType(); + } + + @Override + public long contentLength() { + return buffer.size(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + sink.write(buffer.snapshot()); + } + }; + } + + private RequestBody gzip(final RequestBody body) { + return new RequestBody() { + @Override + public MediaType contentType() { + return body.contentType(); + } + + @Override + public long contentLength() { + return -1; // We don't know the compressed length in advance! + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + BufferedSink gzipSink = Okio.buffer(new GzipSink(sink)); + body.writeTo(gzipSink); + gzipSink.close(); + } + }; + } +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/JSON.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/JSON.java new file mode 100644 index 00000000000..ad407544f21 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/JSON.java @@ -0,0 +1,395 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import com.google.gson.TypeAdapter; +import com.google.gson.internal.bind.util.ISO8601Utils; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import com.google.gson.JsonElement; +import io.gsonfire.GsonFireBuilder; +import io.gsonfire.TypeSelector; +import org.threeten.bp.LocalDate; +import org.threeten.bp.OffsetDateTime; +import org.threeten.bp.format.DateTimeFormatter; + +import org.openapitools.client.model.*; +import okio.ByteString; + +import java.io.IOException; +import java.io.StringReader; +import java.lang.reflect.Type; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.Date; +import java.util.Locale; +import java.util.Map; +import java.util.HashMap; + +public class JSON { + private Gson gson; + private boolean isLenientOnJson = false; + private DateTypeAdapter dateTypeAdapter = new DateTypeAdapter(); + private SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter(); + private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter(); + private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter(); + private ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter(); + + public static GsonBuilder createGson() { + GsonFireBuilder fireBuilder = new GsonFireBuilder() + ; + GsonBuilder builder = fireBuilder.createGsonBuilder(); + return builder; + } + + private static String getDiscriminatorValue(JsonElement readElement, String discriminatorField) { + JsonElement element = readElement.getAsJsonObject().get(discriminatorField); + if (null == element) { + throw new IllegalArgumentException("missing discriminator field: <" + discriminatorField + ">"); + } + return element.getAsString(); + } + + private static Class getClassByDiscriminator(Map classByDiscriminatorValue, String discriminatorValue) { + Class clazz = (Class) classByDiscriminatorValue.get(discriminatorValue.toUpperCase(Locale.ROOT)); + if (null == clazz) { + throw new IllegalArgumentException("cannot determine model class of name: <" + discriminatorValue + ">"); + } + return clazz; + } + + public JSON() { + gson = createGson() + .registerTypeAdapter(Date.class, dateTypeAdapter) + .registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter) + .registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter) + .registerTypeAdapter(LocalDate.class, localDateTypeAdapter) + .registerTypeAdapter(byte[].class, byteArrayAdapter) + .create(); + } + + /** + * Get Gson. + * + * @return Gson + */ + public Gson getGson() { + return gson; + } + + /** + * Set Gson. + * + * @param gson Gson + * @return JSON + */ + public JSON setGson(Gson gson) { + this.gson = gson; + return this; + } + + public JSON setLenientOnJson(boolean lenientOnJson) { + isLenientOnJson = lenientOnJson; + return this; + } + + /** + * Serialize the given Java object into JSON string. + * + * @param obj Object + * @return String representation of the JSON + */ + public String serialize(Object obj) { + return gson.toJson(obj); + } + + /** + * Deserialize the given JSON string to Java object. + * + * @param Type + * @param body The JSON string + * @param returnType The type to deserialize into + * @return The deserialized Java object + */ + @SuppressWarnings("unchecked") + public T deserialize(String body, Type returnType) { + try { + if (isLenientOnJson) { + JsonReader jsonReader = new JsonReader(new StringReader(body)); + // see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean) + jsonReader.setLenient(true); + return gson.fromJson(jsonReader, returnType); + } else { + return gson.fromJson(body, returnType); + } + } catch (JsonParseException e) { + // Fallback processing when failed to parse JSON form response body: + // return the response body string directly for the String return type; + if (returnType.equals(String.class)) { + return (T) body; + } else { + throw (e); + } + } + } + + /** + * Gson TypeAdapter for Byte Array type + */ + public class ByteArrayAdapter extends TypeAdapter { + + @Override + public void write(JsonWriter out, byte[] value) throws IOException { + if (value == null) { + out.nullValue(); + } else { + out.value(ByteString.of(value).base64()); + } + } + + @Override + public byte[] read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String bytesAsBase64 = in.nextString(); + ByteString byteString = ByteString.decodeBase64(bytesAsBase64); + return byteString.toByteArray(); + } + } + } + + /** + * Gson TypeAdapter for JSR310 OffsetDateTime type + */ + public static class OffsetDateTimeTypeAdapter extends TypeAdapter { + + private DateTimeFormatter formatter; + + public OffsetDateTimeTypeAdapter() { + this(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } + + public OffsetDateTimeTypeAdapter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + public void setFormat(DateTimeFormatter dateFormat) { + this.formatter = dateFormat; + } + + @Override + public void write(JsonWriter out, OffsetDateTime date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.format(date)); + } + } + + @Override + public OffsetDateTime read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + if (date.endsWith("+0000")) { + date = date.substring(0, date.length()-5) + "Z"; + } + return OffsetDateTime.parse(date, formatter); + } + } + } + + /** + * Gson TypeAdapter for JSR310 LocalDate type + */ + public class LocalDateTypeAdapter extends TypeAdapter { + + private DateTimeFormatter formatter; + + public LocalDateTypeAdapter() { + this(DateTimeFormatter.ISO_LOCAL_DATE); + } + + public LocalDateTypeAdapter(DateTimeFormatter formatter) { + this.formatter = formatter; + } + + public void setFormat(DateTimeFormatter dateFormat) { + this.formatter = dateFormat; + } + + @Override + public void write(JsonWriter out, LocalDate date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + out.value(formatter.format(date)); + } + } + + @Override + public LocalDate read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + return LocalDate.parse(date, formatter); + } + } + } + + public JSON setOffsetDateTimeFormat(DateTimeFormatter dateFormat) { + offsetDateTimeTypeAdapter.setFormat(dateFormat); + return this; + } + + public JSON setLocalDateFormat(DateTimeFormatter dateFormat) { + localDateTypeAdapter.setFormat(dateFormat); + return this; + } + + /** + * Gson TypeAdapter for java.sql.Date type + * If the dateFormat is null, a simple "yyyy-MM-dd" format will be used + * (more efficient than SimpleDateFormat). + */ + public static class SqlDateTypeAdapter extends TypeAdapter { + + private DateFormat dateFormat; + + public SqlDateTypeAdapter() {} + + public SqlDateTypeAdapter(DateFormat dateFormat) { + this.dateFormat = dateFormat; + } + + public void setFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + } + + @Override + public void write(JsonWriter out, java.sql.Date date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + String value; + if (dateFormat != null) { + value = dateFormat.format(date); + } else { + value = date.toString(); + } + out.value(value); + } + } + + @Override + public java.sql.Date read(JsonReader in) throws IOException { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + try { + if (dateFormat != null) { + return new java.sql.Date(dateFormat.parse(date).getTime()); + } + return new java.sql.Date(ISO8601Utils.parse(date, new ParsePosition(0)).getTime()); + } catch (ParseException e) { + throw new JsonParseException(e); + } + } + } + } + + /** + * Gson TypeAdapter for java.util.Date type + * If the dateFormat is null, ISO8601Utils will be used. + */ + public static class DateTypeAdapter extends TypeAdapter { + + private DateFormat dateFormat; + + public DateTypeAdapter() {} + + public DateTypeAdapter(DateFormat dateFormat) { + this.dateFormat = dateFormat; + } + + public void setFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + } + + @Override + public void write(JsonWriter out, Date date) throws IOException { + if (date == null) { + out.nullValue(); + } else { + String value; + if (dateFormat != null) { + value = dateFormat.format(date); + } else { + value = ISO8601Utils.format(date, true); + } + out.value(value); + } + } + + @Override + public Date read(JsonReader in) throws IOException { + try { + switch (in.peek()) { + case NULL: + in.nextNull(); + return null; + default: + String date = in.nextString(); + try { + if (dateFormat != null) { + return dateFormat.parse(date); + } + return ISO8601Utils.parse(date, new ParsePosition(0)); + } catch (ParseException e) { + throw new JsonParseException(e); + } + } + } catch (IllegalArgumentException e) { + throw new JsonParseException(e); + } + } + } + + public JSON setDateFormat(DateFormat dateFormat) { + dateTypeAdapter.setFormat(dateFormat); + return this; + } + + public JSON setSqlDateFormat(DateFormat dateFormat) { + sqlDateTypeAdapter.setFormat(dateFormat); + return this; + } + +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/Pair.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/Pair.java new file mode 100644 index 00000000000..322c36522b9 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/Pair.java @@ -0,0 +1,61 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + + +public class Pair { + private String name = ""; + private String value = ""; + + public Pair (String name, String value) { + setName(name); + setValue(value); + } + + private void setName(String name) { + if (!isValidString(name)) { + return; + } + + this.name = name; + } + + private void setValue(String value) { + if (!isValidString(value)) { + return; + } + + this.value = value; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + private boolean isValidString(String arg) { + if (arg == null) { + return false; + } + + if (arg.trim().isEmpty()) { + return false; + } + + return true; + } +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ProgressRequestBody.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ProgressRequestBody.java new file mode 100644 index 00000000000..e02a8eb3df3 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ProgressRequestBody.java @@ -0,0 +1,73 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +import okhttp3.MediaType; +import okhttp3.RequestBody; + +import java.io.IOException; + +import okio.Buffer; +import okio.BufferedSink; +import okio.ForwardingSink; +import okio.Okio; +import okio.Sink; + +public class ProgressRequestBody extends RequestBody { + + private final RequestBody requestBody; + + private final ApiCallback callback; + + public ProgressRequestBody(RequestBody requestBody, ApiCallback callback) { + this.requestBody = requestBody; + this.callback = callback; + } + + @Override + public MediaType contentType() { + return requestBody.contentType(); + } + + @Override + public long contentLength() throws IOException { + return requestBody.contentLength(); + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + BufferedSink bufferedSink = Okio.buffer(sink(sink)); + requestBody.writeTo(bufferedSink); + bufferedSink.flush(); + } + + private Sink sink(Sink sink) { + return new ForwardingSink(sink) { + + long bytesWritten = 0L; + long contentLength = 0L; + + @Override + public void write(Buffer source, long byteCount) throws IOException { + super.write(source, byteCount); + if (contentLength == 0) { + contentLength = contentLength(); + } + + bytesWritten += byteCount; + callback.onUploadProgress(bytesWritten, contentLength, bytesWritten == contentLength); + } + }; + } +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ProgressResponseBody.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ProgressResponseBody.java new file mode 100644 index 00000000000..90108445531 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/ProgressResponseBody.java @@ -0,0 +1,72 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + +import okhttp3.MediaType; +import okhttp3.ResponseBody; + +import java.io.IOException; + +import okio.Buffer; +import okio.BufferedSource; +import okio.ForwardingSource; +import okio.Okio; +import okio.Source; + +public class ProgressResponseBody extends ResponseBody { + + private final ResponseBody responseBody; + private final ApiCallback callback; + private BufferedSource bufferedSource; + + public ProgressResponseBody(ResponseBody responseBody, ApiCallback callback) { + this.responseBody = responseBody; + this.callback = callback; + } + + @Override + public MediaType contentType() { + return responseBody.contentType(); + } + + @Override + public long contentLength() { + return responseBody.contentLength(); + } + + @Override + public BufferedSource source() { + if (bufferedSource == null) { + bufferedSource = Okio.buffer(source(responseBody.source())); + } + return bufferedSource; + } + + private Source source(Source source) { + return new ForwardingSource(source) { + long totalBytesRead = 0L; + + @Override + public long read(Buffer sink, long byteCount) throws IOException { + long bytesRead = super.read(sink, byteCount); + // read() returns the number of bytes read, or -1 if this source is exhausted. + totalBytesRead += bytesRead != -1 ? bytesRead : 0; + callback.onDownloadProgress(totalBytesRead, responseBody.contentLength(), bytesRead == -1); + return bytesRead; + } + }; + } +} + + diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/StringUtil.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/StringUtil.java new file mode 100644 index 00000000000..9d03dee5fba --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/StringUtil.java @@ -0,0 +1,61 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client; + + +public class StringUtil { + /** + * Check if the given array contains the given value (with case-insensitive comparison). + * + * @param array The array + * @param value The value to search + * @return true if the array contains the value + */ + public static boolean containsIgnoreCase(String[] array, String value) { + for (String str : array) { + if (value == null && str == null) { + return true; + } + if (value != null && value.equalsIgnoreCase(str)) { + return true; + } + } + return false; + } + + /** + * Join an array of strings with the given separator. + *

+ * Note: This might be replaced by utility method from commons-lang or guava someday + * if one of those libraries is added as dependency. + *

+ * + * @param array The array of strings + * @param separator The separator + * @return the resulting string + */ + public static String join(String[] array, String separator) { + int len = array.length; + if (len == 0) { + return ""; + } + + StringBuilder out = new StringBuilder(); + out.append(array[0]); + for (int i = 1; i < len; i++) { + out.append(separator).append(array[i]); + } + return out.toString(); + } +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/api/FakeApi.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/api/FakeApi.java new file mode 100644 index 00000000000..1af8b736f71 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/api/FakeApi.java @@ -0,0 +1,140 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.api; + +import org.openapitools.client.ApiCallback; +import org.openapitools.client.ApiClient; +import org.openapitools.client.ApiException; +import org.openapitools.client.ApiResponse; +import org.openapitools.client.Configuration; +import org.openapitools.client.Pair; +import org.openapitools.client.ProgressRequestBody; +import org.openapitools.client.ProgressResponseBody; + +import com.google.gson.reflect.TypeToken; + +import java.io.IOException; + + + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class FakeApi { + private ApiClient localVarApiClient; + + public FakeApi() { + this(Configuration.getDefaultApiClient()); + } + + public FakeApi(ApiClient apiClient) { + this.localVarApiClient = apiClient; + } + + public ApiClient getApiClient() { + return localVarApiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.localVarApiClient = apiClient; + } + + /** + * Build call for testCodeInjectEndRnNR + * @param testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + * @param _callback Callback for upload/download progress + * @return Call to execute + * @throws ApiException If fail to serialize the request body object + */ + public okhttp3.Call testCodeInjectEndRnNRCall(String testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR, final ApiCallback _callback) throws ApiException { + Object localVarPostBody = new Object(); + + // create path and map variables + String localVarPath = "/fake"; + + List localVarQueryParams = new ArrayList(); + List localVarCollectionQueryParams = new ArrayList(); + Map localVarHeaderParams = new HashMap(); + Map localVarFormParams = new HashMap(); + if (testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR != null) { + localVarFormParams.put("test code inject */ ' " =end -- \r\n \n \r", testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR); + } + + final String[] localVarAccepts = { + + }; + final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); + if (localVarAccept != null) { + localVarHeaderParams.put("Accept", localVarAccept); + } + + final String[] localVarContentTypes = { + "application/x-www-form-urlencoded", "*_/ ' =end -- " + }; + final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); + localVarHeaderParams.put("Content-Type", localVarContentType); + + String[] localVarAuthNames = new String[] { }; + return localVarApiClient.buildCall(localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, _callback); + } + + @SuppressWarnings("rawtypes") + private okhttp3.Call testCodeInjectEndRnNRValidateBeforeCall(String testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR, final ApiCallback _callback) throws ApiException { + + + okhttp3.Call localVarCall = testCodeInjectEndRnNRCall(testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR, _callback); + return localVarCall; + + } + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body + */ + public void testCodeInjectEndRnNR(String testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR) throws ApiException { + testCodeInjectEndRnNRWithHttpInfo(testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR); + } + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + * @return ApiResponse<Void> + * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body + */ + public ApiResponse testCodeInjectEndRnNRWithHttpInfo(String testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR) throws ApiException { + okhttp3.Call localVarCall = testCodeInjectEndRnNRValidateBeforeCall(testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR, null); + return localVarApiClient.execute(localVarCall); + } + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r (asynchronously) + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + * @param _callback The callback to be executed when the API call finishes + * @return The request call + * @throws ApiException If fail to process the API call, e.g. serializing the request body object + */ + public okhttp3.Call testCodeInjectEndRnNRAsync(String testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR, final ApiCallback _callback) throws ApiException { + + okhttp3.Call localVarCall = testCodeInjectEndRnNRValidateBeforeCall(testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR, _callback); + localVarApiClient.executeAsync(localVarCall, _callback); + return localVarCall; + } +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/auth/ApiKeyAuth.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/auth/ApiKeyAuth.java new file mode 100644 index 00000000000..47ed6c2e1d6 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/auth/ApiKeyAuth.java @@ -0,0 +1,75 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.auth; + +import org.openapitools.client.Pair; + +import java.util.Map; +import java.util.List; + + +public class ApiKeyAuth implements Authentication { + private final String location; + private final String paramName; + + private String apiKey; + private String apiKeyPrefix; + + public ApiKeyAuth(String location, String paramName) { + this.location = location; + this.paramName = paramName; + } + + public String getLocation() { + return location; + } + + public String getParamName() { + return paramName; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public String getApiKeyPrefix() { + return apiKeyPrefix; + } + + public void setApiKeyPrefix(String apiKeyPrefix) { + this.apiKeyPrefix = apiKeyPrefix; + } + + @Override + public void applyToParams(List queryParams, Map headerParams) { + if (apiKey == null) { + return; + } + String value; + if (apiKeyPrefix != null) { + value = apiKeyPrefix + " " + apiKey; + } else { + value = apiKey; + } + if ("query".equals(location)) { + queryParams.add(new Pair(paramName, value)); + } else if ("header".equals(location)) { + headerParams.put(paramName, value); + } + } +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/auth/Authentication.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/auth/Authentication.java new file mode 100644 index 00000000000..2bfd4ca1a0b --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/auth/Authentication.java @@ -0,0 +1,29 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.auth; + +import org.openapitools.client.Pair; + +import java.util.Map; +import java.util.List; + +public interface Authentication { + /** + * Apply authentication settings to header and query params. + * + * @param queryParams List of query parameters + * @param headerParams Map of header parameters + */ + void applyToParams(List queryParams, Map headerParams); +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/auth/HttpBasicAuth.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/auth/HttpBasicAuth.java new file mode 100644 index 00000000000..184c764577d --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/auth/HttpBasicAuth.java @@ -0,0 +1,54 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.auth; + +import org.openapitools.client.Pair; + +import okhttp3.Credentials; + +import java.util.Map; +import java.util.List; + +import java.io.UnsupportedEncodingException; + +public class HttpBasicAuth implements Authentication { + private String username; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public void applyToParams(List queryParams, Map headerParams) { + if (username == null && password == null) { + return; + } + headerParams.put("Authorization", Credentials.basic( + username == null ? "" : username, + password == null ? "" : password)); + } +} diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/model/ModelReturn.java b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/model/ModelReturn.java new file mode 100644 index 00000000000..435e89bcd3f --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/main/java/org/openapitools/client/model/ModelReturn.java @@ -0,0 +1,95 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.model; + +import java.util.Objects; +import java.util.Arrays; +import com.google.gson.TypeAdapter; +import com.google.gson.annotations.JsonAdapter; +import com.google.gson.annotations.SerializedName; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.io.IOException; + +/** + * Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r + */ +@ApiModel(description = "Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r") + +public class ModelReturn { + public static final String SERIALIZED_NAME_RETURN = "return"; + @SerializedName(SERIALIZED_NAME_RETURN) + private Integer _return; + + public ModelReturn _return(Integer _return) { + this._return = _return; + return this; + } + + /** + * property description *_/ ' \" =end -- \\r\\n \\n \\r + * @return _return + **/ + @ApiModelProperty(value = "property description *_/ ' \" =end -- \\r\\n \\n \\r") + public Integer getReturn() { + return _return; + } + + public void setReturn(Integer _return) { + this._return = _return; + } + + + @Override + public boolean equals(java.lang.Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ModelReturn _return = (ModelReturn) o; + return Objects.equals(this._return, _return._return); + } + + @Override + public int hashCode() { + return Objects.hash(_return); + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class ModelReturn {\n"); + sb.append(" _return: ").append(toIndentedString(_return)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(java.lang.Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/samples/client/petstore-security-test/java/okhttp-gson/src/test/java/org/openapitools/client/api/FakeApiTest.java b/samples/client/petstore-security-test/java/okhttp-gson/src/test/java/org/openapitools/client/api/FakeApiTest.java new file mode 100644 index 00000000000..ec920abcb37 --- /dev/null +++ b/samples/client/petstore-security-test/java/okhttp-gson/src/test/java/org/openapitools/client/api/FakeApiTest.java @@ -0,0 +1,50 @@ +/* + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.openapitools.client.api; + +import org.openapitools.client.ApiException; +import org.junit.Test; +import org.junit.Ignore; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * API tests for FakeApi + */ +@Ignore +public class FakeApiTest { + + private final FakeApi api = new FakeApi(); + + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * + * @throws ApiException + * if the Api call fails + */ + @Test + public void testCodeInjectEndRnNRTest() throws ApiException { + String testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR = null; + api.testCodeInjectEndRnNR(testCodeInjectStarSlashQuoteDoubleQuoteEqualEndBackSlashRBackSlashNBackSlashNBackSlashR); + + // TODO: test validations + } + +} diff --git a/samples/client/petstore-security-test/javascript-closure-angular/.openapi-generator-ignore b/samples/client/petstore-security-test/javascript-closure-angular/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/javascript-closure-angular/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/javascript-closure-angular/.openapi-generator/VERSION b/samples/client/petstore-security-test/javascript-closure-angular/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/javascript-closure-angular/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/javascript-closure-angular/API/Client/FakeApi.js b/samples/client/petstore-security-test/javascript-closure-angular/API/Client/FakeApi.js new file mode 100644 index 00000000000..a219cef1a2c --- /dev/null +++ b/samples/client/petstore-security-test/javascript-closure-angular/API/Client/FakeApi.js @@ -0,0 +1,83 @@ +/** + * @fileoverview AUTOMATICALLY GENERATED service for API.Client.FakeApi. + * Do not edit this file by hand or your changes will be lost next time it is + * generated. + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * Version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Generated by: org.openapitools.codegen.languages.JavascriptClosureAngularClientCodegen + */ +/** + * @license Apache-2.0 *_/ ' \" =end -- \\r\\n \\n \\r + * http://www.apache.org/licenses/LICENSE-2.0.html *_/ ' \" =end -- \\r\\n \\n \\r + */ + +goog.provide('API.Client.FakeApi'); + + +/** + * @constructor + * @param {!angular.$http} $http + * @param {!Object} $httpParamSerializer + * @param {!angular.$injector} $injector + * @struct + */ +API.Client.FakeApi = function($http, $httpParamSerializer, $injector) { + /** @private {!string} */ + this.basePath_ = $injector.has('FakeApiBasePath') ? + /** @type {!string} */ ($injector.get('FakeApiBasePath')) : + 'http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r'; + + /** @private {!Object} */ + this.defaultHeaders_ = $injector.has('FakeApiDefaultHeaders') ? + /** @type {!Object} */ ( + $injector.get('FakeApiDefaultHeaders')) : + {}; + + /** @private {!angular.$http} */ + this.http_ = $http; + + /** @package {!Object} */ + this.httpParamSerializer = $injector.get('$httpParamSerializer'); +} +API.Client.FakeApi.$inject = ['$http', '$httpParamSerializer', '$injector']; + +/** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param {!string=} opt_testCodeInjectEndRnNR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r + * @param {!angular.$http.Config=} opt_extraHttpRequestParams Extra HTTP parameters to send. + * @return {!angular.$q.Promise} + */ +API.Client.FakeApi.prototype.testCodeInjectEndRnNR = function(opt_testCodeInjectEndRnNR, opt_extraHttpRequestParams) { + /** @const {string} */ + var path = this.basePath_ + '/fake'; + + /** @type {!Object} */ + var queryParameters = {}; + + /** @type {!Object} */ + var headerParams = angular.extend({}, this.defaultHeaders_); + /** @type {!Object} */ + var formParams = {}; + + headerParams['Content-Type'] = 'application/x-www-form-urlencoded'; + + formParams['test code inject */ ' " =end -- \r\n \n \r'] = opt_testCodeInjectEndRnNR; + + /** @type {!Object} */ + var httpRequestParams = { + method: 'PUT', + url: path, + json: false, + data: this.httpParamSerializer(formParams), + params: queryParameters, + headers: headerParams + }; + + if (opt_extraHttpRequestParams) { + httpRequestParams = angular.extend(httpRequestParams, opt_extraHttpRequestParams); + } + + return (/** @type {?} */ (this.http_))(httpRequestParams); +} diff --git a/samples/client/petstore-security-test/javascript-closure-angular/API/Client/ModelReturn.js b/samples/client/petstore-security-test/javascript-closure-angular/API/Client/ModelReturn.js new file mode 100644 index 00000000000..bfc1c02f017 --- /dev/null +++ b/samples/client/petstore-security-test/javascript-closure-angular/API/Client/ModelReturn.js @@ -0,0 +1,15 @@ +goog.provide('API.Client.Return'); + +/** + * Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r + * @record + */ +API.Client.ModelReturn = function() {} + +/** + * property description *_/ ' \" =end -- \\r\\n \\n \\r + * @type {!number} + * @export + */ +API.Client.ModelReturn.prototype._return; + diff --git a/samples/client/petstore-security-test/javascript/.babelrc b/samples/client/petstore-security-test/javascript/.babelrc new file mode 100644 index 00000000000..67b369ed370 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["env", "stage-0"] +} diff --git a/samples/client/petstore-security-test/javascript/.openapi-generator-ignore b/samples/client/petstore-security-test/javascript/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/javascript/.openapi-generator/VERSION b/samples/client/petstore-security-test/javascript/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/javascript/.travis.yml b/samples/client/petstore-security-test/javascript/.travis.yml new file mode 100644 index 00000000000..e49f4692f7c --- /dev/null +++ b/samples/client/petstore-security-test/javascript/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +node_js: + - "6" + - "6.1" + - "5" + - "5.11" + diff --git a/samples/client/petstore-security-test/javascript/README.md b/samples/client/petstore-security-test/javascript/README.md new file mode 100644 index 00000000000..92c1a1de237 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/README.md @@ -0,0 +1,147 @@ +# open_api_petstore____end____rn_n_r + +OpenApiPetstoreEndRnNR - JavaScript client for open_api_petstore____end____rn_n_r +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +This SDK is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +- Package version: 1.0.0 *_/ =end -- \r\n \n \r +- Build package: org.openapitools.codegen.languages.JavascriptClientCodegen + +## Installation + +### For [Node.js](https://nodejs.org/) + +#### npm + +To publish the library as a [npm](https://www.npmjs.com/), +please follow the procedure in ["Publishing npm packages"](https://docs.npmjs.com/getting-started/publishing-npm-packages). + +Then install it via: + +```shell +npm install open_api_petstore____end____rn_n_r --save +``` + +##### Local development + +To use the library locally without publishing to a remote npm registry, first install the dependencies by changing +into the directory containing `package.json` (and this README). Let's call this `JAVASCRIPT_CLIENT_DIR`. Then run: + +```shell +npm install +``` + +Next, [link](https://docs.npmjs.com/cli/link) it globally in npm with the following, also from `JAVASCRIPT_CLIENT_DIR`: + +```shell +npm link +``` + +Finally, switch to the directory you want to use your open_api_petstore____end____rn_n_r from, and run: + +```shell +npm link /path/to/ +``` + +You should now be able to `require('open_api_petstore____end____rn_n_r')` in javascript files from the directory you ran the last +command above from. + +#### git +# +If the library is hosted at a git repository, e.g. +https://github.com/GIT_USER_ID/GIT_REPO_ID +then install it via: + +```shell + npm install GIT_USER_ID/GIT_REPO_ID --save +``` + +### For browser + +The library also works in the browser environment via npm and [browserify](http://browserify.org/). After following +the above steps with Node.js and installing browserify with `npm install -g browserify`, +perform the following (assuming *main.js* is your entry file, that's to say your javascript file where you actually +use this library): + +```shell +browserify main.js > bundle.js +``` + +Then include *bundle.js* in the HTML pages. + +### Webpack Configuration + +Using Webpack you may encounter the following error: "Module not found: Error: +Cannot resolve module", most certainly you should disable AMD loader. Add/merge +the following section to your webpack config: + +```javascript +module: { + rules: [ + { + parser: { + amd: false + } + } + ] +} +``` + +## Getting Started + +Please follow the [installation](#installation) instruction and execute the following JS code: + +```javascript +var OpenApiPetstoreEndRnNR = require('open_api_petstore____end____rn_n_r'); + + +var api = new OpenApiPetstoreEndRnNR.FakeApi() +var opts = { + 'testCodeInjectEndRnNR': "testCodeInjectEndRnNR_example" // {String} To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r +}; + +var callback = function(error, data, response) { + if (error) { + console.error(error); + } else { + console.log('API called successfully.'); + } +}; +api.testCodeInjectEndRnNR(opts, callback); + +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*OpenApiPetstoreEndRnNR.FakeApi* | [**testCodeInjectEndRnNR**](docs/FakeApi.md#testCodeInjectEndRnNR) | **PUT** /fake | To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + +## Documentation for Models + + - [OpenApiPetstoreEndRnNR.ModelReturn](docs/ModelReturn.md) + + +## Documentation for Authorization + + +### api_key + +- **Type**: API key +- **API key parameter name**: api_key */ ' " =end -- \r\n \n \r +- **Location**: HTTP header + + +### petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - write:pets: modify pets in your account *_/ ' \" =end -- \\r\\n \\n \\r + - read:pets: read your pets *_/ ' \" =end -- \\r\\n \\n \\r + diff --git a/samples/client/petstore-security-test/javascript/docs/FakeApi.md b/samples/client/petstore-security-test/javascript/docs/FakeApi.md new file mode 100644 index 00000000000..a5063b4fe52 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/docs/FakeApi.md @@ -0,0 +1,54 @@ +# OpenApiPetstoreEndRnNR.FakeApi + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**testCodeInjectEndRnNR**](FakeApi.md#testCodeInjectEndRnNR) | **PUT** /fake | To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + + +# **testCodeInjectEndRnNR** +> testCodeInjectEndRnNR(opts) + +To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + +To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + +### Example +```javascript +var OpenApiPetstoreEndRnNR = require('open_api_petstore____end____rn_n_r'); + +var apiInstance = new OpenApiPetstoreEndRnNR.FakeApi(); +var opts = { + 'testCodeInjectEndRnNR': "testCodeInjectEndRnNR_example" // String | To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r +}; +var callback = function(error, data, response) { + if (error) { + console.error(error); + } else { + console.log('API called successfully.'); + } +}; +apiInstance.testCodeInjectEndRnNR(opts, callback); +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **testCodeInjectEndRnNR** | **String**| To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r | [optional] + +### Return type + +null (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded, *_/ =end -- + - **Accept**: Not defined + diff --git a/samples/client/petstore-security-test/javascript/docs/ModelReturn.md b/samples/client/petstore-security-test/javascript/docs/ModelReturn.md new file mode 100644 index 00000000000..1ccf256e4e7 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/docs/ModelReturn.md @@ -0,0 +1,8 @@ +# OpenApiPetstoreEndRnNR.ModelReturn + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**_return** | **Number** | property description *_/ ' \" =end -- \\r\\n \\n \\r | [optional] + + diff --git a/samples/client/petstore-security-test/javascript/git_push.sh b/samples/client/petstore-security-test/javascript/git_push.sh new file mode 100644 index 00000000000..04dd5df38e8 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the Git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/javascript/mocha.opts b/samples/client/petstore-security-test/javascript/mocha.opts new file mode 100644 index 00000000000..907011807d6 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/mocha.opts @@ -0,0 +1 @@ +--timeout 10000 diff --git a/samples/client/petstore-security-test/javascript/package.json b/samples/client/petstore-security-test/javascript/package.json new file mode 100644 index 00000000000..e6445e0559b --- /dev/null +++ b/samples/client/petstore-security-test/javascript/package.json @@ -0,0 +1,21 @@ +{ + "name": "open_api_petstore____end____rn_n_r", + "version": "1.0.0 *_/ =end -- \r\n \n \r", + "description": "This_spec_is_mainly_for_testing_Petstore_server_and_contains_fake_endpoints_models__Please_do_not_use_this_for_any_other_purpose__Special_characters_______end______", + "license": "Apache-2.0 */ ' " =end -- \r\n \n \r", + "main": "src/index.js", + "scripts": { + "test": "./node_modules/mocha/bin/mocha --recursive" + }, + "browser": { + "fs": false + }, + "dependencies": { + "superagent": "3.7.0" + }, + "devDependencies": { + "expect.js": "~0.3.1", + "mocha": "^5.2.0", + "sinon": "1.17.3" + } +} diff --git a/samples/client/petstore-security-test/javascript/src/ApiClient.js b/samples/client/petstore-security-test/javascript/src/ApiClient.js new file mode 100644 index 00000000000..423eb39d878 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/src/ApiClient.js @@ -0,0 +1,663 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * + * OpenAPI Generator version: 4.0.0-SNAPSHOT + * + * Do not edit the class manually. + * + */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['superagent', 'querystring'], factory); + } else if (typeof module === 'object' && module.exports) { + // CommonJS-like environments that support module.exports, like Node. + module.exports = factory(require('superagent'), require('querystring')); + } else { + // Browser globals (root is window) + if (!root.OpenApiPetstoreEndRnNR) { + root.OpenApiPetstoreEndRnNR = {}; + } + root.OpenApiPetstoreEndRnNR.ApiClient = factory(root.superagent, root.querystring); + } +}(this, function(superagent, querystring) { + 'use strict'; + + /** + * @module ApiClient + * @version 1.0.0 *_/ =end -- \r\n \n \r + */ + + /** + * Manages low level client-server communications, parameter marshalling, etc. There should not be any need for an + * application to use this class directly - the *Api and model classes provide the public API for the service. The + * contents of this file should be regarded as internal but are documented for completeness. + * @alias module:ApiClient + * @class + */ + var exports = function() { + /** + * The base URL against which to resolve every API call's (relative) path. + * @type {String} + * @default http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r + */ + this.basePath = 'http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r'.replace(/\/+$/, ''); + + /** + * The authentication methods to be included for all API calls. + * @type {Array.} + */ + this.authentications = { + 'api_key': {type: 'apiKey', 'in': 'header', name: 'api_key */ ' " =end -- \r\n \n \r'}, + 'petstore_auth': {type: 'oauth2'} + }; + /** + * The default HTTP headers to be included for all API calls. + * @type {Array.} + * @default {} + */ + this.defaultHeaders = {}; + + /** + * The default HTTP timeout for all API calls. + * @type {Number} + * @default 60000 + */ + this.timeout = 60000; + + /** + * If set to false an additional timestamp parameter is added to all API GET calls to + * prevent browser caching + * @type {Boolean} + * @default true + */ + this.cache = true; + + /** + * If set to true, the client will save the cookies from each server + * response, and return them in the next request. + * @default false + */ + this.enableCookies = false; + + /* + * Used to save and return cookies in a node.js (non-browser) setting, + * if this.enableCookies is set to true. + */ + if (typeof window === 'undefined') { + this.agent = new superagent.agent(); + } + + /* + * Allow user to override superagent agent + */ + this.requestAgent = null; + + /* + * Allow user to add superagent plugins + */ + this.plugins = null; + }; + + /** + * Returns a string representation for an actual parameter. + * @param param The actual parameter. + * @returns {String} The string representation of param. + */ + exports.prototype.paramToString = function(param) { + if (param == undefined || param == null) { + return ''; + } + if (param instanceof Date) { + return param.toJSON(); + } + return param.toString(); + }; + + /** + * Builds full URL by appending the given path to the base URL and replacing path parameter place-holders with parameter values. + * NOTE: query parameters are not handled here. + * @param {String} path The path to append to the base URL. + * @param {Object} pathParams The parameter values to append. + * @returns {String} The encoded path with parameter values substituted. + */ + exports.prototype.buildUrl = function(path, pathParams, apiBasePath) { + if (!path.match(/^\//)) { + path = '/' + path; + } + var url = this.basePath + path; + + // use API (operation, path) base path if defined + if (apiBasePath !== null && apiBasePath !== undefined) { + url = apiBasePath + path; + } + + var _this = this; + url = url.replace(/\{([\w-]+)\}/g, function(fullMatch, key) { + var value; + if (pathParams.hasOwnProperty(key)) { + value = _this.paramToString(pathParams[key]); + } else { + value = fullMatch; + } + return encodeURIComponent(value); + }); + return url; + }; + + /** + * Checks whether the given content type represents JSON.
+ * JSON content type examples:
+ *
    + *
  • application/json
  • + *
  • application/json; charset=UTF8
  • + *
  • APPLICATION/JSON
  • + *
+ * @param {String} contentType The MIME content type to check. + * @returns {Boolean} true if contentType represents JSON, otherwise false. + */ + exports.prototype.isJsonMime = function(contentType) { + return Boolean(contentType != null && contentType.match(/^application\/json(;.*)?$/i)); + }; + + /** + * Chooses a content type from the given array, with JSON preferred; i.e. return JSON if included, otherwise return the first. + * @param {Array.} contentTypes + * @returns {String} The chosen content type, preferring JSON. + */ + exports.prototype.jsonPreferredMime = function(contentTypes) { + for (var i = 0; i < contentTypes.length; i++) { + if (this.isJsonMime(contentTypes[i])) { + return contentTypes[i]; + } + } + return contentTypes[0]; + }; + + /** + * Checks whether the given parameter value represents file-like content. + * @param param The parameter to check. + * @returns {Boolean} true if param represents a file. + */ + exports.prototype.isFileParam = function(param) { + // fs.ReadStream in Node.js and Electron (but not in runtime like browserify) + if (typeof require === 'function') { + var fs; + try { + fs = require('fs'); + } catch (err) {} + if (fs && fs.ReadStream && param instanceof fs.ReadStream) { + return true; + } + } + // Buffer in Node.js + if (typeof Buffer === 'function' && param instanceof Buffer) { + return true; + } + // Blob in browser + if (typeof Blob === 'function' && param instanceof Blob) { + return true; + } + // File in browser (it seems File object is also instance of Blob, but keep this for safe) + if (typeof File === 'function' && param instanceof File) { + return true; + } + return false; + }; + + /** + * Normalizes parameter values: + *
    + *
  • remove nils
  • + *
  • keep files and arrays
  • + *
  • format to string with `paramToString` for other cases
  • + *
+ * @param {Object.} params The parameters as object properties. + * @returns {Object.} normalized parameters. + */ + exports.prototype.normalizeParams = function(params) { + var newParams = {}; + for (var key in params) { + if (params.hasOwnProperty(key) && params[key] != undefined && params[key] != null) { + var value = params[key]; + if (this.isFileParam(value) || Array.isArray(value)) { + newParams[key] = value; + } else { + newParams[key] = this.paramToString(value); + } + } + } + return newParams; + }; + + /** + * Enumeration of collection format separator strategies. + * @enum {String} + * @readonly + */ + exports.CollectionFormatEnum = { + /** + * Comma-separated values. Value: csv + * @const + */ + CSV: ',', + /** + * Space-separated values. Value: ssv + * @const + */ + SSV: ' ', + /** + * Tab-separated values. Value: tsv + * @const + */ + TSV: '\t', + /** + * Pipe(|)-separated values. Value: pipes + * @const + */ + PIPES: '|', + /** + * Native array. Value: multi + * @const + */ + MULTI: 'multi' + }; + + /** + * Builds a string representation of an array-type actual parameter, according to the given collection format. + * @param {Array} param An array parameter. + * @param {module:ApiClient.CollectionFormatEnum} collectionFormat The array element separator strategy. + * @returns {String|Array} A string representation of the supplied collection, using the specified delimiter. Returns + * param as is if collectionFormat is multi. + */ + exports.prototype.buildCollectionParam = function buildCollectionParam(param, collectionFormat) { + if (param == null) { + return null; + } + switch (collectionFormat) { + case 'csv': + return param.map(this.paramToString).join(','); + case 'ssv': + return param.map(this.paramToString).join(' '); + case 'tsv': + return param.map(this.paramToString).join('\t'); + case 'pipes': + return param.map(this.paramToString).join('|'); + case 'multi': + // return the array directly as SuperAgent will handle it as expected + return param.map(this.paramToString); + default: + throw new Error('Unknown collection format: ' + collectionFormat); + } + }; + + /** + * Applies authentication headers to the request. + * @param {Object} request The request object created by a superagent() call. + * @param {Array.} authNames An array of authentication method names. + */ + exports.prototype.applyAuthToRequest = function(request, authNames) { + var _this = this; + authNames.forEach(function(authName) { + var auth = _this.authentications[authName]; + switch (auth.type) { + case 'basic': + if (auth.username || auth.password) { + request.auth(auth.username || '', auth.password || ''); + } + break; + case 'bearer': + if (auth.accessToken) { + request.set({'Authorization': 'Bearer ' + auth.accessToken}); + } + break; + case 'apiKey': + if (auth.apiKey) { + var data = {}; + if (auth.apiKeyPrefix) { + data[auth.name] = auth.apiKeyPrefix + ' ' + auth.apiKey; + } else { + data[auth.name] = auth.apiKey; + } + if (auth['in'] === 'header') { + request.set(data); + } else { + request.query(data); + } + } + break; + case 'oauth2': + if (auth.accessToken) { + request.set({'Authorization': 'Bearer ' + auth.accessToken}); + } + break; + default: + throw new Error('Unknown authentication type: ' + auth.type); + } + }); + }; + + /** + * Deserializes an HTTP response body into a value of the specified type. + * @param {Object} response A SuperAgent response object. + * @param {(String|Array.|Object.|Function)} returnType The type to return. Pass a string for simple types + * or the constructor function for a complex type. Pass an array containing the type name to return an array of that type. To + * return an object, pass an object with one property whose name is the key type and whose value is the corresponding value type: + * all properties on data will be converted to this type. + * @returns A value of the specified type. + */ + exports.prototype.deserialize = function deserialize(response, returnType) { + if (response == null || returnType == null || response.status == 204) { + return null; + } + // Rely on SuperAgent for parsing response body. + // See http://visionmedia.github.io/superagent/#parsing-response-bodies + var data = response.body; + if (data == null || (typeof data === 'object' && typeof data.length === 'undefined' && !Object.keys(data).length)) { + // SuperAgent does not always produce a body; use the unparsed response as a fallback + data = response.text; + } + return exports.convertToType(data, returnType); + }; + + /** + * Callback function to receive the result of the operation. + * @callback module:ApiClient~callApiCallback + * @param {String} error Error message, if any. + * @param data The data returned by the service call. + * @param {String} response The complete HTTP response. + */ + + /** + * Invokes the REST service using the supplied settings and parameters. + * @param {String} path The base URL to invoke. + * @param {String} httpMethod The HTTP method to use. + * @param {Object.} pathParams A map of path parameters and their values. + * @param {Object.} queryParams A map of query parameters and their values. + * @param {Object.} collectionQueryParams A map of collection query parameters and their values. + * @param {Object.} headerParams A map of header parameters and their values. + * @param {Object.} formParams A map of form parameters and their values. + * @param {Object} bodyParam The value to pass as the request body. + * @param {Array.} authNames An array of authentication type names. + * @param {Array.} contentTypes An array of request MIME types. + * @param {Array.} accepts An array of acceptable response MIME types. + * @param {(String|Array|ObjectFunction)} returnType The required type to return; can be a string for simple types or the + * constructor for a complex type. + * @param {module:ApiClient~callApiCallback} callback The callback function. + * @returns {Object} The SuperAgent request object. + */ + exports.prototype.callApi = function callApi(path, httpMethod, pathParams, + queryParams, collectionQueryParams, headerParams, formParams, bodyParam, authNames, contentTypes, accepts, + returnType, apiBasePath, callback) { + + var _this = this; + var url = this.buildUrl(path, pathParams, apiBasePath); + var request = superagent(httpMethod, url); + + if (this.plugins !== null) { + for (var index in this.plugins) { + if (this.plugins.hasOwnProperty(index)) { + request.use(this.plugins[index]) + } + } + } + + // apply authentications + this.applyAuthToRequest(request, authNames); + + // set collection query parameters + for (var key in collectionQueryParams) { + if (collectionQueryParams.hasOwnProperty(key)) { + var param = collectionQueryParams[key]; + if (param.collectionFormat === 'csv') { + // SuperAgent normally percent-encodes all reserved characters in a query parameter. However, + // commas are used as delimiters for the 'csv' collectionFormat so they must not be encoded. We + // must therefore construct and encode 'csv' collection query parameters manually. + if (param.value != null) { + var value = param.value.map(this.paramToString).map(encodeURIComponent).join(','); + request.query(encodeURIComponent(key) + "=" + value); + } + } else { + // All other collection query parameters should be treated as ordinary query parameters. + queryParams[key] = this.buildCollectionParam(param.value, param.collectionFormat); + } + } + } + + // set query parameters + if (httpMethod.toUpperCase() === 'GET' && this.cache === false) { + queryParams['_'] = new Date().getTime(); + } + request.query(this.normalizeParams(queryParams)); + + // set header parameters + request.set(this.defaultHeaders).set(this.normalizeParams(headerParams)); + + + // set requestAgent if it is set by user + if (this.requestAgent) { + request.agent(this.requestAgent); + } + + // set request timeout + request.timeout(this.timeout); + + var contentType = this.jsonPreferredMime(contentTypes); + if (contentType) { + // Issue with superagent and multipart/form-data (https://github.com/visionmedia/superagent/issues/746) + if(contentType != 'multipart/form-data') { + request.type(contentType); + } + } else if (!request.header['Content-Type']) { + request.type('application/json'); + } + + if (contentType === 'application/x-www-form-urlencoded') { + request.send(querystring.stringify(this.normalizeParams(formParams))); + } else if (contentType == 'multipart/form-data') { + var _formParams = this.normalizeParams(formParams); + for (var key in _formParams) { + if (_formParams.hasOwnProperty(key)) { + if (this.isFileParam(_formParams[key])) { + // file field + request.attach(key, _formParams[key]); + } else { + request.field(key, _formParams[key]); + } + } + } + } else if (bodyParam !== null && bodyParam !== undefined) { + request.send(bodyParam); + } + + var accept = this.jsonPreferredMime(accepts); + if (accept) { + request.accept(accept); + } + + if (returnType === 'Blob') { + request.responseType('blob'); + } else if (returnType === 'String') { + request.responseType('string'); + } + + // Attach previously saved cookies, if enabled + if (this.enableCookies){ + if (typeof window === 'undefined') { + this.agent._attachCookies(request); + } + else { + request.withCredentials(); + } + } + + + request.end(function(error, response) { + if (callback) { + var data = null; + if (!error) { + try { + data = _this.deserialize(response, returnType); + if (_this.enableCookies && typeof window === 'undefined'){ + _this.agent._saveCookies(response); + } + } catch (err) { + error = err; + } + } + callback(error, data, response); + } + }); + + return request; + }; + + /** + * Parses an ISO-8601 string representation of a date value. + * @param {String} str The date value as a string. + * @returns {Date} The parsed date object. + */ + exports.parseDate = function(str) { + return new Date(str.replace(/T/i, ' ')); + }; + + /** + * Converts a value to the specified type. + * @param {(String|Object)} data The data to convert, as a string or object. + * @param {(String|Array.|Object.|Function)} type The type to return. Pass a string for simple types + * or the constructor function for a complex type. Pass an array containing the type name to return an array of that type. To + * return an object, pass an object with one property whose name is the key type and whose value is the corresponding value type: + * all properties on data will be converted to this type. + * @returns An instance of the specified type or null or undefined if data is null or undefined. + */ + exports.convertToType = function(data, type) { + if (data === null || data === undefined) + return data + + switch (type) { + case 'Boolean': + return Boolean(data); + case 'Integer': + return parseInt(data, 10); + case 'Number': + return parseFloat(data); + case 'String': + return String(data); + case 'Date': + return this.parseDate(String(data)); + case 'Blob': + return data; + default: + if (type === Object) { + // generic object, return directly + return data; + } else if (typeof type.constructFromObject === 'function') { + // for model type like User or enum class + return type.constructFromObject(data); + } else if (Array.isArray(type)) { + // for array type like: ['String'] + var itemType = type[0]; + return data.map(function(item) { + return exports.convertToType(item, itemType); + }); + } else if (typeof type === 'object') { + // for plain object type like: {'String': 'Integer'} + var keyType, valueType; + for (var k in type) { + if (type.hasOwnProperty(k)) { + keyType = k; + valueType = type[k]; + break; + } + } + var result = {}; + for (var k in data) { + if (data.hasOwnProperty(k)) { + var key = exports.convertToType(k, keyType); + var value = exports.convertToType(data[k], valueType); + result[key] = value; + } + } + return result; + } else { + // for unknown type, return the data directly + return data; + } + } + }; + + /** + * Gets an array of host settings + * @returns An array of host settings + */ + exports.hostSettings = function() { + return [ + { + 'url': "//petstore.swagger.io */ ' " =end -- \r\n \n \r/v2 */ ' " =end -- \r\n \n \r", + 'description': "No description provided", + } + ]; + }; + + exports.getBasePathFromSettings = function(index, variables={}) { + var servers = this.hostSettings(); + + // check array index out of bound + if (index < 0 || index >= servers.length) { + throw new Error("Invalid index " + index + " when selecting the host settings. Must be less than " + servers.length); + } + + var server = servers[index]; + var url = server['url']; + + // go through variable and assign a value + for (var variable_name in server['variables']) { + if (variable_name in variables) { + if (server['variables'][variable_name]['enum_values'].includes(variables[variable_name])) { + url = url.replace("{" + variable_name + "}", variables[variable_name]); + } else { + throw new Error("The variable `" + variable_name + "` in the host URL has invalid value " + variables[variable_name] + ". Must be " + server['variables'][variable_name]['enum_values'] + "."); + } + } else { + // use default value + url = url.replace("{" + variable_name + "}", server['variables'][variable_name]['default_value']) + } + } + return url; + }; + + /** + * Constructs a new map or array model from REST data. + * @param data {Object|Array} The REST data. + * @param obj {Object|Array} The target object or array. + */ + exports.constructFromObject = function(data, obj, itemType) { + if (Array.isArray(data)) { + for (var i = 0; i < data.length; i++) { + if (data.hasOwnProperty(i)) + obj[i] = exports.convertToType(data[i], itemType); + } + } else { + for (var k in data) { + if (data.hasOwnProperty(k)) + obj[k] = exports.convertToType(data[k], itemType); + } + } + }; + + /** + * The default API client implementation. + * @type {module:ApiClient} + */ + exports.instance = new exports(); + + return exports; +})); diff --git a/samples/client/petstore-security-test/javascript/src/api/FakeApi.js b/samples/client/petstore-security-test/javascript/src/api/FakeApi.js new file mode 100644 index 00000000000..1c694e88705 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/src/api/FakeApi.js @@ -0,0 +1,96 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * + * OpenAPI Generator version: 4.0.0-SNAPSHOT + * + * Do not edit the class manually. + * + */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['ApiClient'], factory); + } else if (typeof module === 'object' && module.exports) { + // CommonJS-like environments that support module.exports, like Node. + module.exports = factory(require('../ApiClient')); + } else { + // Browser globals (root is window) + if (!root.OpenApiPetstoreEndRnNR) { + root.OpenApiPetstoreEndRnNR = {}; + } + root.OpenApiPetstoreEndRnNR.FakeApi = factory(root.OpenApiPetstoreEndRnNR.ApiClient); + } +}(this, function(ApiClient) { + 'use strict'; + + /** + * Fake service. + * @module api/FakeApi + * @version 1.0.0 *_/ =end -- \r\n \n \r + */ + + /** + * Constructs a new FakeApi. + * @alias module:api/FakeApi + * @class + * @param {module:ApiClient} [apiClient] Optional API client implementation to use, + * default to {@link module:ApiClient#instance} if unspecified. + */ + var exports = function(apiClient) { + this.apiClient = apiClient || ApiClient.instance; + + + /** + * Callback function to receive the result of the testCodeInjectEndRnNR operation. + * @callback module:api/FakeApi~testCodeInjectEndRnNRCallback + * @param {String} error Error message, if any. + * @param data This operation does not return a value. + * @param {String} response The complete HTTP response. + */ + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param {Object} opts Optional parameters + * @param {String} opts.testCodeInjectEndRnNR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r + * @param {module:api/FakeApi~testCodeInjectEndRnNRCallback} callback The callback function, accepting three arguments: error, data, response + */ + this.testCodeInjectEndRnNR = function(opts, callback) { + opts = opts || {}; + var postBody = null; + + + var pathParams = { + }; + var queryParams = { + }; + var collectionQueryParams = { + }; + var headerParams = { + }; + var formParams = { + 'test code inject */ ' " =end -- \r\n \n \r': opts['testCodeInjectEndRnNR'] + }; + + var authNames = []; + var contentTypes = ['application/x-www-form-urlencoded', '*_/ =end -- ']; + var accepts = []; + var returnType = null; + return this.apiClient.callApi( + '/fake', 'PUT', + pathParams, queryParams, collectionQueryParams, headerParams, formParams, postBody, + authNames, contentTypes, accepts, returnType, null, callback + ); + } + }; + + return exports; +})); diff --git a/samples/client/petstore-security-test/javascript/src/index.js b/samples/client/petstore-security-test/javascript/src/index.js new file mode 100644 index 00000000000..8d154af222f --- /dev/null +++ b/samples/client/petstore-security-test/javascript/src/index.js @@ -0,0 +1,78 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * + * OpenAPI Generator version: 4.0.0-SNAPSHOT + * + * Do not edit the class manually. + * + */ + +(function(factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['ApiClient', 'model/ModelReturn', 'api/FakeApi'], factory); + } else if (typeof module === 'object' && module.exports) { + // CommonJS-like environments that support module.exports, like Node. + module.exports = factory(require('./ApiClient'), require('./model/ModelReturn'), require('./api/FakeApi')); + } +}(function(ApiClient, ModelReturn, FakeApi) { + 'use strict'; + + /** + * This_spec_is_mainly_for_testing_Petstore_server_and_contains_fake_endpoints_models__Please_do_not_use_this_for_any_other_purpose__Special_characters_______end______.
+ * The index module provides access to constructors for all the classes which comprise the public API. + *

+ * An AMD (recommended!) or CommonJS application will generally do something equivalent to the following: + *

+   * var OpenApiPetstoreEndRnNR = require('index'); // See note below*.
+   * var xxxSvc = new OpenApiPetstoreEndRnNR.XxxApi(); // Allocate the API class we're going to use.
+   * var yyyModel = new OpenApiPetstoreEndRnNR.Yyy(); // Construct a model instance.
+   * yyyModel.someProperty = 'someValue';
+   * ...
+   * var zzz = xxxSvc.doSomething(yyyModel); // Invoke the service.
+   * ...
+   * 
+ * *NOTE: For a top-level AMD script, use require(['index'], function(){...}) + * and put the application logic within the callback function. + *

+ *

+ * A non-AMD browser application (discouraged) might do something like this: + *

+   * var xxxSvc = new OpenApiPetstoreEndRnNR.XxxApi(); // Allocate the API class we're going to use.
+   * var yyy = new OpenApiPetstoreEndRnNR.Yyy(); // Construct a model instance.
+   * yyyModel.someProperty = 'someValue';
+   * ...
+   * var zzz = xxxSvc.doSomething(yyyModel); // Invoke the service.
+   * ...
+   * 
+ *

+ * @module index + * @version 1.0.0 *_/ =end -- \r\n \n \r + */ + var exports = { + /** + * The ApiClient constructor. + * @property {module:ApiClient} + */ + ApiClient: ApiClient, + /** + * The ModelReturn model constructor. + * @property {module:model/ModelReturn} + */ + ModelReturn: ModelReturn, + /** + * The FakeApi service constructor. + * @property {module:api/FakeApi} + */ + FakeApi: FakeApi + }; + + return exports; +})); diff --git a/samples/client/petstore-security-test/javascript/src/model/ModelReturn.js b/samples/client/petstore-security-test/javascript/src/model/ModelReturn.js new file mode 100644 index 00000000000..f4a0a819fc6 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/src/model/ModelReturn.js @@ -0,0 +1,81 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * + * OpenAPI Generator version: 4.0.0-SNAPSHOT + * + * Do not edit the class manually. + * + */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['ApiClient'], factory); + } else if (typeof module === 'object' && module.exports) { + // CommonJS-like environments that support module.exports, like Node. + module.exports = factory(require('../ApiClient')); + } else { + // Browser globals (root is window) + if (!root.OpenApiPetstoreEndRnNR) { + root.OpenApiPetstoreEndRnNR = {}; + } + root.OpenApiPetstoreEndRnNR.ModelReturn = factory(root.OpenApiPetstoreEndRnNR.ApiClient); + } +}(this, function(ApiClient) { + 'use strict'; + + + + /** + * The ModelReturn model module. + * @module model/ModelReturn + * @version 1.0.0 *_/ =end -- \r\n \n \r + */ + + /** + * Constructs a new ModelReturn. + * Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r + * @alias module:model/ModelReturn + * @class + */ + var exports = function() { + var _this = this; + + }; + + /** + * Constructs a ModelReturn from a plain JavaScript object, optionally creating a new instance. + * Copies all relevant properties from data to obj if supplied or a new instance if not. + * @param {Object} data The plain JavaScript object bearing properties of interest. + * @param {module:model/ModelReturn} obj Optional instance to populate. + * @return {module:model/ModelReturn} The populated ModelReturn instance. + */ + exports.constructFromObject = function(data, obj) { + if (data) { + obj = obj || new exports(); + if (data.hasOwnProperty('return')) { + obj['return'] = ApiClient.convertToType(data['return'], 'Number'); + } + } + return obj; + } + + /** + * property description *_/ ' \" =end -- \\r\\n \\n \\r + * @member {Number} return + */ + exports.prototype['return'] = undefined; + + + + return exports; +})); + + diff --git a/samples/client/petstore-security-test/javascript/test/api/FakeApi.spec.js b/samples/client/petstore-security-test/javascript/test/api/FakeApi.spec.js new file mode 100644 index 00000000000..98356886b50 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/test/api/FakeApi.spec.js @@ -0,0 +1,66 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * + * OpenAPI Generator version: 4.0.0-SNAPSHOT + * + * Do not edit the class manually. + * + */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. + define(['expect.js', '../../src/index'], factory); + } else if (typeof module === 'object' && module.exports) { + // CommonJS-like environments that support module.exports, like Node. + factory(require('expect.js'), require('../../src/index')); + } else { + // Browser globals (root is window) + factory(root.expect, root.OpenApiPetstoreEndRnNR); + } +}(this, function(expect, OpenApiPetstoreEndRnNR) { + 'use strict'; + + var instance; + + beforeEach(function() { + instance = new OpenApiPetstoreEndRnNR.FakeApi(); + }); + + var getProperty = function(object, getter, property) { + // Use getter method if present; otherwise, get the property directly. + if (typeof object[getter] === 'function') + return object[getter](); + else + return object[property]; + } + + var setProperty = function(object, setter, property, value) { + // Use setter method if present; otherwise, set the property directly. + if (typeof object[setter] === 'function') + object[setter](value); + else + object[property] = value; + } + + describe('FakeApi', function() { + describe('testCodeInjectEndRnNR', function() { + it('should call testCodeInjectEndRnNR successfully', function(done) { + //uncomment below and update the code to test testCodeInjectEndRnNR + //instance.testCodeInjectEndRnNR(function(error) { + // if (error) throw error; + //expect().to.be(); + //}); + done(); + }); + }); + }); + +})); diff --git a/samples/client/petstore-security-test/javascript/test/model/ModelReturn.spec.js b/samples/client/petstore-security-test/javascript/test/model/ModelReturn.spec.js new file mode 100644 index 00000000000..ce80cd9a995 --- /dev/null +++ b/samples/client/petstore-security-test/javascript/test/model/ModelReturn.spec.js @@ -0,0 +1,68 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * + * OpenAPI Generator version: 4.0.0-SNAPSHOT + * + * Do not edit the class manually. + * + */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. + define(['expect.js', '../../src/index'], factory); + } else if (typeof module === 'object' && module.exports) { + // CommonJS-like environments that support module.exports, like Node. + factory(require('expect.js'), require('../../src/index')); + } else { + // Browser globals (root is window) + factory(root.expect, root.OpenApiPetstoreEndRnNR); + } +}(this, function(expect, OpenApiPetstoreEndRnNR) { + 'use strict'; + + var instance; + + beforeEach(function() { + instance = new OpenApiPetstoreEndRnNR.ModelReturn(); + }); + + var getProperty = function(object, getter, property) { + // Use getter method if present; otherwise, get the property directly. + if (typeof object[getter] === 'function') + return object[getter](); + else + return object[property]; + } + + var setProperty = function(object, setter, property, value) { + // Use setter method if present; otherwise, set the property directly. + if (typeof object[setter] === 'function') + object[setter](value); + else + object[property] = value; + } + + describe('ModelReturn', function() { + it('should create an instance of ModelReturn', function() { + // uncomment below and update the code to test ModelReturn + //var instance = new OpenApiPetstoreEndRnNR.ModelReturn(); + //expect(instance).to.be.a(OpenApiPetstoreEndRnNR.ModelReturn); + }); + + it('should have the property _return (base name: "return")', function() { + // uncomment below and update the code to test the property _return + //var instance = new OpenApiPetstoreEndRnNR.ModelReturn(); + //expect(instance).to.be(); + }); + + }); + +})); diff --git a/samples/client/petstore-security-test/objc/.gitignore b/samples/client/petstore-security-test/objc/.gitignore new file mode 100644 index 00000000000..79d9331b6d4 --- /dev/null +++ b/samples/client/petstore-security-test/objc/.gitignore @@ -0,0 +1,53 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md + +fastlane/report.xml +fastlane/screenshots diff --git a/samples/client/petstore-security-test/objc/.openapi-generator-ignore b/samples/client/petstore-security-test/objc/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/objc/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/objc/.openapi-generator/VERSION b/samples/client/petstore-security-test/objc/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/objc/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient.podspec b/samples/client/petstore-security-test/objc/OpenAPIClient.podspec new file mode 100644 index 00000000000..6ac94f55a4b --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient.podspec @@ -0,0 +1,37 @@ +# +# Be sure to run `pod lib lint OpenAPIClient.podspec' to ensure this is a +# valid spec and remove all comments before submitting the spec. +# +# Any lines starting with a # are optional, but encouraged +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = "OpenAPIClient" + s.version = "1.0.0" + + s.summary = "OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r" + s.description = <<-DESC + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + DESC + + s.platform = :ios, '7.0' + s.requires_arc = true + + s.framework = 'SystemConfiguration' + + s.homepage = "https://github.com/openapitools/openapi-generator" + s.license = "Proprietary" + s.source = { :git => "https://github.com/openapitools/openapi-generator.git", :tag => "#{s.version}" } + s.author = { "OpenAPI" => "team@openapitools.org" } + + s.source_files = 'OpenAPIClient/**/*.{m,h}' + s.public_header_files = 'OpenAPIClient/**/*.h' + + + s.dependency 'AFNetworking', '~> 3' + s.dependency 'JSONModel', '~> 1.2' + s.dependency 'ISO8601', '~> 0.6' +end + diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Api/OAIFakeApi.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Api/OAIFakeApi.h new file mode 100644 index 00000000000..a89c4edcfeb --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Api/OAIFakeApi.h @@ -0,0 +1,38 @@ +#import +#import "OAIApi.h" + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + + +@interface OAIFakeApi: NSObject + +extern NSString* kOAIFakeApiErrorDomain; +extern NSInteger kOAIFakeApiMissingParamErrorCode; + +-(instancetype) initWithApiClient:(OAIApiClient *)apiClient NS_DESIGNATED_INITIALIZER; + +/// To test code injection *_/ ' \" =end -- \\r\\n \\n \\r +/// To test code injection *_/ ' \" =end -- \\r\\n \\n \\r +/// +/// @param testCodeInjectEndRnNR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) +/// +/// code:400 message:"To test code injection *_/ ' \" =end -- \\r\\n \\n \\r" +/// +/// @return void +-(NSURLSessionTask*) testCodeInjectEndRnNRWithTestCodeInjectEndRnNR: (NSString*) testCodeInjectEndRnNR + completionHandler: (void (^)(NSError* error)) handler; + + + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Api/OAIFakeApi.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Api/OAIFakeApi.m new file mode 100644 index 00000000000..e9b288fae17 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Api/OAIFakeApi.m @@ -0,0 +1,110 @@ +#import "OAIFakeApi.h" +#import "OAIQueryParamCollection.h" +#import "OAIApiClient.h" + + +@interface OAIFakeApi () + +@property (nonatomic, strong, readwrite) NSMutableDictionary *mutableDefaultHeaders; + +@end + +@implementation OAIFakeApi + +NSString* kOAIFakeApiErrorDomain = @"OAIFakeApiErrorDomain"; +NSInteger kOAIFakeApiMissingParamErrorCode = 234513; + +@synthesize apiClient = _apiClient; + +#pragma mark - Initialize methods + +- (instancetype) init { + return [self initWithApiClient:[OAIApiClient sharedClient]]; +} + + +-(instancetype) initWithApiClient:(OAIApiClient *)apiClient { + self = [super init]; + if (self) { + _apiClient = apiClient; + _mutableDefaultHeaders = [NSMutableDictionary dictionary]; + } + return self; +} + +#pragma mark - + +-(NSString*) defaultHeaderForKey:(NSString*)key { + return self.mutableDefaultHeaders[key]; +} + +-(void) setDefaultHeaderValue:(NSString*) value forKey:(NSString*)key { + [self.mutableDefaultHeaders setValue:value forKey:key]; +} + +-(NSDictionary *)defaultHeaders { + return self.mutableDefaultHeaders; +} + +#pragma mark - Api Methods + +/// +/// To test code injection *_/ ' \" =end -- \\r\\n \\n \\r +/// To test code injection *_/ ' \" =end -- \\r\\n \\n \\r +/// @param testCodeInjectEndRnNR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) +/// +/// @returns void +/// +-(NSURLSessionTask*) testCodeInjectEndRnNRWithTestCodeInjectEndRnNR: (NSString*) testCodeInjectEndRnNR + completionHandler: (void (^)(NSError* error)) handler { + NSMutableString* resourcePath = [NSMutableString stringWithFormat:@"/fake"]; + + NSMutableDictionary *pathParams = [[NSMutableDictionary alloc] init]; + + NSMutableDictionary* queryParams = [[NSMutableDictionary alloc] init]; + NSMutableDictionary* headerParams = [NSMutableDictionary dictionaryWithDictionary:self.apiClient.configuration.defaultHeaders]; + [headerParams addEntriesFromDictionary:self.defaultHeaders]; + // HTTP header `Accept` + NSString *acceptHeader = [self.apiClient.sanitizer selectHeaderAccept:@[]]; + if(acceptHeader.length > 0) { + headerParams[@"Accept"] = acceptHeader; + } + + // response content type + NSString *responseContentType = [[acceptHeader componentsSeparatedByString:@", "] firstObject] ?: @""; + + // request content type + NSString *requestContentType = [self.apiClient.sanitizer selectHeaderContentType:@[@"application/x-www-form-urlencoded", @"*_/ ' =end -- "]]; + + // Authentication setting + NSArray *authSettings = @[]; + + id bodyParam = nil; + NSMutableDictionary *formParams = [[NSMutableDictionary alloc] init]; + NSMutableDictionary *localVarFiles = [[NSMutableDictionary alloc] init]; + if (testCodeInjectEndRnNR) { + formParams[@"test code inject */ ' " =end -- \r\n \n \r"] = testCodeInjectEndRnNR; + } + + return [self.apiClient requestWithPath: resourcePath + method: @"PUT" + pathParams: pathParams + queryParams: queryParams + formParams: formParams + files: localVarFiles + body: bodyParam + headerParams: headerParams + authSettings: authSettings + requestContentType: requestContentType + responseContentType: responseContentType + responseType: nil + completionBlock: ^(id data, NSError *error) { + if(handler) { + handler(error); + } + }]; +} + + + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/JSONValueTransformer+ISO8601.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/JSONValueTransformer+ISO8601.h new file mode 100644 index 00000000000..426f5889da1 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/JSONValueTransformer+ISO8601.h @@ -0,0 +1,19 @@ +#import +#import + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +@interface JSONValueTransformer (ISO8601) + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/JSONValueTransformer+ISO8601.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/JSONValueTransformer+ISO8601.m new file mode 100644 index 00000000000..61ae254a8aa --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/JSONValueTransformer+ISO8601.m @@ -0,0 +1,17 @@ +#import +#import "JSONValueTransformer+ISO8601.h" +#import "OAISanitizer.h" + +@implementation JSONValueTransformer (ISO8601) + +- (NSDate *) NSDateFromNSString:(NSString *)string +{ + return [NSDate dateWithISO8601String:string]; +} + +- (NSString *)JSONObjectFromNSDate:(NSDate *)date +{ + return [OAISanitizer dateToString:date]; +} + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIApi.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIApi.h new file mode 100644 index 00000000000..c39700f4c6a --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIApi.h @@ -0,0 +1,29 @@ +#import + +@class OAIApiClient; + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +@protocol OAIApi + +@property(readonly, nonatomic, strong) OAIApiClient *apiClient; + +-(instancetype) initWithApiClient:(OAIApiClient *)apiClient; + +-(void) setDefaultHeaderValue:(NSString*) value forKey:(NSString*)key; +-(NSString*) defaultHeaderForKey:(NSString*)key; + +-(NSDictionary *)defaultHeaders; + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIApiClient.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIApiClient.h new file mode 100644 index 00000000000..57ec3cd9314 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIApiClient.h @@ -0,0 +1,121 @@ +#import +#import "OAIConfiguration.h" +#import "OAIResponseDeserializer.h" +#import "OAISanitizer.h" + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +/** + * A key for `NSError` user info dictionaries. + * + * The corresponding value is the parsed response body for an HTTP error. + */ +extern NSString *const OAIResponseObjectErrorKey; + + +@interface OAIApiClient : AFHTTPSessionManager + +@property (nonatomic, strong, readonly) id configuration; + +@property(nonatomic, assign) NSTimeInterval timeoutInterval; + +@property(nonatomic, strong) id responseDeserializer; + +@property(nonatomic, strong) id sanitizer; + +/** + * Gets if the client is unreachable + * + * @return The client offline state + */ ++(BOOL) getOfflineState; + +/** + * Sets the client reachability, this may be overridden by the reachability manager if reachability changes + * + * @param status The client reachability status. + */ ++(void) setReachabilityStatus:(AFNetworkReachabilityStatus) status; + +/** + * Gets the client reachability + * + * @return The client reachability. + */ ++(AFNetworkReachabilityStatus) getReachabilityStatus; + +@property (nonatomic, strong) NSDictionary< NSString *, AFHTTPRequestSerializer *>* requestSerializerForContentType; + +/** + * Gets client singleton instance + */ ++ (instancetype) sharedClient; + + +/** + * Updates header parameters and query parameters for authentication + * + * @param headers The header parameter will be updated, passed by pointer to pointer. + * @param querys The query parameters will be updated, passed by pointer to pointer. + * @param authSettings The authentication names NSArray. + */ +- (void) updateHeaderParams:(NSDictionary **)headers queryParams:(NSDictionary **)querys WithAuthSettings:(NSArray *)authSettings; + + +/** + * Initializes the session manager with a configuration. + * + * @param configuration The configuration implementation + */ +- (instancetype)initWithConfiguration:(id)configuration; + +/** +* Initializes the session manager with a configuration and url +* +* @param url The base url +* @param configuration The configuration implementation +*/ +- (instancetype)initWithBaseURL:(NSURL *)url configuration:(id)configuration; + +/** + * Performs request + * + * @param path Request url. + * @param method Request method. + * @param pathParams Request path parameters. + * @param queryParams Request query parameters. + * @param body Request body. + * @param headerParams Request header parameters. + * @param authSettings Request authentication names. + * @param requestContentType Request content-type. + * @param responseContentType Response content-type. + * @param completionBlock The block will be executed when the request completed. + * + * @return The created session task. + */ +- (NSURLSessionTask*) requestWithPath: (NSString*) path + method: (NSString*) method + pathParams: (NSDictionary *) pathParams + queryParams: (NSDictionary*) queryParams + formParams: (NSDictionary *) formParams + files: (NSDictionary *) files + body: (id) body + headerParams: (NSDictionary*) headerParams + authSettings: (NSArray *) authSettings + requestContentType: (NSString*) requestContentType + responseContentType: (NSString*) responseContentType + responseType: (NSString *) responseType + completionBlock: (void (^)(id, NSError *))completionBlock; + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIApiClient.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIApiClient.m new file mode 100644 index 00000000000..bcbd477d298 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIApiClient.m @@ -0,0 +1,376 @@ + +#import "OAILogger.h" +#import "OAIApiClient.h" +#import "OAIJSONRequestSerializer.h" +#import "OAIQueryParamCollection.h" +#import "OAIDefaultConfiguration.h" + +NSString *const OAIResponseObjectErrorKey = @"OAIResponseObject"; + +static NSString * const kOAIContentDispositionKey = @"Content-Disposition"; + +static NSDictionary * OAI__headerFieldsForResponse(NSURLResponse *response) { + if(![response isKindOfClass:[NSHTTPURLResponse class]]) { + return nil; + } + return ((NSHTTPURLResponse*)response).allHeaderFields; +} + +static NSString * OAI__fileNameForResponse(NSURLResponse *response) { + NSDictionary * headers = OAI__headerFieldsForResponse(response); + if(!headers[kOAIContentDispositionKey]) { + return [NSString stringWithFormat:@"%@", [[NSProcessInfo processInfo] globallyUniqueString]]; + } + NSString *pattern = @"filename=['\"]?([^'\"\\s]+)['\"]?"; + NSRegularExpression *regexp = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil]; + NSString *contentDispositionHeader = headers[kOAIContentDispositionKey]; + NSTextCheckingResult *match = [regexp firstMatchInString:contentDispositionHeader options:0 range:NSMakeRange(0, [contentDispositionHeader length])]; + return [contentDispositionHeader substringWithRange:[match rangeAtIndex:1]]; +} + + +@interface OAIApiClient () + +@property (nonatomic, strong, readwrite) id configuration; + +@property (nonatomic, strong) NSArray* downloadTaskResponseTypes; + +@end + +@implementation OAIApiClient + +#pragma mark - Singleton Methods + ++ (instancetype) sharedClient { + static OAIApiClient *sharedClient = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedClient = [[self alloc] init]; + }); + return sharedClient; +} + +#pragma mark - Initialize Methods + +- (instancetype)init { + return [self initWithConfiguration:[OAIDefaultConfiguration sharedConfig]]; +} + +- (instancetype)initWithBaseURL:(NSURL *)url { + return [self initWithBaseURL:url configuration:[OAIDefaultConfiguration sharedConfig]]; +} + +- (instancetype)initWithConfiguration:(id)configuration { + return [self initWithBaseURL:[NSURL URLWithString:configuration.host] configuration:configuration]; +} + +- (instancetype)initWithBaseURL:(NSURL *)url configuration:(id)configuration { + self = [super initWithBaseURL:url]; + if (self) { + _configuration = configuration; + _timeoutInterval = 60; + _responseDeserializer = [[OAIResponseDeserializer alloc] init]; + _sanitizer = [[OAISanitizer alloc] init]; + + _downloadTaskResponseTypes = @[@"NSURL*", @"NSURL"]; + + AFHTTPRequestSerializer* afhttpRequestSerializer = [AFHTTPRequestSerializer serializer]; + OAIJSONRequestSerializer * swgjsonRequestSerializer = [OAIJSONRequestSerializer serializer]; + _requestSerializerForContentType = @{kOAIApplicationJSONType : swgjsonRequestSerializer, + @"application/x-www-form-urlencoded": afhttpRequestSerializer, + @"multipart/form-data": afhttpRequestSerializer + }; + self.securityPolicy = [self createSecurityPolicy]; + self.responseSerializer = [AFHTTPResponseSerializer serializer]; + } + return self; +} + +#pragma mark - Task Methods + +- (NSURLSessionDataTask*) taskWithCompletionBlock: (NSURLRequest *)request completionBlock: (void (^)(id, NSError *))completionBlock { + + NSURLSessionDataTask *task = [self dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { + OAIDebugLogResponse(response, responseObject,request,error); + if(!error) { + completionBlock(responseObject, nil); + return; + } + NSMutableDictionary *userInfo = [error.userInfo mutableCopy]; + if (responseObject) { + // Add in the (parsed) response body. + userInfo[OAIResponseObjectErrorKey] = responseObject; + } + NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo]; + completionBlock(nil, augmentedError); + }]; + + return task; +} + +- (NSURLSessionDataTask*) downloadTaskWithCompletionBlock: (NSURLRequest *)request completionBlock: (void (^)(id, NSError *))completionBlock { + + __block NSString * tempFolderPath = [self.configuration.tempFolderPath copy]; + + NSURLSessionDataTask* task = [self dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { + OAIDebugLogResponse(response, responseObject,request,error); + + if(error) { + NSMutableDictionary *userInfo = [error.userInfo mutableCopy]; + if (responseObject) { + userInfo[OAIResponseObjectErrorKey] = responseObject; + } + NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo]; + completionBlock(nil, augmentedError); + return; + } + + NSString *directory = tempFolderPath ?: NSTemporaryDirectory(); + NSString *filename = OAI__fileNameForResponse(response); + + NSString *filepath = [directory stringByAppendingPathComponent:filename]; + NSURL *file = [NSURL fileURLWithPath:filepath]; + + [responseObject writeToURL:file atomically:YES]; + + completionBlock(file, nil); + }]; + + return task; +} + +#pragma mark - Perform Request Methods + +- (NSURLSessionTask*) requestWithPath: (NSString*) path + method: (NSString*) method + pathParams: (NSDictionary *) pathParams + queryParams: (NSDictionary*) queryParams + formParams: (NSDictionary *) formParams + files: (NSDictionary *) files + body: (id) body + headerParams: (NSDictionary*) headerParams + authSettings: (NSArray *) authSettings + requestContentType: (NSString*) requestContentType + responseContentType: (NSString*) responseContentType + responseType: (NSString *) responseType + completionBlock: (void (^)(id, NSError *))completionBlock { + + AFHTTPRequestSerializer * requestSerializer = [self requestSerializerForRequestContentType:requestContentType]; + + __weak id sanitizer = self.sanitizer; + + // sanitize parameters + pathParams = [sanitizer sanitizeForSerialization:pathParams]; + queryParams = [sanitizer sanitizeForSerialization:queryParams]; + headerParams = [sanitizer sanitizeForSerialization:headerParams]; + formParams = [sanitizer sanitizeForSerialization:formParams]; + if(![body isKindOfClass:[NSData class]]) { + body = [sanitizer sanitizeForSerialization:body]; + } + + // auth setting + [self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings]; + + NSMutableString *resourcePath = [NSMutableString stringWithString:path]; + [pathParams enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + NSString * safeString = ([obj isKindOfClass:[NSString class]]) ? obj : [NSString stringWithFormat:@"%@", obj]; + safeString = OAIPercentEscapedStringFromString(safeString); + [resourcePath replaceCharactersInRange:[resourcePath rangeOfString:[NSString stringWithFormat:@"{%@}", key]] withString:safeString]; + }]; + + NSString* pathWithQueryParams = [self pathWithQueryParamsToString:resourcePath queryParams:queryParams]; + if ([pathWithQueryParams hasPrefix:@"/"]) { + pathWithQueryParams = [pathWithQueryParams substringFromIndex:1]; + } + + NSString* urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString]; + + NSError *requestCreateError = nil; + NSMutableURLRequest * request = nil; + if (files.count > 0) { + request = [requestSerializer multipartFormRequestWithMethod:@"POST" URLString:urlString parameters:nil constructingBodyWithBlock:^(id formData) { + [formParams enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + NSString *objString = [sanitizer parameterToString:obj]; + NSData *data = [objString dataUsingEncoding:NSUTF8StringEncoding]; + [formData appendPartWithFormData:data name:key]; + }]; + [files enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + NSURL *filePath = (NSURL *)obj; + [formData appendPartWithFileURL:filePath name:key error:nil]; + }]; + } error:&requestCreateError]; + } + else { + if (formParams) { + request = [requestSerializer requestWithMethod:method URLString:urlString parameters:formParams error:&requestCreateError]; + } + if (body) { + request = [requestSerializer requestWithMethod:method URLString:urlString parameters:body error:&requestCreateError]; + } + } + if(!request) { + completionBlock(nil, requestCreateError); + return nil; + } + + if ([headerParams count] > 0){ + for(NSString * key in [headerParams keyEnumerator]){ + [request setValue:[headerParams valueForKey:key] forHTTPHeaderField:key]; + } + } + [requestSerializer setValue:responseContentType forHTTPHeaderField:@"Accept"]; + + [self postProcessRequest:request]; + + + NSURLSessionTask *task = nil; + + if ([self.downloadTaskResponseTypes containsObject:responseType]) { + task = [self downloadTaskWithCompletionBlock:request completionBlock:^(id data, NSError *error) { + completionBlock(data, error); + }]; + } else { + __weak typeof(self) weakSelf = self; + task = [self taskWithCompletionBlock:request completionBlock:^(id data, NSError *error) { + NSError * serializationError; + id response = [weakSelf.responseDeserializer deserialize:data class:responseType error:&serializationError]; + + if(!response && !error){ + error = serializationError; + } + completionBlock(response, error); + }]; + } + + [task resume]; + + return task; +} + +-(AFHTTPRequestSerializer *)requestSerializerForRequestContentType:(NSString *)requestContentType { + AFHTTPRequestSerializer * serializer = self.requestSerializerForContentType[requestContentType]; + if(!serializer) { + NSAssert(NO, @"Unsupported request content type %@", requestContentType); + serializer = [AFHTTPRequestSerializer serializer]; + } + serializer.timeoutInterval = self.timeoutInterval; + return serializer; +} + +//Added for easier override to modify request +-(void)postProcessRequest:(NSMutableURLRequest *)request { + +} + +#pragma mark - + +- (NSString*) pathWithQueryParamsToString:(NSString*) path queryParams:(NSDictionary*) queryParams { + if(queryParams.count == 0) { + return path; + } + NSString * separator = nil; + NSUInteger counter = 0; + + NSMutableString * requestUrl = [NSMutableString stringWithFormat:@"%@", path]; + + NSDictionary *separatorStyles = @{@"csv" : @",", + @"tsv" : @"\t", + @"pipes": @"|" + }; + for(NSString * key in [queryParams keyEnumerator]){ + if (counter == 0) { + separator = @"?"; + } else { + separator = @"&"; + } + id queryParam = [queryParams valueForKey:key]; + if(!queryParam) { + continue; + } + NSString *safeKey = OAIPercentEscapedStringFromString(key); + if ([queryParam isKindOfClass:[NSString class]]){ + [requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator, safeKey, OAIPercentEscapedStringFromString(queryParam)]]; + + } else if ([queryParam isKindOfClass:[OAIQueryParamCollection class]]){ + OAIQueryParamCollection * coll = (OAIQueryParamCollection*) queryParam; + NSArray* values = [coll values]; + NSString* format = [coll format]; + + if([format isEqualToString:@"multi"]) { + for(id obj in values) { + if (counter > 0) { + separator = @"&"; + } + NSString * safeValue = OAIPercentEscapedStringFromString([NSString stringWithFormat:@"%@",obj]); + [requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator, safeKey, safeValue]]; + counter += 1; + } + continue; + } + NSString * separatorStyle = separatorStyles[format]; + NSString * safeValue = OAIPercentEscapedStringFromString([values componentsJoinedByString:separatorStyle]); + [requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator, safeKey, safeValue]]; + } else { + NSString * safeValue = OAIPercentEscapedStringFromString([NSString stringWithFormat:@"%@",queryParam]); + [requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator, safeKey, safeValue]]; + } + counter += 1; + } + return requestUrl; +} + +/** + * Update header and query params based on authentication settings + */ +- (void) updateHeaderParams:(NSDictionary * *)headers queryParams:(NSDictionary * *)querys WithAuthSettings:(NSArray *)authSettings { + + if ([authSettings count] == 0) { + return; + } + + NSMutableDictionary *headersWithAuth = [NSMutableDictionary dictionaryWithDictionary:*headers]; + NSMutableDictionary *querysWithAuth = [NSMutableDictionary dictionaryWithDictionary:*querys]; + + id config = self.configuration; + for (NSString *auth in authSettings) { + NSDictionary *authSetting = config.authSettings[auth]; + + if(!authSetting) { // auth setting is set only if the key is non-empty + continue; + } + NSString *type = authSetting[@"in"]; + NSString *key = authSetting[@"key"]; + NSString *value = authSetting[@"value"]; + if ([type isEqualToString:@"header"] && [key length] > 0 ) { + headersWithAuth[key] = value; + } else if ([type isEqualToString:@"query"] && [key length] != 0) { + querysWithAuth[key] = value; + } + } + + *headers = [NSDictionary dictionaryWithDictionary:headersWithAuth]; + *querys = [NSDictionary dictionaryWithDictionary:querysWithAuth]; +} + +- (AFSecurityPolicy *) createSecurityPolicy { + AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; + + id config = self.configuration; + + if (config.sslCaCert) { + NSData *certData = [NSData dataWithContentsOfFile:config.sslCaCert]; + [securityPolicy setPinnedCertificates:[NSSet setWithObject:certData]]; + } + + if (config.verifySSL) { + [securityPolicy setAllowInvalidCertificates:NO]; + } + else { + [securityPolicy setAllowInvalidCertificates:YES]; + [securityPolicy setValidatesDomainName:NO]; + } + + return securityPolicy; +} + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIBasicAuthTokenProvider.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIBasicAuthTokenProvider.h new file mode 100644 index 00000000000..b67a39067e2 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIBasicAuthTokenProvider.h @@ -0,0 +1,14 @@ +/** The `OAIBasicAuthTokenProvider` class creates a basic auth token from username and password. + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +#import + +@interface OAIBasicAuthTokenProvider : NSObject + ++ (NSString *)createBasicAuthTokenWithUsername:(NSString *)username password:(NSString *)password; + +@end \ No newline at end of file diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIBasicAuthTokenProvider.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIBasicAuthTokenProvider.m new file mode 100644 index 00000000000..70afc93438a --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIBasicAuthTokenProvider.m @@ -0,0 +1,19 @@ +#import "OAIBasicAuthTokenProvider.h" + +@implementation OAIBasicAuthTokenProvider + ++ (NSString *)createBasicAuthTokenWithUsername:(NSString *)username password:(NSString *)password { + + // return empty string if username and password are empty + if (username.length == 0 && password.length == 0){ + return @""; + } + + NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", username, password]; + NSData *data = [basicAuthCredentials dataUsingEncoding:NSUTF8StringEncoding]; + basicAuthCredentials = [NSString stringWithFormat:@"Basic %@", [data base64EncodedStringWithOptions:0]]; + + return basicAuthCredentials; +} + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIConfiguration.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIConfiguration.h new file mode 100644 index 00000000000..370501f7412 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIConfiguration.h @@ -0,0 +1,89 @@ +#import + +@class OAILogger; + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +static NSString * const kOAIAPIVersion = @"1.0.0"; + +@protocol OAIConfiguration + +/** + * Api logger + */ +@property (readonly, nonatomic) OAILogger *logger; + +/** + * Base url + */ +@property (readonly, nonatomic) NSString *host; + +/** + * Api key values for Api Key type Authentication + */ +@property (readonly, nonatomic) NSDictionary *apiKey; + +/** + * Api key prefix values to be prepend to the respective api key + */ +@property (readonly, nonatomic) NSDictionary *apiKeyPrefix; + +/** + * Username for HTTP Basic Authentication + */ +@property (readonly, nonatomic) NSString *username; + +/** + * Password for HTTP Basic Authentication + */ +@property (readonly, nonatomic) NSString *password; + +/** + * Access token for OAuth + */ +@property (readonly, nonatomic) NSString *accessToken; + +/** + * Temp folder for file download + */ +@property (readonly, nonatomic) NSString *tempFolderPath; + +/** + * Debug switch, default false + */ +@property (readonly, nonatomic) BOOL debug; + +/** + * SSL/TLS verification + * Set this to NO to skip verifying SSL certificate when calling API from https server + */ +@property (readonly, nonatomic) BOOL verifySSL; + +/** + * SSL/TLS verification + * Set this to customize the certificate file to verify the peer + */ +@property (readonly, nonatomic) NSString *sslCaCert; + +/** + * Authentication Settings + */ +@property (readonly, nonatomic) NSDictionary *authSettings; + +/** +* Default headers for all services +*/ +@property (readonly, nonatomic, strong) NSDictionary *defaultHeaders; + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIDefaultConfiguration.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIDefaultConfiguration.h new file mode 100644 index 00000000000..e4bab531907 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIDefaultConfiguration.h @@ -0,0 +1,171 @@ +#import +#import "OAIConfiguration.h" + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +@class OAIApiClient; + +@interface OAIDefaultConfiguration : NSObject + + +/** + * Default api logger + */ +@property (nonatomic, strong) OAILogger * logger; + +/** + * Default base url + */ +@property (nonatomic) NSString *host; + +/** + * Api key values for Api Key type Authentication + * + * To add or remove api key, use `setApiKey:forApiKeyIdentifier:`. + */ +@property (readonly, nonatomic, strong) NSDictionary *apiKey; + +/** + * Api key prefix values to be prepend to the respective api key + * + * To add or remove prefix, use `setApiKeyPrefix:forApiKeyPrefixIdentifier:`. + */ +@property (readonly, nonatomic, strong) NSDictionary *apiKeyPrefix; + +/** + * Username for HTTP Basic Authentication + */ + @property (nonatomic) NSString *username; + +/** + * Password for HTTP Basic Authentication + */ +@property (nonatomic) NSString *password; + +/** + * Access token for OAuth + */ +@property (nonatomic) NSString *accessToken; + +/** + * Temp folder for file download + */ +@property (nonatomic) NSString *tempFolderPath; + +/** + * Debug switch, default false + */ +@property (nonatomic) BOOL debug; + +/** + * Gets configuration singleton instance + */ ++ (instancetype) sharedConfig; + +/** + * SSL/TLS verification + * Set this to NO to skip verifying SSL certificate when calling API from https server + */ +@property (nonatomic) BOOL verifySSL; + +/** + * SSL/TLS verification + * Set this to customize the certificate file to verify the peer + */ +@property (nonatomic) NSString *sslCaCert; + +/** + * The time zone to use for date serialization + */ +@property (nonatomic) NSTimeZone *serializationTimeZone; + +/** + * Sets API key + * + * To remove an apiKey for an identifier, just set the apiKey to nil. + * + * @param apiKey API key or token. + * @param identifier API key identifier (authentication schema). + * + */ +- (void) setApiKey:(NSString *)apiKey forApiKeyIdentifier:(NSString*)identifier; + +/** + * Removes api key + * + * @param identifier API key identifier. + */ +- (void) removeApiKey:(NSString *)identifier; + +/** + * Sets the prefix for API key + * + * @param prefix API key prefix. + * @param identifier API key identifier. + */ +- (void) setApiKeyPrefix:(NSString *)prefix forApiKeyPrefixIdentifier:(NSString *)identifier; + +/** + * Removes api key prefix + * + * @param identifier API key identifier. + */ +- (void) removeApiKeyPrefix:(NSString *)identifier; + +/** + * Gets API key (with prefix if set) + */ +- (NSString *) getApiKeyWithPrefix:(NSString *) key; + +/** + * Gets Basic Auth token + */ +- (NSString *) getBasicAuthToken; + +/** + * Gets OAuth access token + */ +- (NSString *) getAccessToken; + +/** + * Gets Authentication Settings + */ +- (NSDictionary *) authSettings; + +/** +* Default headers for all services +*/ +@property (readonly, nonatomic, strong) NSDictionary *defaultHeaders; + +/** +* Removes header from defaultHeaders +* +* @param key Header name. +*/ +-(void) removeDefaultHeaderForKey:(NSString*)key; + +/** +* Sets the header for key +* +* @param value Value for header name +* @param key Header name +*/ +-(void) setDefaultHeaderValue:(NSString*) value forKey:(NSString*)key; + +/** +* @param key Header key name. +*/ +-(NSString*) defaultHeaderForKey:(NSString*)key; + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIDefaultConfiguration.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIDefaultConfiguration.m new file mode 100644 index 00000000000..c9b5b9afacd --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIDefaultConfiguration.m @@ -0,0 +1,152 @@ +#import "OAIDefaultConfiguration.h" +#import "OAIBasicAuthTokenProvider.h" +#import "OAILogger.h" + +@interface OAIDefaultConfiguration () + +@property (nonatomic, strong) NSMutableDictionary *mutableDefaultHeaders; +@property (nonatomic, strong) NSMutableDictionary *mutableApiKey; +@property (nonatomic, strong) NSMutableDictionary *mutableApiKeyPrefix; + +@end + +@implementation OAIDefaultConfiguration + +#pragma mark - Singleton Methods + ++ (instancetype) sharedConfig { + static OAIDefaultConfiguration *shardConfig = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + shardConfig = [[self alloc] init]; + }); + return shardConfig; +} + +#pragma mark - Initialize Methods + +- (instancetype) init { + self = [super init]; + if (self) { + _host = @"http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r"; + _username = @""; + _password = @""; + _accessToken= @""; + _verifySSL = YES; + _mutableApiKey = [NSMutableDictionary dictionary]; + _mutableApiKeyPrefix = [NSMutableDictionary dictionary]; + _mutableDefaultHeaders = [NSMutableDictionary dictionary]; + + _logger = [OAILogger sharedLogger]; + } + return self; +} + +#pragma mark - Instance Methods + +- (NSString *) getApiKeyWithPrefix:(NSString *)key { + NSString *prefix = self.apiKeyPrefix[key]; + NSString *apiKey = self.apiKey[key]; + if (prefix && apiKey != (id)[NSNull null] && apiKey.length > 0) { // both api key prefix and api key are set + return [NSString stringWithFormat:@"%@ %@", prefix, apiKey]; + } + else if (apiKey != (id)[NSNull null] && apiKey.length > 0) { // only api key, no api key prefix + return [NSString stringWithFormat:@"%@", self.apiKey[key]]; + } + else { // return empty string if nothing is set + return @""; + } +} + +- (NSString *) getBasicAuthToken { + + NSString *basicAuthToken = [OAIBasicAuthTokenProvider createBasicAuthTokenWithUsername:self.username password:self.password]; + return basicAuthToken; +} + +- (NSString *) getAccessToken { + if (self.accessToken.length == 0) { // token not set, return empty string + return @""; + } else { + return [NSString stringWithFormat:@"Bearer %@", self.accessToken]; + } +} + +#pragma mark - Setter Methods + +- (void) setApiKey:(NSString *)apiKey forApiKeyIdentifier:(NSString *)identifier { + [self.mutableApiKey setValue:apiKey forKey:identifier]; +} + +- (void) removeApiKey:(NSString *)identifier { + [self.mutableApiKey removeObjectForKey:identifier]; +} + +- (void) setApiKeyPrefix:(NSString *)prefix forApiKeyPrefixIdentifier:(NSString *)identifier { + [self.mutableApiKeyPrefix setValue:prefix forKey:identifier]; +} + +- (void) removeApiKeyPrefix:(NSString *)identifier { + [self.mutableApiKeyPrefix removeObjectForKey:identifier]; +} + +#pragma mark - Getter Methods + +- (NSDictionary *) apiKey { + return [NSDictionary dictionaryWithDictionary:self.mutableApiKey]; +} + +- (NSDictionary *) apiKeyPrefix { + return [NSDictionary dictionaryWithDictionary:self.mutableApiKeyPrefix]; +} + +#pragma mark - + +- (NSDictionary *) authSettings { + return @{ + @"api_key": + @{ + @"type": @"api_key", + @"in": @"header", + @"key": @"api_key */ ' " =end -- \r\n \n \r", + @"value": [self getApiKeyWithPrefix:@"api_key */ ' " =end -- \r\n \n \r"] + }, + @"petstore_auth": + @{ + @"type": @"oauth", + @"in": @"header", + @"key": @"Authorization", + @"value": [self getAccessToken] + }, + }; +} + +-(BOOL)debug { + return self.logger.isEnabled; +} + +-(void)setDebug:(BOOL)debug { + self.logger.enabled = debug; +} + +- (void)setDefaultHeaderValue:(NSString *)value forKey:(NSString *)key { + if(!value) { + [self.mutableDefaultHeaders removeObjectForKey:key]; + return; + } + self.mutableDefaultHeaders[key] = value; +} + +-(void) removeDefaultHeaderForKey:(NSString*)key { + [self.mutableDefaultHeaders removeObjectForKey:key]; +} + +- (NSString *)defaultHeaderForKey:(NSString *)key { + return self.mutableDefaultHeaders[key]; +} + +- (NSDictionary *)defaultHeaders { + return [self.mutableDefaultHeaders copy]; +} + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIJSONRequestSerializer.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIJSONRequestSerializer.h new file mode 100644 index 00000000000..a6163a7bdc5 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIJSONRequestSerializer.h @@ -0,0 +1,18 @@ +#import +#import + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +@interface OAIJSONRequestSerializer : AFJSONRequestSerializer +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIJSONRequestSerializer.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIJSONRequestSerializer.m new file mode 100644 index 00000000000..644f07c174b --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIJSONRequestSerializer.m @@ -0,0 +1,37 @@ +#import "OAIJSONRequestSerializer.h" + +@implementation OAIJSONRequestSerializer + +/// +/// When customize a request serializer, +/// the serializer must conform the protocol `AFURLRequestSerialization` +/// and implements the protocol method `requestBySerializingRequest:withParameters:error:` +/// +/// @param request The original request. +/// @param parameters The parameters to be encoded. +/// @param error The error that occurred while attempting to encode the request parameters. +/// +/// @return A serialized request. +/// +- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request + withParameters:(id)parameters + error:(NSError *__autoreleasing *)error +{ + if (!parameters) { + return request; + } + // If the body data which will be serialized isn't NSArray or NSDictionary + // then put the data in the http request body directly. + if ([parameters isKindOfClass:[NSArray class]] || [parameters isKindOfClass:[NSDictionary class]]) { + return [super requestBySerializingRequest:request withParameters:parameters error:error]; + } + NSMutableURLRequest *mutableRequest = [request mutableCopy]; + if([parameters isKindOfClass:[NSData class]]) { + [mutableRequest setHTTPBody:parameters]; + } else { + [mutableRequest setHTTPBody:[parameters dataUsingEncoding:self.stringEncoding]]; + } + return mutableRequest; +} + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAILogger.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAILogger.h new file mode 100644 index 00000000000..a30dcd1a08f --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAILogger.h @@ -0,0 +1,61 @@ +#import + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#ifndef OAIDebugLogResponse +#define OAIDebugLogResponse(response, responseObject,request, error) [[OAILogger sharedLogger] logResponse:response responseObject:responseObject request:request error:error]; +#endif + +/** + * Log debug message macro + */ +#ifndef OAIDebugLog +#define OAIDebugLog(format, ...) [[OAILogger sharedLogger] debugLog:[NSString stringWithFormat:@"%s", __PRETTY_FUNCTION__] message: format, ##__VA_ARGS__]; +#endif + +@interface OAILogger : NSObject + ++(instancetype)sharedLogger; + +/** + * Enabled switch, default NO - default set by OAIConfiguration debug property + */ +@property (nonatomic, assign, getter=isEnabled) BOOL enabled; + +/** + * Debug file location, default log in console + */ +@property (nonatomic, strong) NSString *loggingFile; + +/** + * Log file handler, this property is used by sdk internally. + */ +@property (nonatomic, strong, readonly) NSFileHandle *loggingFileHandler; + +/** + * Log debug message + */ +-(void)debugLog:(NSString *)method message:(NSString *)format, ...; + +/** + * Logs request and response + * + * @param response NSURLResponse for the HTTP request. + * @param responseObject response object of the HTTP request. + * @param request The HTTP request. + * @param error The error of the HTTP request. + */ +- (void)logResponse:(NSURLResponse *)response responseObject:(id)responseObject request:(NSURLRequest *)request error:(NSError *)error; + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAILogger.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAILogger.m new file mode 100644 index 00000000000..42b950681ad --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAILogger.m @@ -0,0 +1,73 @@ +#import "OAILogger.h" + +@interface OAILogger () + +@end + +@implementation OAILogger + ++ (instancetype) sharedLogger { + static OAILogger *shardLogger = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + shardLogger = [[self alloc] init]; + }); + return shardLogger; +} + +#pragma mark - Log Methods + +- (void)debugLog:(NSString *)method message:(NSString *)format, ... { + if (!self.isEnabled) { + return; + } + + NSMutableString *message = [NSMutableString stringWithCapacity:1]; + + if (method) { + [message appendFormat:@"%@: ", method]; + } + + va_list args; + va_start(args, format); + + [message appendString:[[NSString alloc] initWithFormat:format arguments:args]]; + + // If set logging file handler, log into file, + // otherwise log into console. + if (self.loggingFileHandler) { + [self.loggingFileHandler seekToEndOfFile]; + [self.loggingFileHandler writeData:[message dataUsingEncoding:NSUTF8StringEncoding]]; + } else { + NSLog(@"%@", message); + } + + va_end(args); +} + +- (void)logResponse:(NSURLResponse *)response responseObject:(id)responseObject request:(NSURLRequest *)request error:(NSError *)error { + NSString *message = [NSString stringWithFormat:@"\n[DEBUG] HTTP request body \n~BEGIN~\n %@\n~END~\n"\ + "[DEBUG] HTTP response body \n~BEGIN~\n %@\n~END~\n", + [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding], + responseObject]; + + OAIDebugLog(message); +} + +- (void) setLoggingFile:(NSString *)loggingFile { + if(_loggingFile == loggingFile) { + return; + } + // close old file handler + if ([self.loggingFileHandler isKindOfClass:[NSFileHandle class]]) { + [self.loggingFileHandler closeFile]; + } + _loggingFile = loggingFile; + _loggingFileHandler = [NSFileHandle fileHandleForWritingAtPath:_loggingFile]; + if (_loggingFileHandler == nil) { + [[NSFileManager defaultManager] createFileAtPath:_loggingFile contents:nil attributes:nil]; + _loggingFileHandler = [NSFileHandle fileHandleForWritingAtPath:_loggingFile]; + } +} + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIObject.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIObject.h new file mode 100644 index 00000000000..062f504d823 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIObject.h @@ -0,0 +1,19 @@ +#import +#import + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +@interface OAIObject : JSONModel + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIObject.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIObject.m new file mode 100644 index 00000000000..fd31d41df3e --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIObject.m @@ -0,0 +1,42 @@ +#import "OAIObject.h" + +@implementation OAIObject + +/** + * Workaround for JSONModel multithreading issues + * https://github.com/icanzilb/JSONModel/issues/441 + */ +- (instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError **)err { + static NSMutableSet *classNames; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + classNames = [NSMutableSet new]; + }); + + BOOL initSync; + @synchronized([self class]) + { + NSString *className = NSStringFromClass([self class]); + initSync = ![classNames containsObject:className]; + if(initSync) + { + [classNames addObject:className]; + self = [super initWithDictionary:dict error:err]; + } + } + if(!initSync) + { + self = [super initWithDictionary:dict error:err]; + } + return self; +} + +/** + * Gets the string presentation of the object. + * This method will be called when logging model object using `NSLog`. + */ +- (NSString *)description { + return [[self toDictionary] description]; +} + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIQueryParamCollection.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIQueryParamCollection.h new file mode 100644 index 00000000000..2a9a8a91ec8 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIQueryParamCollection.h @@ -0,0 +1,24 @@ +#import + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +@interface OAIQueryParamCollection : NSObject + +@property(nonatomic, readonly) NSArray* values; +@property(nonatomic, readonly) NSString* format; + +- (id) initWithValuesAndFormat: (NSArray*) values + format: (NSString*) format; + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIQueryParamCollection.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIQueryParamCollection.m new file mode 100644 index 00000000000..fba39676e82 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIQueryParamCollection.m @@ -0,0 +1,20 @@ +#import "OAIQueryParamCollection.h" + +@implementation OAIQueryParamCollection + +@synthesize values = _values; +@synthesize format = _format; + +- (id)initWithValuesAndFormat:(NSArray *)values + format:(NSString *)format { + + self = [super init]; + if (self) { + _values = values; + _format = format; + } + + return self; +} + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIResponseDeserializer.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIResponseDeserializer.h new file mode 100644 index 00000000000..875942364e0 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIResponseDeserializer.h @@ -0,0 +1,57 @@ +#import + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +/** + * A key for deserialization ErrorDomain + */ +extern NSString *const OAIDeserializationErrorDomainKey; + +/** + * Code for deserialization type mismatch error + */ +extern NSInteger const OAITypeMismatchErrorCode; + +/** + * Code for deserialization empty value error + */ +extern NSInteger const OAIEmptyValueOccurredErrorCode; + +/** + * Error code for unknown response + */ +extern NSInteger const OAIUnknownResponseObjectErrorCode; + +@protocol OAIResponseDeserializer + +/** + * Deserializes the given data to Objective-C object. + * + * @param data The data will be deserialized. + * @param className The type of objective-c object. + * @param error The error + */ +- (id) deserialize:(id) data class:(NSString *) className error:(NSError**)error; + +@end + +@interface OAIResponseDeserializer : NSObject + +/** + * If a null value occurs in dictionary or array if set to YES whole response will be invalid else will be ignored + * @default NO + */ +@property (nonatomic, assign) BOOL treatNullAsError; + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIResponseDeserializer.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIResponseDeserializer.m new file mode 100644 index 00000000000..46ffcb25eee --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAIResponseDeserializer.m @@ -0,0 +1,247 @@ +#import "OAIResponseDeserializer.h" +#import +#import + +NSString *const OAIDeserializationErrorDomainKey = @"OAIDeserializationErrorDomainKey"; + +NSInteger const OAITypeMismatchErrorCode = 143553; + +NSInteger const OAIEmptyValueOccurredErrorCode = 143509; + +NSInteger const OAIUnknownResponseObjectErrorCode = 143528; + + +@interface OAIResponseDeserializer () + +@property (nonatomic, strong) NSNumberFormatter* numberFormatter; +@property (nonatomic, strong) NSArray *primitiveTypes; +@property (nonatomic, strong) NSArray *basicReturnTypes; +@property (nonatomic, strong) NSArray *dataReturnTypes; + +@property (nonatomic, strong) NSRegularExpression* arrayOfModelsPatExpression; +@property (nonatomic, strong) NSRegularExpression* arrayOfPrimitivesPatExpression; +@property (nonatomic, strong) NSRegularExpression* dictPatExpression; +@property (nonatomic, strong) NSRegularExpression* dictModelsPatExpression; + +@end + +@implementation OAIResponseDeserializer + +- (instancetype)init { + self = [super init]; + if (self) { + NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; + formatter.numberStyle = NSNumberFormatterDecimalStyle; + _numberFormatter = formatter; + _primitiveTypes = @[@"NSString", @"NSDate", @"NSNumber"]; + _basicReturnTypes = @[@"NSObject", @"id"]; + _dataReturnTypes = @[@"NSData"]; + + _arrayOfModelsPatExpression = [NSRegularExpression regularExpressionWithPattern:@"NSArray<(.+)>" + options:NSRegularExpressionCaseInsensitive + error:nil]; + _arrayOfPrimitivesPatExpression = [NSRegularExpression regularExpressionWithPattern:@"NSArray\\* /\\* (.+) \\*/" + options:NSRegularExpressionCaseInsensitive + error:nil]; + _dictPatExpression = [NSRegularExpression regularExpressionWithPattern:@"NSDictionary\\* /\\* (.+?), (.+) \\*/" + options:NSRegularExpressionCaseInsensitive + error:nil]; + _dictModelsPatExpression = [NSRegularExpression regularExpressionWithPattern:@"NSDictionary\\<(.+?), (.+)*\\>" + options:NSRegularExpressionCaseInsensitive + error:nil]; + } + return self; +} + +#pragma mark - Deserialize methods + +- (id) deserialize:(id) data class:(NSString *) className error:(NSError **) error { + if (!data || !className) { + return nil; + } + + if ([className hasSuffix:@"*"]) { + className = [className substringToIndex:[className length] - 1]; + } + if([self.dataReturnTypes containsObject:className]) { + return data; + } + id jsonData = nil; + if([data isKindOfClass:[NSData class]]) { + jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:error]; + } else { + jsonData = data; + } + if(!jsonData) { + jsonData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + } else if([jsonData isKindOfClass:[NSNull class]]) { + return nil; + } + + // pure object + if ([self.basicReturnTypes containsObject:className]) { + return jsonData; + } + + // primitives + if ([self.primitiveTypes containsObject:className]) { + return [self deserializePrimitiveValue:jsonData class:className error:error]; + } + + NSTextCheckingResult *match = nil; + NSRange range = NSMakeRange(0, [className length]); + // list of models + match = [self.arrayOfModelsPatExpression firstMatchInString:className options:0 range:range]; + if (match) { + NSString *innerType = [className substringWithRange:[match rangeAtIndex:1]]; + return [self deserializeArrayValue:jsonData innerType:innerType error:error]; + } + + // list of primitives + match = [self.arrayOfPrimitivesPatExpression firstMatchInString:className options:0 range:range]; + if (match) { + NSString *innerType = [className substringWithRange:[match rangeAtIndex:1]]; + return [self deserializeArrayValue:jsonData innerType:innerType error:error]; + } + + // map + match = [self.dictPatExpression firstMatchInString:className options:0 range:range]; + if (match) { + NSString *valueType = [className substringWithRange:[match rangeAtIndex:2]]; + return [self deserializeDictionaryValue:jsonData valueType:valueType error:error]; + } + + match = [self.dictModelsPatExpression firstMatchInString:className options:0 range:range]; + if (match) { + NSString *valueType = [className substringWithRange:[match rangeAtIndex:2]]; + return [self deserializeDictionaryValue:jsonData valueType:valueType error:error]; + } + + // model + Class ModelClass = NSClassFromString(className); + if ([ModelClass instancesRespondToSelector:@selector(initWithDictionary:error:)]) { + return [(JSONModel *) [ModelClass alloc] initWithDictionary:jsonData error:error]; + } + + if(error) { + *error = [self unknownResponseErrorWithExpectedType:className data:jsonData]; + } + return nil; +} + +- (id) deserializeDictionaryValue:(id) data valueType:(NSString *) valueType error:(NSError**)error { + if(![data isKindOfClass: [NSDictionary class]]) { + if(error) { + *error = [self typeMismatchErrorWithExpectedType:NSStringFromClass([NSDictionary class]) data:data]; + } + return nil; + } + __block NSMutableDictionary *resultDict = [NSMutableDictionary dictionaryWithCapacity:[data count]]; + for (id key in [data allKeys]) { + id obj = [data valueForKey:key]; + id dicObj = [self deserialize:obj class:valueType error:error]; + if(dicObj) { + [resultDict setValue:dicObj forKey:key]; + } else if([obj isKindOfClass:[NSNull class]]) { + if(self.treatNullAsError) { + if (error) { + *error = [self emptyValueOccurredError]; + } + resultDict = nil; + break; + } + } else { + resultDict = nil; + break; + } + } + return resultDict; +} + +- (id) deserializeArrayValue:(id) data innerType:(NSString *) innerType error:(NSError**)error { + if(![data isKindOfClass: [NSArray class]]) { + if(error) { + *error = [self typeMismatchErrorWithExpectedType:NSStringFromClass([NSArray class]) data:data]; + } + return nil; + } + NSMutableArray* resultArray = [NSMutableArray arrayWithCapacity:[data count]]; + for (id obj in data) { + id arrObj = [self deserialize:obj class:innerType error:error]; + if(arrObj) { + [resultArray addObject:arrObj]; + } else if([obj isKindOfClass:[NSNull class]]) { + if(self.treatNullAsError) { + if (error) { + *error = [self emptyValueOccurredError]; + } + resultArray = nil; + break; + } + } else { + resultArray = nil; + break; + } + } + return resultArray; +}; + +- (id) deserializePrimitiveValue:(id) data class:(NSString *) className error:(NSError**)error { + if ([className isEqualToString:@"NSString"]) { + return [NSString stringWithFormat:@"%@",data]; + } + else if ([className isEqualToString:@"NSDate"]) { + return [self deserializeDateValue:data error:error]; + } + else if ([className isEqualToString:@"NSNumber"]) { + // NSNumber from NSNumber + if ([data isKindOfClass:[NSNumber class]]) { + return data; + } + else if ([data isKindOfClass:[NSString class]]) { + // NSNumber (NSCFBoolean) from NSString + if ([[data lowercaseString] isEqualToString:@"true"] || [[data lowercaseString] isEqualToString:@"false"]) { + return @([data boolValue]); + // NSNumber from NSString + } else { + NSNumber* formattedValue = [self.numberFormatter numberFromString:data]; + if(!formattedValue && [data length] > 0 && error) { + *error = [self typeMismatchErrorWithExpectedType:className data:data]; + } + return formattedValue; + } + } + } + if(error) { + *error = [self typeMismatchErrorWithExpectedType:className data:data]; + } + return nil; +} + +- (id) deserializeDateValue:(id) data error:(NSError**)error { + NSDate *date =[NSDate dateWithISO8601String:data]; + if(!date && [data length] > 0 && error) { + *error = [self typeMismatchErrorWithExpectedType:NSStringFromClass([NSDate class]) data:data]; + } + return date; +}; + +-(NSError *)typeMismatchErrorWithExpectedType:(NSString *)expected data:(id)data { + NSString * message = [NSString stringWithFormat:NSLocalizedString(@"Received response [%@] is not an object of type %@",nil),data, expected]; + NSDictionary * userInfo = @{NSLocalizedDescriptionKey : message}; + return [NSError errorWithDomain:OAIDeserializationErrorDomainKey code:OAITypeMismatchErrorCode userInfo:userInfo]; +} + +-(NSError *)emptyValueOccurredError { + NSString * message = NSLocalizedString(@"Received response contains null value in dictionary or array response",nil); + NSDictionary * userInfo = @{NSLocalizedDescriptionKey : message}; + return [NSError errorWithDomain:OAIDeserializationErrorDomainKey code:OAIEmptyValueOccurredErrorCode userInfo:userInfo]; +} + +-(NSError *)unknownResponseErrorWithExpectedType:(NSString *)expected data:(id)data { + NSString * message = [NSString stringWithFormat:NSLocalizedString(@"Unknown response expected type %@ [response: %@]",nil),expected,data]; + NSDictionary * userInfo = @{NSLocalizedDescriptionKey : message}; + return [NSError errorWithDomain:OAIDeserializationErrorDomainKey code:OAIUnknownResponseObjectErrorCode userInfo:userInfo]; +} + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAISanitizer.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAISanitizer.h new file mode 100644 index 00000000000..d39ba6d5efd --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAISanitizer.h @@ -0,0 +1,63 @@ +#import + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +extern NSString * OAIPercentEscapedStringFromString(NSString *string); + +extern NSString * const kOAIApplicationJSONType; + +@protocol OAISanitizer + +/** + * Sanitize object for request + * + * @param object The query/path/header/form/body param to be sanitized. + */ +- (id) sanitizeForSerialization:(id) object; + +/** + * Convert parameter to NSString + */ +- (NSString *) parameterToString: (id) param; + +/** + * Convert date to NSString + */ ++ (NSString *)dateToString:(id)date; + +/** + * Detects Accept header from accepts NSArray + * + * @param accepts NSArray of header + * + * @return The Accept header + */ +-(NSString *) selectHeaderAccept:(NSArray *)accepts; + +/** + * Detects Content-Type header from contentTypes NSArray + * + * @param contentTypes NSArray of header + * + * @return The Content-Type header + */ +-(NSString *) selectHeaderContentType:(NSArray *)contentTypes; + +@end + +@interface OAISanitizer : NSObject + + + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAISanitizer.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAISanitizer.m new file mode 100644 index 00000000000..cbc3f662810 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Core/OAISanitizer.m @@ -0,0 +1,170 @@ +#import "OAISanitizer.h" +#import "OAIObject.h" +#import "OAIQueryParamCollection.h" +#import "OAIDefaultConfiguration.h" +#import + +NSString * const kOAIApplicationJSONType = @"application/json"; + +NSString * OAIPercentEscapedStringFromString(NSString *string) { + static NSString * const kOAICharactersGeneralDelimitersToEncode = @":#[]@"; + static NSString * const kOAICharactersSubDelimitersToEncode = @"!$&'()*+,;="; + + NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy]; + [allowedCharacterSet removeCharactersInString:[kOAICharactersGeneralDelimitersToEncode stringByAppendingString:kOAICharactersSubDelimitersToEncode]]; + + static NSUInteger const batchSize = 50; + + NSUInteger index = 0; + NSMutableString *escaped = @"".mutableCopy; + + while (index < string.length) { + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wgnu" + NSUInteger length = MIN(string.length - index, batchSize); + #pragma GCC diagnostic pop + NSRange range = NSMakeRange(index, length); + + // To avoid breaking up character sequences such as 👴🏻👮🏽 + range = [string rangeOfComposedCharacterSequencesForRange:range]; + + NSString *substring = [string substringWithRange:range]; + NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet]; + [escaped appendString:encoded]; + + index += range.length; + } + + return escaped; +} + +@interface OAISanitizer () + +@property (nonatomic, strong) NSRegularExpression* jsonHeaderTypeExpression; + +@end + +@implementation OAISanitizer + +-(instancetype)init { + self = [super init]; + if ( !self ) { + return nil; + } + _jsonHeaderTypeExpression = [NSRegularExpression regularExpressionWithPattern:@"(.*)application(.*)json(.*)" options:NSRegularExpressionCaseInsensitive error:nil]; + return self; +} + + +- (id) sanitizeForSerialization:(id) object { + if (object == nil) { + return nil; + } + else if ([object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNumber class]] || [object isKindOfClass:[OAIQueryParamCollection class]]) { + return object; + } + else if ([object isKindOfClass:[NSDate class]]) { + return [OAISanitizer dateToString:object]; + } + else if ([object isKindOfClass:[NSArray class]]) { + NSArray *objectArray = object; + NSMutableArray *sanitizedObjs = [NSMutableArray arrayWithCapacity:[objectArray count]]; + [object enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + id sanitizedObj = [self sanitizeForSerialization:obj]; + if (sanitizedObj) { + [sanitizedObjs addObject:sanitizedObj]; + } + }]; + return sanitizedObjs; + } + else if ([object isKindOfClass:[NSDictionary class]]) { + NSDictionary *objectDict = object; + NSMutableDictionary *sanitizedObjs = [NSMutableDictionary dictionaryWithCapacity:[objectDict count]]; + [object enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + id sanitizedObj = [self sanitizeForSerialization:obj]; + if (sanitizedObj) { + sanitizedObjs[key] = sanitizedObj; + } + }]; + return sanitizedObjs; + } + else if ([object isKindOfClass:[OAIObject class]]) { + return [object toDictionary]; + } + else { + NSException *e = [NSException + exceptionWithName:@"InvalidObjectArgumentException" + reason:[NSString stringWithFormat:@"*** The argument object: %@ is invalid", object] + userInfo:nil]; + @throw e; + } +} + +- (NSString *) parameterToString:(id)param { + if ([param isKindOfClass:[NSString class]]) { + return param; + } + else if ([param isKindOfClass:[NSNumber class]]) { + return [param stringValue]; + } + else if ([param isKindOfClass:[NSDate class]]) { + return [OAISanitizer dateToString:param]; + } + else if ([param isKindOfClass:[NSArray class]]) { + NSMutableArray *mutableParam = [NSMutableArray array]; + [param enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + [mutableParam addObject:[self parameterToString:obj]]; + }]; + return [mutableParam componentsJoinedByString:@","]; + } + else { + NSException *e = [NSException + exceptionWithName:@"InvalidObjectArgumentException" + reason:[NSString stringWithFormat:@"*** The argument object: %@ is invalid", param] + userInfo:nil]; + @throw e; + } +} + ++ (NSString *)dateToString:(id)date { + NSTimeZone* timeZone = [OAIDefaultConfiguration sharedConfig].serializationTimeZone; + return [date ISO8601StringWithTimeZone:timeZone usingCalendar:nil]; +} + +#pragma mark - Utility Methods + +/* + * Detect `Accept` from accepts + */ +- (NSString *) selectHeaderAccept:(NSArray *)accepts { + if (accepts.count == 0) { + return @""; + } + NSMutableArray *lowerAccepts = [[NSMutableArray alloc] initWithCapacity:[accepts count]]; + for (NSString *string in accepts) { + if ([self.jsonHeaderTypeExpression matchesInString:string options:0 range:NSMakeRange(0, [string length])].count > 0) { + return kOAIApplicationJSONType; + } + [lowerAccepts addObject:[string lowercaseString]]; + } + return [lowerAccepts componentsJoinedByString:@", "]; +} + +/* + * Detect `Content-Type` from contentTypes + */ +- (NSString *) selectHeaderContentType:(NSArray *)contentTypes { + if (contentTypes.count == 0) { + return kOAIApplicationJSONType; + } + NSMutableArray *lowerContentTypes = [[NSMutableArray alloc] initWithCapacity:[contentTypes count]]; + for (NSString *string in contentTypes) { + if([self.jsonHeaderTypeExpression matchesInString:string options:0 range:NSMakeRange(0, [string length])].count > 0){ + return kOAIApplicationJSONType; + } + [lowerContentTypes addObject:[string lowercaseString]]; + } + return [lowerContentTypes firstObject]; +} + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Model/OAIReturn.h b/samples/client/petstore-security-test/objc/OpenAPIClient/Model/OAIReturn.h new file mode 100644 index 00000000000..2a9e91ecb79 --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Model/OAIReturn.h @@ -0,0 +1,29 @@ +#import +#import "OAIObject.h" + +/** +* OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r +* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- +* +* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +* Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + + + + +@protocol OAIReturn +@end + +@interface OAIReturn : OAIObject + +/* property description *_/ ' \" =end -- \\r\\n \\n \\r [optional] + */ +@property(nonatomic) NSNumber* _return; + +@end diff --git a/samples/client/petstore-security-test/objc/OpenAPIClient/Model/OAIReturn.m b/samples/client/petstore-security-test/objc/OpenAPIClient/Model/OAIReturn.m new file mode 100644 index 00000000000..7e141aa4cac --- /dev/null +++ b/samples/client/petstore-security-test/objc/OpenAPIClient/Model/OAIReturn.m @@ -0,0 +1,34 @@ +#import "OAIReturn.h" + +@implementation OAIReturn + +- (instancetype)init { + self = [super init]; + if (self) { + // initialize property's default value, if any + + } + return self; +} + + +/** + * Maps json key to property name. + * This method is used by `JSONModel`. + */ ++ (JSONKeyMapper *)keyMapper { + return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{ @"_return": @"return" }]; +} + +/** + * Indicates whether the property with the given name is optional. + * If `propertyName` is optional, then return `YES`, otherwise return `NO`. + * This method is used by `JSONModel`. + */ ++ (BOOL)propertyIsOptional:(NSString *)propertyName { + + NSArray *optionalProperties = @[@"_return"]; + return [optionalProperties containsObject:propertyName]; +} + +@end diff --git a/samples/client/petstore-security-test/objc/README.md b/samples/client/petstore-security-test/objc/README.md new file mode 100644 index 00000000000..397e10ca2a9 --- /dev/null +++ b/samples/client/petstore-security-test/objc/README.md @@ -0,0 +1,112 @@ +# OpenAPIClient + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + +This ObjC package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +- Package version: +- Build package: org.openapitools.codegen.languages.ObjcClientCodegen + +## Requirements + +The SDK requires [**ARC (Automatic Reference Counting)**](http://stackoverflow.com/questions/7778356/how-to-enable-disable-automatic-reference-counting) to be enabled in the Xcode project. + +## Installation & Usage +### Install from Github using [CocoaPods](https://cocoapods.org/) + +Add the following to the Podfile: + +```ruby +pod 'OpenAPIClient', :git => 'https://github.com/GIT_USER_ID/GIT_REPO_ID.git' +``` + +To specify a particular branch, append `, :branch => 'branch-name-here'` + +To specify a particular commit, append `, :commit => '11aa22'` + +### Install from local path using [CocoaPods](https://cocoapods.org/) + +Put the SDK under your project folder (e.g. /path/to/objc_project/Vendor/OpenAPIClient) and then add the following to the Podfile: + +```ruby +pod 'OpenAPIClient', :path => 'Vendor/OpenAPIClient' +``` + +### Usage + +Import the following: + +```objc +#import +#import +// load models +#import +// load API classes for accessing endpoints +#import + +``` + +## Recommendation + +It's recommended to create an instance of ApiClient per thread in a multi-threaded environment to avoid any potential issues. + +## Getting Started + +Please follow the [installation procedure](#installation--usage) and then run the following: + +```objc + + +NSString* *testCodeInjectEndRnNR = @"testCodeInjectEndRnNR_example"; // To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + +OAIFakeApi *apiInstance = [[OAIFakeApi alloc] init]; + +// To test code injection *_/ ' \" =end -- \\r\\n \\n \\r +[apiInstance testCodeInjectEndRnNRWithTestCodeInjectEndRnNR:testCodeInjectEndRnNR + completionHandler: ^(NSError* error) { + if (error) { + NSLog(@"Error: %@", error); + } + }]; + +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*OAIFakeApi* | [**testCodeInjectEndRnNR**](docs/OAIFakeApi.md#testcodeinjectendrnnr) | **PUT** /fake | To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + +## Documentation For Models + + - [OAIReturn](docs/OAIReturn.md) + + +## Documentation For Authorization + + +## api_key + +- **Type**: API key +- **API key parameter name**: api_key */ ' " =end -- \r\n \n \r +- **Location**: HTTP header + +## petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - **write:pets**: modify pets in your account *_/ ' \" =end -- \\r\\n \\n \\r + - **read:pets**: read your pets *_/ ' \" =end -- \\r\\n \\n \\r + + +## Author + +something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + + diff --git a/samples/client/petstore-security-test/objc/docs/OAIFakeApi.md b/samples/client/petstore-security-test/objc/docs/OAIFakeApi.md new file mode 100644 index 00000000000..6d7eff9266b --- /dev/null +++ b/samples/client/petstore-security-test/objc/docs/OAIFakeApi.md @@ -0,0 +1,56 @@ +# OAIFakeApi + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**testCodeInjectEndRnNR**](OAIFakeApi.md#testcodeinjectendrnnr) | **PUT** /fake | To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + +# **testCodeInjectEndRnNR** +```objc +-(NSURLSessionTask*) testCodeInjectEndRnNRWithTestCodeInjectEndRnNR: (NSString*) testCodeInjectEndRnNR + completionHandler: (void (^)(NSError* error)) handler; +``` + +To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + +To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + +### Example +```objc + +NSString* testCodeInjectEndRnNR = @"testCodeInjectEndRnNR_example"; // To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + +OAIFakeApi*apiInstance = [[OAIFakeApi alloc] init]; + +// To test code injection *_/ ' \" =end -- \\r\\n \\n \\r +[apiInstance testCodeInjectEndRnNRWithTestCodeInjectEndRnNR:testCodeInjectEndRnNR + completionHandler: ^(NSError* error) { + if (error) { + NSLog(@"Error calling OAIFakeApi->testCodeInjectEndRnNR: %@", error); + } + }]; +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **testCodeInjectEndRnNR** | **NSString***| To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r | [optional] + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded, *_/ ' =end -- + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/client/petstore-security-test/objc/docs/OAIReturn.md b/samples/client/petstore-security-test/objc/docs/OAIReturn.md new file mode 100644 index 00000000000..b592827ceec --- /dev/null +++ b/samples/client/petstore-security-test/objc/docs/OAIReturn.md @@ -0,0 +1,10 @@ +# OAIReturn + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**_return** | **NSNumber*** | property description *_/ ' \" =end -- \\r\\n \\n \\r | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore-security-test/objc/git_push.sh b/samples/client/petstore-security-test/objc/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/objc/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/perl/.gitignore b/samples/client/petstore-security-test/perl/.gitignore new file mode 100644 index 00000000000..ae2ad536abb --- /dev/null +++ b/samples/client/petstore-security-test/perl/.gitignore @@ -0,0 +1,20 @@ +/blib/ +/.build/ +_build/ +cover_db/ +inc/ +Build +!Build/ +Build.bat +.last_cover_stats +/Makefile +/Makefile.old +/MANIFEST.bak +/META.yml +/META.json +/MYMETA.* +nytprof.out +/pm_to_blib +*.o +*.bs +/_eumm/ diff --git a/samples/client/petstore-security-test/perl/.openapi-generator-ignore b/samples/client/petstore-security-test/perl/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/perl/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/perl/.openapi-generator/VERSION b/samples/client/petstore-security-test/perl/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/perl/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/perl/README.md b/samples/client/petstore-security-test/perl/README.md new file mode 100644 index 00000000000..3066152878b --- /dev/null +++ b/samples/client/petstore-security-test/perl/README.md @@ -0,0 +1,294 @@ +# NAME + +WWW::OpenAPIClient::Role - a Moose role for the OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +# VERSION + +Automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +- Package version: 1.0.0 +- Build package: org.openapitools.codegen.languages.PerlClientCodegen + +## A note on Moose + +This role is the only component of the library that uses Moose. See +WWW::OpenAPIClient::ApiFactory for non-Moosey usage. + +# SYNOPSIS + +The Perl Generator in the OpenAPI Generator project builds a library of Perl modules to interact with +a web service defined by a OpenAPI Specification. See below for how to build the +library. + +This module provides an interface to the generated library. All the classes, +objects, and methods (well, not quite \*all\*, see below) are flattened into this +role. + + package MyApp; + use Moose; + with 'WWW::OpenAPIClient::Role'; + + package main; + + my $api = MyApp->new({ tokens => $tokens }); + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + + +## Structure of the library + +The library consists of a set of API classes, one for each endpoint. These APIs +implement the method calls available on each endpoint. + +Additionally, there is a set of "object" classes, which represent the objects +returned by and sent to the methods on the endpoints. + +An API factory class is provided, which builds instances of each endpoint API. + +This Moose role flattens all the methods from the endpoint APIs onto the consuming +class. It also provides methods to retrieve the endpoint API objects, and the API +factory object, should you need it. + +For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. + +## Configuring authentication + +In the normal case, the OpenAPI Spec will describe what parameters are +required and where to put them. You just need to supply the tokens. + + my $tokens = { + # basic + username => $username, + password => $password, + + # oauth + access_token => $oauth_token, + + # keys + $some_key => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + + $another => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + ..., + + }; + + my $api = MyApp->new({ tokens => $tokens }); + +Note these are all optional, as are `prefix` and `in`, and depend on the API +you are accessing. Usually `prefix` and `in` will be determined by the code generator from +the spec and you will not need to set them at run time. If not, `in` will +default to 'head' and `prefix` to the empty string. + +The tokens will be placed in a L instance +as follows, but you don't need to know about this. + +- `$cfg->{username}` + + String. The username for basic auth. + +- `$cfg->{password}` + + String. The password for basic auth. + +- `$cfg->{api_key}` + + Hashref. Keyed on the name of each key (there can be multiple tokens). + + $cfg->{api_key} = { + secretKey => 'aaaabbbbccccdddd', + anotherKey => '1111222233334444', + }; + +- `$cfg->{api_key_prefix}` + + Hashref. Keyed on the name of each key (there can be multiple tokens). Note not + all api keys require a prefix. + + $cfg->{api_key_prefix} = { + secretKey => 'string', + anotherKey => 'same or some other string', + }; + +- `$cfg->{access_token}` + + String. The OAuth access token. + +# METHODS + +## `base_url` + +The generated code has the `base_url` already set as a default value. This method +returns the current value of `base_url`. + +## `api_factory` + +Returns an API factory object. You probably won't need to call this directly. + + $self->api_factory('Pet'); # returns a WWW::OpenAPIClient::PetApi instance + + $self->pet_api; # the same + +# MISSING METHODS + +Most of the methods on the API are delegated to individual endpoint API objects +(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the +same method name (e.g. `new()`), these methods can't be delegated. So you need +to call `$api->pet_api->new()`. + +In principle, every API is susceptible to the presence of a few, random, undelegatable +method names. In practice, because of the way method names are constructed, it's +unlikely in general that any methods will be undelegatable, except for: + + new() + class_documentation() + method_documentation() + +To call these methods, you need to get a handle on the relevant object, either +by calling `$api->foo_api` or by retrieving an object, e.g. +`$api->get_pet_by_id(pet_id => $pet_id)`. They are class methods, so +you could also call them on class names. + +# BUILDING YOUR LIBRARY + +See the homepage `https://openapi-generator.tech` for full details. +But briefly, clone the git repository, build the codegen codebase, set up your build +config file, then run the API build script. You will need git, Java 7 or 8 and Apache +maven 3.0.3 or better already installed. + +The config file should specify the project name for the generated library: + + {"moduleName":"WWW::MyProjectName"} + +Your library files will be built under `WWW::MyProjectName`. + + $ git clone https://github.com/openapitools/openapi-generator + $ cd openapi-generator + $ mvn package + $ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \ + -i [URL or file path to JSON OpenAPI API spec] \ + -g perl \ + -c /path/to/config/file.json \ + -o /path/to/output/folder + +Bang, all done. Run the `autodoc` script in the `bin` directory to see the API +you just built. + +# AUTOMATIC DOCUMENTATION + +You can print out a summary of the generated API by running the included +`autodoc` script in the `bin` directory of your generated library. A few +output formats are supported: + + Usage: autodoc [OPTION] + + -w wide format (default) + -n narrow format + -p POD format + -H HTML format + -m Markdown format + -h print this help message + -c your application class + + +The `-c` option allows you to load and inspect your own application. A dummy +namespace is used if you don't supply your own class. + +# DOCUMENTATION FROM THE OpenAPI Spec + +Additional documentation for each class and method may be provided by the OpenAPI +spec. If so, this is available via the `class_documentation()` and +`method_documentation()` methods on each generated object class, and the +`method_documentation()` method on the endpoint API classes: + + my $cmdoc = $api->pet_api->method_documentation->{$method_name}; + + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; + + +Each of these calls returns a hashref with various useful pieces of information. + +# LOAD THE MODULES + +To load the API packages: +```perl +use WWW::OpenAPIClient::FakeApi; + +``` + +To load the models: +```perl +use WWW::OpenAPIClient::Object::ModelReturn; + +```` + +# GETTING STARTED +Put the Perl SDK under the 'lib' folder in your project directory, then run the following +```perl +#!/usr/bin/perl +use lib 'lib'; +use strict; +use warnings; +# load the API package +use WWW::OpenAPIClient::FakeApi; + +# load the models +use WWW::OpenAPIClient::Object::ModelReturn; + +# for displaying the API response data +use Data::Dumper; +use WWW::OpenAPIClient::; + +my $api_instance = WWW::OpenAPIClient::->new( +); + +my $test_code_inject_*/_'_"_=end____\r\n_\n_\r = "test_code_inject_*/_'_\"_=_end____\\r\\n_\\n_\\r_example"; # string | To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r + +eval { + $api_instance->test_code_inject____end__rn_n_r(test_code_inject_*/_'_"_=end____\r\n_\n_\r => $test_code_inject_*/_'_"_=end____\r\n_\n_\r); +}; +if ($@) { + warn "Exception when calling FakeApi->test_code_inject____end__rn_n_r: $@\n"; +} + +``` + +# DOCUMENTATION FOR API ENDPOINTS + +All URIs are relative to *http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*FakeApi* | [**test_code_inject____end__rn_n_r**](docs/FakeApi.md#test_code_inject____end__rn_n_r) | **PUT** /fake | To test code injection */ ' \" =_end -- \\r\\n \\n \\r + + +# DOCUMENTATION FOR MODELS + - [WWW::OpenAPIClient::Object::ModelReturn](docs/ModelReturn.md) + + +# DOCUMENTATION FOR AUTHORIZATION + +## api_key + +- **Type**: API key +- **API key parameter name**: api_key */ ' " =end -- \r\n \n \r +- **Location**: HTTP header + +## petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - **write:pets**: modify pets in your account */ ' \" =_end -- \\r\\n \\n \\r + - **read:pets**: read your pets */ ' \" =_end -- \\r\\n \\n \\r + diff --git a/samples/client/petstore-security-test/perl/bin/autodoc b/samples/client/petstore-security-test/perl/bin/autodoc new file mode 100644 index 00000000000..f2292179ca7 --- /dev/null +++ b/samples/client/petstore-security-test/perl/bin/autodoc @@ -0,0 +1,77 @@ +#!/usr/bin/perl +use FindBin; +use File::Spec; +use lib File::Spec->catdir($FindBin::Bin, '..', 'lib'); + +use Moose::Util qw(apply_all_roles); +use Getopt::Std; + +my %options=(); +getopts("wnphmHc:", \%options); +help if $options{h}; + +my $my_app = $options{c} || 'My::App'; + +if ($options{c}) { + eval <new; + +if ($options{H}) { + my $pod2html = "pod2html --backlink --css http://st.pimg.net/tucs/style.css?3"; + open STDOUT, "| $pod2html" or die "Can't fork: $!"; + $api->autodoc($opt); + close STDOUT or die "Can't close: $!"; +} +elsif ($options{m}) { + my $pod2markdown = "pod2markdown --html-encode-chars 1"; + open STDOUT, "| $pod2markdown" or die "Can't fork: $!"; + $api->autodoc($opt); + close STDOUT or die "Can't close: $!"; +} +else { + $api->autodoc($opt); +} + +exit(0); + +# -------------------- +sub help { + print <new({ tokens => $tokens }); + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + + +## Structure of the library + +The library consists of a set of API classes, one for each endpoint. These APIs +implement the method calls available on each endpoint. + +Additionally, there is a set of "object" classes, which represent the objects +returned by and sent to the methods on the endpoints. + +An API factory class is provided, which builds instances of each endpoint API. + +This Moose role flattens all the methods from the endpoint APIs onto the consuming +class. It also provides methods to retrieve the endpoint API objects, and the API +factory object, should you need it. + +For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. + +## Configuring authentication + +In the normal case, the OpenAPI Spec will describe what parameters are +required and where to put them. You just need to supply the tokens. + + my $tokens = { + # basic + username => $username, + password => $password, + + # oauth + access_token => $oauth_token, + + # keys + $some_key => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + + $another => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + ..., + + }; + + my $api = MyApp->new({ tokens => $tokens }); + +Note these are all optional, as are `prefix` and `in`, and depend on the API +you are accessing. Usually `prefix` and `in` will be determined by the code generator from +the spec and you will not need to set them at run time. If not, `in` will +default to 'head' and `prefix` to the empty string. + +The tokens will be placed in a L instance +as follows, but you don't need to know about this. + +- `$cfg->{username}` + + String. The username for basic auth. + +- `$cfg->{password}` + + String. The password for basic auth. + +- `$cfg->{api_key}` + + Hashref. Keyed on the name of each key (there can be multiple tokens). + + $cfg->{api_key} = { + secretKey => 'aaaabbbbccccdddd', + anotherKey => '1111222233334444', + }; + +- `$cfg->{api_key_prefix}` + + Hashref. Keyed on the name of each key (there can be multiple tokens). Note not + all api keys require a prefix. + + $cfg->{api_key_prefix} = { + secretKey => 'string', + anotherKey => 'same or some other string', + }; + +- `$cfg->{access_token}` + + String. The OAuth access token. + +# METHODS + +## `base_url` + +The generated code has the `base_url` already set as a default value. This method +returns the current value of `base_url`. + +## `api_factory` + +Returns an API factory object. You probably won't need to call this directly. + + $self->api_factory('Pet'); # returns a Something::Deep::PetApi instance + + $self->pet_api; # the same + +# MISSING METHODS + +Most of the methods on the API are delegated to individual endpoint API objects +(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the +same method name (e.g. `new()`), these methods can't be delegated. So you need +to call `$api->pet_api->new()`. + +In principle, every API is susceptible to the presence of a few, random, undelegatable +method names. In practice, because of the way method names are constructed, it's +unlikely in general that any methods will be undelegatable, except for: + + new() + class_documentation() + method_documentation() + +To call these methods, you need to get a handle on the relevant object, either +by calling `$api->foo_api` or by retrieving an object, e.g. +`$api->get_pet_by_id(pet_id => $pet_id)`. They are class methods, so +you could also call them on class names. + +# BUILDING YOUR LIBRARY + +See the homepage `https://openapi-generator.tech` for full details. +But briefly, clone the git repository, build the codegen codebase, set up your build +config file, then run the API build script. You will need git, Java 7 or 8 and Apache +maven 3.0.3 or better already installed. + +The config file should specify the project name for the generated library: + + {"moduleName":"WWW::MyProjectName"} + +Your library files will be built under `WWW::MyProjectName`. + + $ git clone https://github.com/openapitools/openapi-generator + $ cd openapi-generator + $ mvn package + $ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \ + -i [URL or file path to JSON OpenAPI API spec] \ + -g perl \ + -c /path/to/config/file.json \ + -o /path/to/output/folder + +Bang, all done. Run the `autodoc` script in the `bin` directory to see the API +you just built. + +# AUTOMATIC DOCUMENTATION + +You can print out a summary of the generated API by running the included +`autodoc` script in the `bin` directory of your generated library. A few +output formats are supported: + + Usage: autodoc [OPTION] + + -w wide format (default) + -n narrow format + -p POD format + -H HTML format + -m Markdown format + -h print this help message + -c your application class + + +The `-c` option allows you to load and inspect your own application. A dummy +namespace is used if you don't supply your own class. + +# DOCUMENTATION FROM THE OpenAPI Spec + +Additional documentation for each class and method may be provided by the OpenAPI +spec. If so, this is available via the `class_documentation()` and +`method_documentation()` methods on each generated object class, and the +`method_documentation()` method on the endpoint API classes: + + my $cmdoc = $api->pet_api->method_documentation->{$method_name}; + + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; + + +Each of these calls returns a hashref with various useful pieces of information. + +# LOAD THE MODULES + +To load the API packages: +```perl +use Something::Deep::FakeApi; + +``` + +To load the models: +```perl +use Something::Deep::Object::ModelReturn; + +```` + +# GETTING STARTED +Put the Perl SDK under the 'lib' folder in your project directory, then run the following +```perl +#!/usr/bin/perl +use lib 'lib'; +use strict; +use warnings; +# load the API package +use Something::Deep::FakeApi; + +# load the models +use Something::Deep::Object::ModelReturn; + +# for displaying the API response data +use Data::Dumper; +use Something::Deep::; + +my $api_instance = Something::Deep::->new( +); + +my $test_code_inject_*/_'_"_=end____\r\n_\n_\r = "test_code_inject_*/_'_\"_=_end____\\r\\n_\\n_\\r_example"; # string | To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r + +eval { + $api_instance->test_code_inject____end__rn_n_r(test_code_inject_*/_'_"_=end____\r\n_\n_\r => $test_code_inject_*/_'_"_=end____\r\n_\n_\r); +}; +if ($@) { + warn "Exception when calling FakeApi->test_code_inject____end__rn_n_r: $@\n"; +} + +``` + +# DOCUMENTATION FOR API ENDPOINTS + +All URIs are relative to *http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*FakeApi* | [**test_code_inject____end__rn_n_r**](docs/FakeApi.md#test_code_inject____end__rn_n_r) | **PUT** /fake | To test code injection */ ' \" =_end -- \\r\\n \\n \\r + + +# DOCUMENTATION FOR MODELS + - [Something::Deep::Object::ModelReturn](docs/ModelReturn.md) + + +# DOCUMENTATION FOR AUTHORIZATION + +## api_key + +- **Type**: API key +- **API key parameter name**: api_key */ ' " =end -- \r\n \n \r +- **Location**: HTTP header + +## petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - **write:pets**: modify pets in your account */ ' \" =_end -- \\r\\n \\n \\r + - **read:pets**: read your pets */ ' \" =_end -- \\r\\n \\n \\r + diff --git a/samples/client/petstore-security-test/perl/deep_module_test/bin/autodoc b/samples/client/petstore-security-test/perl/deep_module_test/bin/autodoc new file mode 100644 index 00000000000..174b386d61b --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/bin/autodoc @@ -0,0 +1,77 @@ +#!/usr/bin/perl +use FindBin; +use File::Spec; +use lib File::Spec->catdir($FindBin::Bin, '..', 'lib'); + +use Moose::Util qw(apply_all_roles); +use Getopt::Std; + +my %options=(); +getopts("wnphmHc:", \%options); +help if $options{h}; + +my $my_app = $options{c} || 'My::App'; + +if ($options{c}) { + eval <new; + +if ($options{H}) { + my $pod2html = "pod2html --backlink --css http://st.pimg.net/tucs/style.css?3"; + open STDOUT, "| $pod2html" or die "Can't fork: $!"; + $api->autodoc($opt); + close STDOUT or die "Can't close: $!"; +} +elsif ($options{m}) { + my $pod2markdown = "pod2markdown --html-encode-chars 1"; + open STDOUT, "| $pod2markdown" or die "Can't fork: $!"; + $api->autodoc($opt); + close STDOUT or die "Can't close: $!"; +} +else { + $api->autodoc($opt); +} + +exit(0); + +# -------------------- +sub help { + print < test_code_inject____end__rn_n_r(test_code_inject_*/_'_"_=end____\r\n_\n_\r => $test_code_inject_*/_'_"_=end____\r\n_\n_\r) + +To test code injection */ ' \" =_end -- \\r\\n \\n \\r + +To test code injection */ ' \" =_end -- \\r\\n \\n \\r + +### Example +```perl +use Data::Dumper; +use Something::Deep::FakeApi; +my $api_instance = Something::Deep::FakeApi->new( +); + +my $test_code_inject_*/_'_"_=end____\r\n_\n_\r = "test_code_inject_*/_'_\"_=_end____\\r\\n_\\n_\\r_example"; # string | To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r + +eval { + $api_instance->test_code_inject____end__rn_n_r(test_code_inject_*/_'_"_=end____\r\n_\n_\r => $test_code_inject_*/_'_"_=end____\r\n_\n_\r); +}; +if ($@) { + warn "Exception when calling FakeApi->test_code_inject____end__rn_n_r: $@\n"; +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **test_code_inject_*/_'_"_=end____\r\n_\n_\r** | **string**| To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r | [optional] + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded, */ \" =_end -- + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/client/petstore-security-test/perl/deep_module_test/docs/ModelReturn.md b/samples/client/petstore-security-test/perl/deep_module_test/docs/ModelReturn.md new file mode 100644 index 00000000000..9e9b9a29403 --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/docs/ModelReturn.md @@ -0,0 +1,15 @@ +# Something::Deep::Object::ModelReturn + +## Load the model package +```perl +use Something::Deep::Object::ModelReturn; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**return** | **int** | property description */ ' \" =_end -- \\r\\n \\n \\r | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore-security-test/perl/deep_module_test/git_push.sh b/samples/client/petstore-security-test/perl/deep_module_test/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/ApiClient.pm b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/ApiClient.pm new file mode 100644 index 00000000000..5f21e506015 --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/ApiClient.pm @@ -0,0 +1,393 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package Something::Deep::ApiClient; + +use strict; +use warnings; +use utf8; + +use MIME::Base64; +use LWP::UserAgent; +use HTTP::Headers; +use HTTP::Response; +use HTTP::Request::Common qw(DELETE POST GET HEAD PUT); +use HTTP::Status; +use URI::Query; +use JSON; +use URI::Escape; +use Scalar::Util; +use Log::Any qw($log); +use Carp; +use Module::Runtime qw(use_module); + +use Something::Deep::Configuration; + +sub new { + my $class = shift; + + my $config; + if ( $_[0] && ref $_[0] && ref $_[0] eq 'Something::Deep::Configuration' ) { + $config = $_[0]; + } else { + $config = Something::Deep::Configuration->new(@_); + } + + my (%args) = ( + 'ua' => LWP::UserAgent->new, + 'config' => $config, + ); + + return bless \%args, $class; +} + +# Set the user agent of the API client +# +# @param string $user_agent The user agent of the API client +# +sub set_user_agent { + my ($self, $user_agent) = @_; + $self->{http_user_agent}= $user_agent; +} + +# Set timeout +# +# @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] +# +sub set_timeout { + my ($self, $seconds) = @_; + if (!looks_like_number($seconds)) { + croak('Timeout variable must be numeric.'); + } + $self->{http_timeout} = $seconds; +} + +# make the HTTP request +# @param string $resourcePath path to method endpoint +# @param string $method method to call +# @param array $queryParams parameters to be place in query URL +# @param array $postData parameters to be placed in POST body +# @param array $headerParams parameters to be place in request header +# @return mixed +sub call_api { + my $self = shift; + my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data, $auth_settings) = @_; + + # update parameters based on authentication settings + $self->update_params_for_auth($header_params, $query_params, $auth_settings); + + my $_url = $self->{config}{base_url} . $resource_path; + + # build query + if (%$query_params) { + $_url = ($_url . '?' . eval { URI::Query->new($query_params)->stringify }); + } + + # body data + $body_data = to_json($body_data->to_hash) if defined $body_data && $body_data->can('to_hash'); # model to json string + my $_body_data = %$post_params ? $post_params : $body_data; + + # Make the HTTP request + my $_request; + if ($method eq 'POST') { + # multipart + $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? + 'form-data' : $header_params->{'Content-Type'}; + + $_request = POST($_url, %$header_params, Content => $_body_data); + + } + elsif ($method eq 'PUT') { + # multipart + $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? + 'form-data' : $header_params->{'Content-Type'}; + + $_request = PUT($_url, %$header_params, Content => $_body_data); + + } + elsif ($method eq 'GET') { + my $headers = HTTP::Headers->new(%$header_params); + $_request = GET($_url, %$header_params); + } + elsif ($method eq 'HEAD') { + my $headers = HTTP::Headers->new(%$header_params); + $_request = HEAD($_url,%$header_params); + } + elsif ($method eq 'DELETE') { #TODO support form data + my $headers = HTTP::Headers->new(%$header_params); + $_request = DELETE($_url, %$headers); + } + elsif ($method eq 'PATCH') { #TODO + } + else { + } + + $self->{ua}->timeout($self->{http_timeout} || $self->{config}{http_timeout}); + $self->{ua}->agent($self->{http_user_agent} || $self->{config}{http_user_agent}); + + $log->debugf("REQUEST: %s", $_request->as_string); + my $_response = $self->{ua}->request($_request); + $log->debugf("RESPONSE: %s", $_response->as_string); + + unless ($_response->is_success) { + croak(sprintf "API Exception(%s): %s\n%s", $_response->code, $_response->message, $_response->content); + } + + return $_response->content; + +} + +# Take value and turn it into a string suitable for inclusion in +# the path, by url-encoding. +# @param string $value a string which will be part of the path +# @return string the serialized object +sub to_path_value { + my ($self, $value) = @_; + return uri_escape($self->to_string($value)); +} + + +# Take value and turn it into a string suitable for inclusion in +# the query, by imploding comma-separated if it's an object. +# If it's a string, pass through unchanged. It will be url-encoded +# later. +# @param object $object an object to be serialized to a string +# @return string the serialized object +sub to_query_value { + my ($self, $object) = @_; + if (ref($object) eq 'ARRAY') { + return join(',', @$object); + } else { + return $self->to_string($object); + } +} + + +# Take value and turn it into a string suitable for inclusion in +# the header. If it's a string, pass through unchanged +# If it's a datetime object, format it in ISO8601 +# @param string $value a string which will be part of the header +# @return string the header string +sub to_header_value { + my ($self, $value) = @_; + return $self->to_string($value); +} + +# Take value and turn it into a string suitable for inclusion in +# the http body (form parameter). If it's a string, pass through unchanged +# If it's a datetime object, format it in ISO8601 +# @param string $value the value of the form parameter +# @return string the form string +sub to_form_value { + my ($self, $value) = @_; + return $self->to_string($value); +} + +# Take value and turn it into a string suitable for inclusion in +# the parameter. If it's a string, pass through unchanged +# If it's a datetime object, format it in ISO8601 +# @param string $value the value of the parameter +# @return string the header string +sub to_string { + my ($self, $value) = @_; + if (ref($value) eq "DateTime") { # datetime in ISO8601 format + return $value->datetime(); + } + else { + return $value; + } +} + +# Deserialize a JSON string into an object +# +# @param string $class class name is passed as a string +# @param string $data data of the body +# @return object an instance of $class +sub deserialize +{ + my ($self, $class, $data) = @_; + $log->debugf("deserializing %s for %s", $data, $class); + + if (not defined $data) { + return undef; + } elsif ( (substr($class, 0, 5)) eq 'HASH[') { #hash + if ($class =~ /^HASH\[(.*),(.*)\]$/) { + my ($key_type, $type) = ($1, $2); + my %hash; + my $decoded_data = decode_json $data; + foreach my $key (keys %$decoded_data) { + if (ref $decoded_data->{$key} eq 'HASH') { + $hash{$key} = $self->deserialize($type, encode_json $decoded_data->{$key}); + } else { + $hash{$key} = $self->deserialize($type, $decoded_data->{$key}); + } + } + return \%hash; + } else { + #TODO log error + } + } elsif ( (substr($class, 0, 6)) eq 'ARRAY[' ) { # array of data + return $data if $data eq '[]'; # return if empty array + + my $_sub_class = substr($class, 6, -1); + my $_json_data = decode_json $data; + my @_values = (); + foreach my $_value (@$_json_data) { + if (ref $_value eq 'ARRAY') { + push @_values, $self->deserialize($_sub_class, encode_json $_value); + } else { + push @_values, $self->deserialize($_sub_class, $_value); + } + } + return \@_values; + } elsif ($class eq 'DateTime') { + return DateTime->from_epoch(epoch => str2time($data)); + } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { + return $data; + } else { # model + my $_instance = use_module("Something::Deep::Object::$class")->new; + if (ref $data eq "HASH") { + return $_instance->from_hash($data); + } else { # string, need to json decode first + return $_instance->from_hash(decode_json $data); + } + } +} + +# return 'Accept' based on an array of accept provided +# @param [Array] header_accept_array Array fo 'Accept' +# @return String Accept (e.g. application/json) +sub select_header_accept +{ + my ($self, @header) = @_; + + if (@header == 0 || (@header == 1 && $header[0] eq '')) { + return undef; + } elsif (grep(/^application\/json$/i, @header)) { + return 'application/json'; + } else { + return join(',', @header); + } + +} + +# return the content type based on an array of content-type provided +# @param [Array] content_type_array Array fo content-type +# @return String Content-Type (e.g. application/json) +sub select_header_content_type +{ + my ($self, @header) = @_; + + if (@header == 0 || (@header == 1 && $header[0] eq '')) { + return 'application/json'; # default to application/json + } elsif (grep(/^application\/json$/i, @header)) { + return 'application/json'; + } else { + return join(',', @header); + } + +} + +# Get API key (with prefix if set) +# @param string key name +# @return string API key with the prefix +sub get_api_key_with_prefix +{ + my ($self, $key_name) = @_; + + my $api_key = $self->{config}{api_key}{$key_name}; + + return unless $api_key; + + my $prefix = $self->{config}{api_key_prefix}{$key_name}; + return $prefix ? "$prefix $api_key" : $api_key; +} + +# update header and query param based on authentication setting +# +# @param array $headerParams header parameters (by ref) +# @param array $queryParams query parameters (by ref) +# @param array $authSettings array of authentication scheme (e.g ['api_key']) +sub update_params_for_auth { + my ($self, $header_params, $query_params, $auth_settings) = @_; + + return $self->_global_auth_setup($header_params, $query_params) + unless $auth_settings && @$auth_settings; + + # one endpoint can have more than 1 auth settings + foreach my $auth (@$auth_settings) { + # determine which one to use + if (!defined($auth)) { + # TODO show warning about auth setting not defined + } + elsif ($auth eq 'api_key') { + my $api_key = $self->get_api_key_with_prefix('api_key */ ' " =end -- \r\n \n \r'); + if ($api_key) { + $header_params->{'api_key */ ' " =end -- \r\n \n \r'} = $api_key; + } + } + elsif ($auth eq 'petstore_auth') { + if ($self->{config}{access_token}) { + $header_params->{'Authorization'} = 'Bearer ' . $self->{config}{access_token}; + } + } + else { + # TODO show warning about security definition not found + } + } +} + +# The endpoint API class has not found any settings for auth. This may be deliberate, +# in which case update_params_for_auth() will be a no-op. But it may also be that the +# OpenAPI Spec does not describe the intended authorization. So we check in the config for any +# auth tokens and if we find any, we use them for all endpoints; +sub _global_auth_setup { + my ($self, $header_params, $query_params) = @_; + + my $tokens = $self->{config}->get_tokens; + return unless keys %$tokens; + + # basic + if (my $uname = delete $tokens->{username}) { + my $pword = delete $tokens->{password}; + $header_params->{'Authorization'} = 'Basic '.encode_base64($uname.":".$pword); + } + + # oauth + if (my $access_token = delete $tokens->{access_token}) { + $header_params->{'Authorization'} = 'Bearer ' . $access_token; + } + + # other keys + foreach my $token_name (keys %$tokens) { + my $in = $tokens->{$token_name}->{in}; + my $token = $self->get_api_key_with_prefix($token_name); + if ($in eq 'head') { + $header_params->{$token_name} = $token; + } + elsif ($in eq 'query') { + $query_params->{$token_name} = $token; + } + else { + die "Don't know where to put token '$token_name' ('$in' is not 'head' or 'query')"; + } + } +} + +1; diff --git a/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/ApiFactory.pm b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/ApiFactory.pm new file mode 100644 index 00000000000..2daf8d96d2b --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/ApiFactory.pm @@ -0,0 +1,128 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package Something::Deep::ApiFactory; + +use strict; +use warnings; +use utf8; + +use Carp; +use Module::Find; + +usesub Something::Deep::Object; + +use Something::Deep::ApiClient; + +=head1 Name + + Something::Deep::ApiFactory - constructs APIs to retrieve Something::Deep objects + +=head1 Synopsis + + package My::Petstore::App; + + use Something::Deep::ApiFactory; + + my $api_factory = Something::Deep::ApiFactory->new( ... ); # any args for ApiClient constructor + + # later... + my $pet_api = $api_factory->get_api('Pet'); + + # $pet_api isa Something::Deep::PetApi + + my $pet = $pet_api->get_pet_by_id(pet_id => $pet_id); + + # object attributes have proper accessors: + printf "Pet's name is %s", $pet->name; + + # change the value stored on the object: + $pet->name('Dave'); + +=cut + +# Load all the API classes and construct a lookup table at startup time +my %_apis = map { $_ =~ /^Something::Deep::(.*)$/; $1 => $_ } + grep {$_ =~ /Api$/} + usesub 'Something::Deep'; + +=head1 new($api_client) + + create a new Something::Deep::ApiFactory instance with the given Something::Deep::ApiClient instance. + +=head1 new(%parameters) + + Any parameters are optional, and are passed to and stored on the api_client object. + + See L and L for valid parameters + +=cut + +sub new { + my ($class) = shift; + + my $api_client; + if ($_[0] && ref $_[0] && ref $_[0] eq 'Something::Deep::ApiClient' ) { + $api_client = $_[0]; + } else { + $api_client = Something::Deep::ApiClient->new(@_); + } + bless { api_client => $api_client }, $class; +} + +=head1 get_api($which) + + Returns an API object of the requested type. + + $which is a nickname for the class: + + FooBarClient::BazApi has nickname 'Baz' + +=cut + +sub get_api { + my ($self, $which) = @_; + croak "API not specified" unless $which; + my $api_class = $_apis{"${which}Api"} || croak "No known API for '$which'"; + return $api_class->new($self->api_client); +} + +=head1 api_client() + + Returns the api_client object, should you ever need it. + +=cut + +sub api_client { $_[0]->{api_client} } + +=head1 apis_available() +=cut + +sub apis_available { return map { $_ =~ s/Api$//; $_ } sort keys %_apis } + +=head1 classname_for() +=cut + +sub classname_for { + my ($self, $api_name) = @_; + return $_apis{"${api_name}Api"}; +} + + +1; diff --git a/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Configuration.pm b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Configuration.pm new file mode 100644 index 00000000000..6af3655a6c9 --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Configuration.pm @@ -0,0 +1,170 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package Something::Deep::Configuration; + +use strict; +use warnings; +use utf8; + +use Log::Any qw($log); +use Carp; + +use constant VERSION => '1.0.0'; + +=head1 Name + + Something::Deep::Configuration - holds the configuration for all Something::Deep Modules + +=head1 new(%parameters) + +=over 4 + +=item http_timeout: (optional) + +Integer. timeout for HTTP requests in seconds + +default: 180 + +=item http_user_agent: (optional) + +String. custom UserAgent header + +default: OpenAPI-Generator/1.0.0/perl + +=item api_key: (optional) + +Hashref. Keyed on the name of each key (there can be multiple tokens). + + api_key => { + secretKey => 'aaaabbbbccccdddd', + anotherKey => '1111222233334444', + }; + +=item api_key_prefix: (optional) + +Hashref. Keyed on the name of each key (there can be multiple tokens). Note not all api keys require a prefix. + + api_key_prefix => { + secretKey => 'string', + anotherKey => 'same or some other string', + }; + +=item api_key_in: (optional) + +=item username: (optional) + +String. The username for basic auth. + +=item password: (optional) + +String. The password for basic auth. + +=item access_token: (optional) + +String. The OAuth access token. + +=item base_url: (optional) + +String. The base URL of the API + +default: http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r + +=back + +=cut + +sub new { + my ($self, %p) = (shift,@_); + + # class/static variables + $p{http_timeout} //= 180; + $p{http_user_agent} //= 'OpenAPI-Generator/1.0.0/perl'; + + # authentication setting + $p{api_key} //= {}; + $p{api_key_prefix} //= {}; + $p{api_key_in} //= {}; + + # username and password for HTTP basic authentication + $p{username} //= ''; + $p{password} //= ''; + + # access token for OAuth + $p{access_token} //= ''; + + # base_url + $p{base_url} //= 'http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r'; + + return bless \%p => $self; +} + + +sub get_tokens { + my $self = shift; + + my $tokens = {}; + $tokens->{username} = $self->{username} if $self->{username}; + $tokens->{password} = $self->{password} if $self->{password}; + $tokens->{access_token} = $self->{access_token} if $self->{access_token}; + + foreach my $token_name (keys %{ $self->{api_key} }) { + $tokens->{$token_name}->{token} = $self->{api_key}{$token_name}; + $tokens->{$token_name}->{prefix} = $self->{api_key_prefix}{$token_name}; + $tokens->{$token_name}->{in} = $self->{api_key_in}{$token_name}; + } + + return $tokens; +} + +sub clear_tokens { + my $self = shift; + my %tokens = %{$self->get_tokens}; # copy + + $self->{username} = ''; + $self->{password} = ''; + $self->{access_token} = ''; + + $self->{api_key} = {}; + $self->{api_key_prefix} = {}; + $self->{api_key_in} = {}; + + return \%tokens; +} + +sub accept_tokens { + my ($self, $tokens) = @_; + + foreach my $known_name (qw(username password access_token)) { + next unless $tokens->{$known_name}; + $self->{$known_name} = delete $tokens->{$known_name}; + } + + foreach my $token_name (keys %$tokens) { + $self->{api_key}{$token_name} = $tokens->{$token_name}{token}; + if ($tokens->{$token_name}{prefix}) { + $self->{api_key_prefix}{$token_name} = $tokens->{$token_name}{prefix}; + } + my $in = $tokens->{$token_name}->{in} || 'head'; + croak "Tokens can only go in 'head' or 'query' (not in '$in')" unless $in =~ /^(?:head|query)$/; + $self->{api_key_in}{$token_name} = $in; + } +} + +1; diff --git a/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/FakeApi.pm b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/FakeApi.pm new file mode 100644 index 00000000000..c841d1fd627 --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/FakeApi.pm @@ -0,0 +1,107 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package Something::Deep::FakeApi; + +require 5.6.0; +use strict; +use warnings; +use utf8; +use Exporter; +use Carp qw( croak ); +use Log::Any qw($log); + +use Something::Deep::ApiClient; + +use base "Class::Data::Inheritable"; + +__PACKAGE__->mk_classdata('method_documentation' => {}); + +sub new { + my $class = shift; + my $api_client; + + if ($_[0] && ref $_[0] && ref $_[0] eq 'Something::Deep::ApiClient' ) { + $api_client = $_[0]; + } else { + $api_client = Something::Deep::ApiClient->new(@_); + } + + bless { api_client => $api_client }, $class; + +} + + +# +# test_code_inject____end__rn_n_r +# +# To test code injection */ ' \" =_end -- \\r\\n \\n \\r +# +# @param string $test_code_inject_*/_'_"_=end____\r\n_\n_\r To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r (optional) +{ + my $params = { + 'test_code_inject_*/_'_"_=end____\r\n_\n_\r' => { + data_type => 'string', + description => 'To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ 'test_code_inject____end__rn_n_r' } = { + summary => 'To test code injection */ ' \" =_end -- \\r\\n \\n \\r', + params => $params, + returns => undef, + }; +} +# @return void +# +sub test_code_inject____end__rn_n_r { + my ($self, %args) = @_; + + # parse inputs + my $_resource_path = '/fake'; + + my $_method = 'PUT'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; + + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept(); + if ($_header_accept) { + $header_params->{'Accept'} = $_header_accept; + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/x-www-form-urlencoded', '*/ \" =_end -- '); + + # form params + if ( exists $args{'test_code_inject_*/_'_"_=end____\r\n_\n_\r'} ) { + $form_params->{'test code inject */ ' " =end -- \r\n \n \r'} = $self->{api_client}->to_form_value($args{'test_code_inject_*/_'_"_=end____\r\n_\n_\r'}); + } + + my $_body_data; + # authentication setting, if any + my $auth_settings = [qw()]; + + # make the API Call + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; +} + +1; diff --git a/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Object/ModelReturn.pm b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Object/ModelReturn.pm new file mode 100644 index 00000000000..f388b11028d --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Object/ModelReturn.pm @@ -0,0 +1,177 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package Something::Deep::Object::ModelReturn; + +require 5.6.0; +use strict; +use warnings; +use utf8; +use JSON qw(decode_json); +use Data::Dumper; +use Module::Runtime qw(use_module); +use Log::Any qw($log); +use Date::Parse; +use DateTime; + + +use base ("Class::Accessor", "Class::Data::Inheritable"); + +# +#Model for testing reserved words */ ' \" =_end -- \\r\\n \\n \\r +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. +# REF: https://openapi-generator.tech +# + +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +__PACKAGE__->mk_classdata('attribute_map' => {}); +__PACKAGE__->mk_classdata('openapi_types' => {}); +__PACKAGE__->mk_classdata('method_documentation' => {}); +__PACKAGE__->mk_classdata('class_documentation' => {}); + +# new plain object +sub new { + my ($class, %args) = @_; + + my $self = bless {}, $class; + + $self->init(%args); + + return $self; +} + +# initialize the object +sub init +{ + my ($self, %args) = @_; + + foreach my $attribute (keys %{$self->attribute_map}) { + my $args_key = $self->attribute_map->{$attribute}; + $self->$attribute( $args{ $args_key } ); + } +} + +# return perl hash +sub to_hash { + my $self = shift; + my $_hash = decode_json(JSON->new->convert_blessed->encode($self)); + + return $_hash; +} + +# used by JSON for serialization +sub TO_JSON { + my $self = shift; + my $_data = {}; + foreach my $_key (keys %{$self->attribute_map}) { + if (defined $self->{$_key}) { + $_data->{$self->attribute_map->{$_key}} = $self->{$_key}; + } + } + + return $_data; +} + +# from Perl hashref +sub from_hash { + my ($self, $hash) = @_; + + # loop through attributes and use openapi_types to deserialize the data + while ( my ($_key, $_type) = each %{$self->openapi_types} ) { + my $_json_attribute = $self->attribute_map->{$_key}; + if ($_type =~ /^array\[/i) { # array + my $_subclass = substr($_type, 6, -1); + my @_array = (); + foreach my $_element (@{$hash->{$_json_attribute}}) { + push @_array, $self->_deserialize($_subclass, $_element); + } + $self->{$_key} = \@_array; + } elsif (exists $hash->{$_json_attribute}) { #hash(model), primitive, datetime + $self->{$_key} = $self->_deserialize($_type, $hash->{$_json_attribute}); + } else { + $log->debugf("Warning: %s (%s) does not exist in input hash\n", $_key, $_json_attribute); + } + } + + return $self; +} + +# deserialize non-array data +sub _deserialize { + my ($self, $type, $data) = @_; + $log->debugf("deserializing %s with %s",Dumper($data), $type); + + if ($type eq 'DateTime') { + return DateTime->from_epoch(epoch => str2time($data)); + } elsif ( grep( /^$type$/, ('int', 'double', 'string', 'boolean'))) { + return $data; + } else { # hash(model) + my $_instance = eval "Something::Deep::Object::$type->new()"; + return $_instance->from_hash($data); + } +} + + + +__PACKAGE__->class_documentation({description => 'Model for testing reserved words */ ' \" =_end -- \\r\\n \\n \\r', + class => 'ModelReturn', + required => [], # TODO +} ); + +__PACKAGE__->method_documentation({ + 'return' => { + datatype => 'int', + base_name => 'return', + description => 'property description */ ' \" =_end -- \\r\\n \\n \\r', + format => '', + read_only => '', + }, +}); + +__PACKAGE__->openapi_types( { + 'return' => 'int' +} ); + +__PACKAGE__->attribute_map( { + 'return' => 'return' +} ); + +__PACKAGE__->mk_accessors(keys %{__PACKAGE__->attribute_map}); + + +1; diff --git a/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Role.pm b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Role.pm new file mode 100644 index 00000000000..7868105980c --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Role.pm @@ -0,0 +1,337 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package Something::Deep::Role; +use utf8; + +use Moose::Role; +use namespace::autoclean; +use Class::Inspector; +use Log::Any qw($log); +use Something::Deep::ApiFactory; + +has base_url => ( is => 'ro', + required => 0, + isa => 'Str', + documentation => 'Root of the server that requests are sent to', + ); + +has api_factory => ( is => 'ro', + isa => 'Something::Deep::ApiFactory', + builder => '_build_af', + lazy => 1, + documentation => 'Builds an instance of the endpoint API class', + ); + +has tokens => ( is => 'ro', + isa => 'HashRef', + required => 0, + default => sub { {} }, + documentation => 'The auth tokens required by the application - basic, OAuth and/or API key(s)', + ); + +has _cfg => ( is => 'ro', + isa => 'Something::Deep::Configuration', + default => sub { Something::Deep::Configuration->new() }, + ); + +has version_info => ( is => 'ro', + isa => 'HashRef', + default => sub { { + app_name => 'OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r', + app_version => '1.0.0 */ ' \" =_end -- \\r\\n \\n \\r', + generator_class => 'org.openapitools.codegen.languages.PerlClientCodegen', + } }, + documentation => 'Information about the application version and the codegen codebase version' + ); + +sub BUILD { + my $self = shift; + + $self->_cfg->accept_tokens( $self->tokens ) if keys %{$self->tokens}; + + # ignore these symbols imported into API namespaces + my %outsiders = map {$_ => 1} qw( croak ); + + my %delegates; + + # collect the methods callable on each API + foreach my $api_name ($self->api_factory->apis_available) { + my $api_class = $self->api_factory->classname_for($api_name); + my $methods = Class::Inspector->methods($api_class, 'expanded'); # not Moose, so use CI instead + my @local_methods = grep {! /^_/} grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; + push( @{$delegates{$_}}, {api_name => $api_name, api_class => $api_class} ) for @local_methods; + } + + # remove clashes + foreach my $method (keys %delegates) { + if ( @{$delegates{$method}} > 1 ) { + my ($apis) = delete $delegates{$method}; + } + } + + # build the flattened API + foreach my $api_name ($self->api_factory->apis_available) { + my $att_name = sprintf "%s_api", lc($api_name); + my $api_class = $self->api_factory->classname_for($api_name); + my @delegated = grep { $delegates{$_}->[0]->{api_name} eq $api_name } keys %delegates; + $log->debugf("Adding API: '%s' handles %s", $att_name, join ', ', @delegated); + $self->meta->add_attribute( $att_name => ( + is => 'ro', + isa => $api_class, + default => sub {$self->api_factory->get_api($api_name)}, + lazy => 1, + handles => \@delegated, + ) ); + } +} + +sub _build_af { + my $self = shift; + my %args; + $args{base_url} = $self->base_url if $self->base_url; + return Something::Deep::ApiFactory->new(%args); +} + +=head1 NAME + +Something::Deep::Role - a Moose role for the OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +=head2 OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r + +=head1 VERSION + +Automatically generated by the Perl OpenAPI Generator project: + +=over 4 +=item Build package: org.openapitools.codegen.languages.PerlClientCodegen + +=item Codegen version: + +=back + +=head2 A note on Moose + +This role is the only component of the library that uses Moose. See +Something::Deep::ApiFactory for non-Moosey usage. + +=head1 SYNOPSIS + +The Perl Generator in the OpenAPI Generator project builds a library of Perl modules to interact with +a web service defined by a OpenAPI Specification. See below for how to build the +library. + +This module provides an interface to the generated library. All the classes, +objects, and methods (well, not quite *all*, see below) are flattened into this +role. + + package MyApp; + use Moose; + with 'Something::Deep::Role'; + + package main; + + my $api = MyApp->new({ tokens => $tokens }); + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + +=head2 Structure of the library + +The library consists of a set of API classes, one for each endpoint. These APIs +implement the method calls available on each endpoint. + +Additionally, there is a set of "object" classes, which represent the objects +returned by and sent to the methods on the endpoints. + +An API factory class is provided, which builds instances of each endpoint API. + +This Moose role flattens all the methods from the endpoint APIs onto the consuming +class. It also provides methods to retrieve the endpoint API objects, and the API +factory object, should you need it. + +For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. + +=head2 Configuring authentication + +In the normal case, the OpenAPI Spec will describe what parameters are +required and where to put them. You just need to supply the tokens. + + my $tokens = { + # basic + username => $username, + password => $password, + + # oauth + access_token => $oauth_token, + + # keys + $some_key => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + + $another => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + ..., + + }; + + my $api = MyApp->new({ tokens => $tokens }); + +Note these are all optional, as are C and C, and depend on the API +you are accessing. Usually C and C will be determined by the code generator from +the spec and you will not need to set them at run time. If not, C will +default to 'head' and C to the empty string. + +The tokens will be placed in a L instance +as follows, but you don't need to know about this. + +=over 4 + +=item C<$cfg-\>{username}> + +String. The username for basic auth. + +=item C<$cfg-\>{password}> + +String. The password for basic auth. + +=item C<$cfg-\>{api_key}> + +Hashref. Keyed on the name of each key (there can be multiple tokens). + + $cfg->{api_key} = { + secretKey => 'aaaabbbbccccdddd', + anotherKey => '1111222233334444', + }; + +=item C<$cfg->{api_key_prefix}> + +Hashref. Keyed on the name of each key (there can be multiple tokens). Note not +all api keys require a prefix. + + $cfg->{api_key_prefix} = { + secretKey => 'string', + anotherKey => 'same or some other string', + }; + +=item C<$config-\>{access_token}> + +String. The OAuth access token. + +=back + +=head1 METHODS + +=head2 C + +The generated code has the C already set as a default value. This method +returns the current value of C. + +=head2 C + +Returns an API factory object. You probably won't need to call this directly. + + $self->api_factory('Pet'); # returns a Something::Deep::PetApi instance + + $self->pet_api; # the same + +=head1 MISSING METHODS + +Most of the methods on the API are delegated to individual endpoint API objects +(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the +same method name (e.g. C), these methods can't be delegated. So you need +to call C<$api-Epet_api-Enew()>. + +In principle, every API is susceptible to the presence of a few, random, undelegatable +method names. In practice, because of the way method names are constructed, it's +unlikely in general that any methods will be undelegatable, except for: + + new() + class_documentation() + method_documentation() + +To call these methods, you need to get a handle on the relevant object, either +by calling C<$api-Efoo_api> or by retrieving an object, e.g. +C<$api-Eget_pet_by_id(pet_id =E $pet_id)>. They are class methods, so +you could also call them on class names. + +=head1 BUILDING YOUR LIBRARY + +See the homepage C for full details. +But briefly, clone the git repository, build the codegen codebase, set up your build +config file, then run the API build script. You will need git, Java 7 or 8 and Apache +maven 3.0.3 or better already installed. + +The config file should specify the project name for the generated library: + + {"moduleName":"WWW::MyProjectName"} + +Your library files will be built under C. + + $ git clone https://github.com/openapitools/openapi-generator + $ cd openapi-generator + $ mvn package + $ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \ + -i [URL or file path to JSON OpenAPI API spec] \ + -g perl \ + -c /path/to/config/file.json \ + -o /path/to/output/folder + +Bang, all done. Run the C script in the C directory to see the API +you just built. + +=head1 AUTOMATIC DOCUMENTATION + +You can print out a summary of the generated API by running the included +C script in the C directory of your generated library. A few +output formats are supported: + + Usage: autodoc [OPTION] + + -w wide format (default) + -n narrow format + -p POD format + -H HTML format + -m Markdown format + -h print this help message + -c your application class + +The C<-c> option allows you to load and inspect your own application. A dummy +namespace is used if you don't supply your own class. + +=head1 DOCUMENTATION FROM THE OpenAPI Spec + +Additional documentation for each class and method may be provided by the OpenAPI +spec. If so, this is available via the C and +C methods on each generated object class, and the +C method on the endpoint API classes: + + my $cmdoc = $api->pet_api->method_documentation->{$method_name}; + + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; + +Each of these calls returns a hashref with various useful pieces of information. + +=cut + +1; diff --git a/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Role/AutoDoc.pm b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Role/AutoDoc.pm new file mode 100644 index 00000000000..88d7dc71c35 --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/lib/Something/Deep/Role/AutoDoc.pm @@ -0,0 +1,446 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package Something::Deep::Role::AutoDoc; +use List::MoreUtils qw(uniq); + +use Moose::Role; + +sub autodoc { + my ($self, $how) = @_; + + die "Unknown format '$how'" unless $how =~ /^(pod|wide|narrow)$/; + + $self->_printisa($how); + $self->_printmethods($how); + $self->_printattrs($how); + print "\n"; +} + +sub _printisa { + my ($self, $how) = @_; + my $meta = $self->meta; + + my $myclass = ref $self; + + my $super = join ', ', $meta->superclasses; + my @roles = $meta->calculate_all_roles; + #shift(@roles) if @roles > 1; # if > 1, the first is a composite, the rest are the roles + + my $isa = join ', ', grep {$_ ne $myclass} $meta->linearized_isa; + my $sub = join ', ', $meta->subclasses; + my $dsub = join ', ', $meta->direct_subclasses; + + my $app_name = $self->version_info->{app_name}; + my $app_version = $self->version_info->{app_version}; + my $generated_date = $self->version_info->{generated_date}; + my $generator_class = $self->version_info->{generator_class}; + + $~ = $how eq 'pod' ? 'INHERIT_POD' : 'INHERIT'; + write; + + my ($rolepkg, $role_reqs); + + foreach my $role (@roles) { + $rolepkg = $role->{package} || next; # some are anonymous, or something + next if $rolepkg eq 'Something::Deep::Role::AutoDoc'; + $role_reqs = join ', ', keys %{$role->{required_methods}}; + $role_reqs ||= ''; + $~ = $how eq 'pod' ? 'ROLES_POD' : 'ROLES'; + write; + } + + if ($how eq 'pod') { + $~ = 'ROLES_POD_CLOSE'; + write; + } + +# ----- format specs ----- + format INHERIT = + +@* - +$myclass + ISA: @* + $isa + Direct subclasses: @* + $dsub + All subclasses: @* + $sub + + Target API: @* @* + $app_name, $app_version + Generated on: @* + $generated_date + Generator class: @* + $generator_class + +. + format ROLES = + Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ + $rolepkg + requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ + $role_reqs + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $role_reqs +. + + format INHERIT_POD = +=head1 NAME + +@* +$myclass + +=head1 VERSION + +=head2 @* version: @* + $app_name, $app_version + +Automatically generated by the Perl Generator in the OpenAPI Generator project: + +=over 4 + +=item Build date: @* + $generated_date + +=item Build package: @* + $generator_class + +=item Codegen version: + + +=back + +=head1 INHERITANCE + +=head2 Base class(es) + +@* +$isa + +=head2 Direct subclasses + +@* +$dsub + +=head2 All subclasses + +@* +$sub + + +=head1 COMPOSITION + +@* composes the following roles: +$myclass + + +. + format ROLES_POD = +=head2 C<@*> + $rolepkg + +Requires: + +@* +$role_reqs + +. + format ROLES_POD_CLOSE = + + +. +# ----- / format specs ----- +} + +sub _printmethods { + my ($self, $how) = @_; + + if ($how eq 'narrow') { + print <_printmethod($_, $how) for uniq sort $self->meta->get_all_method_names; #$self->meta->get_method_list, + + if ($how eq 'pod') { + $~ = 'METHOD_POD_CLOSE'; + write; + } + + +} + +sub _printmethod { + my ($self, $methodname, $how) = @_; + return if $methodname =~ /^_/; + return if $self->meta->has_attribute($methodname); + my %internal = map {$_ => 1} qw(BUILD BUILDARGS meta can new DEMOLISHALL DESTROY + DOES isa BUILDALL does VERSION dump + ); + return if $internal{$methodname}; + my $method = $self->meta->get_method($methodname) or return; # symbols imported into namespaces i.e. not known by Moose + + return if $method->original_package_name eq __PACKAGE__; + + my $delegate_to = ''; + my $via = ''; + my $on = ''; + my $doc = ''; + my $original_pkg = $method->original_package_name; + if ($method->can('associated_attribute')) { + $delegate_to = $method->delegate_to_method; + my $aa = $method->associated_attribute; + $on = $aa->{isa}; + $via = $aa->{name}; + $original_pkg = $on; + $doc = $original_pkg->method_documentation->{$delegate_to}->{summary}; + } + else { + $doc = $method->documentation; + } + + if ($how eq 'narrow') { + $~ = 'METHOD_NARROW'; + write; + } + elsif ($how eq 'pod' and $delegate_to) { + $~ = 'METHOD_POD_DELEGATED'; + write; + } + elsif ($how eq 'pod') { + $~ = 'METHOD_POD'; + write; + } + else { + $~ = 'METHOD'; + write; + } + +# ----- format specs ----- + format METHODHEAD = + +METHODS +------- +Name delegates to on via +=========================================================================================================================================================================== +. + format METHOD = +@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<... +$methodname, $delegate_to, $on, $via +. + + format METHOD_NARROW = +@* +$methodname + original pkg: @* + $original_pkg + delegates to: @* + $delegate_to + on: @* + $on + via: @* + $via + +. + + format METHODHEAD_POD = + +=head1 METHODS + +. + + format METHOD_POD = + +=head2 C<@*()> + $methodname + + Defined in: @* + $original_pkg + + +. + format METHOD_POD_DELEGATED = + +=head2 C<@*()> + $methodname + + Defined in: @* + $original_pkg + Delegates to: @*() + $delegate_to + On: @* + $on + Via: @*() + $via + Doc: @* + $doc + Same as: $self->@*->@*() + $via, $delegate_to + +. + format METHOD_POD_CLOSE = + +. +# ----- / format specs ----- +} + +sub _printattrs { + my ($self, $how) = @_; + + if ($how eq 'narrow') { + print <_printattr($_, $how) for sort $self->meta->get_attribute_list; + + if ($how eq 'pod') { + $~ = 'ATTR_POD_CLOSE'; + write; + } +} + +sub _printattr { + my ($self, $attrname, $how) = @_; + return if $attrname =~ /^_/; + my $attr = $self->meta->get_attribute($attrname) or die "No attr for $attrname"; + + my $is; + $is = 'rw' if $attr->get_read_method && $attr->get_write_method; + $is = 'ro' if $attr->get_read_method && ! $attr->get_write_method; + $is = 'wo' if $attr->get_write_method && ! $attr->get_read_method; + $is = '--' if ! $attr->get_write_method && ! $attr->get_read_method; + $is or die "No \$is for $attrname"; + + my $tc = $attr->type_constraint || ''; + my $from = $attr->associated_class->name || ''; + my $reqd = $attr->is_required ? 'yes' : 'no'; + my $lazy = $attr->is_lazy ? 'yes' : 'no'; + my $has_doc = $attr->has_documentation ? 'yes' : 'no'; # *_api attributes will never have doc, but other attributes might have + my $doc = $attr->documentation || ''; + my $handles = join ', ', sort @{$attr->handles || []}; + $handles ||= ''; + + if ($how eq 'narrow') { + $~ = 'ATTR_NARROW'; + } + elsif ($how eq 'pod') { + $~ = 'ATTR_POD'; + } + else { + $~ = 'ATTR'; + } + + write; + +# ----- format specs ----- + format ATTRHEAD = + +ATTRIBUTES +---------- +Name is isa reqd lazy doc handles +============================================================================================================== +. + format ATTR = +@<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<< @<<< @<<< @<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +$attrname, $is, $tc, $reqd, $lazy, $has_doc, $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles +. + + format ATTR_NARROW = +@* +$attrname + is: @* + $is + isa: @* + $tc + reqd: @* + $reqd + lazy: @* + $lazy + doc: @* + $doc + handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles + +. + format ATTRHEAD_POD = +=head1 ATTRIBUTES + +. + format ATTR_POD = + +=head2 C<@*> + $attrname + + is: @* + $is + isa: @* + $tc + reqd: @* + $reqd + lazy: @* + $lazy + doc: @* + $doc + handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles + +. + format ATTR_POD_CLOSE = + + +. +# ----- / format specs ----- +} + + + +1; diff --git a/samples/client/petstore-security-test/perl/deep_module_test/t/FakeApiTest.t b/samples/client/petstore-security-test/perl/deep_module_test/t/FakeApiTest.t new file mode 100644 index 00000000000..ca04a78c976 --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/t/FakeApiTest.t @@ -0,0 +1,41 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator +# Please update the test cases below to test the API endpoints. +# Ref: https://openapi-generator.tech +# +use Test::More tests => 1; #TODO update number of test cases +use Test::Exception; + +use lib 'lib'; +use strict; +use warnings; + +use_ok('Something::Deep::FakeApi'); + +my $api = Something::Deep::FakeApi->new(); +isa_ok($api, 'Something::Deep::FakeApi'); + +# +# test_code_inject____end__rn_n_r test +# +{ + my $test_code_inject_*/_'_"_=end____\r\n_\n_\r = undef; # replace NULL with a proper value + my $result = $api->test_code_inject____end__rn_n_r(test_code_inject_*/_'_"_=end____\r\n_\n_\r => $test_code_inject_*/_'_"_=end____\r\n_\n_\r); +} + + +1; diff --git a/samples/client/petstore-security-test/perl/deep_module_test/t/ModelReturnTest.t b/samples/client/petstore-security-test/perl/deep_module_test/t/ModelReturnTest.t new file mode 100644 index 00000000000..ed6c8167820 --- /dev/null +++ b/samples/client/petstore-security-test/perl/deep_module_test/t/ModelReturnTest.t @@ -0,0 +1,33 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by the OpenAPI Generator +# Please update the test cases below to test the model. +# Ref: https://openapi-generator.tech +# +use Test::More tests => 2; +use Test::Exception; + +use lib 'lib'; +use strict; +use warnings; + + +use_ok('Something::Deep::Object::ModelReturn'); + +my $instance = Something::Deep::Object::ModelReturn->new(); + +isa_ok($instance, 'Something::Deep::Object::ModelReturn'); + diff --git a/samples/client/petstore-security-test/perl/docs/FakeApi.md b/samples/client/petstore-security-test/perl/docs/FakeApi.md new file mode 100644 index 00000000000..5813a12fd4b --- /dev/null +++ b/samples/client/petstore-security-test/perl/docs/FakeApi.md @@ -0,0 +1,59 @@ +# WWW::OpenAPIClient::FakeApi + +## Load the API package +```perl +use WWW::OpenAPIClient::Object::FakeApi; +``` + +All URIs are relative to *http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**test_code_inject____end__rn_n_r**](FakeApi.md#test_code_inject____end__rn_n_r) | **PUT** /fake | To test code injection */ ' \" =_end -- \\r\\n \\n \\r + + +# **test_code_inject____end__rn_n_r** +> test_code_inject____end__rn_n_r(test_code_inject_*/_'_"_=end____\r\n_\n_\r => $test_code_inject_*/_'_"_=end____\r\n_\n_\r) + +To test code injection */ ' \" =_end -- \\r\\n \\n \\r + +To test code injection */ ' \" =_end -- \\r\\n \\n \\r + +### Example +```perl +use Data::Dumper; +use WWW::OpenAPIClient::FakeApi; +my $api_instance = WWW::OpenAPIClient::FakeApi->new( +); + +my $test_code_inject_*/_'_"_=end____\r\n_\n_\r = "test_code_inject_*/_'_\"_=_end____\\r\\n_\\n_\\r_example"; # string | To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r + +eval { + $api_instance->test_code_inject____end__rn_n_r(test_code_inject_*/_'_"_=end____\r\n_\n_\r => $test_code_inject_*/_'_"_=end____\r\n_\n_\r); +}; +if ($@) { + warn "Exception when calling FakeApi->test_code_inject____end__rn_n_r: $@\n"; +} +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **test_code_inject_*/_'_"_=end____\r\n_\n_\r** | **string**| To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r | [optional] + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded, */ \" =_end -- + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/client/petstore-security-test/perl/docs/ModelReturn.md b/samples/client/petstore-security-test/perl/docs/ModelReturn.md new file mode 100644 index 00000000000..bf1161d2fc4 --- /dev/null +++ b/samples/client/petstore-security-test/perl/docs/ModelReturn.md @@ -0,0 +1,15 @@ +# WWW::OpenAPIClient::Object::ModelReturn + +## Load the model package +```perl +use WWW::OpenAPIClient::Object::ModelReturn; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**return** | **int** | property description */ ' \" =_end -- \\r\\n \\n \\r | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore-security-test/perl/git_push.sh b/samples/client/petstore-security-test/perl/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/perl/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/ApiClient.pm b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/ApiClient.pm new file mode 100644 index 00000000000..a793474d162 --- /dev/null +++ b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/ApiClient.pm @@ -0,0 +1,393 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package WWW::OpenAPIClient::ApiClient; + +use strict; +use warnings; +use utf8; + +use MIME::Base64; +use LWP::UserAgent; +use HTTP::Headers; +use HTTP::Response; +use HTTP::Request::Common qw(DELETE POST GET HEAD PUT); +use HTTP::Status; +use URI::Query; +use JSON; +use URI::Escape; +use Scalar::Util; +use Log::Any qw($log); +use Carp; +use Module::Runtime qw(use_module); + +use WWW::OpenAPIClient::Configuration; + +sub new { + my $class = shift; + + my $config; + if ( $_[0] && ref $_[0] && ref $_[0] eq 'WWW::OpenAPIClient::Configuration' ) { + $config = $_[0]; + } else { + $config = WWW::OpenAPIClient::Configuration->new(@_); + } + + my (%args) = ( + 'ua' => LWP::UserAgent->new, + 'config' => $config, + ); + + return bless \%args, $class; +} + +# Set the user agent of the API client +# +# @param string $user_agent The user agent of the API client +# +sub set_user_agent { + my ($self, $user_agent) = @_; + $self->{http_user_agent}= $user_agent; +} + +# Set timeout +# +# @param integer $seconds Number of seconds before timing out [set to 0 for no timeout] +# +sub set_timeout { + my ($self, $seconds) = @_; + if (!looks_like_number($seconds)) { + croak('Timeout variable must be numeric.'); + } + $self->{http_timeout} = $seconds; +} + +# make the HTTP request +# @param string $resourcePath path to method endpoint +# @param string $method method to call +# @param array $queryParams parameters to be place in query URL +# @param array $postData parameters to be placed in POST body +# @param array $headerParams parameters to be place in request header +# @return mixed +sub call_api { + my $self = shift; + my ($resource_path, $method, $query_params, $post_params, $header_params, $body_data, $auth_settings) = @_; + + # update parameters based on authentication settings + $self->update_params_for_auth($header_params, $query_params, $auth_settings); + + my $_url = $self->{config}{base_url} . $resource_path; + + # build query + if (%$query_params) { + $_url = ($_url . '?' . eval { URI::Query->new($query_params)->stringify }); + } + + # body data + $body_data = to_json($body_data->to_hash) if defined $body_data && $body_data->can('to_hash'); # model to json string + my $_body_data = %$post_params ? $post_params : $body_data; + + # Make the HTTP request + my $_request; + if ($method eq 'POST') { + # multipart + $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? + 'form-data' : $header_params->{'Content-Type'}; + + $_request = POST($_url, %$header_params, Content => $_body_data); + + } + elsif ($method eq 'PUT') { + # multipart + $header_params->{'Content-Type'} = lc $header_params->{'Content-Type'} eq 'multipart/form' ? + 'form-data' : $header_params->{'Content-Type'}; + + $_request = PUT($_url, %$header_params, Content => $_body_data); + + } + elsif ($method eq 'GET') { + my $headers = HTTP::Headers->new(%$header_params); + $_request = GET($_url, %$header_params); + } + elsif ($method eq 'HEAD') { + my $headers = HTTP::Headers->new(%$header_params); + $_request = HEAD($_url,%$header_params); + } + elsif ($method eq 'DELETE') { #TODO support form data + my $headers = HTTP::Headers->new(%$header_params); + $_request = DELETE($_url, %$headers); + } + elsif ($method eq 'PATCH') { #TODO + } + else { + } + + $self->{ua}->timeout($self->{http_timeout} || $self->{config}{http_timeout}); + $self->{ua}->agent($self->{http_user_agent} || $self->{config}{http_user_agent}); + + $log->debugf("REQUEST: %s", $_request->as_string); + my $_response = $self->{ua}->request($_request); + $log->debugf("RESPONSE: %s", $_response->as_string); + + unless ($_response->is_success) { + croak(sprintf "API Exception(%s): %s\n%s", $_response->code, $_response->message, $_response->content); + } + + return $_response->content; + +} + +# Take value and turn it into a string suitable for inclusion in +# the path, by url-encoding. +# @param string $value a string which will be part of the path +# @return string the serialized object +sub to_path_value { + my ($self, $value) = @_; + return uri_escape($self->to_string($value)); +} + + +# Take value and turn it into a string suitable for inclusion in +# the query, by imploding comma-separated if it's an object. +# If it's a string, pass through unchanged. It will be url-encoded +# later. +# @param object $object an object to be serialized to a string +# @return string the serialized object +sub to_query_value { + my ($self, $object) = @_; + if (ref($object) eq 'ARRAY') { + return join(',', @$object); + } else { + return $self->to_string($object); + } +} + + +# Take value and turn it into a string suitable for inclusion in +# the header. If it's a string, pass through unchanged +# If it's a datetime object, format it in ISO8601 +# @param string $value a string which will be part of the header +# @return string the header string +sub to_header_value { + my ($self, $value) = @_; + return $self->to_string($value); +} + +# Take value and turn it into a string suitable for inclusion in +# the http body (form parameter). If it's a string, pass through unchanged +# If it's a datetime object, format it in ISO8601 +# @param string $value the value of the form parameter +# @return string the form string +sub to_form_value { + my ($self, $value) = @_; + return $self->to_string($value); +} + +# Take value and turn it into a string suitable for inclusion in +# the parameter. If it's a string, pass through unchanged +# If it's a datetime object, format it in ISO8601 +# @param string $value the value of the parameter +# @return string the header string +sub to_string { + my ($self, $value) = @_; + if (ref($value) eq "DateTime") { # datetime in ISO8601 format + return $value->datetime(); + } + else { + return $value; + } +} + +# Deserialize a JSON string into an object +# +# @param string $class class name is passed as a string +# @param string $data data of the body +# @return object an instance of $class +sub deserialize +{ + my ($self, $class, $data) = @_; + $log->debugf("deserializing %s for %s", $data, $class); + + if (not defined $data) { + return undef; + } elsif ( (substr($class, 0, 5)) eq 'HASH[') { #hash + if ($class =~ /^HASH\[(.*),(.*)\]$/) { + my ($key_type, $type) = ($1, $2); + my %hash; + my $decoded_data = decode_json $data; + foreach my $key (keys %$decoded_data) { + if (ref $decoded_data->{$key} eq 'HASH') { + $hash{$key} = $self->deserialize($type, encode_json $decoded_data->{$key}); + } else { + $hash{$key} = $self->deserialize($type, $decoded_data->{$key}); + } + } + return \%hash; + } else { + #TODO log error + } + } elsif ( (substr($class, 0, 6)) eq 'ARRAY[' ) { # array of data + return $data if $data eq '[]'; # return if empty array + + my $_sub_class = substr($class, 6, -1); + my $_json_data = decode_json $data; + my @_values = (); + foreach my $_value (@$_json_data) { + if (ref $_value eq 'ARRAY') { + push @_values, $self->deserialize($_sub_class, encode_json $_value); + } else { + push @_values, $self->deserialize($_sub_class, $_value); + } + } + return \@_values; + } elsif ($class eq 'DateTime') { + return DateTime->from_epoch(epoch => str2time($data)); + } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { + return $data; + } else { # model + my $_instance = use_module("WWW::OpenAPIClient::Object::$class")->new; + if (ref $data eq "HASH") { + return $_instance->from_hash($data); + } else { # string, need to json decode first + return $_instance->from_hash(decode_json $data); + } + } +} + +# return 'Accept' based on an array of accept provided +# @param [Array] header_accept_array Array fo 'Accept' +# @return String Accept (e.g. application/json) +sub select_header_accept +{ + my ($self, @header) = @_; + + if (@header == 0 || (@header == 1 && $header[0] eq '')) { + return undef; + } elsif (grep(/^application\/json$/i, @header)) { + return 'application/json'; + } else { + return join(',', @header); + } + +} + +# return the content type based on an array of content-type provided +# @param [Array] content_type_array Array fo content-type +# @return String Content-Type (e.g. application/json) +sub select_header_content_type +{ + my ($self, @header) = @_; + + if (@header == 0 || (@header == 1 && $header[0] eq '')) { + return 'application/json'; # default to application/json + } elsif (grep(/^application\/json$/i, @header)) { + return 'application/json'; + } else { + return join(',', @header); + } + +} + +# Get API key (with prefix if set) +# @param string key name +# @return string API key with the prefix +sub get_api_key_with_prefix +{ + my ($self, $key_name) = @_; + + my $api_key = $self->{config}{api_key}{$key_name}; + + return unless $api_key; + + my $prefix = $self->{config}{api_key_prefix}{$key_name}; + return $prefix ? "$prefix $api_key" : $api_key; +} + +# update header and query param based on authentication setting +# +# @param array $headerParams header parameters (by ref) +# @param array $queryParams query parameters (by ref) +# @param array $authSettings array of authentication scheme (e.g ['api_key']) +sub update_params_for_auth { + my ($self, $header_params, $query_params, $auth_settings) = @_; + + return $self->_global_auth_setup($header_params, $query_params) + unless $auth_settings && @$auth_settings; + + # one endpoint can have more than 1 auth settings + foreach my $auth (@$auth_settings) { + # determine which one to use + if (!defined($auth)) { + # TODO show warning about auth setting not defined + } + elsif ($auth eq 'api_key') { + my $api_key = $self->get_api_key_with_prefix('api_key */ ' " =end -- \r\n \n \r'); + if ($api_key) { + $header_params->{'api_key */ ' " =end -- \r\n \n \r'} = $api_key; + } + } + elsif ($auth eq 'petstore_auth') { + if ($self->{config}{access_token}) { + $header_params->{'Authorization'} = 'Bearer ' . $self->{config}{access_token}; + } + } + else { + # TODO show warning about security definition not found + } + } +} + +# The endpoint API class has not found any settings for auth. This may be deliberate, +# in which case update_params_for_auth() will be a no-op. But it may also be that the +# OpenAPI Spec does not describe the intended authorization. So we check in the config for any +# auth tokens and if we find any, we use them for all endpoints; +sub _global_auth_setup { + my ($self, $header_params, $query_params) = @_; + + my $tokens = $self->{config}->get_tokens; + return unless keys %$tokens; + + # basic + if (my $uname = delete $tokens->{username}) { + my $pword = delete $tokens->{password}; + $header_params->{'Authorization'} = 'Basic '.encode_base64($uname.":".$pword); + } + + # oauth + if (my $access_token = delete $tokens->{access_token}) { + $header_params->{'Authorization'} = 'Bearer ' . $access_token; + } + + # other keys + foreach my $token_name (keys %$tokens) { + my $in = $tokens->{$token_name}->{in}; + my $token = $self->get_api_key_with_prefix($token_name); + if ($in eq 'head') { + $header_params->{$token_name} = $token; + } + elsif ($in eq 'query') { + $query_params->{$token_name} = $token; + } + else { + die "Don't know where to put token '$token_name' ('$in' is not 'head' or 'query')"; + } + } +} + +1; diff --git a/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/ApiFactory.pm b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/ApiFactory.pm new file mode 100644 index 00000000000..7565cd317c1 --- /dev/null +++ b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/ApiFactory.pm @@ -0,0 +1,128 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package WWW::OpenAPIClient::ApiFactory; + +use strict; +use warnings; +use utf8; + +use Carp; +use Module::Find; + +usesub WWW::OpenAPIClient::Object; + +use WWW::OpenAPIClient::ApiClient; + +=head1 Name + + WWW::OpenAPIClient::ApiFactory - constructs APIs to retrieve WWW::OpenAPIClient objects + +=head1 Synopsis + + package My::Petstore::App; + + use WWW::OpenAPIClient::ApiFactory; + + my $api_factory = WWW::OpenAPIClient::ApiFactory->new( ... ); # any args for ApiClient constructor + + # later... + my $pet_api = $api_factory->get_api('Pet'); + + # $pet_api isa WWW::OpenAPIClient::PetApi + + my $pet = $pet_api->get_pet_by_id(pet_id => $pet_id); + + # object attributes have proper accessors: + printf "Pet's name is %s", $pet->name; + + # change the value stored on the object: + $pet->name('Dave'); + +=cut + +# Load all the API classes and construct a lookup table at startup time +my %_apis = map { $_ =~ /^WWW::OpenAPIClient::(.*)$/; $1 => $_ } + grep {$_ =~ /Api$/} + usesub 'WWW::OpenAPIClient'; + +=head1 new($api_client) + + create a new WWW::OpenAPIClient::ApiFactory instance with the given WWW::OpenAPIClient::ApiClient instance. + +=head1 new(%parameters) + + Any parameters are optional, and are passed to and stored on the api_client object. + + See L and L for valid parameters + +=cut + +sub new { + my ($class) = shift; + + my $api_client; + if ($_[0] && ref $_[0] && ref $_[0] eq 'WWW::OpenAPIClient::ApiClient' ) { + $api_client = $_[0]; + } else { + $api_client = WWW::OpenAPIClient::ApiClient->new(@_); + } + bless { api_client => $api_client }, $class; +} + +=head1 get_api($which) + + Returns an API object of the requested type. + + $which is a nickname for the class: + + FooBarClient::BazApi has nickname 'Baz' + +=cut + +sub get_api { + my ($self, $which) = @_; + croak "API not specified" unless $which; + my $api_class = $_apis{"${which}Api"} || croak "No known API for '$which'"; + return $api_class->new($self->api_client); +} + +=head1 api_client() + + Returns the api_client object, should you ever need it. + +=cut + +sub api_client { $_[0]->{api_client} } + +=head1 apis_available() +=cut + +sub apis_available { return map { $_ =~ s/Api$//; $_ } sort keys %_apis } + +=head1 classname_for() +=cut + +sub classname_for { + my ($self, $api_name) = @_; + return $_apis{"${api_name}Api"}; +} + + +1; diff --git a/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Configuration.pm b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Configuration.pm new file mode 100644 index 00000000000..d8a4535129d --- /dev/null +++ b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Configuration.pm @@ -0,0 +1,170 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package WWW::OpenAPIClient::Configuration; + +use strict; +use warnings; +use utf8; + +use Log::Any qw($log); +use Carp; + +use constant VERSION => '1.0.0'; + +=head1 Name + + WWW::OpenAPIClient::Configuration - holds the configuration for all WWW::OpenAPIClient Modules + +=head1 new(%parameters) + +=over 4 + +=item http_timeout: (optional) + +Integer. timeout for HTTP requests in seconds + +default: 180 + +=item http_user_agent: (optional) + +String. custom UserAgent header + +default: OpenAPI-Generator/1.0.0/perl + +=item api_key: (optional) + +Hashref. Keyed on the name of each key (there can be multiple tokens). + + api_key => { + secretKey => 'aaaabbbbccccdddd', + anotherKey => '1111222233334444', + }; + +=item api_key_prefix: (optional) + +Hashref. Keyed on the name of each key (there can be multiple tokens). Note not all api keys require a prefix. + + api_key_prefix => { + secretKey => 'string', + anotherKey => 'same or some other string', + }; + +=item api_key_in: (optional) + +=item username: (optional) + +String. The username for basic auth. + +=item password: (optional) + +String. The password for basic auth. + +=item access_token: (optional) + +String. The OAuth access token. + +=item base_url: (optional) + +String. The base URL of the API + +default: http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r + +=back + +=cut + +sub new { + my ($self, %p) = (shift,@_); + + # class/static variables + $p{http_timeout} //= 180; + $p{http_user_agent} //= 'OpenAPI-Generator/1.0.0/perl'; + + # authentication setting + $p{api_key} //= {}; + $p{api_key_prefix} //= {}; + $p{api_key_in} //= {}; + + # username and password for HTTP basic authentication + $p{username} //= ''; + $p{password} //= ''; + + # access token for OAuth + $p{access_token} //= ''; + + # base_url + $p{base_url} //= 'http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r'; + + return bless \%p => $self; +} + + +sub get_tokens { + my $self = shift; + + my $tokens = {}; + $tokens->{username} = $self->{username} if $self->{username}; + $tokens->{password} = $self->{password} if $self->{password}; + $tokens->{access_token} = $self->{access_token} if $self->{access_token}; + + foreach my $token_name (keys %{ $self->{api_key} }) { + $tokens->{$token_name}->{token} = $self->{api_key}{$token_name}; + $tokens->{$token_name}->{prefix} = $self->{api_key_prefix}{$token_name}; + $tokens->{$token_name}->{in} = $self->{api_key_in}{$token_name}; + } + + return $tokens; +} + +sub clear_tokens { + my $self = shift; + my %tokens = %{$self->get_tokens}; # copy + + $self->{username} = ''; + $self->{password} = ''; + $self->{access_token} = ''; + + $self->{api_key} = {}; + $self->{api_key_prefix} = {}; + $self->{api_key_in} = {}; + + return \%tokens; +} + +sub accept_tokens { + my ($self, $tokens) = @_; + + foreach my $known_name (qw(username password access_token)) { + next unless $tokens->{$known_name}; + $self->{$known_name} = delete $tokens->{$known_name}; + } + + foreach my $token_name (keys %$tokens) { + $self->{api_key}{$token_name} = $tokens->{$token_name}{token}; + if ($tokens->{$token_name}{prefix}) { + $self->{api_key_prefix}{$token_name} = $tokens->{$token_name}{prefix}; + } + my $in = $tokens->{$token_name}->{in} || 'head'; + croak "Tokens can only go in 'head' or 'query' (not in '$in')" unless $in =~ /^(?:head|query)$/; + $self->{api_key_in}{$token_name} = $in; + } +} + +1; diff --git a/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/FakeApi.pm b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/FakeApi.pm new file mode 100644 index 00000000000..eda868c3c9c --- /dev/null +++ b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/FakeApi.pm @@ -0,0 +1,107 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package WWW::OpenAPIClient::FakeApi; + +require 5.6.0; +use strict; +use warnings; +use utf8; +use Exporter; +use Carp qw( croak ); +use Log::Any qw($log); + +use WWW::OpenAPIClient::ApiClient; + +use base "Class::Data::Inheritable"; + +__PACKAGE__->mk_classdata('method_documentation' => {}); + +sub new { + my $class = shift; + my $api_client; + + if ($_[0] && ref $_[0] && ref $_[0] eq 'WWW::OpenAPIClient::ApiClient' ) { + $api_client = $_[0]; + } else { + $api_client = WWW::OpenAPIClient::ApiClient->new(@_); + } + + bless { api_client => $api_client }, $class; + +} + + +# +# test_code_inject____end__rn_n_r +# +# To test code injection */ ' \" =_end -- \\r\\n \\n \\r +# +# @param string $test_code_inject_*/_'_"_=end____\r\n_\n_\r To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r (optional) +{ + my $params = { + 'test_code_inject_*/_'_"_=end____\r\n_\n_\r' => { + data_type => 'string', + description => 'To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r', + required => '0', + }, + }; + __PACKAGE__->method_documentation->{ 'test_code_inject____end__rn_n_r' } = { + summary => 'To test code injection */ ' \" =_end -- \\r\\n \\n \\r', + params => $params, + returns => undef, + }; +} +# @return void +# +sub test_code_inject____end__rn_n_r { + my ($self, %args) = @_; + + # parse inputs + my $_resource_path = '/fake'; + + my $_method = 'PUT'; + my $query_params = {}; + my $header_params = {}; + my $form_params = {}; + + # 'Accept' and 'Content-Type' header + my $_header_accept = $self->{api_client}->select_header_accept(); + if ($_header_accept) { + $header_params->{'Accept'} = $_header_accept; + } + $header_params->{'Content-Type'} = $self->{api_client}->select_header_content_type('application/x-www-form-urlencoded', '*/ \" =_end -- '); + + # form params + if ( exists $args{'test_code_inject_*/_'_"_=end____\r\n_\n_\r'} ) { + $form_params->{'test code inject */ ' " =end -- \r\n \n \r'} = $self->{api_client}->to_form_value($args{'test_code_inject_*/_'_"_=end____\r\n_\n_\r'}); + } + + my $_body_data; + # authentication setting, if any + my $auth_settings = [qw()]; + + # make the API Call + $self->{api_client}->call_api($_resource_path, $_method, + $query_params, $form_params, + $header_params, $_body_data, $auth_settings); + return; +} + +1; diff --git a/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Object/ModelReturn.pm b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Object/ModelReturn.pm new file mode 100644 index 00000000000..2120215969b --- /dev/null +++ b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Object/ModelReturn.pm @@ -0,0 +1,177 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package WWW::OpenAPIClient::Object::ModelReturn; + +require 5.6.0; +use strict; +use warnings; +use utf8; +use JSON qw(decode_json); +use Data::Dumper; +use Module::Runtime qw(use_module); +use Log::Any qw($log); +use Date::Parse; +use DateTime; + + +use base ("Class::Accessor", "Class::Data::Inheritable"); + +# +#Model for testing reserved words */ ' \" =_end -- \\r\\n \\n \\r +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. +# REF: https://openapi-generator.tech +# + +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +__PACKAGE__->mk_classdata('attribute_map' => {}); +__PACKAGE__->mk_classdata('openapi_types' => {}); +__PACKAGE__->mk_classdata('method_documentation' => {}); +__PACKAGE__->mk_classdata('class_documentation' => {}); + +# new plain object +sub new { + my ($class, %args) = @_; + + my $self = bless {}, $class; + + $self->init(%args); + + return $self; +} + +# initialize the object +sub init +{ + my ($self, %args) = @_; + + foreach my $attribute (keys %{$self->attribute_map}) { + my $args_key = $self->attribute_map->{$attribute}; + $self->$attribute( $args{ $args_key } ); + } +} + +# return perl hash +sub to_hash { + my $self = shift; + my $_hash = decode_json(JSON->new->convert_blessed->encode($self)); + + return $_hash; +} + +# used by JSON for serialization +sub TO_JSON { + my $self = shift; + my $_data = {}; + foreach my $_key (keys %{$self->attribute_map}) { + if (defined $self->{$_key}) { + $_data->{$self->attribute_map->{$_key}} = $self->{$_key}; + } + } + + return $_data; +} + +# from Perl hashref +sub from_hash { + my ($self, $hash) = @_; + + # loop through attributes and use openapi_types to deserialize the data + while ( my ($_key, $_type) = each %{$self->openapi_types} ) { + my $_json_attribute = $self->attribute_map->{$_key}; + if ($_type =~ /^array\[/i) { # array + my $_subclass = substr($_type, 6, -1); + my @_array = (); + foreach my $_element (@{$hash->{$_json_attribute}}) { + push @_array, $self->_deserialize($_subclass, $_element); + } + $self->{$_key} = \@_array; + } elsif (exists $hash->{$_json_attribute}) { #hash(model), primitive, datetime + $self->{$_key} = $self->_deserialize($_type, $hash->{$_json_attribute}); + } else { + $log->debugf("Warning: %s (%s) does not exist in input hash\n", $_key, $_json_attribute); + } + } + + return $self; +} + +# deserialize non-array data +sub _deserialize { + my ($self, $type, $data) = @_; + $log->debugf("deserializing %s with %s",Dumper($data), $type); + + if ($type eq 'DateTime') { + return DateTime->from_epoch(epoch => str2time($data)); + } elsif ( grep( /^$type$/, ('int', 'double', 'string', 'boolean'))) { + return $data; + } else { # hash(model) + my $_instance = eval "WWW::OpenAPIClient::Object::$type->new()"; + return $_instance->from_hash($data); + } +} + + + +__PACKAGE__->class_documentation({description => 'Model for testing reserved words */ ' \" =_end -- \\r\\n \\n \\r', + class => 'ModelReturn', + required => [], # TODO +} ); + +__PACKAGE__->method_documentation({ + 'return' => { + datatype => 'int', + base_name => 'return', + description => 'property description */ ' \" =_end -- \\r\\n \\n \\r', + format => '', + read_only => '', + }, +}); + +__PACKAGE__->openapi_types( { + 'return' => 'int' +} ); + +__PACKAGE__->attribute_map( { + 'return' => 'return' +} ); + +__PACKAGE__->mk_accessors(keys %{__PACKAGE__->attribute_map}); + + +1; diff --git a/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Role.pm b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Role.pm new file mode 100644 index 00000000000..5fd3a81e949 --- /dev/null +++ b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Role.pm @@ -0,0 +1,337 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package WWW::OpenAPIClient::Role; +use utf8; + +use Moose::Role; +use namespace::autoclean; +use Class::Inspector; +use Log::Any qw($log); +use WWW::OpenAPIClient::ApiFactory; + +has base_url => ( is => 'ro', + required => 0, + isa => 'Str', + documentation => 'Root of the server that requests are sent to', + ); + +has api_factory => ( is => 'ro', + isa => 'WWW::OpenAPIClient::ApiFactory', + builder => '_build_af', + lazy => 1, + documentation => 'Builds an instance of the endpoint API class', + ); + +has tokens => ( is => 'ro', + isa => 'HashRef', + required => 0, + default => sub { {} }, + documentation => 'The auth tokens required by the application - basic, OAuth and/or API key(s)', + ); + +has _cfg => ( is => 'ro', + isa => 'WWW::OpenAPIClient::Configuration', + default => sub { WWW::OpenAPIClient::Configuration->new() }, + ); + +has version_info => ( is => 'ro', + isa => 'HashRef', + default => sub { { + app_name => 'OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r', + app_version => '1.0.0 */ ' \" =_end -- \\r\\n \\n \\r', + generator_class => 'org.openapitools.codegen.languages.PerlClientCodegen', + } }, + documentation => 'Information about the application version and the codegen codebase version' + ); + +sub BUILD { + my $self = shift; + + $self->_cfg->accept_tokens( $self->tokens ) if keys %{$self->tokens}; + + # ignore these symbols imported into API namespaces + my %outsiders = map {$_ => 1} qw( croak ); + + my %delegates; + + # collect the methods callable on each API + foreach my $api_name ($self->api_factory->apis_available) { + my $api_class = $self->api_factory->classname_for($api_name); + my $methods = Class::Inspector->methods($api_class, 'expanded'); # not Moose, so use CI instead + my @local_methods = grep {! /^_/} grep {! $outsiders{$_}} map {$_->[2]} grep {$_->[1] eq $api_class} @$methods; + push( @{$delegates{$_}}, {api_name => $api_name, api_class => $api_class} ) for @local_methods; + } + + # remove clashes + foreach my $method (keys %delegates) { + if ( @{$delegates{$method}} > 1 ) { + my ($apis) = delete $delegates{$method}; + } + } + + # build the flattened API + foreach my $api_name ($self->api_factory->apis_available) { + my $att_name = sprintf "%s_api", lc($api_name); + my $api_class = $self->api_factory->classname_for($api_name); + my @delegated = grep { $delegates{$_}->[0]->{api_name} eq $api_name } keys %delegates; + $log->debugf("Adding API: '%s' handles %s", $att_name, join ', ', @delegated); + $self->meta->add_attribute( $att_name => ( + is => 'ro', + isa => $api_class, + default => sub {$self->api_factory->get_api($api_name)}, + lazy => 1, + handles => \@delegated, + ) ); + } +} + +sub _build_af { + my $self = shift; + my %args; + $args{base_url} = $self->base_url if $self->base_url; + return WWW::OpenAPIClient::ApiFactory->new(%args); +} + +=head1 NAME + +WWW::OpenAPIClient::Role - a Moose role for the OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +=head2 OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r + +=head1 VERSION + +Automatically generated by the Perl OpenAPI Generator project: + +=over 4 +=item Build package: org.openapitools.codegen.languages.PerlClientCodegen + +=item Codegen version: + +=back + +=head2 A note on Moose + +This role is the only component of the library that uses Moose. See +WWW::OpenAPIClient::ApiFactory for non-Moosey usage. + +=head1 SYNOPSIS + +The Perl Generator in the OpenAPI Generator project builds a library of Perl modules to interact with +a web service defined by a OpenAPI Specification. See below for how to build the +library. + +This module provides an interface to the generated library. All the classes, +objects, and methods (well, not quite *all*, see below) are flattened into this +role. + + package MyApp; + use Moose; + with 'WWW::OpenAPIClient::Role'; + + package main; + + my $api = MyApp->new({ tokens => $tokens }); + + my $pet = $api->get_pet_by_id(pet_id => $pet_id); + +=head2 Structure of the library + +The library consists of a set of API classes, one for each endpoint. These APIs +implement the method calls available on each endpoint. + +Additionally, there is a set of "object" classes, which represent the objects +returned by and sent to the methods on the endpoints. + +An API factory class is provided, which builds instances of each endpoint API. + +This Moose role flattens all the methods from the endpoint APIs onto the consuming +class. It also provides methods to retrieve the endpoint API objects, and the API +factory object, should you need it. + +For documentation of all these methods, see AUTOMATIC DOCUMENTATION below. + +=head2 Configuring authentication + +In the normal case, the OpenAPI Spec will describe what parameters are +required and where to put them. You just need to supply the tokens. + + my $tokens = { + # basic + username => $username, + password => $password, + + # oauth + access_token => $oauth_token, + + # keys + $some_key => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + + $another => { token => $token, + prefix => $prefix, + in => $in, # 'head||query', + }, + ..., + + }; + + my $api = MyApp->new({ tokens => $tokens }); + +Note these are all optional, as are C and C, and depend on the API +you are accessing. Usually C and C will be determined by the code generator from +the spec and you will not need to set them at run time. If not, C will +default to 'head' and C to the empty string. + +The tokens will be placed in a L instance +as follows, but you don't need to know about this. + +=over 4 + +=item C<$cfg-\>{username}> + +String. The username for basic auth. + +=item C<$cfg-\>{password}> + +String. The password for basic auth. + +=item C<$cfg-\>{api_key}> + +Hashref. Keyed on the name of each key (there can be multiple tokens). + + $cfg->{api_key} = { + secretKey => 'aaaabbbbccccdddd', + anotherKey => '1111222233334444', + }; + +=item C<$cfg->{api_key_prefix}> + +Hashref. Keyed on the name of each key (there can be multiple tokens). Note not +all api keys require a prefix. + + $cfg->{api_key_prefix} = { + secretKey => 'string', + anotherKey => 'same or some other string', + }; + +=item C<$config-\>{access_token}> + +String. The OAuth access token. + +=back + +=head1 METHODS + +=head2 C + +The generated code has the C already set as a default value. This method +returns the current value of C. + +=head2 C + +Returns an API factory object. You probably won't need to call this directly. + + $self->api_factory('Pet'); # returns a WWW::OpenAPIClient::PetApi instance + + $self->pet_api; # the same + +=head1 MISSING METHODS + +Most of the methods on the API are delegated to individual endpoint API objects +(e.g. Pet API, Store API, User API etc). Where different endpoint APIs use the +same method name (e.g. C), these methods can't be delegated. So you need +to call C<$api-Epet_api-Enew()>. + +In principle, every API is susceptible to the presence of a few, random, undelegatable +method names. In practice, because of the way method names are constructed, it's +unlikely in general that any methods will be undelegatable, except for: + + new() + class_documentation() + method_documentation() + +To call these methods, you need to get a handle on the relevant object, either +by calling C<$api-Efoo_api> or by retrieving an object, e.g. +C<$api-Eget_pet_by_id(pet_id =E $pet_id)>. They are class methods, so +you could also call them on class names. + +=head1 BUILDING YOUR LIBRARY + +See the homepage C for full details. +But briefly, clone the git repository, build the codegen codebase, set up your build +config file, then run the API build script. You will need git, Java 7 or 8 and Apache +maven 3.0.3 or better already installed. + +The config file should specify the project name for the generated library: + + {"moduleName":"WWW::MyProjectName"} + +Your library files will be built under C. + + $ git clone https://github.com/openapitools/openapi-generator + $ cd openapi-generator + $ mvn package + $ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \ + -i [URL or file path to JSON OpenAPI API spec] \ + -g perl \ + -c /path/to/config/file.json \ + -o /path/to/output/folder + +Bang, all done. Run the C script in the C directory to see the API +you just built. + +=head1 AUTOMATIC DOCUMENTATION + +You can print out a summary of the generated API by running the included +C script in the C directory of your generated library. A few +output formats are supported: + + Usage: autodoc [OPTION] + + -w wide format (default) + -n narrow format + -p POD format + -H HTML format + -m Markdown format + -h print this help message + -c your application class + +The C<-c> option allows you to load and inspect your own application. A dummy +namespace is used if you don't supply your own class. + +=head1 DOCUMENTATION FROM THE OpenAPI Spec + +Additional documentation for each class and method may be provided by the OpenAPI +spec. If so, this is available via the C and +C methods on each generated object class, and the +C method on the endpoint API classes: + + my $cmdoc = $api->pet_api->method_documentation->{$method_name}; + + my $odoc = $api->get_pet_by_id->(pet_id => $pet_id)->class_documentation; + my $omdoc = $api->get_pet_by_id->(pet_id => $pet_id)->method_documentation->{method_name}; + +Each of these calls returns a hashref with various useful pieces of information. + +=cut + +1; diff --git a/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Role/AutoDoc.pm b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Role/AutoDoc.pm new file mode 100644 index 00000000000..e64e01d6437 --- /dev/null +++ b/samples/client/petstore-security-test/perl/lib/WWW/OpenAPIClient/Role/AutoDoc.pm @@ -0,0 +1,446 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +# Do not edit the class manually. +# Ref: https://openapi-generator.tech +# +package WWW::OpenAPIClient::Role::AutoDoc; +use List::MoreUtils qw(uniq); + +use Moose::Role; + +sub autodoc { + my ($self, $how) = @_; + + die "Unknown format '$how'" unless $how =~ /^(pod|wide|narrow)$/; + + $self->_printisa($how); + $self->_printmethods($how); + $self->_printattrs($how); + print "\n"; +} + +sub _printisa { + my ($self, $how) = @_; + my $meta = $self->meta; + + my $myclass = ref $self; + + my $super = join ', ', $meta->superclasses; + my @roles = $meta->calculate_all_roles; + #shift(@roles) if @roles > 1; # if > 1, the first is a composite, the rest are the roles + + my $isa = join ', ', grep {$_ ne $myclass} $meta->linearized_isa; + my $sub = join ', ', $meta->subclasses; + my $dsub = join ', ', $meta->direct_subclasses; + + my $app_name = $self->version_info->{app_name}; + my $app_version = $self->version_info->{app_version}; + my $generated_date = $self->version_info->{generated_date}; + my $generator_class = $self->version_info->{generator_class}; + + $~ = $how eq 'pod' ? 'INHERIT_POD' : 'INHERIT'; + write; + + my ($rolepkg, $role_reqs); + + foreach my $role (@roles) { + $rolepkg = $role->{package} || next; # some are anonymous, or something + next if $rolepkg eq 'WWW::OpenAPIClient::Role::AutoDoc'; + $role_reqs = join ', ', keys %{$role->{required_methods}}; + $role_reqs ||= ''; + $~ = $how eq 'pod' ? 'ROLES_POD' : 'ROLES'; + write; + } + + if ($how eq 'pod') { + $~ = 'ROLES_POD_CLOSE'; + write; + } + +# ----- format specs ----- + format INHERIT = + +@* - +$myclass + ISA: @* + $isa + Direct subclasses: @* + $dsub + All subclasses: @* + $sub + + Target API: @* @* + $app_name, $app_version + Generated on: @* + $generated_date + Generator class: @* + $generator_class + +. + format ROLES = + Composes: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ + $rolepkg + requires: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~ + $role_reqs + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $role_reqs +. + + format INHERIT_POD = +=head1 NAME + +@* +$myclass + +=head1 VERSION + +=head2 @* version: @* + $app_name, $app_version + +Automatically generated by the Perl Generator in the OpenAPI Generator project: + +=over 4 + +=item Build date: @* + $generated_date + +=item Build package: @* + $generator_class + +=item Codegen version: + + +=back + +=head1 INHERITANCE + +=head2 Base class(es) + +@* +$isa + +=head2 Direct subclasses + +@* +$dsub + +=head2 All subclasses + +@* +$sub + + +=head1 COMPOSITION + +@* composes the following roles: +$myclass + + +. + format ROLES_POD = +=head2 C<@*> + $rolepkg + +Requires: + +@* +$role_reqs + +. + format ROLES_POD_CLOSE = + + +. +# ----- / format specs ----- +} + +sub _printmethods { + my ($self, $how) = @_; + + if ($how eq 'narrow') { + print <_printmethod($_, $how) for uniq sort $self->meta->get_all_method_names; #$self->meta->get_method_list, + + if ($how eq 'pod') { + $~ = 'METHOD_POD_CLOSE'; + write; + } + + +} + +sub _printmethod { + my ($self, $methodname, $how) = @_; + return if $methodname =~ /^_/; + return if $self->meta->has_attribute($methodname); + my %internal = map {$_ => 1} qw(BUILD BUILDARGS meta can new DEMOLISHALL DESTROY + DOES isa BUILDALL does VERSION dump + ); + return if $internal{$methodname}; + my $method = $self->meta->get_method($methodname) or return; # symbols imported into namespaces i.e. not known by Moose + + return if $method->original_package_name eq __PACKAGE__; + + my $delegate_to = ''; + my $via = ''; + my $on = ''; + my $doc = ''; + my $original_pkg = $method->original_package_name; + if ($method->can('associated_attribute')) { + $delegate_to = $method->delegate_to_method; + my $aa = $method->associated_attribute; + $on = $aa->{isa}; + $via = $aa->{name}; + $original_pkg = $on; + $doc = $original_pkg->method_documentation->{$delegate_to}->{summary}; + } + else { + $doc = $method->documentation; + } + + if ($how eq 'narrow') { + $~ = 'METHOD_NARROW'; + write; + } + elsif ($how eq 'pod' and $delegate_to) { + $~ = 'METHOD_POD_DELEGATED'; + write; + } + elsif ($how eq 'pod') { + $~ = 'METHOD_POD'; + write; + } + else { + $~ = 'METHOD'; + write; + } + +# ----- format specs ----- + format METHODHEAD = + +METHODS +------- +Name delegates to on via +=========================================================================================================================================================================== +. + format METHOD = +@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<<<<<<<<... +$methodname, $delegate_to, $on, $via +. + + format METHOD_NARROW = +@* +$methodname + original pkg: @* + $original_pkg + delegates to: @* + $delegate_to + on: @* + $on + via: @* + $via + +. + + format METHODHEAD_POD = + +=head1 METHODS + +. + + format METHOD_POD = + +=head2 C<@*()> + $methodname + + Defined in: @* + $original_pkg + + +. + format METHOD_POD_DELEGATED = + +=head2 C<@*()> + $methodname + + Defined in: @* + $original_pkg + Delegates to: @*() + $delegate_to + On: @* + $on + Via: @*() + $via + Doc: @* + $doc + Same as: $self->@*->@*() + $via, $delegate_to + +. + format METHOD_POD_CLOSE = + +. +# ----- / format specs ----- +} + +sub _printattrs { + my ($self, $how) = @_; + + if ($how eq 'narrow') { + print <_printattr($_, $how) for sort $self->meta->get_attribute_list; + + if ($how eq 'pod') { + $~ = 'ATTR_POD_CLOSE'; + write; + } +} + +sub _printattr { + my ($self, $attrname, $how) = @_; + return if $attrname =~ /^_/; + my $attr = $self->meta->get_attribute($attrname) or die "No attr for $attrname"; + + my $is; + $is = 'rw' if $attr->get_read_method && $attr->get_write_method; + $is = 'ro' if $attr->get_read_method && ! $attr->get_write_method; + $is = 'wo' if $attr->get_write_method && ! $attr->get_read_method; + $is = '--' if ! $attr->get_write_method && ! $attr->get_read_method; + $is or die "No \$is for $attrname"; + + my $tc = $attr->type_constraint || ''; + my $from = $attr->associated_class->name || ''; + my $reqd = $attr->is_required ? 'yes' : 'no'; + my $lazy = $attr->is_lazy ? 'yes' : 'no'; + my $has_doc = $attr->has_documentation ? 'yes' : 'no'; # *_api attributes will never have doc, but other attributes might have + my $doc = $attr->documentation || ''; + my $handles = join ', ', sort @{$attr->handles || []}; + $handles ||= ''; + + if ($how eq 'narrow') { + $~ = 'ATTR_NARROW'; + } + elsif ($how eq 'pod') { + $~ = 'ATTR_POD'; + } + else { + $~ = 'ATTR'; + } + + write; + +# ----- format specs ----- + format ATTRHEAD = + +ATTRIBUTES +---------- +Name is isa reqd lazy doc handles +============================================================================================================== +. + format ATTR = +@<<<<<<<<<<<<<<<<< @< @<<<<<<<<<<<<<<<<<<<<<<<< @<<< @<<< @<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +$attrname, $is, $tc, $reqd, $lazy, $has_doc, $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles +. + + format ATTR_NARROW = +@* +$attrname + is: @* + $is + isa: @* + $tc + reqd: @* + $reqd + lazy: @* + $lazy + doc: @* + $doc + handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles + +. + format ATTRHEAD_POD = +=head1 ATTRIBUTES + +. + format ATTR_POD = + +=head2 C<@*> + $attrname + + is: @* + $is + isa: @* + $tc + reqd: @* + $reqd + lazy: @* + $lazy + doc: @* + $doc + handles: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + $handles + ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ + $handles + +. + format ATTR_POD_CLOSE = + + +. +# ----- / format specs ----- +} + + + +1; diff --git a/samples/client/petstore-security-test/perl/t/FakeApiTest.t b/samples/client/petstore-security-test/perl/t/FakeApiTest.t new file mode 100644 index 00000000000..9cdab079dc8 --- /dev/null +++ b/samples/client/petstore-security-test/perl/t/FakeApiTest.t @@ -0,0 +1,41 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by OpenAPI Generator +# Please update the test cases below to test the API endpoints. +# Ref: https://openapi-generator.tech +# +use Test::More tests => 1; #TODO update number of test cases +use Test::Exception; + +use lib 'lib'; +use strict; +use warnings; + +use_ok('WWW::OpenAPIClient::FakeApi'); + +my $api = WWW::OpenAPIClient::FakeApi->new(); +isa_ok($api, 'WWW::OpenAPIClient::FakeApi'); + +# +# test_code_inject____end__rn_n_r test +# +{ + my $test_code_inject_*/_'_"_=end____\r\n_\n_\r = undef; # replace NULL with a proper value + my $result = $api->test_code_inject____end__rn_n_r(test_code_inject_*/_'_"_=end____\r\n_\n_\r => $test_code_inject_*/_'_"_=end____\r\n_\n_\r); +} + + +1; diff --git a/samples/client/petstore-security-test/perl/t/ModelReturnTest.t b/samples/client/petstore-security-test/perl/t/ModelReturnTest.t new file mode 100644 index 00000000000..095b4fdcfb1 --- /dev/null +++ b/samples/client/petstore-security-test/perl/t/ModelReturnTest.t @@ -0,0 +1,33 @@ +=begin comment + +OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech + +=end comment + +=cut + +# +# NOTE: This class is auto generated by the OpenAPI Generator +# Please update the test cases below to test the model. +# Ref: https://openapi-generator.tech +# +use Test::More tests => 2; +use Test::Exception; + +use lib 'lib'; +use strict; +use warnings; + + +use_ok('WWW::OpenAPIClient::Object::ModelReturn'); + +my $instance = WWW::OpenAPIClient::Object::ModelReturn->new(); + +isa_ok($instance, 'WWW::OpenAPIClient::Object::ModelReturn'); + diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/.gitignore b/samples/client/petstore-security-test/php/OpenAPIClient-php/.gitignore new file mode 100644 index 00000000000..edcf63f6aee --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/.gitignore @@ -0,0 +1,8 @@ +# ref: https://github.com/github/gitignore/blob/master/Composer.gitignore + +composer.phar +/vendor/ + +# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control +# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file +composer.lock \ No newline at end of file diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/.openapi-generator-ignore b/samples/client/petstore-security-test/php/OpenAPIClient-php/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/.openapi-generator/VERSION b/samples/client/petstore-security-test/php/OpenAPIClient-php/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/.php_cs b/samples/client/petstore-security-test/php/OpenAPIClient-php/.php_cs new file mode 100644 index 00000000000..4fbe53ec5ff --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/.php_cs @@ -0,0 +1,23 @@ +setUsingCache(true) + ->setRules([ + '@PSR2' => true, + 'ordered_imports' => true, + 'phpdoc_order' => true, + 'array_syntax' => [ 'syntax' => 'short' ], + 'strict_comparison' => true, + 'strict_param' => true, + 'no_trailing_whitespace' => false, + 'no_trailing_whitespace_in_comment' => false, + 'braces' => false, + 'single_blank_line_at_eof' => false, + 'blank_line_after_namespace' => false, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->exclude('test') + ->exclude('tests') + ->in(__DIR__) + ); diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/.travis.yml b/samples/client/petstore-security-test/php/OpenAPIClient-php/.travis.yml new file mode 100644 index 00000000000..d77f3825f6f --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/.travis.yml @@ -0,0 +1,10 @@ +language: php +sudo: false +php: + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - hhvm +before_install: "composer install" +script: "vendor/bin/phpunit" diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/README.md b/samples/client/petstore-security-test/php/OpenAPIClient-php/README.md new file mode 100644 index 00000000000..e7a0065856d --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/README.md @@ -0,0 +1,115 @@ +# OpenAPIClient-php +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + +This PHP package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +- Build package: org.openapitools.codegen.languages.PhpClientCodegen + +## Requirements + +PHP 5.5 and later + +## Installation & Usage +### Composer + +To install the bindings via [Composer](http://getcomposer.org/), add the following to `composer.json`: + +``` +{ + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/GIT_USER_ID/GIT_REPO_ID.git" + } + ], + "require": { + "GIT_USER_ID/GIT_REPO_ID": "*@dev" + } +} +``` + +Then run `composer install` + +### Manual Installation + +Download the files and include `autoload.php`: + +```php + require_once('/path/to/OpenAPIClient-php/vendor/autoload.php'); +``` + +## Tests + +To run the unit tests: + +``` +composer install +./vendor/bin/phpunit +``` + +## Getting Started + +Please follow the [installation procedure](#installation--usage) and then run the following: + +```php +testCodeInjectEndRnNR($test_code_inject____end____rn_n_r); +} catch (Exception $e) { + echo 'Exception when calling FakeApi->testCodeInjectEndRnNR: ', $e->getMessage(), PHP_EOL; +} + +?> +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*FakeApi* | [**testCodeInjectEndRnNR**](docs/Api/FakeApi.md#testcodeinjectendrnnr) | **PUT** /fake | To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + +## Documentation For Models + + - [ModelReturn](docs/Model/ModelReturn.md) + + +## Documentation For Authorization + + +## api_key + +- **Type**: API key +- **API key parameter name**: api_key */ ' " =end -- \r\n \n \r +- **Location**: HTTP header + + +## petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: +- **write:pets**: modify pets in your account *_/ ' \" =end -- \\r\\n \\n \\r +- **read:pets**: read your pets *_/ ' \" =end -- \\r\\n \\n \\r + + +## Author + +something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + + diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/composer.json b/samples/client/petstore-security-test/php/OpenAPIClient-php/composer.json new file mode 100644 index 00000000000..df2e7f52710 --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/composer.json @@ -0,0 +1,39 @@ +{ + "name": "GIT_USER_ID/GIT_REPO_ID", + "description": "This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end --", + "keywords": [ + "openapitools", + "openapi-generator", + "openapi", + "php", + "sdk", + "rest", + "api" + ], + "homepage": "https://openapi-generator.tech", + "license": "proprietary", + "authors": [ + { + "name": "OpenAPI-Generator contributors", + "homepage": "https://openapi-generator.tech" + } + ], + "require": { + "php": ">=7.1", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "guzzlehttp/guzzle": "^6.2" + }, + "require-dev": { + "phpunit/phpunit": "^7.4", + "squizlabs/php_codesniffer": "~2.6", + "friendsofphp/php-cs-fixer": "~2.12" + }, + "autoload": { + "psr-4": { "OpenAPI\\Client\\" : "lib/" } + }, + "autoload-dev": { + "psr-4": { "OpenAPI\\Client\\" : "test/" } + } +} diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/docs/Api/FakeApi.md b/samples/client/petstore-security-test/php/OpenAPIClient-php/docs/Api/FakeApi.md new file mode 100644 index 00000000000..532dc2ff511 --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/docs/Api/FakeApi.md @@ -0,0 +1,58 @@ +# OpenAPI\Client\FakeApi + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**testCodeInjectEndRnNR**](FakeApi.md#testCodeInjectEndRnNR) | **PUT** /fake | To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + +# **testCodeInjectEndRnNR** +> testCodeInjectEndRnNR($test_code_inject____end____rn_n_r) + +To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + +To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + +### Example +```php +testCodeInjectEndRnNR($test_code_inject____end____rn_n_r); +} catch (Exception $e) { + echo 'Exception when calling FakeApi->testCodeInjectEndRnNR: ', $e->getMessage(), PHP_EOL; +} +?> +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **test_code_inject____end____rn_n_r** | **string**| To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r | [optional] + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded, *_/ \" =end -- + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to Model list]](../../README.md#documentation-for-models) [[Back to README]](../../README.md) + diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/docs/Model/ModelReturn.md b/samples/client/petstore-security-test/php/OpenAPIClient-php/docs/Model/ModelReturn.md new file mode 100644 index 00000000000..ca98a8bbe92 --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/docs/Model/ModelReturn.md @@ -0,0 +1,10 @@ +# ModelReturn + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**return** | **int** | property description *_/ ' \" =end -- \\r\\n \\n \\r | [optional] + +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) + + diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/git_push.sh b/samples/client/petstore-security-test/php/OpenAPIClient-php/git_push.sh new file mode 100644 index 00000000000..20057f67ade --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/Api/FakeApi.php b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/Api/FakeApi.php new file mode 100644 index 00000000000..c236e10d9e3 --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/Api/FakeApi.php @@ -0,0 +1,350 @@ +client = $client ?: new Client(); + $this->config = $config ?: new Configuration(); + $this->headerSelector = $selector ?: new HeaderSelector(); + $this->hostIndex = $host_index; + } + + /** + * Set the host index + * + * @param int Host index (required) + */ + public function setHostIndex($host_index) + { + $this->hostIndex = $host_index; + } + + /** + * Get the host index + * + * @return Host index + */ + public function getHostIndex() + { + return $this->hostIndex; + } + + /** + * @return Configuration + */ + public function getConfig() + { + return $this->config; + } + + /** + * Operation testCodeInjectEndRnNR + * + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * + * @param string $test_code_inject____end____rn_n_r To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + * + * @throws \OpenAPI\Client\ApiException on non-2xx response + * @throws \InvalidArgumentException + * @return void + */ + public function testCodeInjectEndRnNR($test_code_inject____end____rn_n_r = null) + { + $this->testCodeInjectEndRnNRWithHttpInfo($test_code_inject____end____rn_n_r); + } + + /** + * Operation testCodeInjectEndRnNRWithHttpInfo + * + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * + * @param string $test_code_inject____end____rn_n_r To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + * + * @throws \OpenAPI\Client\ApiException on non-2xx response + * @throws \InvalidArgumentException + * @return array of null, HTTP status code, HTTP response headers (array of strings) + */ + public function testCodeInjectEndRnNRWithHttpInfo($test_code_inject____end____rn_n_r = null) + { + $request = $this->testCodeInjectEndRnNRRequest($test_code_inject____end____rn_n_r); + + try { + $options = $this->createHttpClientOption(); + try { + $response = $this->client->send($request, $options); + } catch (RequestException $e) { + throw new ApiException( + "[{$e->getCode()}] {$e->getMessage()}", + $e->getCode(), + $e->getResponse() ? $e->getResponse()->getHeaders() : null, + $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null + ); + } + + $statusCode = $response->getStatusCode(); + + if ($statusCode < 200 || $statusCode > 299) { + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $request->getUri() + ), + $statusCode, + $response->getHeaders(), + $response->getBody() + ); + } + + return [null, $statusCode, $response->getHeaders()]; + + } catch (ApiException $e) { + switch ($e->getCode()) { + } + throw $e; + } + } + + /** + * Operation testCodeInjectEndRnNRAsync + * + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * + * @param string $test_code_inject____end____rn_n_r To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function testCodeInjectEndRnNRAsync($test_code_inject____end____rn_n_r = null) + { + return $this->testCodeInjectEndRnNRAsyncWithHttpInfo($test_code_inject____end____rn_n_r) + ->then( + function ($response) { + return $response[0]; + } + ); + } + + /** + * Operation testCodeInjectEndRnNRAsyncWithHttpInfo + * + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * + * @param string $test_code_inject____end____rn_n_r To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public function testCodeInjectEndRnNRAsyncWithHttpInfo($test_code_inject____end____rn_n_r = null) + { + $returnType = ''; + $request = $this->testCodeInjectEndRnNRRequest($test_code_inject____end____rn_n_r); + + return $this->client + ->sendAsync($request, $this->createHttpClientOption()) + ->then( + function ($response) use ($returnType) { + return [null, $response->getStatusCode(), $response->getHeaders()]; + }, + function ($exception) { + $response = $exception->getResponse(); + $statusCode = $response->getStatusCode(); + throw new ApiException( + sprintf( + '[%d] Error connecting to the API (%s)', + $statusCode, + $exception->getRequest()->getUri() + ), + $statusCode, + $response->getHeaders(), + $response->getBody() + ); + } + ); + } + + /** + * Create request for operation 'testCodeInjectEndRnNR' + * + * @param string $test_code_inject____end____rn_n_r To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + * + * @throws \InvalidArgumentException + * @return \GuzzleHttp\Psr7\Request + */ + protected function testCodeInjectEndRnNRRequest($test_code_inject____end____rn_n_r = null) + { + + $resourcePath = '/fake'; + $formParams = []; + $queryParams = []; + $headerParams = []; + $httpBody = ''; + $multipart = false; + + + + // form params + if ($test_code_inject____end____rn_n_r !== null) { + $formParams['test code inject */ ' " =end -- \r\n \n \r'] = ObjectSerializer::toFormValue($test_code_inject____end____rn_n_r); + } + // body params + $_tempBody = null; + + if ($multipart) { + $headers = $this->headerSelector->selectHeadersForMultipart( + [] + ); + } else { + $headers = $this->headerSelector->selectHeaders( + [], + ['application/x-www-form-urlencoded', '*_/ \" =end --'] + ); + } + + // for model (json/xml) + if (isset($_tempBody)) { + // $_tempBody is the method argument, if present + if ($headers['Content-Type'] === 'application/json') { + $httpBody = \GuzzleHttp\json_encode(ObjectSerializer::sanitizeForSerialization($_tempBody)); + } else { + $httpBody = $_tempBody; + } + } elseif (count($formParams) > 0) { + if ($multipart) { + $multipartContents = []; + foreach ($formParams as $formParamName => $formParamValue) { + $multipartContents[] = [ + 'name' => $formParamName, + 'contents' => $formParamValue + ]; + } + // for HTTP post (form) + $httpBody = new MultipartStream($multipartContents); + + } elseif ($headers['Content-Type'] === 'application/json') { + $httpBody = \GuzzleHttp\json_encode($formParams); + + } else { + // for HTTP post (form) + $httpBody = \GuzzleHttp\Psr7\build_query($formParams); + } + } + + + $defaultHeaders = []; + if ($this->config->getUserAgent()) { + $defaultHeaders['User-Agent'] = $this->config->getUserAgent(); + } + + $headers = array_merge( + $defaultHeaders, + $headerParams, + $headers + ); + + $query = \GuzzleHttp\Psr7\build_query($queryParams); + return new Request( + 'PUT', + $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''), + $headers, + $httpBody + ); + } + + /** + * Create http client option + * + * @throws \RuntimeException on file opening failure + * @return array of http client options + */ + protected function createHttpClientOption() + { + $options = []; + if ($this->config->getDebug()) { + $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a'); + if (!$options[RequestOptions::DEBUG]) { + throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile()); + } + } + + return $options; + } +} diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/ApiException.php b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/ApiException.php new file mode 100644 index 00000000000..791ed3d05cb --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/ApiException.php @@ -0,0 +1,121 @@ +responseHeaders = $responseHeaders; + $this->responseBody = $responseBody; + } + + /** + * Gets the HTTP response header + * + * @return string[]|null HTTP response header + */ + public function getResponseHeaders() + { + return $this->responseHeaders; + } + + /** + * Gets the HTTP body of the server response either as Json or string + * + * @return mixed HTTP body of the server response either as \stdClass or string + */ + public function getResponseBody() + { + return $this->responseBody; + } + + /** + * Sets the deseralized response object (during deserialization) + * + * @param mixed $obj Deserialized response object + * + * @return void + */ + public function setResponseObject($obj) + { + $this->responseObject = $obj; + } + + /** + * Gets the deseralized response object (during deserialization) + * + * @return mixed the deserialized response object + */ + public function getResponseObject() + { + return $this->responseObject; + } +} diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/Configuration.php b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/Configuration.php new file mode 100644 index 00000000000..b6c6f003810 --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/Configuration.php @@ -0,0 +1,484 @@ +tempFolderPath = sys_get_temp_dir(); + } + + /** + * Sets API key + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * @param string $key API key or token + * + * @return $this + */ + public function setApiKey($apiKeyIdentifier, $key) + { + $this->apiKeys[$apiKeyIdentifier] = $key; + return $this; + } + + /** + * Gets API key + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * + * @return string API key or token + */ + public function getApiKey($apiKeyIdentifier) + { + return isset($this->apiKeys[$apiKeyIdentifier]) ? $this->apiKeys[$apiKeyIdentifier] : null; + } + + /** + * Sets the prefix for API key (e.g. Bearer) + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * @param string $prefix API key prefix, e.g. Bearer + * + * @return $this + */ + public function setApiKeyPrefix($apiKeyIdentifier, $prefix) + { + $this->apiKeyPrefixes[$apiKeyIdentifier] = $prefix; + return $this; + } + + /** + * Gets API key prefix + * + * @param string $apiKeyIdentifier API key identifier (authentication scheme) + * + * @return string + */ + public function getApiKeyPrefix($apiKeyIdentifier) + { + return isset($this->apiKeyPrefixes[$apiKeyIdentifier]) ? $this->apiKeyPrefixes[$apiKeyIdentifier] : null; + } + + /** + * Sets the access token for OAuth + * + * @param string $accessToken Token for OAuth + * + * @return $this + */ + public function setAccessToken($accessToken) + { + $this->accessToken = $accessToken; + return $this; + } + + /** + * Gets the access token for OAuth + * + * @return string Access token for OAuth + */ + public function getAccessToken() + { + return $this->accessToken; + } + + /** + * Sets the username for HTTP basic authentication + * + * @param string $username Username for HTTP basic authentication + * + * @return $this + */ + public function setUsername($username) + { + $this->username = $username; + return $this; + } + + /** + * Gets the username for HTTP basic authentication + * + * @return string Username for HTTP basic authentication + */ + public function getUsername() + { + return $this->username; + } + + /** + * Sets the password for HTTP basic authentication + * + * @param string $password Password for HTTP basic authentication + * + * @return $this + */ + public function setPassword($password) + { + $this->password = $password; + return $this; + } + + /** + * Gets the password for HTTP basic authentication + * + * @return string Password for HTTP basic authentication + */ + public function getPassword() + { + return $this->password; + } + + /** + * Sets the host + * + * @param string $host Host + * + * @return $this + */ + public function setHost($host) + { + $this->host = $host; + return $this; + } + + /** + * Gets the host + * + * @return string Host + */ + public function getHost() + { + return $this->host; + } + + /** + * Sets the user agent of the api client + * + * @param string $userAgent the user agent of the api client + * + * @throws \InvalidArgumentException + * @return $this + */ + public function setUserAgent($userAgent) + { + if (!is_string($userAgent)) { + throw new \InvalidArgumentException('User-agent must be a string.'); + } + + $this->userAgent = $userAgent; + return $this; + } + + /** + * Gets the user agent of the api client + * + * @return string user agent + */ + public function getUserAgent() + { + return $this->userAgent; + } + + /** + * Sets debug flag + * + * @param bool $debug Debug flag + * + * @return $this + */ + public function setDebug($debug) + { + $this->debug = $debug; + return $this; + } + + /** + * Gets the debug flag + * + * @return bool + */ + public function getDebug() + { + return $this->debug; + } + + /** + * Sets the debug file + * + * @param string $debugFile Debug file + * + * @return $this + */ + public function setDebugFile($debugFile) + { + $this->debugFile = $debugFile; + return $this; + } + + /** + * Gets the debug file + * + * @return string + */ + public function getDebugFile() + { + return $this->debugFile; + } + + /** + * Sets the temp folder path + * + * @param string $tempFolderPath Temp folder path + * + * @return $this + */ + public function setTempFolderPath($tempFolderPath) + { + $this->tempFolderPath = $tempFolderPath; + return $this; + } + + /** + * Gets the temp folder path + * + * @return string Temp folder path + */ + public function getTempFolderPath() + { + return $this->tempFolderPath; + } + + /** + * Gets the default configuration instance + * + * @return Configuration + */ + public static function getDefaultConfiguration() + { + if (self::$defaultConfiguration === null) { + self::$defaultConfiguration = new Configuration(); + } + + return self::$defaultConfiguration; + } + + /** + * Sets the detault configuration instance + * + * @param Configuration $config An instance of the Configuration Object + * + * @return void + */ + public static function setDefaultConfiguration(Configuration $config) + { + self::$defaultConfiguration = $config; + } + + /** + * Gets the essential information for debugging + * + * @return string The report for debugging + */ + public static function toDebugReport() + { + $report = 'PHP SDK (OpenAPI\Client) Debug Report:' . PHP_EOL; + $report .= ' OS: ' . php_uname() . PHP_EOL; + $report .= ' PHP Version: ' . PHP_VERSION . PHP_EOL; + $report .= ' OpenAPI Spec Version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r' . PHP_EOL; + $report .= ' Temp Folder Path: ' . self::getDefaultConfiguration()->getTempFolderPath() . PHP_EOL; + + return $report; + } + + /** + * Get API key (with prefix if set) + * + * @param string $apiKeyIdentifier name of apikey + * + * @return string API key with the prefix + */ + public function getApiKeyWithPrefix($apiKeyIdentifier) + { + $prefix = $this->getApiKeyPrefix($apiKeyIdentifier); + $apiKey = $this->getApiKey($apiKeyIdentifier); + + if ($apiKey === null) { + return null; + } + + if ($prefix === null) { + $keyWithPrefix = $apiKey; + } else { + $keyWithPrefix = $prefix . ' ' . $apiKey; + } + + return $keyWithPrefix; + } + + /** + * Returns an array of host settings + * + * @return an array of host settings + */ + public function getHostSettings() + { + return array( + array( + "url" => "//petstore.swagger.io */ ' " =end -- \r\n \n \r/v2 */ ' " =end -- \r\n \n \r", + "description" => "No description provided", + ) + ); + } + + /** + * Returns URL based on the index and variables + * + * @param index array index of the host settings + * @param variables hash of variable and the corresponding value (optional) + * @return URL based on host settings + */ + public function getHostFromSettings($index, $variables = null) + { + if (null === $variables) { + $variables = array(); + } + + $hosts = $this->getHostSettings(); + + // check array index out of bound + if ($index < 0 || $index >= sizeof($hosts)) { + throw new \InvalidArgumentException("Invalid index $index when selecting the host. Must be less than ".sizeof($hosts)); + } + + $host = $hosts[$index]; + $url = $host["url"]; + + // go through variable and assign a value + foreach ($host["variables"] as $name => $variable) { + if (array_key_exists($name, $variables)) { // check to see if it's in the variables provided by the user + if (in_array($variables[$name], $variable["enum_values"])) { // check to see if the value is in the enum + $url = str_replace("{".$name."}", $variables[$name], $url); + } else { + throw new \InvalidArgumentException("The variable `$name` in the host URL has invalid value ".$variables[$name].". Must be ".join(',', $variable["enum_values"])."."); + } + } else { + // use default value + $url = str_replace("{".$name."}", $variable["default_value"], $url); + } + } + + return $url; + } +} diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/HeaderSelector.php b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/HeaderSelector.php new file mode 100644 index 00000000000..d2b74b6489e --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/HeaderSelector.php @@ -0,0 +1,110 @@ +selectAcceptHeader($accept); + if ($accept !== null) { + $headers['Accept'] = $accept; + } + + $headers['Content-Type'] = $this->selectContentTypeHeader($contentTypes); + return $headers; + } + + /** + * @param string[] $accept + * @return array + */ + public function selectHeadersForMultipart($accept) + { + $headers = $this->selectHeaders($accept, []); + + unset($headers['Content-Type']); + return $headers; + } + + /** + * Return the header 'Accept' based on an array of Accept provided + * + * @param string[] $accept Array of header + * + * @return string Accept (e.g. application/json) + */ + private function selectAcceptHeader($accept) + { + if (count($accept) === 0 || (count($accept) === 1 && $accept[0] === '')) { + return null; + } elseif (preg_grep("/application\/json/i", $accept)) { + return 'application/json'; + } else { + return implode(',', $accept); + } + } + + /** + * Return the content type based on an array of content-type provided + * + * @param string[] $contentType Array fo content-type + * + * @return string Content-Type (e.g. application/json) + */ + private function selectContentTypeHeader($contentType) + { + if (count($contentType) === 0 || (count($contentType) === 1 && $contentType[0] === '')) { + return 'application/json'; + } elseif (preg_grep("/application\/json/i", $contentType)) { + return 'application/json'; + } else { + return implode(',', $contentType); + } + } +} + diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/Model/ModelInterface.php b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/Model/ModelInterface.php new file mode 100644 index 00000000000..227a7d0021b --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/Model/ModelInterface.php @@ -0,0 +1,96 @@ + 'int' + ]; + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @var string[] + */ + protected static $openAPIFormats = [ + 'return' => 'int32' + ]; + + /** + * Array of property to type mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPITypes() + { + return self::$openAPITypes; + } + + /** + * Array of property to format mappings. Used for (de)serialization + * + * @return array + */ + public static function openAPIFormats() + { + return self::$openAPIFormats; + } + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @var string[] + */ + protected static $attributeMap = [ + 'return' => 'return' + ]; + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @var string[] + */ + protected static $setters = [ + 'return' => 'setReturn' + ]; + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @var string[] + */ + protected static $getters = [ + 'return' => 'getReturn' + ]; + + /** + * Array of attributes where the key is the local name, + * and the value is the original name + * + * @return array + */ + public static function attributeMap() + { + return self::$attributeMap; + } + + /** + * Array of attributes to setter functions (for deserialization of responses) + * + * @return array + */ + public static function setters() + { + return self::$setters; + } + + /** + * Array of attributes to getter functions (for serialization of requests) + * + * @return array + */ + public static function getters() + { + return self::$getters; + } + + /** + * The original name of the model. + * + * @return string + */ + public function getModelName() + { + return self::$openAPIModelName; + } + + + + + + /** + * Associative array for storing property values + * + * @var mixed[] + */ + protected $container = []; + + /** + * Constructor + * + * @param mixed[] $data Associated array of property values + * initializing the model + */ + public function __construct(array $data = null) + { + $this->container['return'] = isset($data['return']) ? $data['return'] : null; + } + + /** + * Show all the invalid properties with reasons. + * + * @return array invalid properties with reasons + */ + public function listInvalidProperties() + { + $invalidProperties = []; + + return $invalidProperties; + } + + /** + * Validate all the properties in the model + * return true if all passed + * + * @return bool True if all properties are valid + */ + public function valid() + { + return count($this->listInvalidProperties()) === 0; + } + + + /** + * Gets return + * + * @return int|null + */ + public function getReturn() + { + return $this->container['return']; + } + + /** + * Sets return + * + * @param int|null $return property description *_/ ' \" =end -- \\r\\n \\n \\r + * + * @return $this + */ + public function setReturn($return) + { + $this->container['return'] = $return; + + return $this; + } + /** + * Returns true if offset exists. False otherwise. + * + * @param integer $offset Offset + * + * @return boolean + */ + public function offsetExists($offset) + { + return isset($this->container[$offset]); + } + + /** + * Gets offset. + * + * @param integer $offset Offset + * + * @return mixed + */ + public function offsetGet($offset) + { + return isset($this->container[$offset]) ? $this->container[$offset] : null; + } + + /** + * Sets value based on offset. + * + * @param integer $offset Offset + * @param mixed $value Value to be set + * + * @return void + */ + public function offsetSet($offset, $value) + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + /** + * Unsets offset. + * + * @param integer $offset Offset + * + * @return void + */ + public function offsetUnset($offset) + { + unset($this->container[$offset]); + } + + /** + * Gets the string presentation of the object + * + * @return string + */ + public function __toString() + { + return json_encode( + ObjectSerializer::sanitizeForSerialization($this), + JSON_PRETTY_PRINT + ); + } +} + + diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/ObjectSerializer.php b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/ObjectSerializer.php new file mode 100644 index 00000000000..6395ea58aa3 --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/lib/ObjectSerializer.php @@ -0,0 +1,329 @@ +format('Y-m-d') : $data->format(\DateTime::ATOM); + } elseif (is_array($data)) { + foreach ($data as $property => $value) { + $data[$property] = self::sanitizeForSerialization($value); + } + return $data; + } elseif (is_object($data)) { + $values = []; + if ($data instanceof ModelInterface) { + $formats = $data::openAPIFormats(); + foreach ($data::openAPITypes() as $property => $openAPIType) { + $getter = $data::getters()[$property]; + $value = $data->$getter(); + if ($value !== null + && !in_array($openAPIType, ['DateTime', 'bool', 'boolean', 'byte', 'double', 'float', 'int', 'integer', 'mixed', 'number', 'object', 'string', 'void'], true) + && method_exists($openAPIType, 'getAllowableEnumValues') + && !in_array($value, $openAPIType::getAllowableEnumValues(), true)) { + $imploded = implode("', '", $openAPIType::getAllowableEnumValues()); + throw new \InvalidArgumentException("Invalid value for enum '$openAPIType', must be one of: '$imploded'"); + } + if ($value !== null) { + $values[$data::attributeMap()[$property]] = self::sanitizeForSerialization($value, $openAPIType, $formats[$property]); + } + } + } else { + foreach($data as $property => $value) { + $values[$property] = self::sanitizeForSerialization($value); + } + } + return (object)$values; + } else { + return (string)$data; + } + } + + /** + * Sanitize filename by removing path. + * e.g. ../../sun.gif becomes sun.gif + * + * @param string $filename filename to be sanitized + * + * @return string the sanitized filename + */ + public static function sanitizeFilename($filename) + { + if (preg_match("/.*[\/\\\\](.*)$/", $filename, $match)) { + return $match[1]; + } else { + return $filename; + } + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the path, by url-encoding. + * + * @param string $value a string which will be part of the path + * + * @return string the serialized object + */ + public static function toPathValue($value) + { + return rawurlencode(self::toString($value)); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the query, by imploding comma-separated if it's an object. + * If it's a string, pass through unchanged. It will be url-encoded + * later. + * + * @param string[]|string|\DateTime $object an object to be serialized to a string + * + * @return string the serialized object + */ + public static function toQueryValue($object) + { + if (is_array($object)) { + return implode(',', $object); + } else { + return self::toString($object); + } + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the header. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * + * @param string $value a string which will be part of the header + * + * @return string the header string + */ + public static function toHeaderValue($value) + { + return self::toString($value); + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the http body (form parameter). If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * + * @param string|\SplFileObject $value the value of the form parameter + * + * @return string the form string + */ + public static function toFormValue($value) + { + if ($value instanceof \SplFileObject) { + return $value->getRealPath(); + } else { + return self::toString($value); + } + } + + /** + * Take value and turn it into a string suitable for inclusion in + * the parameter. If it's a string, pass through unchanged + * If it's a datetime object, format it in ISO8601 + * + * @param string|\DateTime $value the value of the parameter + * + * @return string the header string + */ + public static function toString($value) + { + if ($value instanceof \DateTime) { // datetime in ISO8601 format + return $value->format(\DateTime::ATOM); + } else { + return $value; + } + } + + /** + * Serialize an array to a string. + * + * @param array $collection collection to serialize to a string + * @param string $collectionFormat the format use for serialization (csv, + * ssv, tsv, pipes, multi) + * @param bool $allowCollectionFormatMulti allow collection format to be a multidimensional array + * + * @return string + */ + public static function serializeCollection(array $collection, $collectionFormat, $allowCollectionFormatMulti = false) + { + if ($allowCollectionFormatMulti && ('multi' === $collectionFormat)) { + // http_build_query() almost does the job for us. We just + // need to fix the result of multidimensional arrays. + return preg_replace('/%5B[0-9]+%5D=/', '=', http_build_query($collection, '', '&')); + } + switch ($collectionFormat) { + case 'pipes': + return implode('|', $collection); + + case 'tsv': + return implode("\t", $collection); + + case 'ssv': + return implode(' ', $collection); + + case 'csv': + // Deliberate fall through. CSV is default format. + default: + return implode(',', $collection); + } + } + + /** + * Deserialize a JSON string into an object + * + * @param mixed $data object or primitive to be deserialized + * @param string $class class name is passed as a string + * @param string[] $httpHeaders HTTP headers + * @param string $discriminator discriminator if polymorphism is used + * + * @return object|array|null a single or an array of $class instances + */ + public static function deserialize($data, $class, $httpHeaders = null) + { + if (null === $data) { + return null; + } elseif (substr($class, 0, 4) === 'map[') { // for associative array e.g. map[string,int] + $data = is_string($data) ? json_decode($data) : $data; + settype($data, 'array'); + $inner = substr($class, 4, -1); + $deserialized = []; + if (strrpos($inner, ",") !== false) { + $subClass_array = explode(',', $inner, 2); + $subClass = $subClass_array[1]; + foreach ($data as $key => $value) { + $deserialized[$key] = self::deserialize($value, $subClass, null); + } + } + return $deserialized; + } elseif (strcasecmp(substr($class, -2), '[]') === 0) { + $data = is_string($data) ? json_decode($data) : $data; + $subClass = substr($class, 0, -2); + $values = []; + foreach ($data as $key => $value) { + $values[] = self::deserialize($value, $subClass, null); + } + return $values; + } elseif ($class === 'object') { + settype($data, 'array'); + return $data; + } elseif ($class === '\DateTime') { + // Some API's return an invalid, empty string as a + // date-time property. DateTime::__construct() will return + // the current time for empty input which is probably not + // what is meant. The invalid empty string is probably to + // be interpreted as a missing field/value. Let's handle + // this graceful. + if (!empty($data)) { + return new \DateTime($data); + } else { + return null; + } + } elseif (in_array($class, ['DateTime', 'bool', 'boolean', 'byte', 'double', 'float', 'int', 'integer', 'mixed', 'number', 'object', 'string', 'void'], true)) { + settype($data, $class); + return $data; + } elseif ($class === '\SplFileObject') { + /** @var \Psr\Http\Message\StreamInterface $data */ + + // determine file name + if (array_key_exists('Content-Disposition', $httpHeaders) && + preg_match('/inline; filename=[\'"]?([^\'"\s]+)[\'"]?$/i', $httpHeaders['Content-Disposition'], $match)) { + $filename = Configuration::getDefaultConfiguration()->getTempFolderPath() . DIRECTORY_SEPARATOR . self::sanitizeFilename($match[1]); + } else { + $filename = tempnam(Configuration::getDefaultConfiguration()->getTempFolderPath(), ''); + } + + $file = fopen($filename, 'w'); + while ($chunk = $data->read(200)) { + fwrite($file, $chunk); + } + fclose($file); + + return new \SplFileObject($filename, 'r'); + } elseif (method_exists($class, 'getAllowableEnumValues')) { + if (!in_array($data, $class::getAllowableEnumValues(), true)) { + $imploded = implode("', '", $class::getAllowableEnumValues()); + throw new \InvalidArgumentException("Invalid value for enum '$class', must be one of: '$imploded'"); + } + return $data; + } else { + $data = is_string($data) ? json_decode($data) : $data; + // If a discriminator is defined and points to a valid subclass, use it. + $discriminator = $class::DISCRIMINATOR; + if (!empty($discriminator) && isset($data->{$discriminator}) && is_string($data->{$discriminator})) { + $subclass = '\OpenAPI\Client\Model\\' . $data->{$discriminator}; + if (is_subclass_of($subclass, $class)) { + $class = $subclass; + } + } + $instance = new $class(); + foreach ($instance::openAPITypes() as $property => $type) { + $propertySetter = $instance::setters()[$property]; + + if (!isset($propertySetter) || !isset($data->{$instance::attributeMap()[$property]})) { + continue; + } + + $propertyValue = $data->{$instance::attributeMap()[$property]}; + if (isset($propertyValue)) { + $instance->$propertySetter(self::deserialize($propertyValue, $type, null)); + } + } + return $instance; + } + } +} diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/phpunit.xml.dist b/samples/client/petstore-security-test/php/OpenAPIClient-php/phpunit.xml.dist new file mode 100644 index 00000000000..08f78faf3bb --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/phpunit.xml.dist @@ -0,0 +1,21 @@ + + + + + ./test/Api + ./test/Model + + + + + + ./lib/Api + ./lib/Model + + + diff --git a/samples/client/petstore-security-test/php/OpenAPIClient-php/test/Api/FakeApiTest.php b/samples/client/petstore-security-test/php/OpenAPIClient-php/test/Api/FakeApiTest.php new file mode 100644 index 00000000000..114ab2da080 --- /dev/null +++ b/samples/client/petstore-security-test/php/OpenAPIClient-php/test/Api/FakeApiTest.php @@ -0,0 +1,84 @@ +test_code_inject____end__rn_n_r: %s\n" % e) + +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io */ ' \" =end -- \\r\\n \\n \\r/v2 */ ' \" =end -- \\r\\n \\n \\r* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*FakeApi* | [**test_code_inject____end__rn_n_r**](docs/FakeApi.md#test_code_inject____end__rn_n_r) | **PUT** /fake | To test code injection */ ' \" =end -- \\r\\n \\n \\r + + +## Documentation For Models + + - [ModelReturn](docs/ModelReturn.md) + + +## Documentation For Authorization + + +## api_key + +- **Type**: API key +- **API key parameter name**: api_key */ ' " =end -- \r\n \n \r +- **Location**: HTTP header + + +## petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - **write:pets**: modify pets in your account */ ' \" =end -- \\r\\n \\n \\r + - **read:pets**: read your pets */ ' \" =end -- \\r\\n \\n \\r + + +## Author + +something@something.abc */ ' \" =end -- \\r\\n \\n \\r + + diff --git a/samples/client/petstore-security-test/python/docs/FakeApi.md b/samples/client/petstore-security-test/python/docs/FakeApi.md new file mode 100644 index 00000000000..42a1ec12307 --- /dev/null +++ b/samples/client/petstore-security-test/python/docs/FakeApi.md @@ -0,0 +1,57 @@ +# petstore_api.FakeApi + +All URIs are relative to *http://petstore.swagger.io */ ' \" =end -- \\r\\n \\n \\r/v2 */ ' \" =end -- \\r\\n \\n \\r* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**test_code_inject____end__rn_n_r**](FakeApi.md#test_code_inject____end__rn_n_r) | **PUT** /fake | To test code injection */ ' \" =end -- \\r\\n \\n \\r + + +# **test_code_inject____end__rn_n_r** +> test_code_inject____end__rn_n_r(test_code_inject____end____rn_n_r=test_code_inject____end____rn_n_r) + +To test code injection */ ' \" =end -- \\r\\n \\n \\r + +To test code injection */ ' \" =end -- \\r\\n \\n \\r + +### Example + +```python +from __future__ import print_function +import time +import petstore_api +from petstore_api.rest import ApiException +from pprint import pprint + +# create an instance of the API class +api_instance = petstore_api.FakeApi() +test_code_inject____end____rn_n_r = 'test_code_inject____end____rn_n_r_example' # str | To test code injection */ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + +try: + # To test code injection */ ' \" =end -- \\r\\n \\n \\r + api_instance.test_code_inject____end__rn_n_r(test_code_inject____end____rn_n_r=test_code_inject____end____rn_n_r) +except ApiException as e: + print("Exception when calling FakeApi->test_code_inject____end__rn_n_r: %s\n" % e) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **test_code_inject____end____rn_n_r** | **str**| To test code injection */ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r | [optional] + +### Return type + +void (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded, */ \" =end -- + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/client/petstore-security-test/python/docs/ModelReturn.md b/samples/client/petstore-security-test/python/docs/ModelReturn.md new file mode 100644 index 00000000000..ad498239b57 --- /dev/null +++ b/samples/client/petstore-security-test/python/docs/ModelReturn.md @@ -0,0 +1,10 @@ +# ModelReturn + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**_return** | **int** | property description */ ' \" =end -- \\r\\n \\n \\r | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/client/petstore-security-test/python/git_push.sh b/samples/client/petstore-security-test/python/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/python/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/python/petstore_api/__init__.py b/samples/client/petstore-security-test/python/petstore_api/__init__.py new file mode 100644 index 00000000000..93e0a9fa9dc --- /dev/null +++ b/samples/client/petstore-security-test/python/petstore_api/__init__.py @@ -0,0 +1,27 @@ +# coding: utf-8 + +# flake8: noqa + +""" + OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =end -- # noqa: E501 + + OpenAPI spec version: 1.0.0 */ ' \" =end -- \\r\\n \\n \\r + Contact: something@something.abc */ ' \" =end -- \\r\\n \\n \\r + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import + +__version__ = "1.0.0" + +# import apis into sdk package +from petstore_api.api.fake_api import FakeApi + +# import ApiClient +from petstore_api.api_client import ApiClient +from petstore_api.configuration import Configuration +# import models into sdk package +from petstore_api.models.model_return import ModelReturn diff --git a/samples/client/petstore-security-test/python/petstore_api/api/__init__.py b/samples/client/petstore-security-test/python/petstore_api/api/__init__.py new file mode 100644 index 00000000000..a2a6f73f45c --- /dev/null +++ b/samples/client/petstore-security-test/python/petstore_api/api/__init__.py @@ -0,0 +1,6 @@ +from __future__ import absolute_import + +# flake8: noqa + +# import apis into api package +from petstore_api.api.fake_api import FakeApi diff --git a/samples/client/petstore-security-test/python/petstore_api/api/fake_api.py b/samples/client/petstore-security-test/python/petstore_api/api/fake_api.py new file mode 100644 index 00000000000..24a1c4fe1b9 --- /dev/null +++ b/samples/client/petstore-security-test/python/petstore_api/api/fake_api.py @@ -0,0 +1,126 @@ +# coding: utf-8 + +""" + OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =end -- # noqa: E501 + + OpenAPI spec version: 1.0.0 */ ' \" =end -- \\r\\n \\n \\r + Contact: something@something.abc */ ' \" =end -- \\r\\n \\n \\r + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import + +import re # noqa: F401 + +# python 2 and python 3 compatibility library +import six + +from petstore_api.api_client import ApiClient + + +class FakeApi(object): + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None): + if api_client is None: + api_client = ApiClient() + self.api_client = api_client + + def test_code_inject____end__rn_n_r(self, **kwargs): # noqa: E501 + """To test code injection */ ' \" =end -- \\r\\n \\n \\r # noqa: E501 + + To test code injection */ ' \" =end -- \\r\\n \\n \\r # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.test_code_inject____end__rn_n_r(async_req=True) + >>> result = thread.get() + + :param async_req bool + :param str test_code_inject____end____rn_n_r: To test code injection */ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r + :return: None + If the method is called asynchronously, + returns the request thread. + """ + kwargs['_return_http_data_only'] = True + if kwargs.get('async_req'): + return self.test_code_inject____end__rn_n_r_with_http_info(**kwargs) # noqa: E501 + else: + (data) = self.test_code_inject____end__rn_n_r_with_http_info(**kwargs) # noqa: E501 + return data + + def test_code_inject____end__rn_n_r_with_http_info(self, **kwargs): # noqa: E501 + """To test code injection */ ' \" =end -- \\r\\n \\n \\r # noqa: E501 + + To test code injection */ ' \" =end -- \\r\\n \\n \\r # noqa: E501 + This method makes a synchronous HTTP request by default. To make an + asynchronous HTTP request, please pass async_req=True + >>> thread = api.test_code_inject____end__rn_n_r_with_http_info(async_req=True) + >>> result = thread.get() + + :param async_req bool + :param str test_code_inject____end____rn_n_r: To test code injection */ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r + :return: None + If the method is called asynchronously, + returns the request thread. + """ + + local_var_params = locals() + + all_params = ['test_code_inject____end____rn_n_r'] # noqa: E501 + all_params.append('async_req') + all_params.append('_return_http_data_only') + all_params.append('_preload_content') + all_params.append('_request_timeout') + + for key, val in six.iteritems(local_var_params['kwargs']): + if key not in all_params: + raise TypeError( + "Got an unexpected keyword argument '%s'" + " to method test_code_inject____end__rn_n_r" % key + ) + local_var_params[key] = val + del local_var_params['kwargs'] + + collection_formats = {} + + path_params = {} + + query_params = [] + + header_params = {} + + form_params = [] + local_var_files = {} + if 'test_code_inject____end____rn_n_r' in local_var_params: + form_params.append(('test code inject */ ' " =end -- \r\n \n \r', local_var_params['test_code_inject____end____rn_n_r'])) # noqa: E501 + + body_params = None + # HTTP header `Content-Type` + header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501 + ['application/x-www-form-urlencoded', '*/ \" =end -- ']) # noqa: E501 + + # Authentication setting + auth_settings = [] # noqa: E501 + + return self.api_client.call_api( + '/fake', 'PUT', + path_params, + query_params, + header_params, + body=body_params, + post_params=form_params, + files=local_var_files, + response_type=None, # noqa: E501 + auth_settings=auth_settings, + async_req=local_var_params.get('async_req'), + _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501 + _preload_content=local_var_params.get('_preload_content', True), + _request_timeout=local_var_params.get('_request_timeout'), + collection_formats=collection_formats) diff --git a/samples/client/petstore-security-test/python/petstore_api/api_client.py b/samples/client/petstore-security-test/python/petstore_api/api_client.py new file mode 100644 index 00000000000..149de58cf16 --- /dev/null +++ b/samples/client/petstore-security-test/python/petstore_api/api_client.py @@ -0,0 +1,643 @@ +# coding: utf-8 +""" + OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =end -- # noqa: E501 + + OpenAPI spec version: 1.0.0 */ ' \" =end -- \\r\\n \\n \\r + Contact: something@something.abc */ ' \" =end -- \\r\\n \\n \\r + Generated by: https://openapi-generator.tech +""" + +from __future__ import absolute_import + +import datetime +import json +import mimetypes +from multiprocessing.pool import ThreadPool +import os +import re +import tempfile + +# python 2 and python 3 compatibility library +import six +from six.moves.urllib.parse import quote + +from petstore_api.configuration import Configuration +import petstore_api.models +from petstore_api import rest + + +class ApiClient(object): + """Generic API client for OpenAPI client library builds. + + OpenAPI generic API client. This client handles the client- + server communication, and is invariant across implementations. Specifics of + the methods and models for each application are generated from the OpenAPI + templates. + + NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + Do not edit the class manually. + + :param configuration: .Configuration object for this client + :param header_name: a header to pass when making calls to the API. + :param header_value: a header value to pass when making calls to + the API. + :param cookie: a cookie to include in the header when making calls + to the API + :param pool_threads: The number of threads to use for async requests + to the API. More threads means more concurrent API requests. + """ + + PRIMITIVE_TYPES = (float, bool, bytes, six.text_type) + six.integer_types + NATIVE_TYPES_MAPPING = { + 'int': int, + 'long': int if six.PY3 else long, # noqa: F821 + 'float': float, + 'str': str, + 'bool': bool, + 'date': datetime.date, + 'datetime': datetime.datetime, + 'object': object, + } + _pool = None + + def __init__(self, configuration=None, header_name=None, header_value=None, + cookie=None, pool_threads=1): + if configuration is None: + configuration = Configuration() + self.configuration = configuration + self.pool_threads = pool_threads + + self.rest_client = rest.RESTClientObject(configuration) + self.default_headers = {} + if header_name is not None: + self.default_headers[header_name] = header_value + self.cookie = cookie + # Set default User-Agent. + self.user_agent = 'OpenAPI-Generator/1.0.0/python' + + def __del__(self): + if self._pool: + self._pool.close() + self._pool.join() + self._pool = None + + @property + def pool(self): + """Create thread pool on first request + avoids instantiating unused threadpool for blocking clients. + """ + if self._pool is None: + self._pool = ThreadPool(self.pool_threads) + return self._pool + + @property + def user_agent(self): + """User agent for this API client""" + return self.default_headers['User-Agent'] + + @user_agent.setter + def user_agent(self, value): + self.default_headers['User-Agent'] = value + + def set_default_header(self, header_name, header_value): + self.default_headers[header_name] = header_value + + def __call_api( + self, resource_path, method, path_params=None, + query_params=None, header_params=None, body=None, post_params=None, + files=None, response_type=None, auth_settings=None, + _return_http_data_only=None, collection_formats=None, + _preload_content=True, _request_timeout=None, _host=None): + + config = self.configuration + + # header parameters + header_params = header_params or {} + header_params.update(self.default_headers) + if self.cookie: + header_params['Cookie'] = self.cookie + if header_params: + header_params = self.sanitize_for_serialization(header_params) + header_params = dict(self.parameters_to_tuples(header_params, + collection_formats)) + + # path parameters + if path_params: + path_params = self.sanitize_for_serialization(path_params) + path_params = self.parameters_to_tuples(path_params, + collection_formats) + for k, v in path_params: + # specified safe chars, encode everything + resource_path = resource_path.replace( + '{%s}' % k, + quote(str(v), safe=config.safe_chars_for_path_param) + ) + + # query parameters + if query_params: + query_params = self.sanitize_for_serialization(query_params) + query_params = self.parameters_to_tuples(query_params, + collection_formats) + + # post parameters + if post_params or files: + post_params = self.prepare_post_parameters(post_params, files) + post_params = self.sanitize_for_serialization(post_params) + post_params = self.parameters_to_tuples(post_params, + collection_formats) + + # auth setting + self.update_params_for_auth(header_params, query_params, auth_settings) + + # body + if body: + body = self.sanitize_for_serialization(body) + + # request url + if _host is None: + url = self.configuration.host + resource_path + else: + # use server/host defined in path or operation instead + url = _host + resource_path + + # perform request and return response + response_data = self.request( + method, url, query_params=query_params, headers=header_params, + post_params=post_params, body=body, + _preload_content=_preload_content, + _request_timeout=_request_timeout) + + self.last_response = response_data + + return_data = response_data + if _preload_content: + # deserialize response data + if response_type: + return_data = self.deserialize(response_data, response_type) + else: + return_data = None + + if _return_http_data_only: + return (return_data) + else: + return (return_data, response_data.status, + response_data.getheaders()) + + def sanitize_for_serialization(self, obj): + """Builds a JSON POST object. + + If obj is None, return None. + If obj is str, int, long, float, bool, return directly. + If obj is datetime.datetime, datetime.date + convert to string in iso8601 format. + If obj is list, sanitize each element in the list. + If obj is dict, return the dict. + If obj is OpenAPI model, return the properties dict. + + :param obj: The data to serialize. + :return: The serialized form of data. + """ + if obj is None: + return None + elif isinstance(obj, self.PRIMITIVE_TYPES): + return obj + elif isinstance(obj, list): + return [self.sanitize_for_serialization(sub_obj) + for sub_obj in obj] + elif isinstance(obj, tuple): + return tuple(self.sanitize_for_serialization(sub_obj) + for sub_obj in obj) + elif isinstance(obj, (datetime.datetime, datetime.date)): + return obj.isoformat() + + if isinstance(obj, dict): + obj_dict = obj + else: + # Convert model obj to dict except + # attributes `openapi_types`, `attribute_map` + # and attributes which value is not None. + # Convert attribute name to json key in + # model definition for request. + obj_dict = {obj.attribute_map[attr]: getattr(obj, attr) + for attr, _ in six.iteritems(obj.openapi_types) + if getattr(obj, attr) is not None} + + return {key: self.sanitize_for_serialization(val) + for key, val in six.iteritems(obj_dict)} + + def deserialize(self, response, response_type): + """Deserializes response into an object. + + :param response: RESTResponse object to be deserialized. + :param response_type: class literal for + deserialized object, or string of class name. + + :return: deserialized object. + """ + # handle file downloading + # save response body into a tmp file and return the instance + if response_type == "file": + return self.__deserialize_file(response) + + # fetch data from response object + try: + data = json.loads(response.data) + except ValueError: + data = response.data + + return self.__deserialize(data, response_type) + + def __deserialize(self, data, klass): + """Deserializes dict, list, str into an object. + + :param data: dict, list or str. + :param klass: class literal, or string of class name. + + :return: object. + """ + if data is None: + return None + + if type(klass) == str: + if klass.startswith('list['): + sub_kls = re.match(r'list\[(.*)\]', klass).group(1) + return [self.__deserialize(sub_data, sub_kls) + for sub_data in data] + + if klass.startswith('dict('): + sub_kls = re.match(r'dict\(([^,]*), (.*)\)', klass).group(2) + return {k: self.__deserialize(v, sub_kls) + for k, v in six.iteritems(data)} + + # convert str to class + if klass in self.NATIVE_TYPES_MAPPING: + klass = self.NATIVE_TYPES_MAPPING[klass] + else: + klass = getattr(petstore_api.models, klass) + + if klass in self.PRIMITIVE_TYPES: + return self.__deserialize_primitive(data, klass) + elif klass == object: + return self.__deserialize_object(data) + elif klass == datetime.date: + return self.__deserialize_date(data) + elif klass == datetime.datetime: + return self.__deserialize_datatime(data) + else: + return self.__deserialize_model(data, klass) + + def call_api(self, resource_path, method, + path_params=None, query_params=None, header_params=None, + body=None, post_params=None, files=None, + response_type=None, auth_settings=None, async_req=None, + _return_http_data_only=None, collection_formats=None, + _preload_content=True, _request_timeout=None, _host=None): + """Makes the HTTP request (synchronous) and returns deserialized data. + + To make an async_req request, set the async_req parameter. + + :param resource_path: Path to method endpoint. + :param method: Method to call. + :param path_params: Path parameters in the url. + :param query_params: Query parameters in the url. + :param header_params: Header parameters to be + placed in the request header. + :param body: Request body. + :param post_params dict: Request post form parameters, + for `application/x-www-form-urlencoded`, `multipart/form-data`. + :param auth_settings list: Auth Settings names for the request. + :param response: Response data type. + :param files dict: key -> filename, value -> filepath, + for `multipart/form-data`. + :param async_req bool: execute request asynchronously + :param _return_http_data_only: response data without head status code + and headers + :param collection_formats: dict of collection formats for path, query, + header, and post parameters. + :param _preload_content: if False, the urllib3.HTTPResponse object will + be returned without reading/decoding response + data. Default is True. + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :return: + If async_req parameter is True, + the request will be called asynchronously. + The method will return the request thread. + If parameter async_req is False or missing, + then the method will return the response directly. + """ + if not async_req: + return self.__call_api(resource_path, method, + path_params, query_params, header_params, + body, post_params, files, + response_type, auth_settings, + _return_http_data_only, collection_formats, + _preload_content, _request_timeout, _host) + else: + thread = self.pool.apply_async(self.__call_api, (resource_path, + method, path_params, query_params, + header_params, body, + post_params, files, + response_type, auth_settings, + _return_http_data_only, + collection_formats, + _preload_content, + _request_timeout, + _host)) + return thread + + def request(self, method, url, query_params=None, headers=None, + post_params=None, body=None, _preload_content=True, + _request_timeout=None): + """Makes the HTTP request using RESTClient.""" + if method == "GET": + return self.rest_client.GET(url, + query_params=query_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + headers=headers) + elif method == "HEAD": + return self.rest_client.HEAD(url, + query_params=query_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + headers=headers) + elif method == "OPTIONS": + return self.rest_client.OPTIONS(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "POST": + return self.rest_client.POST(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "PUT": + return self.rest_client.PUT(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "PATCH": + return self.rest_client.PATCH(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "DELETE": + return self.rest_client.DELETE(url, + query_params=query_params, + headers=headers, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + else: + raise ValueError( + "http method must be `GET`, `HEAD`, `OPTIONS`," + " `POST`, `PATCH`, `PUT` or `DELETE`." + ) + + def parameters_to_tuples(self, params, collection_formats): + """Get parameters as list of tuples, formatting collections. + + :param params: Parameters as dict or list of two-tuples + :param dict collection_formats: Parameter collection formats + :return: Parameters as list of tuples, collections formatted + """ + new_params = [] + if collection_formats is None: + collection_formats = {} + for k, v in six.iteritems(params) if isinstance(params, dict) else params: # noqa: E501 + if k in collection_formats: + collection_format = collection_formats[k] + if collection_format == 'multi': + new_params.extend((k, value) for value in v) + else: + if collection_format == 'ssv': + delimiter = ' ' + elif collection_format == 'tsv': + delimiter = '\t' + elif collection_format == 'pipes': + delimiter = '|' + else: # csv is the default + delimiter = ',' + new_params.append( + (k, delimiter.join(str(value) for value in v))) + else: + new_params.append((k, v)) + return new_params + + def prepare_post_parameters(self, post_params=None, files=None): + """Builds form parameters. + + :param post_params: Normal form parameters. + :param files: File parameters. + :return: Form parameters with files. + """ + params = [] + + if post_params: + params = post_params + + if files: + for k, v in six.iteritems(files): + if not v: + continue + file_names = v if type(v) is list else [v] + for n in file_names: + with open(n, 'rb') as f: + filename = os.path.basename(f.name) + filedata = f.read() + mimetype = (mimetypes.guess_type(filename)[0] or + 'application/octet-stream') + params.append( + tuple([k, tuple([filename, filedata, mimetype])])) + + return params + + def select_header_accept(self, accepts): + """Returns `Accept` based on an array of accepts provided. + + :param accepts: List of headers. + :return: Accept (e.g. application/json). + """ + if not accepts: + return + + accepts = [x.lower() for x in accepts] + + if 'application/json' in accepts: + return 'application/json' + else: + return ', '.join(accepts) + + def select_header_content_type(self, content_types): + """Returns `Content-Type` based on an array of content_types provided. + + :param content_types: List of content-types. + :return: Content-Type (e.g. application/json). + """ + if not content_types: + return 'application/json' + + content_types = [x.lower() for x in content_types] + + if 'application/json' in content_types or '*/*' in content_types: + return 'application/json' + else: + return content_types[0] + + def update_params_for_auth(self, headers, querys, auth_settings): + """Updates header and query params based on authentication setting. + + :param headers: Header parameters dict to be updated. + :param querys: Query parameters tuple list to be updated. + :param auth_settings: Authentication setting identifiers list. + """ + if not auth_settings: + return + + for auth in auth_settings: + auth_setting = self.configuration.auth_settings().get(auth) + if auth_setting: + if not auth_setting['value']: + continue + elif auth_setting['in'] == 'cookie': + headers['Cookie'] = auth_setting['value'] + elif auth_setting['in'] == 'header': + headers[auth_setting['key']] = auth_setting['value'] + elif auth_setting['in'] == 'query': + querys.append((auth_setting['key'], auth_setting['value'])) + else: + raise ValueError( + 'Authentication token must be in `query` or `header`' + ) + + def __deserialize_file(self, response): + """Deserializes body to file + + Saves response body into a file in a temporary folder, + using the filename from the `Content-Disposition` header if provided. + + :param response: RESTResponse. + :return: file path. + """ + fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path) + os.close(fd) + os.remove(path) + + content_disposition = response.getheader("Content-Disposition") + if content_disposition: + filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', + content_disposition).group(1) + path = os.path.join(os.path.dirname(path), filename) + + with open(path, "wb") as f: + f.write(response.data) + + return path + + def __deserialize_primitive(self, data, klass): + """Deserializes string to primitive type. + + :param data: str. + :param klass: class literal. + + :return: int, long, float, str, bool. + """ + try: + return klass(data) + except UnicodeEncodeError: + return six.text_type(data) + except TypeError: + return data + + def __deserialize_object(self, value): + """Return an original value. + + :return: object. + """ + return value + + def __deserialize_date(self, string): + """Deserializes string to date. + + :param string: str. + :return: date. + """ + try: + from dateutil.parser import parse + return parse(string).date() + except ImportError: + return string + except ValueError: + raise rest.ApiException( + status=0, + reason="Failed to parse `{0}` as date object".format(string) + ) + + def __deserialize_datatime(self, string): + """Deserializes string to datetime. + + The string should be in iso8601 datetime format. + + :param string: str. + :return: datetime. + """ + try: + from dateutil.parser import parse + return parse(string) + except ImportError: + return string + except ValueError: + raise rest.ApiException( + status=0, + reason=( + "Failed to parse `{0}` as datetime object" + .format(string) + ) + ) + + def __deserialize_model(self, data, klass): + """Deserializes list or dict to model. + + :param data: dict, list. + :param klass: class literal. + :return: model object. + """ + + if not klass.openapi_types and not hasattr(klass, + 'get_real_child_model'): + return data + + kwargs = {} + if klass.openapi_types is not None: + for attr, attr_type in six.iteritems(klass.openapi_types): + if (data is not None and + klass.attribute_map[attr] in data and + isinstance(data, (list, dict))): + value = data[klass.attribute_map[attr]] + kwargs[attr] = self.__deserialize(value, attr_type) + + instance = klass(**kwargs) + + if hasattr(instance, 'get_real_child_model'): + klass_name = instance.get_real_child_model(data) + if klass_name: + instance = self.__deserialize(data, klass_name) + return instance diff --git a/samples/client/petstore-security-test/python/petstore_api/configuration.py b/samples/client/petstore-security-test/python/petstore_api/configuration.py new file mode 100644 index 00000000000..b7ae97b238d --- /dev/null +++ b/samples/client/petstore-security-test/python/petstore_api/configuration.py @@ -0,0 +1,294 @@ +# coding: utf-8 + +""" + OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =end -- # noqa: E501 + + OpenAPI spec version: 1.0.0 */ ' \" =end -- \\r\\n \\n \\r + Contact: something@something.abc */ ' \" =end -- \\r\\n \\n \\r + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import + +import copy +import logging +import multiprocessing +import sys +import urllib3 + +import six +from six.moves import http_client as httplib + + +class TypeWithDefault(type): + def __init__(cls, name, bases, dct): + super(TypeWithDefault, cls).__init__(name, bases, dct) + cls._default = None + + def __call__(cls): + if cls._default is None: + cls._default = type.__call__(cls) + return copy.copy(cls._default) + + def set_default(cls, default): + cls._default = copy.copy(default) + + +class Configuration(six.with_metaclass(TypeWithDefault, object)): + """NOTE: This class is auto generated by OpenAPI Generator + + Ref: https://openapi-generator.tech + Do not edit the class manually. + """ + + def __init__(self): + """Constructor""" + # Default Base url + self.host = "http://petstore.swagger.io */ ' \" =end -- \\r\\n \\n \\r/v2 */ ' \" =end -- \\r\\n \\n \\r" + # Temp file folder for downloading files + self.temp_folder_path = None + + # Authentication Settings + # dict to store API key(s) + self.api_key = {} + # dict to store API prefix (e.g. Bearer) + self.api_key_prefix = {} + # Username for HTTP basic authentication + self.username = "" + # Password for HTTP basic authentication + self.password = "" + # access token for OAuth/Bearer + self.access_token = "" + # Logging Settings + self.logger = {} + self.logger["package_logger"] = logging.getLogger("petstore_api") + self.logger["urllib3_logger"] = logging.getLogger("urllib3") + # Log format + self.logger_format = '%(asctime)s %(levelname)s %(message)s' + # Log stream handler + self.logger_stream_handler = None + # Log file handler + self.logger_file_handler = None + # Debug file location + self.logger_file = None + # Debug switch + self.debug = False + + # SSL/TLS verification + # Set this to false to skip verifying SSL certificate when calling API + # from https server. + self.verify_ssl = True + # Set this to customize the certificate file to verify the peer. + self.ssl_ca_cert = None + # client certificate file + self.cert_file = None + # client key file + self.key_file = None + # Set this to True/False to enable/disable SSL hostname verification. + self.assert_hostname = None + + # urllib3 connection pool's maximum number of connections saved + # per pool. urllib3 uses 1 connection as default value, but this is + # not the best value when you are making a lot of possibly parallel + # requests to the same host, which is often the case here. + # cpu_count * 5 is used as default value to increase performance. + self.connection_pool_maxsize = multiprocessing.cpu_count() * 5 + + # Proxy URL + self.proxy = None + # Safe chars for path_param + self.safe_chars_for_path_param = '' + + @property + def logger_file(self): + """The logger file. + + If the logger_file is None, then add stream handler and remove file + handler. Otherwise, add file handler and remove stream handler. + + :param value: The logger_file path. + :type: str + """ + return self.__logger_file + + @logger_file.setter + def logger_file(self, value): + """The logger file. + + If the logger_file is None, then add stream handler and remove file + handler. Otherwise, add file handler and remove stream handler. + + :param value: The logger_file path. + :type: str + """ + self.__logger_file = value + if self.__logger_file: + # If set logging file, + # then add file handler and remove stream handler. + self.logger_file_handler = logging.FileHandler(self.__logger_file) + self.logger_file_handler.setFormatter(self.logger_formatter) + for _, logger in six.iteritems(self.logger): + logger.addHandler(self.logger_file_handler) + + @property + def debug(self): + """Debug status + + :param value: The debug status, True or False. + :type: bool + """ + return self.__debug + + @debug.setter + def debug(self, value): + """Debug status + + :param value: The debug status, True or False. + :type: bool + """ + self.__debug = value + if self.__debug: + # if debug status is True, turn on debug logging + for _, logger in six.iteritems(self.logger): + logger.setLevel(logging.DEBUG) + # turn on httplib debug + httplib.HTTPConnection.debuglevel = 1 + else: + # if debug status is False, turn off debug logging, + # setting log level to default `logging.WARNING` + for _, logger in six.iteritems(self.logger): + logger.setLevel(logging.WARNING) + # turn off httplib debug + httplib.HTTPConnection.debuglevel = 0 + + @property + def logger_format(self): + """The logger format. + + The logger_formatter will be updated when sets logger_format. + + :param value: The format string. + :type: str + """ + return self.__logger_format + + @logger_format.setter + def logger_format(self, value): + """The logger format. + + The logger_formatter will be updated when sets logger_format. + + :param value: The format string. + :type: str + """ + self.__logger_format = value + self.logger_formatter = logging.Formatter(self.__logger_format) + + def get_api_key_with_prefix(self, identifier): + """Gets API key (with prefix if set). + + :param identifier: The identifier of apiKey. + :return: The token for api key authentication. + """ + if (self.api_key.get(identifier) and + self.api_key_prefix.get(identifier)): + return self.api_key_prefix[identifier] + ' ' + self.api_key[identifier] # noqa: E501 + elif self.api_key.get(identifier): + return self.api_key[identifier] + + def get_basic_auth_token(self): + """Gets HTTP basic authentication header (string). + + :return: The token for basic HTTP authentication. + """ + return urllib3.util.make_headers( + basic_auth=self.username + ':' + self.password + ).get('authorization') + + def auth_settings(self): + """Gets Auth Settings dict for api client. + + :return: The Auth Settings information dict. + """ + return { + 'api_key': + { + 'type': 'api_key', + 'in': 'header', + 'key': 'api_key */ ' " =end -- \r\n \n \r', + 'value': self.get_api_key_with_prefix('api_key */ ' " =end -- \r\n \n \r') + }, + 'petstore_auth': + { + 'type': 'oauth2', + 'in': 'header', + 'key': 'Authorization', + 'value': 'Bearer ' + self.access_token + }, + } + + def to_debug_report(self): + """Gets the essential information for debugging. + + :return: The report for debugging. + """ + return "Python SDK Debug Report:\n"\ + "OS: {env}\n"\ + "Python Version: {pyversion}\n"\ + "Version of the API: 1.0.0 */ ' \" =end -- \\r\\n \\n \\r\n"\ + "SDK Package Version: 1.0.0".\ + format(env=sys.platform, pyversion=sys.version) + + def get_host_settings(self): + """Gets an array of host settings + + :return: An array of host settings + """ + return [ + { + 'url': "//petstore.swagger.io */ ' " =end -- \r\n \n \r/v2 */ ' " =end -- \r\n \n \r", + 'description': "No description provided", + } + ] + + def get_host_from_settings(self, index, variables={}): + """Gets host URL based on the index and variables + :param index: array index of the host settings + :param variables: hash of variable and the corresponding value + :return: URL based on host settings + """ + + servers = self.get_host_settings() + + # check array index out of bound + if index < 0 or index >= len(servers): + raise ValueError( + "Invalid index {} when selecting the host settings. Must be less than {}" # noqa: E501 + .format(index, len(servers))) + + server = servers[index] + url = server['url'] + + # go through variable and assign a value + for variable_name in server['variables']: + if variable_name in variables: + if variables[variable_name] in server['variables'][ + variable_name]['enum_values']: + url = url.replace("{" + variable_name + "}", + variables[variable_name]) + else: + raise ValueError( + "The variable `{}` in the host URL has invalid value {}. Must be {}." # noqa: E501 + .format( + variable_name, variables[variable_name], + server['variables'][variable_name]['enum_values'])) + else: + # use default value + url = url.replace( + "{" + variable_name + "}", + server['variables'][variable_name]['default_value']) + + return url diff --git a/samples/client/petstore-security-test/python/petstore_api/models/__init__.py b/samples/client/petstore-security-test/python/petstore_api/models/__init__.py new file mode 100644 index 00000000000..df7e03398fd --- /dev/null +++ b/samples/client/petstore-security-test/python/petstore_api/models/__init__.py @@ -0,0 +1,18 @@ +# coding: utf-8 + +# flake8: noqa +""" + OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =end -- # noqa: E501 + + OpenAPI spec version: 1.0.0 */ ' \" =end -- \\r\\n \\n \\r + Contact: something@something.abc */ ' \" =end -- \\r\\n \\n \\r + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import + +# import models into model package +from petstore_api.models.model_return import ModelReturn diff --git a/samples/client/petstore-security-test/python/petstore_api/models/model_return.py b/samples/client/petstore-security-test/python/petstore_api/models/model_return.py new file mode 100644 index 00000000000..c3d94ad9eab --- /dev/null +++ b/samples/client/petstore-security-test/python/petstore_api/models/model_return.py @@ -0,0 +1,115 @@ +# coding: utf-8 + +""" + OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =end -- # noqa: E501 + + OpenAPI spec version: 1.0.0 */ ' \" =end -- \\r\\n \\n \\r + Contact: something@something.abc */ ' \" =end -- \\r\\n \\n \\r + Generated by: https://openapi-generator.tech +""" + + +import pprint +import re # noqa: F401 + +import six + + +class ModelReturn(object): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + """ + Attributes: + openapi_types (dict): The key is attribute name + and the value is attribute type. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + """ + openapi_types = { + '_return': 'int' + } + + attribute_map = { + '_return': 'return' + } + + def __init__(self, _return=None): # noqa: E501 + """ModelReturn - a model defined in OpenAPI""" # noqa: E501 + + self.__return = None + self.discriminator = None + + if _return is not None: + self._return = _return + + @property + def _return(self): + """Gets the _return of this ModelReturn. # noqa: E501 + + property description */ ' \" =end -- \\r\\n \\n \\r # noqa: E501 + + :return: The _return of this ModelReturn. # noqa: E501 + :rtype: int + """ + return self.__return + + @_return.setter + def _return(self, _return): + """Sets the _return of this ModelReturn. + + property description */ ' \" =end -- \\r\\n \\n \\r # noqa: E501 + + :param _return: The _return of this ModelReturn. # noqa: E501 + :type: int + """ + + self.__return = _return + + def to_dict(self): + """Returns the model properties as a dict""" + result = {} + + for attr, _ in six.iteritems(self.openapi_types): + value = getattr(self, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: x.to_dict() if hasattr(x, "to_dict") else x, + value + )) + elif hasattr(value, "to_dict"): + result[attr] = value.to_dict() + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], item[1].to_dict()) + if hasattr(item[1], "to_dict") else item, + value.items() + )) + else: + result[attr] = value + + return result + + def to_str(self): + """Returns the string representation of the model""" + return pprint.pformat(self.to_dict()) + + def __repr__(self): + """For `print` and `pprint`""" + return self.to_str() + + def __eq__(self, other): + """Returns true if both objects are equal""" + if not isinstance(other, ModelReturn): + return False + + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + """Returns true if both objects are not equal""" + return not self == other diff --git a/samples/client/petstore-security-test/python/petstore_api/rest.py b/samples/client/petstore-security-test/python/petstore_api/rest.py new file mode 100644 index 00000000000..de5fe57f5b8 --- /dev/null +++ b/samples/client/petstore-security-test/python/petstore_api/rest.py @@ -0,0 +1,323 @@ +# coding: utf-8 + +""" + OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =end -- # noqa: E501 + + OpenAPI spec version: 1.0.0 */ ' \" =end -- \\r\\n \\n \\r + Contact: something@something.abc */ ' \" =end -- \\r\\n \\n \\r + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import + +import io +import json +import logging +import re +import ssl + +import certifi +# python 2 and python 3 compatibility library +import six +from six.moves.urllib.parse import urlencode + +try: + import urllib3 +except ImportError: + raise ImportError('OpenAPI Python client requires urllib3.') + + +logger = logging.getLogger(__name__) + + +class RESTResponse(io.IOBase): + + def __init__(self, resp): + self.urllib3_response = resp + self.status = resp.status + self.reason = resp.reason + self.data = resp.data + + def getheaders(self): + """Returns a dictionary of the response headers.""" + return self.urllib3_response.getheaders() + + def getheader(self, name, default=None): + """Returns a given response header.""" + return self.urllib3_response.getheader(name, default) + + +class RESTClientObject(object): + + def __init__(self, configuration, pools_size=4, maxsize=None): + # urllib3.PoolManager will pass all kw parameters to connectionpool + # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501 + # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501 + # maxsize is the number of requests to host that are allowed in parallel # noqa: E501 + # Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501 + + # cert_reqs + if configuration.verify_ssl: + cert_reqs = ssl.CERT_REQUIRED + else: + cert_reqs = ssl.CERT_NONE + + # ca_certs + if configuration.ssl_ca_cert: + ca_certs = configuration.ssl_ca_cert + else: + # if not set certificate file, use Mozilla's root certificates. + ca_certs = certifi.where() + + addition_pool_args = {} + if configuration.assert_hostname is not None: + addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501 + + if maxsize is None: + if configuration.connection_pool_maxsize is not None: + maxsize = configuration.connection_pool_maxsize + else: + maxsize = 4 + + # https pool manager + if configuration.proxy: + self.pool_manager = urllib3.ProxyManager( + num_pools=pools_size, + maxsize=maxsize, + cert_reqs=cert_reqs, + ca_certs=ca_certs, + cert_file=configuration.cert_file, + key_file=configuration.key_file, + proxy_url=configuration.proxy, + **addition_pool_args + ) + else: + self.pool_manager = urllib3.PoolManager( + num_pools=pools_size, + maxsize=maxsize, + cert_reqs=cert_reqs, + ca_certs=ca_certs, + cert_file=configuration.cert_file, + key_file=configuration.key_file, + **addition_pool_args + ) + + def request(self, method, url, query_params=None, headers=None, + body=None, post_params=None, _preload_content=True, + _request_timeout=None): + """Perform requests. + + :param method: http request method + :param url: http request url + :param query_params: query parameters in the url + :param headers: http request headers + :param body: request json body, for `application/json` + :param post_params: request post parameters, + `application/x-www-form-urlencoded` + and `multipart/form-data` + :param _preload_content: if False, the urllib3.HTTPResponse object will + be returned without reading/decoding response + data. Default is True. + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + """ + method = method.upper() + assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', + 'PATCH', 'OPTIONS'] + + if post_params and body: + raise ValueError( + "body parameter cannot be used with post_params parameter." + ) + + post_params = post_params or {} + headers = headers or {} + + timeout = None + if _request_timeout: + if isinstance(_request_timeout, (int, ) if six.PY3 else (int, long)): # noqa: E501,F821 + timeout = urllib3.Timeout(total=_request_timeout) + elif (isinstance(_request_timeout, tuple) and + len(_request_timeout) == 2): + timeout = urllib3.Timeout( + connect=_request_timeout[0], read=_request_timeout[1]) + + if 'Content-Type' not in headers: + headers['Content-Type'] = 'application/json' + + try: + # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE` + if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']: + if query_params: + url += '?' + urlencode(query_params) + if re.search('json', headers['Content-Type'], re.IGNORECASE): + request_body = None + if body is not None: + request_body = json.dumps(body) + r = self.pool_manager.request( + method, url, + body=request_body, + preload_content=_preload_content, + timeout=timeout, + headers=headers) + elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501 + r = self.pool_manager.request( + method, url, + fields=post_params, + encode_multipart=False, + preload_content=_preload_content, + timeout=timeout, + headers=headers) + elif headers['Content-Type'] == 'multipart/form-data': + # must del headers['Content-Type'], or the correct + # Content-Type which generated by urllib3 will be + # overwritten. + del headers['Content-Type'] + r = self.pool_manager.request( + method, url, + fields=post_params, + encode_multipart=True, + preload_content=_preload_content, + timeout=timeout, + headers=headers) + # Pass a `string` parameter directly in the body to support + # other content types than Json when `body` argument is + # provided in serialized form + elif isinstance(body, str): + request_body = body + r = self.pool_manager.request( + method, url, + body=request_body, + preload_content=_preload_content, + timeout=timeout, + headers=headers) + else: + # Cannot generate the request from given parameters + msg = """Cannot prepare a request message for provided + arguments. Please check that your arguments match + declared content type.""" + raise ApiException(status=0, reason=msg) + # For `GET`, `HEAD` + else: + r = self.pool_manager.request(method, url, + fields=query_params, + preload_content=_preload_content, + timeout=timeout, + headers=headers) + except urllib3.exceptions.SSLError as e: + msg = "{0}\n{1}".format(type(e).__name__, str(e)) + raise ApiException(status=0, reason=msg) + + if _preload_content: + r = RESTResponse(r) + + # In the python 3, the response.data is bytes. + # we need to decode it to string. + if six.PY3: + r.data = r.data.decode('utf8') + + # log response body + logger.debug("response body: %s", r.data) + + if not 200 <= r.status <= 299: + raise ApiException(http_resp=r) + + return r + + def GET(self, url, headers=None, query_params=None, _preload_content=True, + _request_timeout=None): + return self.request("GET", url, + headers=headers, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + query_params=query_params) + + def HEAD(self, url, headers=None, query_params=None, _preload_content=True, + _request_timeout=None): + return self.request("HEAD", url, + headers=headers, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + query_params=query_params) + + def OPTIONS(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("OPTIONS", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def DELETE(self, url, headers=None, query_params=None, body=None, + _preload_content=True, _request_timeout=None): + return self.request("DELETE", url, + headers=headers, + query_params=query_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def POST(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("POST", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def PUT(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("PUT", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def PATCH(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("PATCH", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + +class ApiException(Exception): + + def __init__(self, status=None, reason=None, http_resp=None): + if http_resp: + self.status = http_resp.status + self.reason = http_resp.reason + self.body = http_resp.data + self.headers = http_resp.getheaders() + else: + self.status = status + self.reason = reason + self.body = None + self.headers = None + + def __str__(self): + """Custom error messages for exception""" + error_message = "({0})\n"\ + "Reason: {1}\n".format(self.status, self.reason) + if self.headers: + error_message += "HTTP response headers: {0}\n".format( + self.headers) + + if self.body: + error_message += "HTTP response body: {0}\n".format(self.body) + + return error_message diff --git a/samples/client/petstore-security-test/python/requirements.txt b/samples/client/petstore-security-test/python/requirements.txt new file mode 100644 index 00000000000..bafdc07532f --- /dev/null +++ b/samples/client/petstore-security-test/python/requirements.txt @@ -0,0 +1,5 @@ +certifi >= 14.05.14 +six >= 1.10 +python_dateutil >= 2.5.3 +setuptools >= 21.0.0 +urllib3 >= 1.15.1 diff --git a/samples/client/petstore-security-test/python/setup.py b/samples/client/petstore-security-test/python/setup.py new file mode 100644 index 00000000000..f411410fae9 --- /dev/null +++ b/samples/client/petstore-security-test/python/setup.py @@ -0,0 +1,40 @@ +# coding: utf-8 + +""" + OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =end -- # noqa: E501 + + OpenAPI spec version: 1.0.0 */ ' \" =end -- \\r\\n \\n \\r + Contact: something@something.abc */ ' \" =end -- \\r\\n \\n \\r + Generated by: https://openapi-generator.tech +""" + + +from setuptools import setup, find_packages # noqa: H301 + +NAME = "petstore-api" +VERSION = "1.0.0" +# To install the library, run the following +# +# python setup.py install +# +# prerequisite: setuptools +# http://pypi.python.org/pypi/setuptools + +REQUIRES = ["urllib3 >= 1.15", "six >= 1.10", "certifi", "python-dateutil"] + +setup( + name=NAME, + version=VERSION, + description="OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r", + author_email="something@something.abc */ ' \" =end -- \\r\\n \\n \\r", + url="", + keywords=["OpenAPI", "OpenAPI-Generator", "OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r"], + install_requires=REQUIRES, + packages=find_packages(), + include_package_data=True, + long_description="""\ + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =end -- # noqa: E501 + """ +) diff --git a/samples/client/petstore-security-test/python/test-requirements.txt b/samples/client/petstore-security-test/python/test-requirements.txt new file mode 100644 index 00000000000..2702246c0e6 --- /dev/null +++ b/samples/client/petstore-security-test/python/test-requirements.txt @@ -0,0 +1,5 @@ +coverage>=4.0.3 +nose>=1.3.7 +pluggy>=0.3.1 +py>=1.4.31 +randomize>=0.13 diff --git a/samples/client/petstore-security-test/python/test/__init__.py b/samples/client/petstore-security-test/python/test/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/samples/client/petstore-security-test/python/test/test_fake_api.py b/samples/client/petstore-security-test/python/test/test_fake_api.py new file mode 100644 index 00000000000..9f4f08e8c29 --- /dev/null +++ b/samples/client/petstore-security-test/python/test/test_fake_api.py @@ -0,0 +1,41 @@ +# coding: utf-8 + +""" + OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =end -- # noqa: E501 + + OpenAPI spec version: 1.0.0 */ ' \" =end -- \\r\\n \\n \\r + Contact: something@something.abc */ ' \" =end -- \\r\\n \\n \\r + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import + +import unittest + +import petstore_api +from petstore_api.api.fake_api import FakeApi # noqa: E501 +from petstore_api.rest import ApiException + + +class TestFakeApi(unittest.TestCase): + """FakeApi unit test stubs""" + + def setUp(self): + self.api = petstore_api.api.fake_api.FakeApi() # noqa: E501 + + def tearDown(self): + pass + + def test_test_code_inject____end__rn_n_r(self): + """Test case for test_code_inject____end__rn_n_r + + To test code injection */ ' \" =end -- \\r\\n \\n \\r # noqa: E501 + """ + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/samples/client/petstore-security-test/python/test/test_model_return.py b/samples/client/petstore-security-test/python/test/test_model_return.py new file mode 100644 index 00000000000..d84016e2526 --- /dev/null +++ b/samples/client/petstore-security-test/python/test/test_model_return.py @@ -0,0 +1,40 @@ +# coding: utf-8 + +""" + OpenAPI Petstore */ ' \" =end -- \\r\\n \\n \\r + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =end -- # noqa: E501 + + OpenAPI spec version: 1.0.0 */ ' \" =end -- \\r\\n \\n \\r + Contact: something@something.abc */ ' \" =end -- \\r\\n \\n \\r + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import + +import unittest + +import petstore_api +from petstore_api.models.model_return import ModelReturn # noqa: E501 +from petstore_api.rest import ApiException + + +class TestModelReturn(unittest.TestCase): + """ModelReturn unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testModelReturn(self): + """Test ModelReturn""" + # FIXME: construct object with mandatory attributes with example values + # model = petstore_api.models.model_return.ModelReturn() # noqa: E501 + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/samples/client/petstore-security-test/python/tox.ini b/samples/client/petstore-security-test/python/tox.ini new file mode 100644 index 00000000000..3d0be613cfc --- /dev/null +++ b/samples/client/petstore-security-test/python/tox.ini @@ -0,0 +1,10 @@ +[tox] +envlist = py27, py3 + +[testenv] +deps=-r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + +commands= + nosetests \ + [] diff --git a/samples/client/petstore-security-test/ruby/.gitignore b/samples/client/petstore-security-test/ruby/.gitignore new file mode 100644 index 00000000000..05a17cb8f0a --- /dev/null +++ b/samples/client/petstore-security-test/ruby/.gitignore @@ -0,0 +1,39 @@ +# Generated by: https://openapi-generator.tech +# + +*.gem +*.rbc +/.config +/coverage/ +/InstalledFiles +/pkg/ +/spec/reports/ +/spec/examples.txt +/test/tmp/ +/test/version_tmp/ +/tmp/ + +## Specific to RubyMotion: +.dat* +.repl_history +build/ + +## Documentation cache and generated files: +/.yardoc/ +/_yardoc/ +/doc/ +/rdoc/ + +## Environment normalization: +/.bundle/ +/vendor/bundle +/lib/bundler/man/ + +# for a library or gem, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# Gemfile.lock +# .ruby-version +# .ruby-gemset + +# unless supporting rvm < 1.11.0 or doing something fancy, ignore this: +.rvmrc diff --git a/samples/client/petstore-security-test/ruby/.openapi-generator-ignore b/samples/client/petstore-security-test/ruby/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/ruby/.openapi-generator/VERSION b/samples/client/petstore-security-test/ruby/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/ruby/.rspec b/samples/client/petstore-security-test/ruby/.rspec new file mode 100644 index 00000000000..83e16f80447 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/.rspec @@ -0,0 +1,2 @@ +--color +--require spec_helper diff --git a/samples/client/petstore-security-test/ruby/.rubocop.yml b/samples/client/petstore-security-test/ruby/.rubocop.yml new file mode 100644 index 00000000000..98c7e3c7e51 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/.rubocop.yml @@ -0,0 +1,154 @@ +# This file is based on https://github.com/rails/rails/blob/master/.rubocop.yml (MIT license) +# Automatically generated by OpenAPI Generator (https://openapi-generator.tech) +AllCops: + TargetRubyVersion: 2.2 + # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop + # to ignore them, so only the ones explicitly set in this file are enabled. + DisabledByDefault: true + Exclude: + - '**/templates/**/*' + - '**/vendor/**/*' + - 'actionpack/lib/action_dispatch/journey/parser.rb' + +# Prefer &&/|| over and/or. +Style/AndOr: + Enabled: true + +# Do not use braces for hash literals when they are the last argument of a +# method call. +Style/BracesAroundHashParameters: + Enabled: true + EnforcedStyle: context_dependent + +# Align `when` with `case`. +Layout/CaseIndentation: + Enabled: true + +# Align comments with method definitions. +Layout/CommentIndentation: + Enabled: true + +Layout/ElseAlignment: + Enabled: true + +Layout/EmptyLineAfterMagicComment: + Enabled: true + +# In a regular class definition, no empty lines around the body. +Layout/EmptyLinesAroundClassBody: + Enabled: true + +# In a regular method definition, no empty lines around the body. +Layout/EmptyLinesAroundMethodBody: + Enabled: true + +# In a regular module definition, no empty lines around the body. +Layout/EmptyLinesAroundModuleBody: + Enabled: true + +Layout/FirstParameterIndentation: + Enabled: true + +# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }. +Style/HashSyntax: + Enabled: false + +# Method definitions after `private` or `protected` isolated calls need one +# extra level of indentation. +Layout/IndentationConsistency: + Enabled: true + EnforcedStyle: rails + +# Two spaces, no tabs (for indentation). +Layout/IndentationWidth: + Enabled: true + +Layout/LeadingCommentSpace: + Enabled: true + +Layout/SpaceAfterColon: + Enabled: true + +Layout/SpaceAfterComma: + Enabled: true + +Layout/SpaceAroundEqualsInParameterDefault: + Enabled: true + +Layout/SpaceAroundKeyword: + Enabled: true + +Layout/SpaceAroundOperators: + Enabled: true + +Layout/SpaceBeforeComma: + Enabled: true + +Layout/SpaceBeforeFirstArg: + Enabled: true + +Style/DefWithParentheses: + Enabled: true + +# Defining a method with parameters needs parentheses. +Style/MethodDefParentheses: + Enabled: true + +Style/FrozenStringLiteralComment: + Enabled: false + EnforcedStyle: always + +# Use `foo {}` not `foo{}`. +Layout/SpaceBeforeBlockBraces: + Enabled: true + +# Use `foo { bar }` not `foo {bar}`. +Layout/SpaceInsideBlockBraces: + Enabled: true + +# Use `{ a: 1 }` not `{a:1}`. +Layout/SpaceInsideHashLiteralBraces: + Enabled: true + +Layout/SpaceInsideParens: + Enabled: true + +# Check quotes usage according to lint rule below. +#Style/StringLiterals: +# Enabled: true +# EnforcedStyle: single_quotes + +# Detect hard tabs, no hard tabs. +Layout/Tab: + Enabled: true + +# Blank lines should not have any spaces. +Layout/TrailingBlankLines: + Enabled: true + +# No trailing whitespace. +Layout/TrailingWhitespace: + Enabled: false + +# Use quotes for string literals when they are enough. +Style/UnneededPercentQ: + Enabled: true + +# Align `end` with the matching keyword or starting expression except for +# assignments, where it should be aligned with the LHS. +Layout/EndAlignment: + Enabled: true + EnforcedStyleAlignWith: variable + AutoCorrect: true + +# Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg. +Lint/RequireParentheses: + Enabled: true + +Style/RedundantReturn: + Enabled: true + AllowMultipleReturnValues: true + +Style/Semicolon: + Enabled: true + AllowAsExpressionSeparator: true diff --git a/samples/client/petstore-security-test/ruby/.travis.yml b/samples/client/petstore-security-test/ruby/.travis.yml new file mode 100644 index 00000000000..d2d526df594 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/.travis.yml @@ -0,0 +1,11 @@ +language: ruby +cache: bundler +rvm: + - 2.3 + - 2.4 + - 2.5 +script: + - bundle install --path vendor/bundle + - bundle exec rspec + - gem build petstore.gemspec + - gem install ./petstore-1.0.0.gem diff --git a/samples/client/petstore-security-test/ruby/Gemfile b/samples/client/petstore-security-test/ruby/Gemfile new file mode 100644 index 00000000000..01ba313fe12 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/Gemfile @@ -0,0 +1,8 @@ +source 'https://rubygems.org' + +gemspec + +group :development, :test do + gem 'rake', '~> 12.0.0' + gem 'pry-byebug' +end diff --git a/samples/client/petstore-security-test/ruby/Gemfile.lock b/samples/client/petstore-security-test/ruby/Gemfile.lock new file mode 100644 index 00000000000..14030efc945 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/Gemfile.lock @@ -0,0 +1,79 @@ +PATH + remote: . + specs: + petstore (1.0.0) + json (~> 2.1, >= 2.1.0) + typhoeus (~> 1.0, >= 1.0.1) + +GEM + remote: https://rubygems.org/ + specs: + ZenTest (4.11.2) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) + autotest (4.4.6) + ZenTest (>= 4.4.1) + autotest-fsevent (0.2.14) + sys-uname + autotest-growl (0.2.16) + autotest-rails-pure (4.1.2) + byebug (10.0.2) + coderay (1.1.2) + crack (0.4.3) + safe_yaml (~> 1.0.0) + diff-lcs (1.3) + ethon (0.11.0) + ffi (>= 1.3.0) + ffi (1.9.25) + hashdiff (0.3.7) + json (2.1.0) + method_source (0.9.0) + pry (0.11.3) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + pry-byebug (3.6.0) + byebug (~> 10.0) + pry (~> 0.10) + public_suffix (3.0.3) + rake (12.0.0) + rspec (3.8.0) + rspec-core (~> 3.8.0) + rspec-expectations (~> 3.8.0) + rspec-mocks (~> 3.8.0) + rspec-core (3.8.0) + rspec-support (~> 3.8.0) + rspec-expectations (3.8.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.8.0) + rspec-mocks (3.8.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.8.0) + rspec-support (3.8.0) + safe_yaml (1.0.4) + sys-uname (1.0.3) + ffi (>= 1.0.0) + typhoeus (1.3.0) + ethon (>= 0.9.0) + vcr (3.0.3) + webmock (1.24.6) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff + +PLATFORMS + ruby + +DEPENDENCIES + autotest (~> 4.4, >= 4.4.6) + autotest-fsevent (~> 0.2, >= 0.2.12) + autotest-growl (~> 0.2, >= 0.2.16) + autotest-rails-pure (~> 4.1, >= 4.1.2) + petstore! + pry-byebug + rake (~> 12.0.0) + rspec (~> 3.6, >= 3.6.0) + vcr (~> 3.0, >= 3.0.1) + webmock (~> 1.24, >= 1.24.3) + +BUNDLED WITH + 1.16.1 diff --git a/samples/client/petstore-security-test/ruby/README.md b/samples/client/petstore-security-test/ruby/README.md new file mode 100644 index 00000000000..3a51c54f517 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/README.md @@ -0,0 +1,104 @@ +# petstore + +Petstore - the Ruby gem for the OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + + + +This SDK is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +- Package version: 1.0.0 +- Build package: org.openapitools.codegen.languages.RubyClientCodegen + +## Installation + +### Build a gem + +To build the Ruby code into a gem: + +```shell +gem build petstore.gemspec +``` + +Then either install the gem locally: + +```shell +gem install ./petstore-1.0.0.gem +``` +(for development, run `gem install --dev ./petstore-1.0.0.gem` to install the development dependencies) + +or publish the gem to a gem hosting service, e.g. [RubyGems](https://rubygems.org/). + +Finally add this to the Gemfile: + + gem 'petstore', '~> 1.0.0' + +### Install from Git + +If the Ruby gem is hosted at a git repository: https://github.com/GIT_USER_ID/GIT_REPO_ID, then add the following in the Gemfile: + + gem 'petstore', :git => 'https://github.com/GIT_USER_ID/GIT_REPO_ID.git' + +### Include the Ruby code directly + +Include the Ruby code directly using `-I` as follows: + +```shell +ruby -Ilib script.rb +``` + +## Getting Started + +Please follow the [installation](#installation) procedure and then run the following code: +```ruby +# Load the gem +require 'petstore' + +api_instance = Petstore::FakeApi.new +opts = { + test_code_inject____end____rn_n_r: 'test_code_inject____end____rn_n_r_example' # String | To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r +} + +begin + #To test code injection */ ' \" =_end -- \\r\\n \\n \\r + api_instance.test_code_inject____end__rn_n_r(opts) +rescue Petstore::ApiError => e + puts "Exception when calling FakeApi->test_code_inject____end__rn_n_r: #{e}" +end + +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*Petstore::FakeApi* | [**test_code_inject____end__rn_n_r**](docs/FakeApi.md#test_code_inject____end__rn_n_r) | **PUT** /fake | To test code injection */ ' \" =_end -- \\r\\n \\n \\r + + +## Documentation for Models + + - [Petstore::ModelReturn](docs/ModelReturn.md) + + +## Documentation for Authorization + + +### api_key + +- **Type**: API key +- **API key parameter name**: api_key */ ' " =end -- \r\n \n \r +- **Location**: HTTP header + +### petstore_auth + +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - write:pets: modify pets in your account */ ' \" =_end -- \\r\\n \\n \\r + - read:pets: read your pets */ ' \" =_end -- \\r\\n \\n \\r + diff --git a/samples/client/petstore-security-test/ruby/Rakefile b/samples/client/petstore-security-test/ruby/Rakefile new file mode 100644 index 00000000000..c72ca30d454 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/Rakefile @@ -0,0 +1,10 @@ +require "bundler/gem_tasks" + +begin + require 'rspec/core/rake_task' + + RSpec::Core::RakeTask.new(:spec) + task default: :spec +rescue LoadError + # no rspec available +end diff --git a/samples/client/petstore-security-test/ruby/docs/FakeApi.md b/samples/client/petstore-security-test/ruby/docs/FakeApi.md new file mode 100644 index 00000000000..979d2bf2045 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/docs/FakeApi.md @@ -0,0 +1,55 @@ +# Petstore::FakeApi + +All URIs are relative to *http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**test_code_inject____end__rn_n_r**](FakeApi.md#test_code_inject____end__rn_n_r) | **PUT** /fake | To test code injection */ ' \" =_end -- \\r\\n \\n \\r + + +# **test_code_inject____end__rn_n_r** +> test_code_inject____end__rn_n_r(opts) + +To test code injection */ ' \" =_end -- \\r\\n \\n \\r + +To test code injection */ ' \" =_end -- \\r\\n \\n \\r + +### Example +```ruby +# load the gem +require 'petstore' + +api_instance = Petstore::FakeApi.new +opts = { + test_code_inject____end____rn_n_r: 'test_code_inject____end____rn_n_r_example' # String | To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r +} + +begin + #To test code injection */ ' \" =_end -- \\r\\n \\n \\r + api_instance.test_code_inject____end__rn_n_r(opts) +rescue Petstore::ApiError => e + puts "Exception when calling FakeApi->test_code_inject____end__rn_n_r: #{e}" +end +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **test_code_inject____end____rn_n_r** | **String**| To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r | [optional] + +### Return type + +nil (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded, */ \" =_end -- + - **Accept**: Not defined + + + diff --git a/samples/client/petstore-security-test/ruby/docs/ModelReturn.md b/samples/client/petstore-security-test/ruby/docs/ModelReturn.md new file mode 100644 index 00000000000..5021c4994d0 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/docs/ModelReturn.md @@ -0,0 +1,16 @@ +# Petstore::ModelReturn + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**_return** | **Integer** | property description */ ' \" =_end -- \\r\\n \\n \\r | [optional] + +## Code Sample + +```ruby +require 'Petstore' + +instance = Petstore::ModelReturn.new(_return: null) +``` + + diff --git a/samples/client/petstore-security-test/ruby/git_push.sh b/samples/client/petstore-security-test/ruby/git_push.sh new file mode 100644 index 00000000000..b9fd6af8e05 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/git_push.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Generated by: https://openapi-generator.tech +# +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/ruby/lib/petstore.rb b/samples/client/petstore-security-test/ruby/lib/petstore.rb new file mode 100644 index 00000000000..742f6c48a2f --- /dev/null +++ b/samples/client/petstore-security-test/ruby/lib/petstore.rb @@ -0,0 +1,41 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +# Common files +require 'petstore/api_client' +require 'petstore/api_error' +require 'petstore/version' +require 'petstore/configuration' + +# Models +require 'petstore/models/model_return' + +# APIs +require 'petstore/api/fake_api' + +module Petstore + class << self + # Customize default settings for the SDK using block. + # Petstore.configure do |config| + # config.username = "xxx" + # config.password = "xxx" + # end + # If no block given, return the default Configuration object. + def configure + if block_given? + yield(Configuration.default) + else + Configuration.default + end + end + end +end diff --git a/samples/client/petstore-security-test/ruby/lib/petstore/api/fake_api.rb b/samples/client/petstore-security-test/ruby/lib/petstore/api/fake_api.rb new file mode 100644 index 00000000000..74791ebdb08 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/lib/petstore/api/fake_api.rb @@ -0,0 +1,71 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +require 'uri' + +module Petstore + class FakeApi + attr_accessor :api_client + + def initialize(api_client = ApiClient.default) + @api_client = api_client + end + # To test code injection */ ' \" =_end -- \\r\\n \\n \\r + # To test code injection */ ' \" =_end -- \\r\\n \\n \\r + # @param [Hash] opts the optional parameters + # @option opts [String] :test_code_inject____end____rn_n_r To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r + # @return [nil] + def test_code_inject____end__rn_n_r(opts = {}) + test_code_inject____end__rn_n_r_with_http_info(opts) + nil + end + + # To test code injection */ ' \" =_end -- \\r\\n \\n \\r + # To test code injection */ ' \" =_end -- \\r\\n \\n \\r + # @param [Hash] opts the optional parameters + # @option opts [String] :test_code_inject____end____rn_n_r To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r + # @return [Array<(nil, Fixnum, Hash)>] nil, response status code and response headers + def test_code_inject____end__rn_n_r_with_http_info(opts = {}) + if @api_client.config.debugging + @api_client.config.logger.debug 'Calling API: FakeApi.test_code_inject____end__rn_n_r ...' + end + # resource path + local_var_path = '/fake' + + # query parameters + query_params = {} + + # header parameters + header_params = {} + # HTTP header 'Content-Type' + header_params['Content-Type'] = @api_client.select_header_content_type(['application/x-www-form-urlencoded', '*/ \" =_end -- ']) + + # form parameters + form_params = {} + form_params['test code inject */ ' " =end -- \r\n \n \r'] = opts[:'test_code_inject____end____rn_n_r'] if !opts[:'test_code_inject____end____rn_n_r'].nil? + + # http body (model) + post_body = nil + auth_names = [] + data, status_code, headers = @api_client.call_api(:PUT, local_var_path, + :header_params => header_params, + :query_params => query_params, + :form_params => form_params, + :body => post_body, + :auth_names => auth_names) + if @api_client.config.debugging + @api_client.config.logger.debug "API called: FakeApi#test_code_inject____end__rn_n_r\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}" + end + return data, status_code, headers + end + end +end diff --git a/samples/client/petstore-security-test/ruby/lib/petstore/api_client.rb b/samples/client/petstore-security-test/ruby/lib/petstore/api_client.rb new file mode 100644 index 00000000000..c097e2038c0 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/lib/petstore/api_client.rb @@ -0,0 +1,387 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +require 'date' +require 'json' +require 'logger' +require 'tempfile' +require 'typhoeus' +require 'uri' + +module Petstore + class ApiClient + # The Configuration object holding settings to be used in the API client. + attr_accessor :config + + # Defines the headers to be used in HTTP requests of all API calls by default. + # + # @return [Hash] + attr_accessor :default_headers + + # Initializes the ApiClient + # @option config [Configuration] Configuration for initializing the object, default to Configuration.default + def initialize(config = Configuration.default) + @config = config + @user_agent = "OpenAPI-Generator/#{VERSION}/ruby" + @default_headers = { + 'Content-Type' => 'application/json', + 'User-Agent' => @user_agent + } + end + + def self.default + @@default ||= ApiClient.new + end + + # Call an API with given options. + # + # @return [Array<(Object, Fixnum, Hash)>] an array of 3 elements: + # the data deserialized from response body (could be nil), response status code and response headers. + def call_api(http_method, path, opts = {}) + request = build_request(http_method, path, opts) + response = request.run + + if @config.debugging + @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n" + end + + unless response.success? + if response.timed_out? + fail ApiError.new('Connection timed out') + elsif response.code == 0 + # Errors from libcurl will be made visible here + fail ApiError.new(:code => 0, + :message => response.return_message) + else + fail ApiError.new(:code => response.code, + :response_headers => response.headers, + :response_body => response.body), + response.status_message + end + end + + if opts[:return_type] + data = deserialize(response, opts[:return_type]) + else + data = nil + end + return data, response.code, response.headers + end + + # Builds the HTTP request + # + # @param [String] http_method HTTP method/verb (e.g. POST) + # @param [String] path URL path (e.g. /account/new) + # @option opts [Hash] :header_params Header parameters + # @option opts [Hash] :query_params Query parameters + # @option opts [Hash] :form_params Query parameters + # @option opts [Object] :body HTTP body (JSON/XML) + # @return [Typhoeus::Request] A Typhoeus Request + def build_request(http_method, path, opts = {}) + url = build_request_url(path) + http_method = http_method.to_sym.downcase + + header_params = @default_headers.merge(opts[:header_params] || {}) + query_params = opts[:query_params] || {} + form_params = opts[:form_params] || {} + + update_params_for_auth! header_params, query_params, opts[:auth_names] + + # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false) + _verify_ssl_host = @config.verify_ssl_host ? 2 : 0 + + req_opts = { + :method => http_method, + :headers => header_params, + :params => query_params, + :params_encoding => @config.params_encoding, + :timeout => @config.timeout, + :ssl_verifypeer => @config.verify_ssl, + :ssl_verifyhost => _verify_ssl_host, + :sslcert => @config.cert_file, + :sslkey => @config.key_file, + :verbose => @config.debugging + } + + # set custom cert, if provided + req_opts[:cainfo] = @config.ssl_ca_cert if @config.ssl_ca_cert + + if [:post, :patch, :put, :delete].include?(http_method) + req_body = build_request_body(header_params, form_params, opts[:body]) + req_opts.update :body => req_body + if @config.debugging + @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n" + end + end + + request = Typhoeus::Request.new(url, req_opts) + download_file(request) if opts[:return_type] == 'File' + request + end + + # Check if the given MIME is a JSON MIME. + # JSON MIME examples: + # application/json + # application/json; charset=UTF8 + # APPLICATION/JSON + # */* + # @param [String] mime MIME + # @return [Boolean] True if the MIME is application/json + def json_mime?(mime) + (mime == '*/*') || !(mime =~ /Application\/.*json(?!p)(;.*)?/i).nil? + end + + # Deserialize the response to the given return type. + # + # @param [Response] response HTTP response + # @param [String] return_type some examples: "User", "Array", "Hash" + def deserialize(response, return_type) + body = response.body + + # handle file downloading - return the File instance processed in request callbacks + # note that response body is empty when the file is written in chunks in request on_body callback + return @tempfile if return_type == 'File' + + return nil if body.nil? || body.empty? + + # return response body directly for String return type + return body if return_type == 'String' + + # ensuring a default content type + content_type = response.headers['Content-Type'] || 'application/json' + + fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type) + + begin + data = JSON.parse("[#{body}]", :symbolize_names => true)[0] + rescue JSON::ParserError => e + if %w(String Date DateTime).include?(return_type) + data = body + else + raise e + end + end + + convert_to_type data, return_type + end + + # Convert data to the given return type. + # @param [Object] data Data to be converted + # @param [String] return_type Return type + # @return [Mixed] Data in a particular type + def convert_to_type(data, return_type) + return nil if data.nil? + case return_type + when 'String' + data.to_s + when 'Integer' + data.to_i + when 'Float' + data.to_f + when 'Boolean' + data == true + when 'DateTime' + # parse date time (expecting ISO 8601 format) + DateTime.parse data + when 'Date' + # parse date time (expecting ISO 8601 format) + Date.parse data + when 'Object' + # generic object (usually a Hash), return directly + data + when /\AArray<(.+)>\z/ + # e.g. Array + sub_type = $1 + data.map { |item| convert_to_type(item, sub_type) } + when /\AHash\\z/ + # e.g. Hash + sub_type = $1 + {}.tap do |hash| + data.each { |k, v| hash[k] = convert_to_type(v, sub_type) } + end + else + # models, e.g. Pet + Petstore.const_get(return_type).build_from_hash(data) + end + end + + # Save response body into a file in (the defined) temporary folder, using the filename + # from the "Content-Disposition" header if provided, otherwise a random filename. + # The response body is written to the file in chunks in order to handle files which + # size is larger than maximum Ruby String or even larger than the maximum memory a Ruby + # process can use. + # + # @see Configuration#temp_folder_path + def download_file(request) + tempfile = nil + encoding = nil + request.on_headers do |response| + content_disposition = response.headers['Content-Disposition'] + if content_disposition && content_disposition =~ /filename=/i + filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] + prefix = sanitize_filename(filename) + else + prefix = 'download-' + end + prefix = prefix + '-' unless prefix.end_with?('-') + encoding = response.body.encoding + tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) + @tempfile = tempfile + end + request.on_body do |chunk| + chunk.force_encoding(encoding) + tempfile.write(chunk) + end + request.on_complete do |response| + tempfile.close if tempfile + @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ + "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ + "will be deleted automatically with GC. It's also recommended to delete the temp file "\ + "explicitly with `tempfile.delete`" + end + end + + # Sanitize filename by removing path. + # e.g. ../../sun.gif becomes sun.gif + # + # @param [String] filename the filename to be sanitized + # @return [String] the sanitized filename + def sanitize_filename(filename) + filename.gsub(/.*[\/\\]/, '') + end + + def build_request_url(path) + # Add leading and trailing slashes to path + path = "/#{path}".gsub(/\/+/, '/') + URI.encode(@config.base_url + path) + end + + # Builds the HTTP request body + # + # @param [Hash] header_params Header parameters + # @param [Hash] form_params Query parameters + # @param [Object] body HTTP body (JSON/XML) + # @return [String] HTTP body data in the form of string + def build_request_body(header_params, form_params, body) + # http form + if header_params['Content-Type'] == 'application/x-www-form-urlencoded' || + header_params['Content-Type'] == 'multipart/form-data' + data = {} + form_params.each do |key, value| + case value + when ::File, ::Array, nil + # let typhoeus handle File, Array and nil parameters + data[key] = value + else + data[key] = value.to_s + end + end + elsif body + data = body.is_a?(String) ? body : body.to_json + else + data = nil + end + data + end + + # Update hearder and query params based on authentication settings. + # + # @param [Hash] header_params Header parameters + # @param [Hash] query_params Query parameters + # @param [String] auth_names Authentication scheme name + def update_params_for_auth!(header_params, query_params, auth_names) + Array(auth_names).each do |auth_name| + auth_setting = @config.auth_settings[auth_name] + next unless auth_setting + case auth_setting[:in] + when 'header' then header_params[auth_setting[:key]] = auth_setting[:value] + when 'query' then query_params[auth_setting[:key]] = auth_setting[:value] + else fail ArgumentError, 'Authentication token must be in `query` of `header`' + end + end + end + + # Sets user agent in HTTP header + # + # @param [String] user_agent User agent (e.g. openapi-generator/ruby/1.0.0) + def user_agent=(user_agent) + @user_agent = user_agent + @default_headers['User-Agent'] = @user_agent + end + + # Return Accept header based on an array of accepts provided. + # @param [Array] accepts array for Accept + # @return [String] the Accept header (e.g. application/json) + def select_header_accept(accepts) + return nil if accepts.nil? || accepts.empty? + # use JSON when present, otherwise use all of the provided + json_accept = accepts.find { |s| json_mime?(s) } + json_accept || accepts.join(',') + end + + # Return Content-Type header based on an array of content types provided. + # @param [Array] content_types array for Content-Type + # @return [String] the Content-Type header (e.g. application/json) + def select_header_content_type(content_types) + # use application/json by default + return 'application/json' if content_types.nil? || content_types.empty? + # use JSON when present, otherwise use the first one + json_content_type = content_types.find { |s| json_mime?(s) } + json_content_type || content_types.first + end + + # Convert object (array, hash, object, etc) to JSON string. + # @param [Object] model object to be converted into JSON string + # @return [String] JSON string representation of the object + def object_to_http_body(model) + return model if model.nil? || model.is_a?(String) + local_body = nil + if model.is_a?(Array) + local_body = model.map { |m| object_to_hash(m) } + else + local_body = object_to_hash(model) + end + local_body.to_json + end + + # Convert object(non-array) to hash. + # @param [Object] obj object to be converted into JSON string + # @return [String] JSON string representation of the object + def object_to_hash(obj) + if obj.respond_to?(:to_hash) + obj.to_hash + else + obj + end + end + + # Build parameter value according to the given collection format. + # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi + def build_collection_param(param, collection_format) + case collection_format + when :csv + param.join(',') + when :ssv + param.join(' ') + when :tsv + param.join("\t") + when :pipes + param.join('|') + when :multi + # return the array directly as typhoeus will handle it as expected + param + else + fail "unknown collection format: #{collection_format.inspect}" + end + end + end +end diff --git a/samples/client/petstore-security-test/ruby/lib/petstore/api_error.rb b/samples/client/petstore-security-test/ruby/lib/petstore/api_error.rb new file mode 100644 index 00000000000..a39ecc654b0 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/lib/petstore/api_error.rb @@ -0,0 +1,57 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +module Petstore + class ApiError < StandardError + attr_reader :code, :response_headers, :response_body + + # Usage examples: + # ApiError.new + # ApiError.new("message") + # ApiError.new(:code => 500, :response_headers => {}, :response_body => "") + # ApiError.new(:code => 404, :message => "Not Found") + def initialize(arg = nil) + if arg.is_a? Hash + if arg.key?(:message) || arg.key?('message') + super(arg[:message] || arg['message']) + else + super arg + end + + arg.each do |k, v| + instance_variable_set "@#{k}", v + end + else + super arg + end + end + + # Override to_s to display a friendly error message + def to_s + message + end + + def message + if @message.nil? + msg = "Error message: the server returns an error" + else + msg = @message + end + + msg += "\nHTTP status code: #{code}" if code + msg += "\nResponse headers: #{response_headers}" if response_headers + msg += "\nResponse body: #{response_body}" if response_body + + msg + end + end +end diff --git a/samples/client/petstore-security-test/ruby/lib/petstore/configuration.rb b/samples/client/petstore-security-test/ruby/lib/petstore/configuration.rb new file mode 100644 index 00000000000..da74103bcc2 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/lib/petstore/configuration.rb @@ -0,0 +1,258 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +require 'uri' + +module Petstore + class Configuration + # Defines url scheme + attr_accessor :scheme + + # Defines url host + attr_accessor :host + + # Defines url base path + attr_accessor :base_path + + # Defines API keys used with API Key authentications. + # + # @return [Hash] key: parameter name, value: parameter value (API key) + # + # @example parameter name is "api_key", API key is "xxx" (e.g. "api_key=xxx" in query string) + # config.api_key['api_key'] = 'xxx' + attr_accessor :api_key + + # Defines API key prefixes used with API Key authentications. + # + # @return [Hash] key: parameter name, value: API key prefix + # + # @example parameter name is "Authorization", API key prefix is "Token" (e.g. "Authorization: Token xxx" in headers) + # config.api_key_prefix['api_key'] = 'Token' + attr_accessor :api_key_prefix + + # Defines the username used with HTTP basic authentication. + # + # @return [String] + attr_accessor :username + + # Defines the password used with HTTP basic authentication. + # + # @return [String] + attr_accessor :password + + # Defines the access token (Bearer) used with OAuth2. + attr_accessor :access_token + + # Set this to enable/disable debugging. When enabled (set to true), HTTP request/response + # details will be logged with `logger.debug` (see the `logger` attribute). + # Default to false. + # + # @return [true, false] + attr_accessor :debugging + + # Defines the logger used for debugging. + # Default to `Rails.logger` (when in Rails) or logging to STDOUT. + # + # @return [#debug] + attr_accessor :logger + + # Defines the temporary folder to store downloaded files + # (for API endpoints that have file response). + # Default to use `Tempfile`. + # + # @return [String] + attr_accessor :temp_folder_path + + # The time limit for HTTP request in seconds. + # Default to 0 (never times out). + attr_accessor :timeout + + # Set this to false to skip client side validation in the operation. + # Default to true. + # @return [true, false] + attr_accessor :client_side_validation + + ### TLS/SSL setting + # Set this to false to skip verifying SSL certificate when calling API from https server. + # Default to true. + # + # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks. + # + # @return [true, false] + attr_accessor :verify_ssl + + ### TLS/SSL setting + # Set this to false to skip verifying SSL host name + # Default to true. + # + # @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks. + # + # @return [true, false] + attr_accessor :verify_ssl_host + + ### TLS/SSL setting + # Set this to customize the certificate file to verify the peer. + # + # @return [String] the path to the certificate file + # + # @see The `cainfo` option of Typhoeus, `--cert` option of libcurl. Related source code: + # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/easy_factory.rb#L145 + attr_accessor :ssl_ca_cert + + ### TLS/SSL setting + # Client certificate file (for client certificate) + attr_accessor :cert_file + + ### TLS/SSL setting + # Client private key file (for client certificate) + attr_accessor :key_file + + # Set this to customize parameters encoding of array parameter with multi collectionFormat. + # Default to nil. + # + # @see The params_encoding option of Ethon. Related source code: + # https://github.com/typhoeus/ethon/blob/master/lib/ethon/easy/queryable.rb#L96 + attr_accessor :params_encoding + + attr_accessor :inject_format + + attr_accessor :force_ending_format + + def initialize + @scheme = 'http' + @host = 'petstore.swagger.io *' + @base_path = '/ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r' + @api_key = {} + @api_key_prefix = {} + @timeout = 0 + @client_side_validation = true + @verify_ssl = true + @verify_ssl_host = true + @params_encoding = nil + @cert_file = nil + @key_file = nil + @debugging = false + @inject_format = false + @force_ending_format = false + @logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT) + + yield(self) if block_given? + end + + # The default Configuration object. + def self.default + @@default ||= Configuration.new + end + + def configure + yield(self) if block_given? + end + + def scheme=(scheme) + # remove :// from scheme + @scheme = scheme.sub(/:\/\//, '') + end + + def host=(host) + # remove http(s):// and anything after a slash + @host = host.sub(/https?:\/\//, '').split('/').first + end + + def base_path=(base_path) + # Add leading and trailing slashes to base_path + @base_path = "/#{base_path}".gsub(/\/+/, '/') + @base_path = '' if @base_path == '/' + end + + def base_url + url = "#{scheme}://#{[host, base_path].join('/').gsub(/\/+/, '/')}".sub(/\/+\z/, '') + URI.encode(url) + end + + # Gets API key (with prefix if set). + # @param [String] param_name the parameter name of API key auth + def api_key_with_prefix(param_name) + if @api_key_prefix[param_name] + "#{@api_key_prefix[param_name]} #{@api_key[param_name]}" + else + @api_key[param_name] + end + end + + # Gets Basic Auth token string + def basic_auth_token + 'Basic ' + ["#{username}:#{password}"].pack('m').delete("\r\n") + end + + # Returns Auth Settings hash for api client. + def auth_settings + { + 'api_key' => + { + type: 'api_key', + in: 'header', + key: 'api_key */ ' " =end -- \r\n \n \r', + value: api_key_with_prefix('api_key */ ' " =end -- \r\n \n \r') + }, + 'petstore_auth' => + { + type: 'oauth2', + in: 'header', + key: 'Authorization', + value: "Bearer #{access_token}" + }, + } + end + + # Returns an array of Server setting + def server_settings + [ + { + url: "//petstore.swagger.io */ ' " =end -- \r\n \n \r/v2 */ ' " =end -- \r\n \n \r", + description: "No descriptoin provided", + } + ] + end + + # Returns URL based on server settings + # + # @param index array index of the server settings + # @param variables hash of variable and the corresponding value + def server_url(index, variables = {}) + servers = server_settings + + # check array index out of bound + if (index < 0 || index >= servers.size) + fail ArgumentError, "Invalid index #{index} when selecting the server. Must be less than #{servers.size}" + end + + server = servers[index] + url = server[:url] + + # go through variable and assign a value + server[:variables].each do |name, variable| + if variables.key?(name) + if (server[:variables][name][:enum_values].include? variables[name]) + url.gsub! "{" + name.to_s + "}", variables[name] + else + fail ArgumentError, "The variable `#{name}` in the server URL has invalid value #{variables[name]}. Must be #{server[:variables][name][:enum_values]}." + end + else + # use default value + url.gsub! "{" + name.to_s + "}", server[:variables][name][:default_value] + end + end + + url + end + end +end diff --git a/samples/client/petstore-security-test/ruby/lib/petstore/models/model_return.rb b/samples/client/petstore-security-test/ruby/lib/petstore/models/model_return.rb new file mode 100644 index 00000000000..b0a1c23120d --- /dev/null +++ b/samples/client/petstore-security-test/ruby/lib/petstore/models/model_return.rb @@ -0,0 +1,198 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +require 'date' + +module Petstore + # Model for testing reserved words */ ' \" =_end -- \\r\\n \\n \\r + class ModelReturn + # property description */ ' \" =_end -- \\r\\n \\n \\r + attr_accessor :_return + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'_return' => :'return' + } + end + + # Attribute type mapping. + def self.openapi_types + { + :'_return' => :'Integer' + } + end + + # Initializes the object + # @param [Hash] attributes Model attributes in the form of hash + def initialize(attributes = {}) + if (!attributes.is_a?(Hash)) + fail ArgumentError, "The input argument (attributes) must be a hash in `Petstore::ModelReturn` initialize method" + end + + # check to see if the attribute exists and convert string to symbol for hash key + attributes = attributes.each_with_object({}) { |(k, v), h| + if (!self.class.attribute_map.key?(k.to_sym)) + fail ArgumentError, "`#{k}` is not a valid attribute in `Petstore::ModelReturn`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect + end + h[k.to_sym] = v + } + + if attributes.key?(:'_return') + self._return = attributes[:'_return'] + end + end + + # Show invalid properties with the reasons. Usually used together with valid? + # @return Array for valid properties with the reasons + def list_invalid_properties + invalid_properties = Array.new + invalid_properties + end + + # Check to see if the all the properties in the model are valid + # @return true if the model is valid + def valid? + true + end + + # Checks equality by comparing each attribute. + # @param [Object] Object to be compared + def ==(o) + return true if self.equal?(o) + self.class == o.class && + _return == o._return + end + + # @see the `==` method + # @param [Object] Object to be compared + def eql?(o) + self == o + end + + # Calculates hash code according to all attributes. + # @return [Fixnum] Hash code + def hash + [_return].hash + end + + # Builds the object from hash + # @param [Hash] attributes Model attributes in the form of hash + # @return [Object] Returns the model itself + def self.build_from_hash(attributes) + new.build_from_hash(attributes) + end + + # Builds the object from hash + # @param [Hash] attributes Model attributes in the form of hash + # @return [Object] Returns the model itself + def build_from_hash(attributes) + return nil unless attributes.is_a?(Hash) + self.class.openapi_types.each_pair do |key, type| + if type =~ /\AArray<(.*)>/i + # check to ensure the input is an array given that the attribute + # is documented as an array but the input is not + if attributes[self.class.attribute_map[key]].is_a?(Array) + self.send("#{key}=", attributes[self.class.attribute_map[key]].map { |v| _deserialize($1, v) }) + end + elsif !attributes[self.class.attribute_map[key]].nil? + self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]])) + end # or else data not found in attributes(hash), not an issue as the data can be optional + end + + self + end + + # Deserializes the data based on type + # @param string type Data type + # @param string value Value to be deserialized + # @return [Object] Deserialized data + def _deserialize(type, value) + case type.to_sym + when :DateTime + DateTime.parse(value) + when :Date + Date.parse(value) + when :String + value.to_s + when :Integer + value.to_i + when :Float + value.to_f + when :Boolean + if value.to_s =~ /\A(true|t|yes|y|1)\z/i + true + else + false + end + when :Object + # generic object (usually a Hash), return directly + value + when /\AArray<(?.+)>\z/ + inner_type = Regexp.last_match[:inner_type] + value.map { |v| _deserialize(inner_type, v) } + when /\AHash<(?.+?), (?.+)>\z/ + k_type = Regexp.last_match[:k_type] + v_type = Regexp.last_match[:v_type] + {}.tap do |hash| + value.each do |k, v| + hash[_deserialize(k_type, k)] = _deserialize(v_type, v) + end + end + else # model + Petstore.const_get(type).build_from_hash(value) + end + end + + # Returns the string representation of the object + # @return [String] String presentation of the object + def to_s + to_hash.to_s + end + + # to_body is an alias to to_hash (backward compatibility) + # @return [Hash] Returns the object in the form of hash + def to_body + to_hash + end + + # Returns the object in the form of hash + # @return [Hash] Returns the object in the form of hash + def to_hash + hash = {} + self.class.attribute_map.each_pair do |attr, param| + value = self.send(attr) + next if value.nil? + hash[param] = _to_hash(value) + end + hash + end + + # Outputs non-array value in the form of hash + # For object, use to_hash. Otherwise, just return the value + # @param [Object] value Any valid value + # @return [Hash] Returns the value in the form of hash + def _to_hash(value) + if value.is_a?(Array) + value.compact.map { |v| _to_hash(v) } + elsif value.is_a?(Hash) + {}.tap do |hash| + value.each { |k, v| hash[k] = _to_hash(v) } + end + elsif value.respond_to? :to_hash + value.to_hash + else + value + end + end + end +end diff --git a/samples/client/petstore-security-test/ruby/lib/petstore/version.rb b/samples/client/petstore-security-test/ruby/lib/petstore/version.rb new file mode 100644 index 00000000000..e858870bf5f --- /dev/null +++ b/samples/client/petstore-security-test/ruby/lib/petstore/version.rb @@ -0,0 +1,15 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +module Petstore + VERSION = '1.0.0' +end diff --git a/samples/client/petstore-security-test/ruby/petstore.gemspec b/samples/client/petstore-security-test/ruby/petstore.gemspec new file mode 100644 index 00000000000..cedbeb02dd5 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/petstore.gemspec @@ -0,0 +1,45 @@ +# -*- encoding: utf-8 -*- + +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +$:.push File.expand_path("../lib", __FILE__) +require "petstore/version" + +Gem::Specification.new do |s| + s.name = "petstore" + s.version = Petstore::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ["OpenAPI-Generator"] + s.email = ["something@something.abc */ ' \" =_end -- \\r\\n \\n \\r"] + s.homepage = "https://openapi-generator.tech" + s.summary = "OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r Ruby Gem" + s.description = "This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- " + s.license = "Unlicense" + s.required_ruby_version = ">= 1.9" + + s.add_runtime_dependency 'typhoeus', '~> 1.0', '>= 1.0.1' + s.add_runtime_dependency 'json', '~> 2.1', '>= 2.1.0' + + s.add_development_dependency 'rspec', '~> 3.6', '>= 3.6.0' + s.add_development_dependency 'vcr', '~> 3.0', '>= 3.0.1' + s.add_development_dependency 'webmock', '~> 1.24', '>= 1.24.3' + s.add_development_dependency 'autotest', '~> 4.4', '>= 4.4.6' + s.add_development_dependency 'autotest-rails-pure', '~> 4.1', '>= 4.1.2' + s.add_development_dependency 'autotest-growl', '~> 0.2', '>= 0.2.16' + s.add_development_dependency 'autotest-fsevent', '~> 0.2', '>= 0.2.12' + + s.files = `find *`.split("\n").uniq.sort.select { |f| !f.empty? } + s.test_files = `find spec/*`.split("\n") + s.executables = [] + s.require_paths = ["lib"] +end diff --git a/samples/client/petstore-security-test/ruby/spec/api/fake_api_spec.rb b/samples/client/petstore-security-test/ruby/spec/api/fake_api_spec.rb new file mode 100644 index 00000000000..d810979862a --- /dev/null +++ b/samples/client/petstore-security-test/ruby/spec/api/fake_api_spec.rb @@ -0,0 +1,47 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +require 'spec_helper' +require 'json' + +# Unit tests for Petstore::FakeApi +# Automatically generated by openapi-generator (https://openapi-generator.tech) +# Please update as you see appropriate +describe 'FakeApi' do + before do + # run before each test + @api_instance = Petstore::FakeApi.new + end + + after do + # run after each test + end + + describe 'test an instance of FakeApi' do + it 'should create an instance of FakeApi' do + expect(@api_instance).to be_instance_of(Petstore::FakeApi) + end + end + + # unit tests for test_code_inject____end__rn_n_r + # To test code injection */ ' \" =_end -- \\r\\n \\n \\r + # To test code injection */ ' \" =_end -- \\r\\n \\n \\r + # @param [Hash] opts the optional parameters + # @option opts [String] :test_code_inject____end____rn_n_r To test code injection */ ' \\\" =_end -- \\\\r\\\\n \\\\n \\\\r + # @return [nil] + describe 'test_code_inject____end__rn_n_r test' do + it 'should work' do + # assertion here. ref: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers + end + end + +end diff --git a/samples/client/petstore-security-test/ruby/spec/api_client_spec.rb b/samples/client/petstore-security-test/ruby/spec/api_client_spec.rb new file mode 100644 index 00000000000..dac3a52089e --- /dev/null +++ b/samples/client/petstore-security-test/ruby/spec/api_client_spec.rb @@ -0,0 +1,226 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +require 'spec_helper' + +describe Petstore::ApiClient do + context 'initialization' do + context 'URL stuff' do + context 'host' do + it 'removes http from host' do + Petstore.configure { |c| c.host = 'http://example.com' } + expect(Petstore::Configuration.default.host).to eq('example.com') + end + + it 'removes https from host' do + Petstore.configure { |c| c.host = 'https://wookiee.com' } + expect(Petstore::ApiClient.default.config.host).to eq('wookiee.com') + end + + it 'removes trailing path from host' do + Petstore.configure { |c| c.host = 'hobo.com/v4' } + expect(Petstore::Configuration.default.host).to eq('hobo.com') + end + end + + context 'base_path' do + it "prepends a slash to base_path" do + Petstore.configure { |c| c.base_path = 'v4/dog' } + expect(Petstore::Configuration.default.base_path).to eq('/v4/dog') + end + + it "doesn't prepend a slash if one is already there" do + Petstore.configure { |c| c.base_path = '/v4/dog' } + expect(Petstore::Configuration.default.base_path).to eq('/v4/dog') + end + + it "ends up as a blank string if nil" do + Petstore.configure { |c| c.base_path = nil } + expect(Petstore::Configuration.default.base_path).to eq('') + end + end + end + end + + describe 'params_encoding in #build_request' do + let(:config) { Petstore::Configuration.new } + let(:api_client) { Petstore::ApiClient.new(config) } + + it 'defaults to nil' do + expect(Petstore::Configuration.default.params_encoding).to eq(nil) + expect(config.params_encoding).to eq(nil) + + request = api_client.build_request(:get, '/test') + expect(request.options[:params_encoding]).to eq(nil) + end + + it 'can be customized' do + config.params_encoding = :multi + request = api_client.build_request(:get, '/test') + expect(request.options[:params_encoding]).to eq(:multi) + end + end + + describe 'timeout in #build_request' do + let(:config) { Petstore::Configuration.new } + let(:api_client) { Petstore::ApiClient.new(config) } + + it 'defaults to 0' do + expect(Petstore::Configuration.default.timeout).to eq(0) + expect(config.timeout).to eq(0) + + request = api_client.build_request(:get, '/test') + expect(request.options[:timeout]).to eq(0) + end + + it 'can be customized' do + config.timeout = 100 + request = api_client.build_request(:get, '/test') + expect(request.options[:timeout]).to eq(100) + end + end + + describe '#deserialize' do + it "handles Array" do + api_client = Petstore::ApiClient.new + headers = { 'Content-Type' => 'application/json' } + response = double('response', headers: headers, body: '[12, 34]') + data = api_client.deserialize(response, 'Array') + expect(data).to be_instance_of(Array) + expect(data).to eq([12, 34]) + end + + it 'handles Array>' do + api_client = Petstore::ApiClient.new + headers = { 'Content-Type' => 'application/json' } + response = double('response', headers: headers, body: '[[12, 34], [56]]') + data = api_client.deserialize(response, 'Array>') + expect(data).to be_instance_of(Array) + expect(data).to eq([[12, 34], [56]]) + end + + it 'handles Hash' do + api_client = Petstore::ApiClient.new + headers = { 'Content-Type' => 'application/json' } + response = double('response', headers: headers, body: '{"message": "Hello"}') + data = api_client.deserialize(response, 'Hash') + expect(data).to be_instance_of(Hash) + expect(data).to eq(:message => 'Hello') + end + end + + describe "#object_to_hash" do + it 'ignores nils and includes empty arrays' do + # uncomment below to test object_to_hash for model + # api_client = Petstore::ApiClient.new + # _model = Petstore::ModelName.new + # update the model attribute below + # _model.id = 1 + # update the expected value (hash) below + # expected = {id: 1, name: '', tags: []} + # expect(api_client.object_to_hash(_model)).to eq(expected) + end + end + + describe '#build_collection_param' do + let(:param) { ['aa', 'bb', 'cc'] } + let(:api_client) { Petstore::ApiClient.new } + + it 'works for csv' do + expect(api_client.build_collection_param(param, :csv)).to eq('aa,bb,cc') + end + + it 'works for ssv' do + expect(api_client.build_collection_param(param, :ssv)).to eq('aa bb cc') + end + + it 'works for tsv' do + expect(api_client.build_collection_param(param, :tsv)).to eq("aa\tbb\tcc") + end + + it 'works for pipes' do + expect(api_client.build_collection_param(param, :pipes)).to eq('aa|bb|cc') + end + + it 'works for multi' do + expect(api_client.build_collection_param(param, :multi)).to eq(['aa', 'bb', 'cc']) + end + + it 'fails for invalid collection format' do + expect(proc { api_client.build_collection_param(param, :INVALID) }).to raise_error(RuntimeError, 'unknown collection format: :INVALID') + end + end + + describe '#json_mime?' do + let(:api_client) { Petstore::ApiClient.new } + + it 'works' do + expect(api_client.json_mime?(nil)).to eq false + expect(api_client.json_mime?('')).to eq false + + expect(api_client.json_mime?('application/json')).to eq true + expect(api_client.json_mime?('application/json; charset=UTF8')).to eq true + expect(api_client.json_mime?('APPLICATION/JSON')).to eq true + + expect(api_client.json_mime?('application/xml')).to eq false + expect(api_client.json_mime?('text/plain')).to eq false + expect(api_client.json_mime?('application/jsonp')).to eq false + end + end + + describe '#select_header_accept' do + let(:api_client) { Petstore::ApiClient.new } + + it 'works' do + expect(api_client.select_header_accept(nil)).to be_nil + expect(api_client.select_header_accept([])).to be_nil + + expect(api_client.select_header_accept(['application/json'])).to eq('application/json') + expect(api_client.select_header_accept(['application/xml', 'application/json; charset=UTF8'])).to eq('application/json; charset=UTF8') + expect(api_client.select_header_accept(['APPLICATION/JSON', 'text/html'])).to eq('APPLICATION/JSON') + + expect(api_client.select_header_accept(['application/xml'])).to eq('application/xml') + expect(api_client.select_header_accept(['text/html', 'application/xml'])).to eq('text/html,application/xml') + end + end + + describe '#select_header_content_type' do + let(:api_client) { Petstore::ApiClient.new } + + it 'works' do + expect(api_client.select_header_content_type(nil)).to eq('application/json') + expect(api_client.select_header_content_type([])).to eq('application/json') + + expect(api_client.select_header_content_type(['application/json'])).to eq('application/json') + expect(api_client.select_header_content_type(['application/xml', 'application/json; charset=UTF8'])).to eq('application/json; charset=UTF8') + expect(api_client.select_header_content_type(['APPLICATION/JSON', 'text/html'])).to eq('APPLICATION/JSON') + expect(api_client.select_header_content_type(['application/xml'])).to eq('application/xml') + expect(api_client.select_header_content_type(['text/plain', 'application/xml'])).to eq('text/plain') + end + end + + describe '#sanitize_filename' do + let(:api_client) { Petstore::ApiClient.new } + + it 'works' do + expect(api_client.sanitize_filename('sun')).to eq('sun') + expect(api_client.sanitize_filename('sun.gif')).to eq('sun.gif') + expect(api_client.sanitize_filename('../sun.gif')).to eq('sun.gif') + expect(api_client.sanitize_filename('/var/tmp/sun.gif')).to eq('sun.gif') + expect(api_client.sanitize_filename('./sun.gif')).to eq('sun.gif') + expect(api_client.sanitize_filename('..\sun.gif')).to eq('sun.gif') + expect(api_client.sanitize_filename('\var\tmp\sun.gif')).to eq('sun.gif') + expect(api_client.sanitize_filename('c:\var\tmp\sun.gif')).to eq('sun.gif') + expect(api_client.sanitize_filename('.\sun.gif')).to eq('sun.gif') + end + end +end diff --git a/samples/client/petstore-security-test/ruby/spec/configuration_spec.rb b/samples/client/petstore-security-test/ruby/spec/configuration_spec.rb new file mode 100644 index 00000000000..a96c86f8ac1 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/spec/configuration_spec.rb @@ -0,0 +1,42 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +require 'spec_helper' + +describe Petstore::Configuration do + let(:config) { Petstore::Configuration.default } + + before(:each) do + # uncomment below to setup host and base_path + # require 'URI' + # uri = URI.parse("http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r") + # Petstore.configure do |c| + # c.host = uri.host + # c.base_path = uri.path + # end + end + + describe '#base_url' do + it 'should have the default value' do + # uncomment below to test default value of the base path + # expect(config.base_url).to eq("http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r") + end + + it 'should remove trailing slashes' do + [nil, '', '/', '//'].each do |base_path| + config.base_path = base_path + # uncomment below to test trailing slashes + # expect(config.base_url).to eq("http://petstore.swagger.io */ ' \" =_end -- \\r\\n \\n \\r/v2 */ ' \" =_end -- \\r\\n \\n \\r") + end + end + end +end diff --git a/samples/client/petstore-security-test/ruby/spec/models/model_return_spec.rb b/samples/client/petstore-security-test/ruby/spec/models/model_return_spec.rb new file mode 100644 index 00000000000..7291382acae --- /dev/null +++ b/samples/client/petstore-security-test/ruby/spec/models/model_return_spec.rb @@ -0,0 +1,41 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +require 'spec_helper' +require 'json' +require 'date' + +# Unit tests for Petstore::ModelReturn +# Automatically generated by openapi-generator (https://openapi-generator.tech) +# Please update as you see appropriate +describe 'ModelReturn' do + before do + # run before each test + @instance = Petstore::ModelReturn.new + end + + after do + # run after each test + end + + describe 'test an instance of ModelReturn' do + it 'should create an instance of ModelReturn' do + expect(@instance).to be_instance_of(Petstore::ModelReturn) + end + end + describe 'test attribute "_return"' do + it 'should work' do + # assertion here. ref: https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers + end + end + +end diff --git a/samples/client/petstore-security-test/ruby/spec/spec_helper.rb b/samples/client/petstore-security-test/ruby/spec/spec_helper.rb new file mode 100644 index 00000000000..73515aedd47 --- /dev/null +++ b/samples/client/petstore-security-test/ruby/spec/spec_helper.rb @@ -0,0 +1,111 @@ +=begin +#OpenAPI Petstore */ ' \" =_end -- \\r\\n \\n \\r + +#This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ */ ' \" =_end -- + +OpenAPI spec version: 1.0.0 */ ' \" =_end -- \\r\\n \\n \\r +Contact: something@something.abc */ ' \" =_end -- \\r\\n \\n \\r +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 4.0.0-SNAPSHOT + +=end + +# load the gem +require 'petstore' + +# The following was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# The `.rspec` file also contains a few flags that are not defaults but that +# users commonly want. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # These two settings work together to allow you to limit a spec run + # to individual examples or groups you care about by tagging them with + # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # get run. + config.filter_run :focus + config.run_all_when_everything_filtered = true + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ + # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode + config.disable_monkey_patching! + + # This setting enables warnings. It's recommended, but in some cases may + # be too noisy due to issues in dependencies. + config.warnings = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = 'doc' + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end diff --git a/samples/client/petstore-security-test/swift/.gitignore b/samples/client/petstore-security-test/swift/.gitignore new file mode 100644 index 00000000000..5e5d5cebcf4 --- /dev/null +++ b/samples/client/petstore-security-test/swift/.gitignore @@ -0,0 +1,63 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md + +fastlane/report.xml +fastlane/screenshots diff --git a/samples/client/petstore-security-test/swift/.openapi-generator-ignore b/samples/client/petstore-security-test/swift/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/swift/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/swift/.openapi-generator/VERSION b/samples/client/petstore-security-test/swift/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/swift/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/swift/Cartfile b/samples/client/petstore-security-test/swift/Cartfile new file mode 100644 index 00000000000..3d90db16891 --- /dev/null +++ b/samples/client/petstore-security-test/swift/Cartfile @@ -0,0 +1 @@ +github "Alamofire/Alamofire" >= 3.1.0 diff --git a/samples/client/petstore-security-test/swift/OpenAPIClient.podspec b/samples/client/petstore-security-test/swift/OpenAPIClient.podspec new file mode 100644 index 00000000000..efcf6b1b019 --- /dev/null +++ b/samples/client/petstore-security-test/swift/OpenAPIClient.podspec @@ -0,0 +1,14 @@ +Pod::Spec.new do |s| + s.name = 'OpenAPIClient' + s.ios.deployment_target = '8.0' + s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '9.0' + s.version = '0.0.1' + s.source = { :git => 'git@github.com:openapitools/openapi-generator.git', :tag => 'v1.0.0' } + s.authors = 'OpenAPI Generator' + s.license = 'Proprietary' + s.homepage = 'https://openapi-generator.tech' + s.summary = 'OpenAPIClient Swift SDK' + s.source_files = 'OpenAPIClient/Classes/**/*.swift' + s.dependency 'Alamofire', '~> 3.5.1' +end diff --git a/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/APIHelper.swift b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/APIHelper.swift new file mode 100644 index 00000000000..2e354e54181 --- /dev/null +++ b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/APIHelper.swift @@ -0,0 +1,50 @@ +// APIHelper.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +class APIHelper { + static func rejectNil(source: [String:AnyObject?]) -> [String:AnyObject]? { + var destination = [String:AnyObject]() + for (key, nillableValue) in source { + if let value: AnyObject = nillableValue { + destination[key] = value + } + } + + if destination.isEmpty { + return nil + } + return destination + } + + static func rejectNilHeaders(source: [String:AnyObject?]) -> [String:String] { + var destination = [String:String]() + for (key, nillableValue) in source { + if let value: AnyObject = nillableValue { + destination[key] = "\(value)" + } + } + return destination + } + + static func convertBoolToString(source: [String: AnyObject]?) -> [String:AnyObject]? { + guard let source = source else { + return nil + } + var destination = [String:AnyObject]() + let theTrue = NSNumber(bool: true) + let theFalse = NSNumber(bool: false) + for (key, value) in source { + switch value { + case let x where x === theTrue || x === theFalse: + destination[key] = "\(value as! Bool)" + default: + destination[key] = value + } + } + return destination + } + +} diff --git a/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/APIs.swift b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/APIs.swift new file mode 100644 index 00000000000..f247ba69e3f --- /dev/null +++ b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/APIs.swift @@ -0,0 +1,77 @@ +// APIs.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation + +public class OpenAPIClientAPI { + public static var basePath = "http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r" + public static var credential: NSURLCredential? + public static var customHeaders: [String:String] = [:] + static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() +} + +public class APIBase { + func toParameters(encodable: JSONEncodable?) -> [String: AnyObject]? { + let encoded: AnyObject? = encodable?.encodeToJSON() + + if encoded! is [AnyObject] { + var dictionary = [String:AnyObject]() + for (index, item) in (encoded as! [AnyObject]).enumerate() { + dictionary["\(index)"] = item + } + return dictionary + } else { + return encoded as? [String:AnyObject] + } + } +} + +public class RequestBuilder { + var credential: NSURLCredential? + var headers: [String:String] + let parameters: [String:AnyObject]? + let isBody: Bool + let method: String + let URLString: String + + /// Optional block to obtain a reference to the request's progress instance when available. + public var onProgressReady: ((NSProgress) -> ())? + + required public init(method: String, URLString: String, parameters: [String:AnyObject]?, isBody: Bool, headers: [String:String] = [:]) { + self.method = method + self.URLString = URLString + self.parameters = parameters + self.isBody = isBody + self.headers = headers + + addHeaders(OpenAPIClientAPI.customHeaders) + } + + public func addHeaders(aHeaders:[String:String]) { + for (header, value) in aHeaders { + headers[header] = value + } + } + + public func execute(completion: (response: Response?, error: ErrorType?) -> Void) { } + + public func addHeader(name name: String, value: String) -> Self { + if !value.isEmpty { + headers[name] = value + } + return self + } + + public func addCredential() -> Self { + self.credential = OpenAPIClientAPI.credential + return self + } +} + +protocol RequestBuilderFactory { + func getBuilder() -> RequestBuilder.Type +} + diff --git a/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/APIs/FakeAPI.swift b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/APIs/FakeAPI.swift new file mode 100644 index 00000000000..ffc5c352faf --- /dev/null +++ b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/APIs/FakeAPI.swift @@ -0,0 +1,50 @@ +// +// FakeAPI.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Alamofire + + + +public class FakeAPI: APIBase { + /** + To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + - parameter testCodeInjectEndRnNR: (form) To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + - parameter completion: completion handler to receive the data and the error objects + */ + public class func testCodeInjectEndRnNR(testCodeInjectEndRnNR testCodeInjectEndRnNR: String? = nil, completion: ((error: ErrorType?) -> Void)) { + testCodeInjectEndRnNRWithRequestBuilder(testCodeInjectEndRnNR: testCodeInjectEndRnNR).execute { (response, error) -> Void in + completion(error: error); + } + } + + + /** + To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + - PUT /fake + - To test code injection *_/ ' \" =end -- \\r\\n \\n \\r - parameter testCodeInjectEndRnNR: (form) To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r (optional) + + - returns: RequestBuilder + */ + public class func testCodeInjectEndRnNRWithRequestBuilder(testCodeInjectEndRnNR testCodeInjectEndRnNR: String? = nil) -> RequestBuilder { + let path = "/fake" + let URLString = OpenAPIClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [ + "test code inject */ ' " =end -- \r\n \n \r": testCodeInjectEndRnNR + ] + + let parameters = APIHelper.rejectNil(nillableParameters) + + let convertedParameters = APIHelper.convertBoolToString(parameters) + + let requestBuilder: RequestBuilder.Type = OpenAPIClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder.init(method: "PUT", URLString: URLString, parameters: convertedParameters, isBody: false) + } + +} diff --git a/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/AlamofireImplementations.swift b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/AlamofireImplementations.swift new file mode 100644 index 00000000000..6752df2dfc0 --- /dev/null +++ b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/AlamofireImplementations.swift @@ -0,0 +1,207 @@ +// AlamofireImplementations.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Alamofire + +class AlamofireRequestBuilderFactory: RequestBuilderFactory { + func getBuilder() -> RequestBuilder.Type { + return AlamofireRequestBuilder.self + } +} + +public struct SynchronizedDictionary { + + private var dictionary = [K: V]() + private let queue = dispatch_queue_create("SynchronizedDictionary", DISPATCH_QUEUE_CONCURRENT) + + public subscript(key: K) -> V? { + get { + var value: V? + + dispatch_sync(queue) { + value = self.dictionary[key] + } + + return value + } + + set { + dispatch_barrier_sync(queue) { + self.dictionary[key] = newValue + } + } + } + +} + +// Store manager to retain its reference +private var managerStore = SynchronizedDictionary() + +class AlamofireRequestBuilder: RequestBuilder { + required init(method: String, URLString: String, parameters: [String : AnyObject]?, isBody: Bool, headers: [String : String] = [:]) { + super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody, headers: headers) + } + + override func execute(completion: (response: Response?, error: ErrorType?) -> Void) { + let managerId = NSUUID().UUIDString + // Create a new manager for each request to customize its request header + let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() + configuration.HTTPAdditionalHeaders = buildHeaders() + let manager = Alamofire.Manager(configuration: configuration) + managerStore[managerId] = manager + + let encoding = isBody ? Alamofire.ParameterEncoding.JSON : Alamofire.ParameterEncoding.URL + let xMethod = Alamofire.Method(rawValue: method) + let fileKeys = parameters == nil ? [] : parameters!.filter { $1.isKindOfClass(NSURL) } + .map { $0.0 } + + if fileKeys.count > 0 { + manager.upload( + xMethod!, URLString, headers: nil, + multipartFormData: { mpForm in + for (k, v) in self.parameters! { + switch v { + case let fileURL as NSURL: + mpForm.appendBodyPart(fileURL: fileURL, name: k) + case let string as NSString: + mpForm.appendBodyPart(data: string.dataUsingEncoding(NSUTF8StringEncoding)!, name: k) + case let number as NSNumber: + mpForm.appendBodyPart(data: number.stringValue.dataUsingEncoding(NSUTF8StringEncoding)!, name: k) + default: + fatalError("Unprocessable value \(v) with key \(k)") + } + } + }, + encodingMemoryThreshold: Manager.MultipartFormDataEncodingMemoryThreshold, + encodingCompletion: { encodingResult in + switch encodingResult { + case .Success(let uploadRequest, _, _): + if let onProgressReady = self.onProgressReady { + onProgressReady(uploadRequest.progress) + } + self.processRequest(uploadRequest, managerId, completion) + case .Failure(let encodingError): + completion(response: nil, error: ErrorResponse.error(415, nil, encodingError)) + } + } + ) + } else { + let request = manager.request(xMethod!, URLString, parameters: parameters, encoding: encoding) + if let onProgressReady = self.onProgressReady { + onProgressReady(request.progress) + } + processRequest(request, managerId, completion) + } + + } + + private func processRequest(request: Request, _ managerId: String, _ completion: (response: Response?, error: ErrorType?) -> Void) { + if let credential = self.credential { + request.authenticate(usingCredential: credential) + } + + let cleanupRequest = { + managerStore[managerId] = nil + } + + let validatedRequest = request.validate() + + switch T.self { + case is String.Type: + validatedRequest.responseString(completionHandler: { (stringResponse) in + cleanupRequest() + + if stringResponse.result.isFailure { + completion( + response: nil, + error: ErrorResponse.error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error!) + ) + return + } + + completion( + response: Response( + response: stringResponse.response!, + body: (stringResponse.result.value ?? "") as! T + ), + error: nil + ) + }) + case is Void.Type: + validatedRequest.responseData(completionHandler: { (voidResponse) in + cleanupRequest() + + if voidResponse.result.isFailure { + completion( + response: nil, + error: ErrorResponse.error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!) + ) + return + } + + completion( + response: Response( + response: voidResponse.response!, + body: nil + ), + error: nil + ) + }) + case is NSData.Type: + validatedRequest.responseData(completionHandler: { (dataResponse) in + cleanupRequest() + + if dataResponse.result.isFailure { + completion( + response: nil, + error: ErrorResponse.error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!) + ) + return + } + + completion( + response: Response( + response: dataResponse.response!, + body: dataResponse.data as! T + ), + error: nil + ) + }) + default: + validatedRequest.responseJSON(options: .AllowFragments) { response in + cleanupRequest() + + if response.result.isFailure { + completion(response: nil, error: ErrorResponse.error(response.response?.statusCode ?? 500, response.data, response.result.error!)) + return + } + + if () is T { + completion(response: Response(response: response.response!, body: () as! T), error: nil) + return + } + if let json: AnyObject = response.result.value { + let body = Decoders.decode(clazz: T.self, source: json) + completion(response: Response(response: response.response!, body: body), error: nil) + return + } else if "" is T { + completion(response: Response(response: response.response!, body: "" as! T), error: nil) + return + } + + completion(response: nil, error: ErrorResponse.error(500, nil, NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))) + } + } + } + + private func buildHeaders() -> [String: AnyObject] { + var httpHeaders = Manager.defaultHTTPHeaders + for (key, value) in self.headers { + httpHeaders[key] = value + } + return httpHeaders + } +} diff --git a/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/Extensions.swift b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/Extensions.swift new file mode 100644 index 00000000000..c04e734a7cb --- /dev/null +++ b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/Extensions.swift @@ -0,0 +1,179 @@ +// Extensions.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Alamofire + +extension Bool: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension Float: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension Int: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension Int32: JSONEncodable { + func encodeToJSON() -> AnyObject { return NSNumber(int: self) } +} + +extension Int64: JSONEncodable { + func encodeToJSON() -> AnyObject { return NSNumber(longLong: self) } +} + +extension Double: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension String: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +private func encodeIfPossible(object: T) -> AnyObject { + if object is JSONEncodable { + return (object as! JSONEncodable).encodeToJSON() + } else { + return object as! AnyObject + } +} + +extension Array: JSONEncodable { + func encodeToJSON() -> AnyObject { + return self.map(encodeIfPossible) + } +} + +extension Dictionary: JSONEncodable { + func encodeToJSON() -> AnyObject { + var dictionary = [NSObject:AnyObject]() + for (key, value) in self { + dictionary[key as! NSObject] = encodeIfPossible(value) + } + return dictionary + } +} + +extension NSData: JSONEncodable { + func encodeToJSON() -> AnyObject { + return self.base64EncodedStringWithOptions(NSDataBase64EncodingOptions()) + } +} + +private let dateFormatter: NSDateFormatter = { + let fmt = NSDateFormatter() + fmt.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ" + fmt.locale = NSLocale(localeIdentifier: "en_US_POSIX") + return fmt +}() + +extension NSDate: JSONEncodable { + func encodeToJSON() -> AnyObject { + return dateFormatter.stringFromDate(self) + } +} + +extension NSUUID: JSONEncodable { + func encodeToJSON() -> AnyObject { + return self.UUIDString + } +} + +/// Represents an ISO-8601 full-date (RFC-3339). +/// ex: 12-31-1999 +/// https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14 +public final class ISOFullDate: CustomStringConvertible { + + public let year: Int + public let month: Int + public let day: Int + + public init(year year: Int, month: Int, day: Int) { + self.year = year + self.month = month + self.day = day + } + + /** + Converts an NSDate to an ISOFullDate. Only interested in the year, month, day components. + + - parameter date: The date to convert. + + - returns: An ISOFullDate constructed from the year, month, day of the date. + */ + public static func from(date date: NSDate) -> ISOFullDate? { + guard let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian) else { + return nil + } + + let components = calendar.components( + [ + .Year, + .Month, + .Day, + ], + fromDate: date + ) + return ISOFullDate( + year: components.year, + month: components.month, + day: components.day + ) + } + + /** + Converts a ISO-8601 full-date string to an ISOFullDate. + + - parameter string: The ISO-8601 full-date format string to convert. + + - returns: An ISOFullDate constructed from the string. + */ + public static func from(string string: String) -> ISOFullDate? { + let components = string + .characters + .split("-") + .map(String.init) + .flatMap { Int($0) } + guard components.count == 3 else { return nil } + + return ISOFullDate( + year: components[0], + month: components[1], + day: components[2] + ) + } + + /** + Converts the receiver to an NSDate, in the default time zone. + + - returns: An NSDate from the components of the receiver, in the default time zone. + */ + public func toDate() -> NSDate? { + let components = NSDateComponents() + components.year = year + components.month = month + components.day = day + components.timeZone = NSTimeZone.defaultTimeZone() + let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian) + return calendar?.dateFromComponents(components) + } + + // MARK: CustomStringConvertible + + public var description: String { + return "\(year)-\(month)-\(day)" + } + +} + +extension ISOFullDate: JSONEncodable { + public func encodeToJSON() -> AnyObject { + return "\(year)-\(month)-\(day)" + } +} + + diff --git a/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/Models.swift b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/Models.swift new file mode 100644 index 00000000000..c59e09259ef --- /dev/null +++ b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/Models.swift @@ -0,0 +1,167 @@ +// Models.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation + +protocol JSONEncodable { + func encodeToJSON() -> AnyObject +} + +public enum ErrorResponse : ErrorType { + case Error(Int, NSData?, ErrorType) +} + +public class Response { + public let statusCode: Int + public let header: [String: String] + public let body: T? + + public init(statusCode: Int, header: [String: String], body: T?) { + self.statusCode = statusCode + self.header = header + self.body = body + } + + public convenience init(response: NSHTTPURLResponse, body: T?) { + let rawHeader = response.allHeaderFields + var header = [String:String]() + for case let (key, value) as (String, String) in rawHeader { + header[key] = value + } + self.init(statusCode: response.statusCode, header: header, body: body) + } +} + +private var once = dispatch_once_t() +class Decoders { + static private var decoders = Dictionary AnyObject)>() + + static func addDecoder(clazz clazz: T.Type, decoder: ((AnyObject) -> T)) { + let key = "\(T.self)" + decoders[key] = { decoder($0) as! AnyObject } + } + + static func decode(clazz clazz: [T].Type, source: AnyObject) -> [T] { + let array = source as! [AnyObject] + return array.map { Decoders.decode(clazz: T.self, source: $0) } + } + + static func decode(clazz clazz: [Key:T].Type, source: AnyObject) -> [Key:T] { + let sourceDictionary = source as! [Key: AnyObject] + var dictionary = [Key:T]() + for (key, value) in sourceDictionary { + dictionary[key] = Decoders.decode(clazz: T.self, source: value) + } + return dictionary + } + + static func decode(clazz clazz: T.Type, source: AnyObject) -> T { + initialize() + if T.self is Int32.Type && source is NSNumber { + return source.intValue as! T; + } + if T.self is Int64.Type && source is NSNumber { + return source.longLongValue as! T; + } + if T.self is NSUUID.Type && source is String { + return NSUUID(UUIDString: source as! String) as! T + } + if source is T { + return source as! T + } + if T.self is NSData.Type && source is String { + return NSData(base64EncodedString: source as! String, options: NSDataBase64DecodingOptions()) as! T + } + + let key = "\(T.self)" + if let decoder = decoders[key] { + return decoder(source) as! T + } else { + fatalError("Source \(source) is not convertible to type \(clazz): Maybe OpenAPI spec file is insufficient") + } + } + + static func decodeOptional(clazz clazz: T.Type, source: AnyObject?) -> T? { + if source is NSNull { + return nil + } + return source.map { (source: AnyObject) -> T in + Decoders.decode(clazz: clazz, source: source) + } + } + + static func decodeOptional(clazz clazz: [T].Type, source: AnyObject?) -> [T]? { + if source is NSNull { + return nil + } + return source.map { (someSource: AnyObject) -> [T] in + Decoders.decode(clazz: clazz, source: someSource) + } + } + + static func decodeOptional(clazz clazz: [Key:T].Type, source: AnyObject?) -> [Key:T]? { + if source is NSNull { + return nil + } + return source.map { (someSource: AnyObject) -> [Key:T] in + Decoders.decode(clazz: clazz, source: someSource) + } + } + + static private func initialize() { + dispatch_once(&once) { + let formatters = [ + "yyyy-MM-dd", + "yyyy-MM-dd'T'HH:mm:ssZZZZZ", + "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ", + "yyyy-MM-dd'T'HH:mm:ss'Z'", + "yyyy-MM-dd'T'HH:mm:ss.SSS" + ].map { (format: String) -> NSDateFormatter in + let formatter = NSDateFormatter() + formatter.locale = NSLocale(localeIdentifier:"en_US_POSIX") + formatter.dateFormat = format + return formatter + } + // Decoder for NSDate + Decoders.addDecoder(clazz: NSDate.self) { (source: AnyObject) -> NSDate in + if let sourceString = source as? String { + for formatter in formatters { + if let date = formatter.dateFromString(sourceString) { + return date + } + } + + } + if let sourceInt = source as? Int { + // treat as a java date + return NSDate(timeIntervalSince1970: Double(sourceInt / 1000) ) + } + fatalError("formatter failed to parse \(source)") + } + + // Decoder for ISOFullDate + Decoders.addDecoder(clazz: ISOFullDate.self, decoder: { (source: AnyObject) -> ISOFullDate in + if let string = source as? String, + let isoDate = ISOFullDate.from(string: string) { + return isoDate + } + fatalError("formatter failed to parse \(source)") + }) + + // Decoder for [Return] + Decoders.addDecoder(clazz: [Return].self) { (source: AnyObject) -> [Return] in + return Decoders.decode(clazz: [Return].self, source: source) + } + // Decoder for Return + Decoders.addDecoder(clazz: Return.self) { (source: AnyObject) -> Return in + let sourceDictionary = source as! [NSObject:AnyObject] + let instance = Return() + instance._return = Decoders.decodeOptional(clazz: Int32.self, source: sourceDictionary["return"]) + return instance + } + } + } +} diff --git a/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/Models/Return.swift b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/Models/Return.swift new file mode 100644 index 00000000000..201ecd32429 --- /dev/null +++ b/samples/client/petstore-security-test/swift/OpenAPIClient/Classes/OpenAPIs/Models/Return.swift @@ -0,0 +1,25 @@ +// +// Return.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation + + +/** Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r */ +public class Return: JSONEncodable { + /** property description *_/ ' \" =end -- \\r\\n \\n \\r */ + public var _return: Int32? + + public init() {} + + // MARK: JSONEncodable + func encodeToJSON() -> AnyObject { + var nillableDictionary = [String:AnyObject?]() + nillableDictionary["return"] = self._return?.encodeToJSON() + let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] + return dictionary + } +} diff --git a/samples/client/petstore-security-test/swift/git_push.sh b/samples/client/petstore-security-test/swift/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/swift/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/typescript-angular/.gitignore b/samples/client/petstore-security-test/typescript-angular/.gitignore new file mode 100644 index 00000000000..149b5765472 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/.gitignore @@ -0,0 +1,4 @@ +wwwroot/*.js +node_modules +typings +dist diff --git a/samples/client/petstore-security-test/typescript-angular/.openapi-generator-ignore b/samples/client/petstore-security-test/typescript-angular/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/typescript-angular/.openapi-generator/VERSION b/samples/client/petstore-security-test/typescript-angular/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-angular/README.md b/samples/client/petstore-security-test/typescript-angular/README.md new file mode 100644 index 00000000000..6fdf5e362fe --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/README.md @@ -0,0 +1,180 @@ +## @ + +### Building + +To install the required dependencies and to build the typescript sources run: +``` +npm install +npm run build +``` + +### publishing + +First build the package then run ```npm publish``` + +### consuming + +Navigate to the folder of your consuming project and run one of next commands. + +_published:_ + +``` +npm install @ --save +``` + +_without publishing (not recommended):_ + +``` +npm install PATH_TO_GENERATED_PACKAGE/-.tgz --save +``` + +_It's important to take the tgz file, otherwise you'll get trouble with links on windows_ + +_using `npm link`:_ + +In PATH_TO_GENERATED_PACKAGE: +``` +npm link +``` + +In your project: +``` +npm link +``` + +__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. +Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Published packages are not effected by this issue. + + +#### General usage + +In your Angular project: + + +``` +// without configuring providers +import { ApiModule } from ''; +import { HttpClientModule } from '@angular/common/http'; + + +@NgModule({ + imports: [ + ApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers +import { ApiModule, Configuration, ConfigurationParameters } from ''; + +export function apiConfigFactory (): Configuration => { + const params: ConfigurationParameters = { + // set configuration parameters here. + } + return new Configuration(params); +} + +@NgModule({ + imports: [ ApiModule.forRoot(apiConfigFactory) ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +import { DefaultApi } from ''; + +export class AppComponent { + constructor(private apiGateway: DefaultApi) { } +} +``` + +Note: The ApiModule is restricted to being instantiated once app wide. +This is to ensure that all services are treated as singletons. + +#### Using multiple OpenAPI files / APIs / ApiModules +In order to use multiple `ApiModules` generated from different OpenAPI files, +you can create an alias name when importing the modules +in order to avoid naming conflicts: +``` +import { ApiModule } from 'my-api-path'; +import { ApiModule as OtherApiModule } from 'my-other-api-path'; +import { HttpClientModule } from '@angular/common/http'; + + +@NgModule({ + imports: [ + ApiModule, + OtherApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ] +}) +export class AppModule { + +} +``` + + +### Set service base path +If different than the generated base path, during app bootstrap, you can provide the base path to your service. + +``` +import { BASE_PATH } from ''; + +bootstrap(AppComponent, [ + { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, +]); +``` +or + +``` +import { BASE_PATH } from ''; + +@NgModule({ + imports: [], + declarations: [ AppComponent ], + providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + + +#### Using @angular/cli +First extend your `src/environments/*.ts` files by adding the corresponding base path: + +``` +export const environment = { + production: false, + API_BASE_PATH: 'http://127.0.0.1:8080' +}; +``` + +In the src/app/app.module.ts: +``` +import { BASE_PATH } from ''; +import { environment } from '../environments/environment'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ ], + providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +``` diff --git a/samples/client/petstore-security-test/typescript-angular/api.module.ts b/samples/client/petstore-security-test/typescript-angular/api.module.ts new file mode 100644 index 00000000000..867cee5c7b2 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/api.module.ts @@ -0,0 +1,33 @@ +import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core'; +import { Configuration } from './configuration'; +import { HttpClient } from '@angular/common/http'; + + +import { FakeService } from './api/fake.service'; + +@NgModule({ + imports: [], + declarations: [], + exports: [], + providers: [ + FakeService ] +}) +export class ApiModule { + public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders { + return { + ngModule: ApiModule, + providers: [ { provide: Configuration, useFactory: configurationFactory } ] + }; + } + + constructor( @Optional() @SkipSelf() parentModule: ApiModule, + @Optional() http: HttpClient) { + if (parentModule) { + throw new Error('ApiModule is already loaded. Import in your base AppModule only.'); + } + if (!http) { + throw new Error('You need to import the HttpClientModule in your AppModule! \n' + + 'See also https://github.com/angular/angular/issues/20575'); + } + } +} diff --git a/samples/client/petstore-security-test/typescript-angular/api/api.ts b/samples/client/petstore-security-test/typescript-angular/api/api.ts new file mode 100644 index 00000000000..1457e1d01f4 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/api/api.ts @@ -0,0 +1,3 @@ +export * from './fake.service'; +import { FakeService } from './fake.service'; +export const APIS = [FakeService]; diff --git a/samples/client/petstore-security-test/typescript-angular/api/fake.service.ts b/samples/client/petstore-security-test/typescript-angular/api/fake.service.ts new file mode 100644 index 00000000000..ede82df3b82 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/api/fake.service.ts @@ -0,0 +1,115 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +/* tslint:disable:no-unused-variable member-ordering */ + +import { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent } from '@angular/common/http'; +import { CustomHttpUrlEncodingCodec } from '../encoder'; + +import { Observable } from 'rxjs'; + + +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + + +@Injectable({ + providedIn: 'root' +}) +export class FakeService { + + protected basePath = 'http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r'; + public defaultHeaders = new HttpHeaders(); + public configuration = new Configuration(); + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) { + + if (configuration) { + this.configuration = configuration; + this.configuration.basePath = configuration.basePath || basePath || this.basePath; + + } else { + this.configuration.basePath = basePath || this.basePath; + } + } + + /** + * @param consumes string[] mime-types + * @return true: consumes contains 'multipart/form-data', false: otherwise + */ + private canConsumeForm(consumes: string[]): boolean { + const form = 'multipart/form-data'; + for (const consume of consumes) { + if (form === consume) { + return true; + } + } + return false; + } + + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param testCodeInjectEndRnNR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe?: 'body', reportProgress?: boolean): Observable; + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe?: 'response', reportProgress?: boolean): Observable>; + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe?: 'events', reportProgress?: boolean): Observable>; + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe: any = 'body', reportProgress: boolean = false ): Observable { + + let headers = this.defaultHeaders; + + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts); + if (httpHeaderAcceptSelected !== undefined) { + headers = headers.set('Accept', httpHeaderAcceptSelected); + } + + // to determine the Content-Type header + const consumes: string[] = [ + 'application/x-www-form-urlencoded', + '*_/ =end -- ' + ]; + + const canConsumeForm = this.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any; }; + let useForm = false; + let convertFormParamsToString = false; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()}); + } + + if (testCodeInjectEndRnNR !== undefined) { + formParams = formParams.append('test code inject */ ' " =end -- \r\n \n \r', testCodeInjectEndRnNR) as any || formParams; + } + + return this.httpClient.put(`${this.configuration.basePath}/fake`, + convertFormParamsToString ? formParams.toString() : formParams, + { + withCredentials: this.configuration.withCredentials, + headers: headers, + observe: observe, + reportProgress: reportProgress + } + ); + } + +} diff --git a/samples/client/petstore-security-test/typescript-angular/configuration.ts b/samples/client/petstore-security-test/typescript-angular/configuration.ts new file mode 100644 index 00000000000..1132f4adc17 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/configuration.ts @@ -0,0 +1,79 @@ +export interface ConfigurationParameters { + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; +} + +export class Configuration { + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + + constructor(configurationParameters: ConfigurationParameters = {}) { + this.apiKeys = configurationParameters.apiKeys; + this.username = configurationParameters.username; + this.password = configurationParameters.password; + this.accessToken = configurationParameters.accessToken; + this.basePath = configurationParameters.basePath; + this.withCredentials = configurationParameters.withCredentials; + } + + /** + * Select the correct content-type to use for a request. + * Uses {@link Configuration#isJsonMime} to determine the correct content-type. + * If no content type is found return the first found type if the contentTypes is not empty + * @param contentTypes - the array of content types that are available for selection + * @returns the selected content-type or undefined if no selection could be made. + */ + public selectHeaderContentType (contentTypes: string[]): string | undefined { + if (contentTypes.length === 0) { + return undefined; + } + + const type = contentTypes.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return contentTypes[0]; + } + return type; + } + + /** + * Select the correct accept content-type to use for a request. + * Uses {@link Configuration#isJsonMime} to determine the correct accept content-type. + * If no content type is found return the first found type if the contentTypes is not empty + * @param accepts - the array of content types that are available for selection. + * @returns the selected content-type or undefined if no selection could be made. + */ + public selectHeaderAccept(accepts: string[]): string | undefined { + if (accepts.length === 0) { + return undefined; + } + + const type = accepts.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return accepts[0]; + } + return type; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } +} diff --git a/samples/client/petstore-security-test/typescript-angular/encoder.ts b/samples/client/petstore-security-test/typescript-angular/encoder.ts new file mode 100644 index 00000000000..f1c6b78c9c8 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/encoder.ts @@ -0,0 +1,18 @@ + import { HttpUrlEncodingCodec } from '@angular/common/http'; + +/** +* CustomHttpUrlEncodingCodec +* Fix plus sign (+) not encoding, so sent as blank space +* See: https://github.com/angular/angular/issues/11058#issuecomment-247367318 +*/ +export class CustomHttpUrlEncodingCodec extends HttpUrlEncodingCodec { + encodeKey(k: string): string { + k = super.encodeKey(k); + return k.replace(/\+/gi, '%2B'); + } + encodeValue(v: string): string { + v = super.encodeValue(v); + return v.replace(/\+/gi, '%2B'); + } +} + diff --git a/samples/client/petstore-security-test/typescript-angular/git_push.sh b/samples/client/petstore-security-test/typescript-angular/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/typescript-angular/index.ts b/samples/client/petstore-security-test/typescript-angular/index.ts new file mode 100644 index 00000000000..c312b70fa3e --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/index.ts @@ -0,0 +1,5 @@ +export * from './api/api'; +export * from './model/models'; +export * from './variables'; +export * from './configuration'; +export * from './api.module'; \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-angular/model/models.ts b/samples/client/petstore-security-test/typescript-angular/model/models.ts new file mode 100644 index 00000000000..472428482c7 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/model/models.ts @@ -0,0 +1 @@ +export * from './return'; diff --git a/samples/client/petstore-security-test/typescript-angular/model/return.ts b/samples/client/petstore-security-test/typescript-angular/model/return.ts new file mode 100644 index 00000000000..52f685bd011 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/model/return.ts @@ -0,0 +1,23 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r + */ +export interface Return { + /** + * property description *_/ ' \" =end -- \\r\\n \\n \\r + */ + _return?: number; +} + diff --git a/samples/client/petstore-security-test/typescript-angular/variables.ts b/samples/client/petstore-security-test/typescript-angular/variables.ts new file mode 100644 index 00000000000..6fe58549f39 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular/variables.ts @@ -0,0 +1,9 @@ +import { InjectionToken } from '@angular/core'; + +export const BASE_PATH = new InjectionToken('basePath'); +export const COLLECTION_FORMATS = { + 'csv': ',', + 'tsv': ' ', + 'ssv': ' ', + 'pipes': '|' +} diff --git a/samples/client/petstore-security-test/typescript-angular2/.gitignore b/samples/client/petstore-security-test/typescript-angular2/.gitignore new file mode 100644 index 00000000000..149b5765472 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/.gitignore @@ -0,0 +1,4 @@ +wwwroot/*.js +node_modules +typings +dist diff --git a/samples/client/petstore-security-test/typescript-angular2/.openapi-generator-ignore b/samples/client/petstore-security-test/typescript-angular2/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/typescript-angular2/.openapi-generator/VERSION b/samples/client/petstore-security-test/typescript-angular2/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-angular2/README.md b/samples/client/petstore-security-test/typescript-angular2/README.md new file mode 100644 index 00000000000..6fdf5e362fe --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/README.md @@ -0,0 +1,180 @@ +## @ + +### Building + +To install the required dependencies and to build the typescript sources run: +``` +npm install +npm run build +``` + +### publishing + +First build the package then run ```npm publish``` + +### consuming + +Navigate to the folder of your consuming project and run one of next commands. + +_published:_ + +``` +npm install @ --save +``` + +_without publishing (not recommended):_ + +``` +npm install PATH_TO_GENERATED_PACKAGE/-.tgz --save +``` + +_It's important to take the tgz file, otherwise you'll get trouble with links on windows_ + +_using `npm link`:_ + +In PATH_TO_GENERATED_PACKAGE: +``` +npm link +``` + +In your project: +``` +npm link +``` + +__Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. +Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Published packages are not effected by this issue. + + +#### General usage + +In your Angular project: + + +``` +// without configuring providers +import { ApiModule } from ''; +import { HttpClientModule } from '@angular/common/http'; + + +@NgModule({ + imports: [ + ApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +// configuring providers +import { ApiModule, Configuration, ConfigurationParameters } from ''; + +export function apiConfigFactory (): Configuration => { + const params: ConfigurationParameters = { + // set configuration parameters here. + } + return new Configuration(params); +} + +@NgModule({ + imports: [ ApiModule.forRoot(apiConfigFactory) ], + declarations: [ AppComponent ], + providers: [], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + +``` +import { DefaultApi } from ''; + +export class AppComponent { + constructor(private apiGateway: DefaultApi) { } +} +``` + +Note: The ApiModule is restricted to being instantiated once app wide. +This is to ensure that all services are treated as singletons. + +#### Using multiple OpenAPI files / APIs / ApiModules +In order to use multiple `ApiModules` generated from different OpenAPI files, +you can create an alias name when importing the modules +in order to avoid naming conflicts: +``` +import { ApiModule } from 'my-api-path'; +import { ApiModule as OtherApiModule } from 'my-other-api-path'; +import { HttpClientModule } from '@angular/common/http'; + + +@NgModule({ + imports: [ + ApiModule, + OtherApiModule, + // make sure to import the HttpClientModule in the AppModule only, + // see https://github.com/angular/angular/issues/20575 + HttpClientModule + ] +}) +export class AppModule { + +} +``` + + +### Set service base path +If different than the generated base path, during app bootstrap, you can provide the base path to your service. + +``` +import { BASE_PATH } from ''; + +bootstrap(AppComponent, [ + { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, +]); +``` +or + +``` +import { BASE_PATH } from ''; + +@NgModule({ + imports: [], + declarations: [ AppComponent ], + providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], + bootstrap: [ AppComponent ] +}) +export class AppModule {} +``` + + +#### Using @angular/cli +First extend your `src/environments/*.ts` files by adding the corresponding base path: + +``` +export const environment = { + production: false, + API_BASE_PATH: 'http://127.0.0.1:8080' +}; +``` + +In the src/app/app.module.ts: +``` +import { BASE_PATH } from ''; +import { environment } from '../environments/environment'; + +@NgModule({ + declarations: [ + AppComponent + ], + imports: [ ], + providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +``` diff --git a/samples/client/petstore-security-test/typescript-angular2/api.module.ts b/samples/client/petstore-security-test/typescript-angular2/api.module.ts new file mode 100644 index 00000000000..867cee5c7b2 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/api.module.ts @@ -0,0 +1,33 @@ +import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core'; +import { Configuration } from './configuration'; +import { HttpClient } from '@angular/common/http'; + + +import { FakeService } from './api/fake.service'; + +@NgModule({ + imports: [], + declarations: [], + exports: [], + providers: [ + FakeService ] +}) +export class ApiModule { + public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders { + return { + ngModule: ApiModule, + providers: [ { provide: Configuration, useFactory: configurationFactory } ] + }; + } + + constructor( @Optional() @SkipSelf() parentModule: ApiModule, + @Optional() http: HttpClient) { + if (parentModule) { + throw new Error('ApiModule is already loaded. Import in your base AppModule only.'); + } + if (!http) { + throw new Error('You need to import the HttpClientModule in your AppModule! \n' + + 'See also https://github.com/angular/angular/issues/20575'); + } + } +} diff --git a/samples/client/petstore-security-test/typescript-angular2/api/api.ts b/samples/client/petstore-security-test/typescript-angular2/api/api.ts new file mode 100644 index 00000000000..1457e1d01f4 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/api/api.ts @@ -0,0 +1,3 @@ +export * from './fake.service'; +import { FakeService } from './fake.service'; +export const APIS = [FakeService]; diff --git a/samples/client/petstore-security-test/typescript-angular2/api/fake.service.ts b/samples/client/petstore-security-test/typescript-angular2/api/fake.service.ts new file mode 100644 index 00000000000..ede82df3b82 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/api/fake.service.ts @@ -0,0 +1,115 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +/* tslint:disable:no-unused-variable member-ordering */ + +import { Inject, Injectable, Optional } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpParams, + HttpResponse, HttpEvent } from '@angular/common/http'; +import { CustomHttpUrlEncodingCodec } from '../encoder'; + +import { Observable } from 'rxjs'; + + +import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + + +@Injectable({ + providedIn: 'root' +}) +export class FakeService { + + protected basePath = 'http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r'; + public defaultHeaders = new HttpHeaders(); + public configuration = new Configuration(); + + constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) { + + if (configuration) { + this.configuration = configuration; + this.configuration.basePath = configuration.basePath || basePath || this.basePath; + + } else { + this.configuration.basePath = basePath || this.basePath; + } + } + + /** + * @param consumes string[] mime-types + * @return true: consumes contains 'multipart/form-data', false: otherwise + */ + private canConsumeForm(consumes: string[]): boolean { + const form = 'multipart/form-data'; + for (const consume of consumes) { + if (form === consume) { + return true; + } + } + return false; + } + + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param testCodeInjectEndRnNR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r + * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. + * @param reportProgress flag to report request and response progress. + */ + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe?: 'body', reportProgress?: boolean): Observable; + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe?: 'response', reportProgress?: boolean): Observable>; + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe?: 'events', reportProgress?: boolean): Observable>; + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe: any = 'body', reportProgress: boolean = false ): Observable { + + let headers = this.defaultHeaders; + + // to determine the Accept header + const httpHeaderAccepts: string[] = [ + ]; + const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts); + if (httpHeaderAcceptSelected !== undefined) { + headers = headers.set('Accept', httpHeaderAcceptSelected); + } + + // to determine the Content-Type header + const consumes: string[] = [ + 'application/x-www-form-urlencoded', + '*_/ =end -- ' + ]; + + const canConsumeForm = this.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any; }; + let useForm = false; + let convertFormParamsToString = false; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()}); + } + + if (testCodeInjectEndRnNR !== undefined) { + formParams = formParams.append('test code inject */ ' " =end -- \r\n \n \r', testCodeInjectEndRnNR) as any || formParams; + } + + return this.httpClient.put(`${this.configuration.basePath}/fake`, + convertFormParamsToString ? formParams.toString() : formParams, + { + withCredentials: this.configuration.withCredentials, + headers: headers, + observe: observe, + reportProgress: reportProgress + } + ); + } + +} diff --git a/samples/client/petstore-security-test/typescript-angular2/configuration.ts b/samples/client/petstore-security-test/typescript-angular2/configuration.ts new file mode 100644 index 00000000000..1132f4adc17 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/configuration.ts @@ -0,0 +1,79 @@ +export interface ConfigurationParameters { + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; +} + +export class Configuration { + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; + + constructor(configurationParameters: ConfigurationParameters = {}) { + this.apiKeys = configurationParameters.apiKeys; + this.username = configurationParameters.username; + this.password = configurationParameters.password; + this.accessToken = configurationParameters.accessToken; + this.basePath = configurationParameters.basePath; + this.withCredentials = configurationParameters.withCredentials; + } + + /** + * Select the correct content-type to use for a request. + * Uses {@link Configuration#isJsonMime} to determine the correct content-type. + * If no content type is found return the first found type if the contentTypes is not empty + * @param contentTypes - the array of content types that are available for selection + * @returns the selected content-type or undefined if no selection could be made. + */ + public selectHeaderContentType (contentTypes: string[]): string | undefined { + if (contentTypes.length === 0) { + return undefined; + } + + const type = contentTypes.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return contentTypes[0]; + } + return type; + } + + /** + * Select the correct accept content-type to use for a request. + * Uses {@link Configuration#isJsonMime} to determine the correct accept content-type. + * If no content type is found return the first found type if the contentTypes is not empty + * @param accepts - the array of content types that are available for selection. + * @returns the selected content-type or undefined if no selection could be made. + */ + public selectHeaderAccept(accepts: string[]): string | undefined { + if (accepts.length === 0) { + return undefined; + } + + const type = accepts.find((x: string) => this.isJsonMime(x)); + if (type === undefined) { + return accepts[0]; + } + return type; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } +} diff --git a/samples/client/petstore-security-test/typescript-angular2/encoder.ts b/samples/client/petstore-security-test/typescript-angular2/encoder.ts new file mode 100644 index 00000000000..f1c6b78c9c8 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/encoder.ts @@ -0,0 +1,18 @@ + import { HttpUrlEncodingCodec } from '@angular/common/http'; + +/** +* CustomHttpUrlEncodingCodec +* Fix plus sign (+) not encoding, so sent as blank space +* See: https://github.com/angular/angular/issues/11058#issuecomment-247367318 +*/ +export class CustomHttpUrlEncodingCodec extends HttpUrlEncodingCodec { + encodeKey(k: string): string { + k = super.encodeKey(k); + return k.replace(/\+/gi, '%2B'); + } + encodeValue(v: string): string { + v = super.encodeValue(v); + return v.replace(/\+/gi, '%2B'); + } +} + diff --git a/samples/client/petstore-security-test/typescript-angular2/git_push.sh b/samples/client/petstore-security-test/typescript-angular2/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/typescript-angular2/index.ts b/samples/client/petstore-security-test/typescript-angular2/index.ts new file mode 100644 index 00000000000..c312b70fa3e --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/index.ts @@ -0,0 +1,5 @@ +export * from './api/api'; +export * from './model/models'; +export * from './variables'; +export * from './configuration'; +export * from './api.module'; \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-angular2/model/models.ts b/samples/client/petstore-security-test/typescript-angular2/model/models.ts new file mode 100644 index 00000000000..472428482c7 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/model/models.ts @@ -0,0 +1 @@ +export * from './return'; diff --git a/samples/client/petstore-security-test/typescript-angular2/model/return.ts b/samples/client/petstore-security-test/typescript-angular2/model/return.ts new file mode 100644 index 00000000000..52f685bd011 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/model/return.ts @@ -0,0 +1,23 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r + */ +export interface Return { + /** + * property description *_/ ' \" =end -- \\r\\n \\n \\r + */ + _return?: number; +} + diff --git a/samples/client/petstore-security-test/typescript-angular2/variables.ts b/samples/client/petstore-security-test/typescript-angular2/variables.ts new file mode 100644 index 00000000000..6fe58549f39 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-angular2/variables.ts @@ -0,0 +1,9 @@ +import { InjectionToken } from '@angular/core'; + +export const BASE_PATH = new InjectionToken('basePath'); +export const COLLECTION_FORMATS = { + 'csv': ',', + 'tsv': ' ', + 'ssv': ' ', + 'pipes': '|' +} diff --git a/samples/client/petstore-security-test/typescript-fetch/.openapi-generator-ignore b/samples/client/petstore-security-test/typescript-fetch/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-fetch/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/typescript-fetch/.openapi-generator/VERSION b/samples/client/petstore-security-test/typescript-fetch/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-fetch/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-fetch/apis/FakeApi.ts b/samples/client/petstore-security-test/typescript-fetch/apis/FakeApi.ts new file mode 100644 index 00000000000..f759a18ce52 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-fetch/apis/FakeApi.ts @@ -0,0 +1,59 @@ +// tslint:disable +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; + +export interface TestCodeInjectEndRnNRRequest { + testCodeInjectEndRnNR?: string; +} + +/** + * no description + */ +export class FakeApi extends runtime.BaseAPI { + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + */ + async testCodeInjectEndRnNRRaw(requestParameters: TestCodeInjectEndRnNRRequest): Promise> { + const queryParameters: runtime.HTTPQuery = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const formData = new FormData(); + if (requestParameters.testCodeInjectEndRnNR !== undefined) { + formData.append('test code inject */ ' " =end -- \r\n \n \r', requestParameters.testCodeInjectEndRnNR as any); + } + + const response = await this.request({ + path: `/fake`, + method: 'PUT', + headers: headerParameters, + query: queryParameters, + body: formData, + }); + + return new runtime.VoidApiResponse(response); + } + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + */ + async testCodeInjectEndRnNR(requestParameters: TestCodeInjectEndRnNRRequest): Promise { + await this.testCodeInjectEndRnNRRaw(requestParameters); + } + +} diff --git a/samples/client/petstore-security-test/typescript-fetch/apis/index.ts b/samples/client/petstore-security-test/typescript-fetch/apis/index.ts new file mode 100644 index 00000000000..9525ab85127 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-fetch/apis/index.ts @@ -0,0 +1 @@ +export * from './FakeApi'; diff --git a/samples/client/petstore-security-test/typescript-fetch/index.ts b/samples/client/petstore-security-test/typescript-fetch/index.ts new file mode 100644 index 00000000000..848ecfa4d10 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-fetch/index.ts @@ -0,0 +1,3 @@ +export * from './runtime'; +export * from './apis'; +export * from './models'; diff --git a/samples/client/petstore-security-test/typescript-fetch/models/Return.ts b/samples/client/petstore-security-test/typescript-fetch/models/Return.ts new file mode 100644 index 00000000000..2c7c5bde635 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-fetch/models/Return.ts @@ -0,0 +1,44 @@ +// tslint:disable +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists } from '../runtime'; +/** + * Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r + * @export + * @interface Return + */ +export interface Return { + /** + * property description *_/ ' \" =end -- \\r\\n \\n \\r + * @type {number} + * @memberof Return + */ + _return?: number; +} + +export function ReturnFromJSON(json: any): Return { + return { + '_return': !exists(json, 'return') ? undefined : json['return'], + }; +} + +export function ReturnToJSON(value?: Return): any { + if (value === undefined) { + return undefined; + } + return { + 'return': value._return, + }; +} + + diff --git a/samples/client/petstore-security-test/typescript-fetch/models/index.ts b/samples/client/petstore-security-test/typescript-fetch/models/index.ts new file mode 100644 index 00000000000..8d45f62a1d6 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-fetch/models/index.ts @@ -0,0 +1 @@ +export * from './Return'; diff --git a/samples/client/petstore-security-test/typescript-fetch/runtime.ts b/samples/client/petstore-security-test/typescript-fetch/runtime.ts new file mode 100644 index 00000000000..1fdcc0a5620 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-fetch/runtime.ts @@ -0,0 +1,272 @@ +// tslint:disable +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export const BASE_PATH = "http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r".replace(/\/+$/, ""); + +/** + * This is the base class for all generated API classes. + */ +export class BaseAPI { + + private middleware: Middleware[]; + + constructor(protected configuration = new Configuration()) { + this.middleware = configuration.middleware; + } + + withMiddleware(this: T, ...middlewares: Middleware[]) { + const next = this.clone(); + next.middleware = next.middleware.concat(...middlewares); + return next; + } + + withPreMiddleware(this: T, ...preMiddlewares: Array) { + const middlewares = preMiddlewares.map((pre) => ({ pre })); + return this.withMiddleware(...middlewares); + } + + withPostMiddleware(this: T, ...postMiddlewares: Array) { + const middlewares = postMiddlewares.map((post) => ({ post })); + return this.withMiddleware(...middlewares); + } + + protected async request(context: RequestOpts): Promise { + const { url, init } = this.createFetchParams(context); + const response = await this.fetchApi(url, init); + if (response.status >= 200 && response.status < 300) { + return response; + } + throw response; + } + + private createFetchParams(context: RequestOpts) { + let url = this.configuration.basePath + context.path; + if (context.query !== undefined && Object.keys(context.query).length !== 0) { + // only add the querystring to the URL if there are query parameters. + // this is done to avoid urls ending with a "?" character which buggy webservers + // do not handle correctly sometimes. + url += '?' + querystring(context.query); + } + const body = context.body instanceof FormData ? context.body : JSON.stringify(context.body); + const init = { + method: context.method, + headers: context.headers, + body, + }; + return { url, init }; + } + + private fetchApi = async (url: string, init: RequestInit) => { + let fetchParams = { url, init }; + for (const middleware of this.middleware) { + if (middleware.pre) { + fetchParams = await middleware.pre({ + fetch: this.fetchApi, + ...fetchParams, + }) || fetchParams; + } + } + let response = await this.configuration.fetchApi(fetchParams.url, fetchParams.init); + for (const middleware of this.middleware) { + if (middleware.post) { + response = await middleware.post({ + fetch: this.fetchApi, + url, + init, + response: response.clone(), + }) || response; + } + } + return response; + } + + /** + * Create a shallow clone of `this` by constructing a new instance + * and then shallow cloning data members. + */ + private clone(this: T): T { + const constructor = this.constructor as any; + const next = new constructor(this.configuration); + next.middleware = this.middleware.slice(); + return next; + } +}; + +export class RequiredError extends Error { + name: "RequiredError" = "RequiredError"; + constructor(public field: string, msg?: string) { + super(msg); + } +} + +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +export type FetchAPI = GlobalFetch['fetch']; + +export interface ConfigurationParameters { + basePath?: string; // override base path + fetchApi?: FetchAPI; // override for fetch implementation + middleware?: Middleware[]; // middleware to apply before/after fetch requests + username?: string; // parameter for basic security + password?: string; // parameter for basic security + apiKey?: string | ((name: string) => string); // parameter for apiKey security + accessToken?: string | ((name: string, scopes?: string[]) => string); // parameter for oauth2 security +} + +export class Configuration { + constructor(private configuration: ConfigurationParameters = {}) {} + + get basePath(): string { + return this.configuration.basePath || BASE_PATH; + } + + get fetchApi(): FetchAPI { + return this.configuration.fetchApi || window.fetch.bind(window); + } + + get middleware(): Middleware[] { + return this.configuration.middleware || []; + } + + get username(): string | undefined { + return this.configuration.username; + } + + get password(): string | undefined { + return this.configuration.password; + } + + get apiKey(): ((name: string) => string) | undefined { + const apiKey = this.configuration.apiKey; + if (apiKey) { + return typeof apiKey === 'function' ? apiKey : () => apiKey; + } + return undefined; + } + + get accessToken(): ((name: string, scopes?: string[]) => string) | undefined { + const accessToken = this.configuration.accessToken; + if (accessToken) { + return typeof accessToken === 'function' ? accessToken : () => accessToken; + } + return undefined; + } +} + +export type Json = any; +export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS'; +export type HTTPHeaders = { [key: string]: string }; +export type HTTPQuery = { [key: string]: string | number | null | boolean | Array | HTTPQuery }; +export type HTTPBody = Json | FormData; +export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; + +export interface FetchParams { + url: string; + init: RequestInit; +} + +export interface RequestOpts { + path: string; + method: HTTPMethod; + headers: HTTPHeaders; + query?: HTTPQuery; + body?: HTTPBody; +} + +export function exists(json: any, key: string) { + const value = json[key]; + return value !== null && value !== undefined; +} + +export function querystring(params: HTTPQuery, prefix: string = '') { + return Object.keys(params) + .map((key) => { + const fullKey = prefix + (prefix.length ? `[${key}]` : key); + const value = params[key]; + if (value instanceof Array) { + const multiValue = value.map(singleValue => encodeURIComponent(String(singleValue))) + .join(`&${encodeURIComponent(fullKey)}=`); + return `${encodeURIComponent(fullKey)}=${multiValue}`; + } + if (value instanceof Object) { + return querystring(value as HTTPQuery, fullKey); + } + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`; + }) + .join('&'); +} + +export interface RequestContext { + fetch: FetchAPI; + url: string; + init: RequestInit; +} + +export interface ResponseContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + response: Response; +} + +export interface Middleware { + pre?(context: RequestContext): Promise; + post?(context: ResponseContext): Promise; +} + +export interface ApiResponse { + raw: Response; + value(): Promise; +} + +export interface ResponseTransformer { + (json: any): T; +} + +export class JSONApiResponse { + constructor(public raw: Response, private transformer: ResponseTransformer = (jsonValue: any) => jsonValue) {} + + async value() { + return this.transformer(await this.raw.json()); + } +} + +export class VoidApiResponse { + constructor(public raw: Response) {} + + async value() { + return undefined; + } +} + +export class BlobApiResponse { + constructor(public raw: Response) {} + + async value() { + return await this.raw.blob(); + }; +} + +export class TextApiResponse { + constructor(public raw: Response) {} + + async value() { + return await this.raw.text(); + }; +} diff --git a/samples/client/petstore-security-test/typescript-fetch/tsconfig.json b/samples/client/petstore-security-test/typescript-fetch/tsconfig.json new file mode 100644 index 00000000000..d65f2a95afc --- /dev/null +++ b/samples/client/petstore-security-test/typescript-fetch/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "declaration": true, + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "outDir": "dist", + "rootDir": ".", + "lib": [ + "es6", + "dom" + ], + "typeRoots": [ + "node_modules/@types" + ] + }, + "exclude": [ + "dist", + "node_modules" + ] +} diff --git a/samples/client/petstore-security-test/typescript-inversify/.openapi-generator-ignore b/samples/client/petstore-security-test/typescript-inversify/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-inversify/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/typescript-inversify/.openapi-generator/VERSION b/samples/client/petstore-security-test/typescript-inversify/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-inversify/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-inversify/ApiServiceBinder.ts b/samples/client/petstore-security-test/typescript-inversify/ApiServiceBinder.ts new file mode 100644 index 00000000000..60f8cd6fa5d --- /dev/null +++ b/samples/client/petstore-security-test/typescript-inversify/ApiServiceBinder.ts @@ -0,0 +1,9 @@ +import {interfaces} from "inversify"; + +import { FakeService } from './api/fake.service'; + +export class ApiServiceBinder { + public static with(container: interfaces.Container) { + container.bind("FakeService").to(FakeService).inSingletonScope(); + } +} diff --git a/samples/client/petstore-security-test/typescript-inversify/Headers.ts b/samples/client/petstore-security-test/typescript-inversify/Headers.ts new file mode 100644 index 00000000000..0fa7760e01e --- /dev/null +++ b/samples/client/petstore-security-test/typescript-inversify/Headers.ts @@ -0,0 +1,3 @@ +export interface Headers { + [index:string]: string +} diff --git a/samples/client/petstore-security-test/typescript-inversify/HttpClient.ts b/samples/client/petstore-security-test/typescript-inversify/HttpClient.ts new file mode 100644 index 00000000000..64fe12a3045 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-inversify/HttpClient.ts @@ -0,0 +1,63 @@ +import IHttpClient from "./IHttpClient"; +import { Observable } from "rxjs/Observable"; +import "whatwg-fetch"; +import HttpResponse from "./HttpResponse"; +import {injectable} from "inversify"; +import "rxjs/add/observable/fromPromise"; +import { Headers } from "./Headers"; + +@injectable() +class HttpClient implements IHttpClient { + + get(url:string, headers?: Headers):Observable { + return this.performNetworkCall(url, "get", undefined, headers); + } + + post(url: string, body: {}|FormData, headers?: Headers): Observable { + return this.performNetworkCall(url, "post", this.getJsonBody(body), this.addJsonHeaders(headers)); + } + + put(url: string, body: {}, headers?: Headers): Observable { + return this.performNetworkCall(url, "put", this.getJsonBody(body), this.addJsonHeaders(headers)); + } + + delete(url: string, headers?: Headers): Observable { + return this.performNetworkCall(url, "delete", undefined, headers); + } + + private getJsonBody(body: {}|FormData) { + return !(body instanceof FormData) ? JSON.stringify(body) : body; + } + + private addJsonHeaders(headers: Headers) { + return Object.assign({}, { + "Accept": "application/json", + "Content-Type": "application/json" + }, headers); + }; + + private performNetworkCall(url: string, method: string, body?: any, headers?: Headers): Observable { + let promise = window.fetch(url, { + method: method, + body: body, + headers: headers + }).then(response => { + let headers: Headers = {}; + response.headers.forEach((value, name) => { + headers[name.toString().toLowerCase()] = value; + }); + return response.text().then(text => { + let contentType = headers["content-type"] || ""; + let payload = contentType.match("application/json") ? JSON.parse(text) : text; + let httpResponse = new HttpResponse(payload, response.status, headers); + + if (response.status >= 400) + throw httpResponse; + return httpResponse; + }); + }); + return Observable.fromPromise(promise); + } +} + +export default HttpClient \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-inversify/HttpResponse.ts b/samples/client/petstore-security-test/typescript-inversify/HttpResponse.ts new file mode 100644 index 00000000000..411240cde2b --- /dev/null +++ b/samples/client/petstore-security-test/typescript-inversify/HttpResponse.ts @@ -0,0 +1,8 @@ +import { Headers } from "./Headers" + +class HttpResponse { + constructor(public response: T, public status:number, public headers?: Headers) { + } +} + +export default HttpResponse \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-inversify/IAPIConfiguration.ts b/samples/client/petstore-security-test/typescript-inversify/IAPIConfiguration.ts new file mode 100644 index 00000000000..2364e83e6cb --- /dev/null +++ b/samples/client/petstore-security-test/typescript-inversify/IAPIConfiguration.ts @@ -0,0 +1,8 @@ +export interface IAPIConfiguration { + apiKeys?: {[ key: string ]: string}; + username?: string; + password?: string; + accessToken?: string | (() => string); + basePath?: string; + withCredentials?: boolean; +} \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-inversify/IHttpClient.ts b/samples/client/petstore-security-test/typescript-inversify/IHttpClient.ts new file mode 100644 index 00000000000..22d9e07c903 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-inversify/IHttpClient.ts @@ -0,0 +1,12 @@ +import { Observable } from "rxjs/Observable"; +import HttpResponse from "./HttpResponse"; +import { Headers } from "./Headers"; + +interface IHttpClient { + get(url:string, headers?: Headers):Observable + post(url:string, body:{}|FormData, headers?: Headers):Observable + put(url:string, body:{}, headers?: Headers):Observable + delete(url:string, headers?: Headers):Observable +} + +export default IHttpClient \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-inversify/api/fake.service.ts b/samples/client/petstore-security-test/typescript-inversify/api/fake.service.ts new file mode 100644 index 00000000000..f3bf6b579e4 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-inversify/api/fake.service.ts @@ -0,0 +1,62 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +/* tslint:disable:no-unused-variable member-ordering */ + +import { Observable } from "rxjs/Observable"; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/toPromise'; +import IHttpClient from "../IHttpClient"; +import { inject, injectable } from "inversify"; +import { IAPIConfiguration } from "../IAPIConfiguration"; +import { Headers } from "../Headers"; +import HttpResponse from "../HttpResponse"; + + +import { COLLECTION_FORMATS } from '../variables'; + + + +@injectable() +export class FakeService { + private basePath: string = 'http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r'; + + constructor(@inject("IApiHttpClient") private httpClient: IHttpClient, + @inject("IAPIConfiguration") private APIConfiguration: IAPIConfiguration ) { + if(this.APIConfiguration.basePath) + this.basePath = this.APIConfiguration.basePath; + } + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param testCodeInjectEndRnNR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r + + */ + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe?: 'body', headers?: Headers): Observable; + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe?: 'response', headers?: Headers): Observable>; + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe: any = 'body', headers: Headers = {}): Observable { + headers['Accept'] = 'application/json'; + + let formData: FormData = new FormData(); + headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'; + if (testCodeInjectEndRnNR !== undefined) { + formData.append('test code inject */ ' " =end -- \r\n \n \r', testCodeInjectEndRnNR); + } + + const response: Observable> = this.httpClient.put(`${this.basePath}/fake`, body, headers); + if (observe == 'body') { + return response.map(httpResponse => (httpResponse.response)); + } + return response; + } + +} diff --git a/samples/client/petstore-security-test/typescript-inversify/model/return.ts b/samples/client/petstore-security-test/typescript-inversify/model/return.ts new file mode 100644 index 00000000000..442d1b5a101 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-inversify/model/return.ts @@ -0,0 +1,22 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r + */ +export interface Return { + /** + * property description *_/ ' \" =end -- \\r\\n \\n \\r + */ + _return?: number; +} diff --git a/samples/client/petstore-security-test/typescript-inversify/variables.ts b/samples/client/petstore-security-test/typescript-inversify/variables.ts new file mode 100644 index 00000000000..5d3805255c2 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-inversify/variables.ts @@ -0,0 +1,6 @@ +export const COLLECTION_FORMATS = { + 'csv': ',', + 'tsv': ' ', + 'ssv': ' ', + 'pipes': '|' +} diff --git a/samples/client/petstore-security-test/typescript-jquery/default/.openapi-generator-ignore b/samples/client/petstore-security-test/typescript-jquery/default/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/default/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/typescript-jquery/default/.openapi-generator/VERSION b/samples/client/petstore-security-test/typescript-jquery/default/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/default/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-jquery/default/api/FakeApi.ts b/samples/client/petstore-security-test/typescript-jquery/default/api/FakeApi.ts new file mode 100644 index 00000000000..92e3e27d0be --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/default/api/FakeApi.ts @@ -0,0 +1,121 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as $ from 'jquery'; +import * as models from '../model/models'; +import { COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + +/* tslint:disable:no-unused-variable member-ordering */ + + +export class FakeApi { + protected basePath = 'http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r'; + public defaultHeaders: Array = []; + public defaultExtraJQueryAjaxSettings?: JQueryAjaxSettings = null; + public configuration: Configuration = new Configuration(); + + constructor(basePath?: string, configuration?: Configuration, defaultExtraJQueryAjaxSettings?: JQueryAjaxSettings) { + if (basePath) { + this.basePath = basePath; + } + if (configuration) { + this.configuration = configuration; + } + if (defaultExtraJQueryAjaxSettings) { + this.defaultExtraJQueryAjaxSettings = defaultExtraJQueryAjaxSettings; + } + } + + private extendObj(objA: T2, objB: T2): T1|T2 { + for (let key in objB) { + if (objB.hasOwnProperty(key)) { + objA[key] = objB[key]; + } + } + return objA; + } + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @summary To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param testCodeInjectEndRnNR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r + */ + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, extraJQueryAjaxSettings?: JQueryAjaxSettings): JQuery.Promise< + { response: JQueryXHR; body?: any; }, + { response: JQueryXHR; errorThrown: string } + > { + let localVarPath = this.basePath + '/fake'; + + let queryParameters: any = {}; + let headerParams: any = {}; + let formParams = new FormData(); + let reqHasFile = false; + + + localVarPath = localVarPath + "?" + $.param(queryParameters); + if (testCodeInjectEndRnNR !== null && testCodeInjectEndRnNR !== undefined) { + formParams.append('test code inject */ ' " =end -- \r\n \n \r', testCodeInjectEndRnNR); + } + // to determine the Content-Type header + let consumes: string[] = [ + 'application/x-www-form-urlencoded', + '*_/ =end -- ' + ]; + + // to determine the Accept header + let produces: string[] = [ + ]; + + if (!reqHasFile) { + headerParams['Content-Type'] = 'application/x-www-form-urlencoded'; + } + + + let requestOptions: JQueryAjaxSettings = { + url: localVarPath, + type: 'PUT', + headers: headerParams, + processData: false + }; + + if (headerParams['Content-Type']) { + requestOptions.contentType = headerParams['Content-Type']; + } + requestOptions.data = formParams; + if (reqHasFile) { + requestOptions.contentType = false; + } + + if (extraJQueryAjaxSettings) { + requestOptions = (Object).assign(requestOptions, extraJQueryAjaxSettings); + } + + if (this.defaultExtraJQueryAjaxSettings) { + requestOptions = (Object).assign(requestOptions, this.defaultExtraJQueryAjaxSettings); + } + + let dfd = $.Deferred< + { response: JQueryXHR; body?: any; }, + { response: JQueryXHR; errorThrown: string } + >(); + $.ajax(requestOptions).then( + (data: any, textStatus: string, jqXHR: JQueryXHR) => + dfd.resolve({response: jqXHR, body: data}), + (xhr: JQueryXHR, textStatus: string, errorThrown: string) => + dfd.reject({response: xhr, errorThrown: errorThrown}) + ); + return dfd.promise(); + } + +} diff --git a/samples/client/petstore-security-test/typescript-jquery/default/api/api.ts b/samples/client/petstore-security-test/typescript-jquery/default/api/api.ts new file mode 100644 index 00000000000..4c0b3c9f56b --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/default/api/api.ts @@ -0,0 +1,3 @@ +export * from './FakeApi'; +import { FakeApi } from './FakeApi'; +export const APIS = [FakeApi]; diff --git a/samples/client/petstore-security-test/typescript-jquery/default/configuration.ts b/samples/client/petstore-security-test/typescript-jquery/default/configuration.ts new file mode 100644 index 00000000000..a566a180e4e --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/default/configuration.ts @@ -0,0 +1,6 @@ +export class Configuration { + apiKey: string; + username: string; + password: string; + accessToken: string | (() => string); +} \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-jquery/default/git_push.sh b/samples/client/petstore-security-test/typescript-jquery/default/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/default/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/typescript-jquery/default/index.ts b/samples/client/petstore-security-test/typescript-jquery/default/index.ts new file mode 100644 index 00000000000..d097c728017 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/default/index.ts @@ -0,0 +1,4 @@ +export * from './api/api'; +export * from './model/models'; +export * from './variables'; +export * from './configuration'; \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-jquery/default/model/Return.ts b/samples/client/petstore-security-test/typescript-jquery/default/model/Return.ts new file mode 100644 index 00000000000..844e69311db --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/default/model/Return.ts @@ -0,0 +1,24 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as models from './models'; + +/** + * Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r + */ +export interface Return { + /** + * property description *_/ ' \" =end -- \\r\\n \\n \\r + */ + _return?: number; + +} diff --git a/samples/client/petstore-security-test/typescript-jquery/default/model/models.ts b/samples/client/petstore-security-test/typescript-jquery/default/model/models.ts new file mode 100644 index 00000000000..8d45f62a1d6 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/default/model/models.ts @@ -0,0 +1 @@ +export * from './Return'; diff --git a/samples/client/petstore-security-test/typescript-jquery/default/variables.ts b/samples/client/petstore-security-test/typescript-jquery/default/variables.ts new file mode 100644 index 00000000000..505ce9355e2 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/default/variables.ts @@ -0,0 +1,7 @@ + +export const COLLECTION_FORMATS = { + 'csv': ',', + 'tsv': ' ', + 'ssv': ' ', + 'pipes': '|' +} \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/.openapi-generator-ignore b/samples/client/petstore-security-test/typescript-jquery/npm/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/.openapi-generator/VERSION b/samples/client/petstore-security-test/typescript-jquery/npm/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/README.md b/samples/client/petstore-security-test/typescript-jquery/npm/README.md new file mode 100644 index 00000000000..4f2d8137489 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/README.md @@ -0,0 +1,45 @@ +## @swagger/angular2-typescript-petstore@0.0.1 + +This generator creates TypeScript/JavaScript client that utilizes [jQuery](https://jquery.com/). The generated Node module can be used in the following environments: + +Environment +* Node.js +* Webpack +* Browserify + +Language level +* ES5 - you must have a Promises/A+ library installed +* ES6 + +Module system +* CommonJS +* ES6 module system + +It can be used in both TypeScript and JavaScript. In TypeScript, the definition should be automatically resolved via `package.json`. ([Reference](http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html)) + +### Building + +To build and compile the typescript sources to javascript use: +``` +npm install +npm run build +``` + +### Publishing + +First build the package then run ```npm publish``` + +### Consuming + +navigate to the folder of your consuming project and run one of the following commands. + +_published:_ + +``` +npm install @swagger/angular2-typescript-petstore@0.0.1 --save +``` + +_unPublished (not recommended):_ + +``` +npm install PATH_TO_GENERATED_PACKAGE --save diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/api/FakeApi.ts b/samples/client/petstore-security-test/typescript-jquery/npm/api/FakeApi.ts new file mode 100644 index 00000000000..92e3e27d0be --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/api/FakeApi.ts @@ -0,0 +1,121 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as $ from 'jquery'; +import * as models from '../model/models'; +import { COLLECTION_FORMATS } from '../variables'; +import { Configuration } from '../configuration'; + +/* tslint:disable:no-unused-variable member-ordering */ + + +export class FakeApi { + protected basePath = 'http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r'; + public defaultHeaders: Array = []; + public defaultExtraJQueryAjaxSettings?: JQueryAjaxSettings = null; + public configuration: Configuration = new Configuration(); + + constructor(basePath?: string, configuration?: Configuration, defaultExtraJQueryAjaxSettings?: JQueryAjaxSettings) { + if (basePath) { + this.basePath = basePath; + } + if (configuration) { + this.configuration = configuration; + } + if (defaultExtraJQueryAjaxSettings) { + this.defaultExtraJQueryAjaxSettings = defaultExtraJQueryAjaxSettings; + } + } + + private extendObj(objA: T2, objB: T2): T1|T2 { + for (let key in objB) { + if (objB.hasOwnProperty(key)) { + objA[key] = objB[key]; + } + } + return objA; + } + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @summary To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param testCodeInjectEndRnNR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r + */ + public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, extraJQueryAjaxSettings?: JQueryAjaxSettings): JQuery.Promise< + { response: JQueryXHR; body?: any; }, + { response: JQueryXHR; errorThrown: string } + > { + let localVarPath = this.basePath + '/fake'; + + let queryParameters: any = {}; + let headerParams: any = {}; + let formParams = new FormData(); + let reqHasFile = false; + + + localVarPath = localVarPath + "?" + $.param(queryParameters); + if (testCodeInjectEndRnNR !== null && testCodeInjectEndRnNR !== undefined) { + formParams.append('test code inject */ ' " =end -- \r\n \n \r', testCodeInjectEndRnNR); + } + // to determine the Content-Type header + let consumes: string[] = [ + 'application/x-www-form-urlencoded', + '*_/ =end -- ' + ]; + + // to determine the Accept header + let produces: string[] = [ + ]; + + if (!reqHasFile) { + headerParams['Content-Type'] = 'application/x-www-form-urlencoded'; + } + + + let requestOptions: JQueryAjaxSettings = { + url: localVarPath, + type: 'PUT', + headers: headerParams, + processData: false + }; + + if (headerParams['Content-Type']) { + requestOptions.contentType = headerParams['Content-Type']; + } + requestOptions.data = formParams; + if (reqHasFile) { + requestOptions.contentType = false; + } + + if (extraJQueryAjaxSettings) { + requestOptions = (Object).assign(requestOptions, extraJQueryAjaxSettings); + } + + if (this.defaultExtraJQueryAjaxSettings) { + requestOptions = (Object).assign(requestOptions, this.defaultExtraJQueryAjaxSettings); + } + + let dfd = $.Deferred< + { response: JQueryXHR; body?: any; }, + { response: JQueryXHR; errorThrown: string } + >(); + $.ajax(requestOptions).then( + (data: any, textStatus: string, jqXHR: JQueryXHR) => + dfd.resolve({response: jqXHR, body: data}), + (xhr: JQueryXHR, textStatus: string, errorThrown: string) => + dfd.reject({response: xhr, errorThrown: errorThrown}) + ); + return dfd.promise(); + } + +} diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/api/api.ts b/samples/client/petstore-security-test/typescript-jquery/npm/api/api.ts new file mode 100644 index 00000000000..4c0b3c9f56b --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/api/api.ts @@ -0,0 +1,3 @@ +export * from './FakeApi'; +import { FakeApi } from './FakeApi'; +export const APIS = [FakeApi]; diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/configuration.ts b/samples/client/petstore-security-test/typescript-jquery/npm/configuration.ts new file mode 100644 index 00000000000..a566a180e4e --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/configuration.ts @@ -0,0 +1,6 @@ +export class Configuration { + apiKey: string; + username: string; + password: string; + accessToken: string | (() => string); +} \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/git_push.sh b/samples/client/petstore-security-test/typescript-jquery/npm/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/index.ts b/samples/client/petstore-security-test/typescript-jquery/npm/index.ts new file mode 100644 index 00000000000..d097c728017 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/index.ts @@ -0,0 +1,4 @@ +export * from './api/api'; +export * from './model/models'; +export * from './variables'; +export * from './configuration'; \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/model/Return.ts b/samples/client/petstore-security-test/typescript-jquery/npm/model/Return.ts new file mode 100644 index 00000000000..844e69311db --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/model/Return.ts @@ -0,0 +1,24 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as models from './models'; + +/** + * Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r + */ +export interface Return { + /** + * property description *_/ ' \" =end -- \\r\\n \\n \\r + */ + _return?: number; + +} diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/model/models.ts b/samples/client/petstore-security-test/typescript-jquery/npm/model/models.ts new file mode 100644 index 00000000000..8d45f62a1d6 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/model/models.ts @@ -0,0 +1 @@ +export * from './Return'; diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/package.json b/samples/client/petstore-security-test/typescript-jquery/npm/package.json new file mode 100644 index 00000000000..ace875c7892 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/package.json @@ -0,0 +1,23 @@ +{ + "name": "@swagger/angular2-typescript-petstore", + "version": "0.0.1", + "description": "JQuery client for @swagger/angular2-typescript-petstore", + "main": "api.js", + "scripts": { + "build": "tsc" + }, + "author": "OpenAPI-Generator Contributors", + "license": "MIT", + "dependencies": { + "bluebird": "^3.3.5", + "request": "^2.72.0", + "jquery": "^3.1.1" + }, + "devDependencies": { + "typescript": "2.2.2", + "typings": "^1.3.0" + }, + "publishConfig":{ + "registry":"https://skimdb.npmjs.com/registry" + } +} diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/tsconfig.json b/samples/client/petstore-security-test/typescript-jquery/npm/tsconfig.json new file mode 100644 index 00000000000..c11ec54d7ca --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "module": "commonjs", + "noImplicitAny": false, + "suppressImplicitAnyIndexErrors": true, + "target": "ES5", + "moduleResolution": "node", + "removeComments": true, + "sourceMap": true, + "noLib": false, + "declaration": true, + "typeRoots": [ + "node_modules/@types" + ] + }, + "files": [ + "index.ts", + "typings/index.d.ts" + ] +} + diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/typings.json b/samples/client/petstore-security-test/typescript-jquery/npm/typings.json new file mode 100644 index 00000000000..306cf301b88 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/typings.json @@ -0,0 +1,10 @@ +{ + "ambientDependencies": { + "bluebird": "registry:dt/bluebird#2.0.0+20160319051630", + "core-js": "registry:dt/core-js#0.0.0+20160317120654", + "node": "registry:dt/node#4.0.0+20160423143914" + }, + "globalDependencies": { + "jquery": "registry:dt/jquery#1.10.0+20170310222111" + } +} \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-jquery/npm/variables.ts b/samples/client/petstore-security-test/typescript-jquery/npm/variables.ts new file mode 100644 index 00000000000..505ce9355e2 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-jquery/npm/variables.ts @@ -0,0 +1,7 @@ + +export const COLLECTION_FORMATS = { + 'csv': ',', + 'tsv': ' ', + 'ssv': ' ', + 'pipes': '|' +} \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-node/.gitignore b/samples/client/petstore-security-test/typescript-node/.gitignore new file mode 100644 index 00000000000..35e2fb2b02e --- /dev/null +++ b/samples/client/petstore-security-test/typescript-node/.gitignore @@ -0,0 +1,3 @@ +wwwroot/*.js +node_modules +typings diff --git a/samples/client/petstore-security-test/typescript-node/.openapi-generator-ignore b/samples/client/petstore-security-test/typescript-node/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-node/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore-security-test/typescript-node/.openapi-generator/VERSION b/samples/client/petstore-security-test/typescript-node/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-node/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-node/api.ts b/samples/client/petstore-security-test/typescript-node/api.ts new file mode 100644 index 00000000000..4b76122d807 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-node/api.ts @@ -0,0 +1,3 @@ +// This is the entrypoint for the package +export * from './api/apis'; +export * from './model/models'; \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-node/api/apis.ts b/samples/client/petstore-security-test/typescript-node/api/apis.ts new file mode 100644 index 00000000000..192d350dd3a --- /dev/null +++ b/samples/client/petstore-security-test/typescript-node/api/apis.ts @@ -0,0 +1,3 @@ +export * from './fakeApi'; +import { FakeApi } from './fakeApi'; +export const APIS = [FakeApi]; diff --git a/samples/client/petstore-security-test/typescript-node/api/fakeApi.ts b/samples/client/petstore-security-test/typescript-node/api/fakeApi.ts new file mode 100644 index 00000000000..a00664839d1 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-node/api/fakeApi.ts @@ -0,0 +1,123 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import localVarRequest = require('request'); +import http = require('http'); +import Promise = require('bluebird'); + +/* tslint:disable:no-unused-locals */ + +import { ObjectSerializer, Authentication, HttpBasicAuth, ApiKeyAuth, OAuth, VoidAuth } from '../model/models'; + +let defaultBasePath = 'http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r'; + +// =============================================== +// This file is autogenerated - Please do not edit +// =============================================== + +export enum FakeApiApiKeys { +} + +export class FakeApi { + protected _basePath = defaultBasePath; + protected defaultHeaders : any = {}; + protected _useQuerystring : boolean = false; + + protected authentications = { + 'default': new VoidAuth(), + } + + constructor(basePath?: string); + constructor(basePathOrUsername: string, password?: string, basePath?: string) { + if (password) { + if (basePath) { + this.basePath = basePath; + } + } else { + if (basePathOrUsername) { + this.basePath = basePathOrUsername + } + } + } + + set useQuerystring(value: boolean) { + this._useQuerystring = value; + } + + set basePath(basePath: string) { + this._basePath = basePath; + } + + get basePath() { + return this._basePath; + } + + public setDefaultAuthentication(auth: Authentication) { + this.authentications.default = auth; + } + + public setApiKey(key: FakeApiApiKeys, value: string) { + (this.authentications as any)[FakeApiApiKeys[key]].apiKey = value; + } + + /** + * To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @summary To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param testCodeInjectEndRnNR To test code injection *_/ ' \\\" =end -- \\\\r\\\\n \\\\n \\\\r + */ + public testCodeInjectEndRnNR (testCodeInjectEndRnNR?: string, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.ClientResponse; body?: any; }> { + const localVarPath = this.basePath + '/fake'; + let localVarQueryParameters: any = {}; + let localVarHeaderParams: any = (Object).assign({}, this.defaultHeaders); + let localVarFormParams: any = {}; + + (Object).assign(localVarHeaderParams, options.headers); + + let localVarUseFormData = false; + + if (testCodeInjectEndRnNR !== undefined) { + localVarFormParams['test code inject */ ' " =end -- \r\n \n \r'] = ObjectSerializer.serialize(testCodeInjectEndRnNR, "string"); + } + + let localVarRequestOptions: localVarRequest.Options = { + method: 'PUT', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + }; + + this.authentications.default.applyToRequest(localVarRequestOptions); + + if (Object.keys(localVarFormParams).length) { + if (localVarUseFormData) { + (localVarRequestOptions).formData = localVarFormParams; + } else { + localVarRequestOptions.form = localVarFormParams; + } + } + return new Promise<{ response: http.ClientResponse; body?: any; }>((resolve, reject) => { + localVarRequest(localVarRequestOptions, (error, response, body) => { + if (error) { + reject(error); + } else { + if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) { + resolve({ response: response, body: body }); + } else { + reject({ response: response, body: body }); + } + } + }); + }); + } +} diff --git a/samples/client/petstore-security-test/typescript-node/git_push.sh b/samples/client/petstore-security-test/typescript-node/git_push.sh new file mode 100644 index 00000000000..8442b80bb44 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-node/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/client/petstore-security-test/typescript-node/model/models.ts b/samples/client/petstore-security-test/typescript-node/model/models.ts new file mode 100644 index 00000000000..b278ea07e6f --- /dev/null +++ b/samples/client/petstore-security-test/typescript-node/model/models.ts @@ -0,0 +1,187 @@ +export * from './return'; + +import localVarRequest = require('request'); + +import { Return } from './return'; + +/* tslint:disable:no-unused-variable */ +let primitives = [ + "string", + "boolean", + "double", + "integer", + "long", + "float", + "number", + "any" + ]; + +let enumsMap: {[index: string]: any} = { +} + +let typeMap: {[index: string]: any} = { + "Return": Return, +} + +export class ObjectSerializer { + public static findCorrectType(data: any, expectedType: string) { + if (data == undefined) { + return expectedType; + } else if (primitives.indexOf(expectedType.toLowerCase()) !== -1) { + return expectedType; + } else if (expectedType === "Date") { + return expectedType; + } else { + if (enumsMap[expectedType]) { + return expectedType; + } + + if (!typeMap[expectedType]) { + return expectedType; // w/e we don't know the type + } + + // Check the discriminator + let discriminatorProperty = typeMap[expectedType].discriminator; + if (discriminatorProperty == null) { + return expectedType; // the type does not have a discriminator. use it. + } else { + if (data[discriminatorProperty]) { + var discriminatorType = data[discriminatorProperty]; + if(typeMap[discriminatorType]){ + return discriminatorType; // use the type given in the discriminator + } else { + return expectedType; // discriminator did not map to a type + } + } else { + return expectedType; // discriminator was not present (or an empty string) + } + } + } + } + + public static serialize(data: any, type: string) { + if (data == undefined) { + return data; + } else if (primitives.indexOf(type.toLowerCase()) !== -1) { + return data; + } else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6 + let subType: string = type.replace("Array<", ""); // Array => Type> + subType = subType.substring(0, subType.length - 1); // Type> => Type + let transformedData: any[] = []; + for (let index in data) { + let date = data[index]; + transformedData.push(ObjectSerializer.serialize(date, subType)); + } + return transformedData; + } else if (type === "Date") { + return data.toISOString(); + } else { + if (enumsMap[type]) { + return data; + } + if (!typeMap[type]) { // in case we dont know the type + return data; + } + + // Get the actual type of this object + type = this.findCorrectType(data, type); + + // get the map for the correct type. + let attributeTypes = typeMap[type].getAttributeTypeMap(); + let instance: {[index: string]: any} = {}; + for (let index in attributeTypes) { + let attributeType = attributeTypes[index]; + instance[attributeType.baseName] = ObjectSerializer.serialize(data[attributeType.name], attributeType.type); + } + return instance; + } + } + + public static deserialize(data: any, type: string) { + // polymorphism may change the actual type. + type = ObjectSerializer.findCorrectType(data, type); + if (data == undefined) { + return data; + } else if (primitives.indexOf(type.toLowerCase()) !== -1) { + return data; + } else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6 + let subType: string = type.replace("Array<", ""); // Array => Type> + subType = subType.substring(0, subType.length - 1); // Type> => Type + let transformedData: any[] = []; + for (let index in data) { + let date = data[index]; + transformedData.push(ObjectSerializer.deserialize(date, subType)); + } + return transformedData; + } else if (type === "Date") { + return new Date(data); + } else { + if (enumsMap[type]) {// is Enum + return data; + } + + if (!typeMap[type]) { // dont know the type + return data; + } + let instance = new typeMap[type](); + let attributeTypes = typeMap[type].getAttributeTypeMap(); + for (let index in attributeTypes) { + let attributeType = attributeTypes[index]; + instance[attributeType.name] = ObjectSerializer.deserialize(data[attributeType.baseName], attributeType.type); + } + return instance; + } + } +} + +export interface Authentication { + /** + * Apply authentication settings to header and query params. + */ + applyToRequest(requestOptions: localVarRequest.Options): void; +} + +export class HttpBasicAuth implements Authentication { + public username: string = ''; + public password: string = ''; + + applyToRequest(requestOptions: localVarRequest.Options): void { + requestOptions.auth = { + username: this.username, password: this.password + } + } +} + +export class ApiKeyAuth implements Authentication { + public apiKey: string = ''; + + constructor(private location: string, private paramName: string) { + } + + applyToRequest(requestOptions: localVarRequest.Options): void { + if (this.location == "query") { + (requestOptions.qs)[this.paramName] = this.apiKey; + } else if (this.location == "header" && requestOptions && requestOptions.headers) { + requestOptions.headers[this.paramName] = this.apiKey; + } + } +} + +export class OAuth implements Authentication { + public accessToken: string = ''; + + applyToRequest(requestOptions: localVarRequest.Options): void { + if (requestOptions && requestOptions.headers) { + requestOptions.headers["Authorization"] = "Bearer " + this.accessToken; + } + } +} + +export class VoidAuth implements Authentication { + public username: string = ''; + public password: string = ''; + + applyToRequest(_: localVarRequest.Options): void { + // Do nothing + } +} \ No newline at end of file diff --git a/samples/client/petstore-security-test/typescript-node/model/return.ts b/samples/client/petstore-security-test/typescript-node/model/return.ts new file mode 100644 index 00000000000..1f8181f2396 --- /dev/null +++ b/samples/client/petstore-security-test/typescript-node/model/return.ts @@ -0,0 +1,36 @@ +/** + * OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: something@something.abc *_/ ' \" =end -- \\r\\n \\n \\r + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** +* Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r +*/ +export class Return { + /** + * property description *_/ ' \" =end -- \\r\\n \\n \\r + */ + '_return'?: number; + + static discriminator: string | undefined = undefined; + + static attributeTypeMap: Array<{name: string, baseName: string, type: string}> = [ + { + "name": "_return", + "baseName": "return", + "type": "number" + } ]; + + static getAttributeTypeMap() { + return Return.attributeTypeMap; + } +} + diff --git a/samples/schema/petstore-security-test/mysql/.openapi-generator-ignore b/samples/schema/petstore-security-test/mysql/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/schema/petstore-security-test/mysql/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/schema/petstore-security-test/mysql/.openapi-generator/VERSION b/samples/schema/petstore-security-test/mysql/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/schema/petstore-security-test/mysql/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/schema/petstore-security-test/mysql/README.md b/samples/schema/petstore-security-test/mysql/README.md new file mode 100644 index 00000000000..54bda8398ac --- /dev/null +++ b/samples/schema/petstore-security-test/mysql/README.md @@ -0,0 +1,48 @@ +# MySQL Schema Codegen + +Main goal of this generator is to provide database structure file almost identical you usually generate with: +- PHPMyAdmin (Export structure only, SQL syntax) +- Adminer +- `mysqldump` function + +[MySQL documentation](https://dev.mysql.com/doc/) + +## Requirements +- MySQL Server ^5.7.8 (`JSON` column type added) + +## Openapi Data Type to MySQL Data Type mapping + +| Openapi Data Type | Openapi Data Format | Dependent properties | MySQL Data Types | Default MySQL Data Type | +| --- | --- | --- | --- | --- | +| `integer` | `int32` | `minimum` / `maximum` / `minimumExclusive` / `maximumExclusive` | `TINYINT` / `SMALLINT` / `MEDIUMINT`/ `INT` / `BIGINT` | `INT` | +| `integer` | `int64` | `minimum` / `maximum` / `minimumExclusive` / `maximumExclusive` | `TINYINT` / `SMALLINT` / `MEDIUMINT` / `INT` / `BIGINT` | `BIGINT` | +| `boolean` | | | `TINYINT` | `TINYINT` | +| `number` | `float` | | `DECIMAL` | `DECIMAL` | +| `number` | `double` | | `DECIMAL` | `DECIMAL` | +| `string` | | `minLength` / `maxLength` | `CHAR` / `VARCHAR` / `TEXT` / `MEDIUMTEXT` / `LONGTEXT` | `TEXT` | +| `string` | `byte` | | `TEXT` | `TEXT` | +| `string` | `binary` | | `MEDIUMBLOB` | `MEDIUMBLOB` | +| `file` | | | `MEDIUMBLOB` | `MEDIUMBLOB` | +| `string` | `date` | | `DATE` | `DATE` | +| `string` | `date-time` | | `DATETIME` | `DATETIME` | +| `string` | `enum` | | `ENUM` | `ENUM` | +| `array` | | | `JSON` | `JSON` | +| `object` | | | `JSON` | `JSON` | +| `\Model\User` (referenced definition) | | | `TEXT` | `TEXT` | + +## How to use + +Produced file(`mysql_schema.sql`) contains every table definition. Current implementation doesn't drop or modify existed tables, if you want rewrite whole schema make sure they're not presented. + +### PHPMyAdmin + +1. Choose **Import** tab from the home screen +2. In section **File to import** click to **Choose File** and find generated `mysql_schema.sql` +3. Make sure **Format** selector set to **SQL** +4. Push **Go** button + +### Adminer + +1. Click **Import** link in left sidebar +2. In **File upload** fieldset click to **Choose Files** and find generated `mysql_schema.sql` +3. Push **Execute** button diff --git a/samples/schema/petstore-security-test/mysql/mysql_schema.sql b/samples/schema/petstore-security-test/mysql/mysql_schema.sql new file mode 100644 index 00000000000..c913612f55b --- /dev/null +++ b/samples/schema/petstore-security-test/mysql/mysql_schema.sql @@ -0,0 +1,16 @@ +/* SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; */ +/* SET AUTOCOMMIT = 0; */ +/* START TRANSACTION; */ +/* SET time_zone = "+00:00"; */ + +-- -------------------------------------------------------- + +-- +-- Table structure for table `Return` generated from model 'Return' +-- Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r +-- + +CREATE TABLE IF NOT EXISTS `Return` ( + `return` INT DEFAULT NULL COMMENT 'property description *_/ ' \" =end -- \\r\\n \\n \\r' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r'; + diff --git a/samples/server/petstore-security-test/lumen/.gitignore b/samples/server/petstore-security-test/lumen/.gitignore new file mode 100644 index 00000000000..390a8878ede --- /dev/null +++ b/samples/server/petstore-security-test/lumen/.gitignore @@ -0,0 +1,8 @@ +# ref: https://github.com/github/gitignore/blob/master/Composer.gitignore + +composer.phar +/vendor/ + +# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control +# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file +# composer.lock \ No newline at end of file diff --git a/samples/server/petstore-security-test/lumen/.openapi-generator-ignore b/samples/server/petstore-security-test/lumen/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/server/petstore-security-test/lumen/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore-security-test/lumen/.openapi-generator/VERSION b/samples/server/petstore-security-test/lumen/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/server/petstore-security-test/lumen/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore-security-test/lumen/lib/.env.example b/samples/server/petstore-security-test/lumen/lib/.env.example new file mode 100644 index 00000000000..9e27ce13c48 --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/.env.example @@ -0,0 +1,17 @@ +APP_ENV=local +APP_DEBUG=true +APP_KEY= +APP_TIMEZONE=UTC + +LOG_CHANNEL=stack +LOG_SLACK_WEBHOOK_URL= + +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=homestead +DB_USERNAME=homestead +DB_PASSWORD=secret + +CACHE_DRIVER=file +QUEUE_DRIVER=sync \ No newline at end of file diff --git a/samples/server/petstore-security-test/lumen/lib/app/Console/Commands/.gitkeep b/samples/server/petstore-security-test/lumen/lib/app/Console/Commands/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/samples/server/petstore-security-test/lumen/lib/app/Console/Kernel.php b/samples/server/petstore-security-test/lumen/lib/app/Console/Kernel.php new file mode 100644 index 00000000000..ed6d21b681e --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/app/Console/Kernel.php @@ -0,0 +1,35 @@ +auth = $auth; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @param string|null $guard + * @return mixed + */ + public function handle($request, Closure $next, $guard = null) + { + if ($this->auth->guard($guard)->guest()) { + return response('Unauthorized.', 401); + } + + return $next($request); + } +} diff --git a/samples/server/petstore-security-test/lumen/lib/app/Http/Middleware/ExampleMiddleware.php b/samples/server/petstore-security-test/lumen/lib/app/Http/Middleware/ExampleMiddleware.php new file mode 100644 index 00000000000..166581c8e69 --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/app/Http/Middleware/ExampleMiddleware.php @@ -0,0 +1,20 @@ +app['auth']->viaRequest('api', function ($request) { + if ($request->input('api_token')) { + return User::where('api_token', $request->input('api_token'))->first(); + } + }); + } +} diff --git a/samples/server/petstore-security-test/lumen/lib/app/Providers/EventServiceProvider.php b/samples/server/petstore-security-test/lumen/lib/app/Providers/EventServiceProvider.php new file mode 100644 index 00000000000..a3d284fc29f --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/app/Providers/EventServiceProvider.php @@ -0,0 +1,19 @@ + [ + 'App\Listeners\ExampleListener', + ], + ]; +} diff --git a/samples/server/petstore-security-test/lumen/lib/app/User.php b/samples/server/petstore-security-test/lumen/lib/app/User.php new file mode 100644 index 00000000000..94adde8542e --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/app/User.php @@ -0,0 +1,40 @@ +make( + 'Illuminate\Contracts\Console\Kernel' +); + +exit($kernel->handle(new ArgvInput, new ConsoleOutput)); diff --git a/samples/server/petstore-security-test/lumen/lib/bootstrap/app.php b/samples/server/petstore-security-test/lumen/lib/bootstrap/app.php new file mode 100644 index 00000000000..58dc9d942b9 --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/bootstrap/app.php @@ -0,0 +1,110 @@ +load(); +} catch (Dotenv\Exception\InvalidPathException $e) { + // +} + +/* +|-------------------------------------------------------------------------- +| Create The Application +|-------------------------------------------------------------------------- +| +| Here we will load the environment and create the application instance +| that serves as the central piece of this framework. We'll use this +| application as an "IoC" container and router for this framework. +| +*/ + +$app = new Laravel\Lumen\Application( + realpath(__DIR__.'/../') +); + +// $app->withFacades(); + +// $app->withEloquent(); + +/* +|-------------------------------------------------------------------------- +| Register Container Bindings +|-------------------------------------------------------------------------- +| +| Now we will register a few bindings in the service container. We will +| register the exception handler and the console kernel. You may add +| your own bindings here if you like or you can make another file. +| +*/ + +$app->singleton( + Illuminate\Contracts\Debug\ExceptionHandler::class, + App\Exceptions\Handler::class +); + +$app->singleton( + Illuminate\Contracts\Console\Kernel::class, + App\Console\Kernel::class +); + +/* +|-------------------------------------------------------------------------- +| Register Middleware +|-------------------------------------------------------------------------- +| +| Next, we will register the middleware with the application. These can +| be global middleware that run before and after each request into a +| route or middleware that'll be assigned to some specific routes. +| +*/ + +// $app->middleware([ +// App\Http\Middleware\ExampleMiddleware::class +// ]); + +// $app->routeMiddleware([ +// 'auth' => App\Http\Middleware\Authenticate::class, +// ]); + +/* +|-------------------------------------------------------------------------- +| Register Service Providers +|-------------------------------------------------------------------------- +| +| Here we will register all of the application's service providers which +| are used to bind services into the container. Service providers are +| totally optional, so you are not required to uncomment this line. +| +*/ + +// $app->register(App\Providers\AppServiceProvider::class); +// $app->register(App\Providers\AuthServiceProvider::class); +// $app->register(App\Providers\EventServiceProvider::class); + +/* +|-------------------------------------------------------------------------- +| Load The Application Routes +|-------------------------------------------------------------------------- +| +| Next we will include the routes file so that they can all be added to +| the application. This will provide all of the URLs the application +| can respond to, as well as the controllers that may handle them. +| +*/ + +$app->router->group([ + 'namespace' => 'App\Http\Controllers', +], function ($router) { + require __DIR__.'/../routes/web.php'; +}); + +$app->withFacades(); + +return $app; diff --git a/samples/server/petstore-security-test/lumen/lib/composer.json b/samples/server/petstore-security-test/lumen/lib/composer.json new file mode 100644 index 00000000000..56f9720b534 --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/composer.json @@ -0,0 +1,56 @@ +{ + "name": "GIT_USER_ID/GIT_REPO_ID", + "description": "", + "keywords": [ + "framework", + "laravel", + "lumen", + "openapi", + "openapitools", + "php", + "sdk", + "api" + ], + "homepage": "http://openapi-generator.tech", + "license": "proprietary", + "authors": [ + { + "name": "OpenAPI-Generator contributors", + "homepage": "https://openapi-generator.tech" + } + ], + "type": "project", + "require": { + "php": ">=7.1.3", + "laravel/lumen-framework": "5.6.*", + "vlucas/phpdotenv": "~2.2" + }, + "require-dev": { + "fzaninotto/faker": "~1.4", + "phpunit/phpunit": "~7.0", + "mockery/mockery": "~1.0" + }, + "autoload": { + "psr-4": { + "App\\": "app/" + } + }, + "autoload-dev": { + "classmap": [ + "tests/", + "database/" + ] + }, + "scripts": { + "post-root-package-install": [ + "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" + ] + }, + "config": { + "preferred-install": "dist", + "sort-packages": true, + "optimize-autoloader": true + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/samples/server/petstore-security-test/lumen/lib/database/factories/ModelFactory.php b/samples/server/petstore-security-test/lumen/lib/database/factories/ModelFactory.php new file mode 100644 index 00000000000..bf9496b0eef --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/database/factories/ModelFactory.php @@ -0,0 +1,19 @@ +define(App\User::class, function (Faker\Generator $faker) { + return [ + 'name' => $faker->name, + 'email' => $faker->email, + ]; +}); diff --git a/samples/server/petstore-security-test/lumen/lib/database/migrations/.gitkeep b/samples/server/petstore-security-test/lumen/lib/database/migrations/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/samples/server/petstore-security-test/lumen/lib/database/seeds/DatabaseSeeder.php b/samples/server/petstore-security-test/lumen/lib/database/seeds/DatabaseSeeder.php new file mode 100644 index 00000000000..23526c9d99c --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/database/seeds/DatabaseSeeder.php @@ -0,0 +1,16 @@ +call('UsersTableSeeder'); + } +} diff --git a/samples/server/petstore-security-test/lumen/lib/public/.htaccess b/samples/server/petstore-security-test/lumen/lib/public/.htaccess new file mode 100644 index 00000000000..b75525bedcd --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/public/.htaccess @@ -0,0 +1,21 @@ + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Handle Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/samples/server/petstore-security-test/lumen/lib/public/index.php b/samples/server/petstore-security-test/lumen/lib/public/index.php new file mode 100644 index 00000000000..7f44de3e275 --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/public/index.php @@ -0,0 +1,34 @@ +run(); diff --git a/samples/server/petstore-security-test/lumen/lib/readme.md b/samples/server/petstore-security-test/lumen/lib/readme.md new file mode 100644 index 00000000000..e0dba8a2f5c --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/readme.md @@ -0,0 +1,27 @@ +# OpenAPITools generated server + +## Overview +This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the +[OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification/) from a remote server, you can easily generate a server stub. This +is an example of building a PHP server. + +This example uses the [Lumen Framework](http://lumen.laravel.com/). To see how to make this your own, please take a look at the template here: + +[TEMPLATES](https://github.com/openapitools/openapi-generator/tree/master/modules/openapi-generator/src/main/resources/lumen/) + +## Installation & Usage +### Composer + +Switch to the generated Lumen server stub directory. +Using `composer update` to install the framework and dependencies via [Composer](http://getcomposer.org/). + +## Note + +The `composer update` should be the first thing to do right after generating Lumen server stub. The autoload.php will be generated only after excuting `composer update`. +Or there would be errors during service or model migration. + +### Running the generated server stub + +```bash +php -S localhost:8080 public/index.php +``` diff --git a/samples/server/petstore-security-test/lumen/lib/resources/views/.gitkeep b/samples/server/petstore-security-test/lumen/lib/resources/views/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/samples/server/petstore-security-test/lumen/lib/routes/web.php b/samples/server/petstore-security-test/lumen/lib/routes/web.php new file mode 100644 index 00000000000..f4099e944b6 --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/routes/web.php @@ -0,0 +1,30 @@ +get('/', function () use ($router) { + return $router->app->version(); +}); + +/** + * put testCodeInjectEndRnNR + * Summary: To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * Notes: To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + */ +$router->put('/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r/fake', 'FakeApi@testCodeInjectEndRnNR'); + diff --git a/samples/server/petstore-security-test/lumen/lib/storage/logs/.gitignore b/samples/server/petstore-security-test/lumen/lib/storage/logs/.gitignore new file mode 100644 index 00000000000..c96a04f008e --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/storage/logs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/samples/server/petstore-security-test/lumen/lib/tests/ExampleTest.php b/samples/server/petstore-security-test/lumen/lib/tests/ExampleTest.php new file mode 100644 index 00000000000..1bad6ef7ed7 --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/tests/ExampleTest.php @@ -0,0 +1,21 @@ +get('/'); + + $this->assertEquals( + $this->app->version(), $this->response->getContent() + ); + } +} diff --git a/samples/server/petstore-security-test/lumen/lib/tests/TestCase.php b/samples/server/petstore-security-test/lumen/lib/tests/TestCase.php new file mode 100644 index 00000000000..89a058d1210 --- /dev/null +++ b/samples/server/petstore-security-test/lumen/lib/tests/TestCase.php @@ -0,0 +1,14 @@ + + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^ index.php [QSA,L] + \ No newline at end of file diff --git a/samples/server/petstore-security-test/php-slim/.openapi-generator-ignore b/samples/server/petstore-security-test/php-slim/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/server/petstore-security-test/php-slim/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore-security-test/php-slim/.openapi-generator/VERSION b/samples/server/petstore-security-test/php-slim/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/server/petstore-security-test/php-slim/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore-security-test/php-slim/README.md b/samples/server/petstore-security-test/php-slim/README.md new file mode 100644 index 00000000000..b48bc58d6b5 --- /dev/null +++ b/samples/server/petstore-security-test/php-slim/README.md @@ -0,0 +1,143 @@ +# php-base - PHP Slim Server library for OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + +* [OpenAPI Generator](https://openapi-generator.tech) +* [Slim Framework Documentation](https://www.slimframework.com/docs/) + +## Requirements + +* Web server with URL rewriting +* PHP 7.0 or newer + +This package contains `.htaccess` for Apache configuration. +If you use another server(Nginx, HHVM, IIS, lighttpd) check out [Web Servers](https://www.slimframework.com/docs/v3/start/web-servers.html) doc. + +## Installation via [Composer](https://getcomposer.org/) + +Navigate into your project's root directory and execute the bash command shown below. +This command downloads the Slim Framework and its third-party dependencies into your project's `vendor/` directory. +```bash +$ composer install +``` + +## Start devserver + +Run the following command in terminal to start localhost web server, assuming `./php-slim-server/` is public-accessible directory with `index.php` file: +```bash +$ php -S localhost:8888 -t php-slim-server +``` +> **Warning** This web server was designed to aid application development. +> It may also be useful for testing purposes or for application demonstrations that are run in controlled environments. +> It is not intended to be a full-featured web server. It should not be used on a public network. + +## Tests + +### PHPUnit + +This package uses PHPUnit 6 or 7(depends from your PHP version) for unit testing. +[Test folder](test) contains templates which you can fill with real test assertions. +How to write tests read at [PHPUnit Manual - Chapter 2. Writing Tests for PHPUnit](https://phpunit.de/manual/6.5/en/writing-tests-for-phpunit.html). + +#### Run + +Command | Target +---- | ---- +`$ composer test` | All tests +`$ composer test-apis` | Apis tests +`$ composer test-models` | Models tests + +#### Config + +Package contains fully functional config `./phpunit.xml.dist` file. Create `./phpunit.xml` in root folder to override it. + +Quote from [3. The Command-Line Test Runner — PHPUnit 7.4 Manual](https://phpunit.readthedocs.io/en/7.4/textui.html#command-line-options): + +> If phpunit.xml or phpunit.xml.dist (in that order) exist in the current working directory and --configuration is not used, the configuration will be automatically read from that file. + +### PHP CodeSniffer + +[PHP CodeSniffer Documentation](https://github.com/squizlabs/PHP_CodeSniffer/wiki). This tool helps to follow coding style and avoid common PHP coding mistakes. + +#### Run + +```bash +$ composer phpcs +``` + +#### Config + +Package contains fully functional config `./phpcs.xml.dist` file. It checks source code against PSR-1 and PSR-2 coding standards. +Create `./phpcs.xml` in root folder to override it. More info at [Using a Default Configuration File](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file) + +### PHPLint + +[PHPLint Documentation](https://github.com/overtrue/phplint). Checks PHP syntax only. + +#### Run + +```bash +$ composer phplint +``` + +## Show errors + +Switch on option in `./index.php`: +```diff + /** + * When true, additional information about exceptions are displayed by the default + * error handler. + * Default: false + */ +--- // 'displayErrorDetails' => false, ++++ 'displayErrorDetails' => true, +``` + +## API Endpoints + +All URIs are relative to *http://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r* + +> Important! Do not modify abstract API controllers directly! Instead extend them by implementation classes like: + +```php +// src/Api/PetApi.php + +namespace OpenAPIServer\Api; + +use OpenAPIServer\Api\AbstractPetApi; + +class PetApi extends AbstractPetApi +{ + + public function addPet($request, $response, $args) + { + // your implementation of addPet method here + } +} +``` + +Place all your implementation classes in `./src` folder accordingly. +For instance, when abstract class located at `./lib/Api/AbstractPetApi.php` you need to create implementation class at `./src/Api/PetApi.php`. + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*AbstractFakeApi* | **testCodeInjectEndRnNR** | **PUT** /fake | To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + +## Models + +* OpenAPIServer\Model\ModelReturn + + +## Authentication + +### Security schema `api_key` +> Important! To make ApiKey authentication work you need to extend [\OpenAPIServer\Auth\AbstractAuthenticator](./lib/Auth/AbstractAuthenticator.php) class by [\OpenAPIServer\Auth\ApiKeyAuthenticator](./src/Auth/ApiKeyAuthenticator.php) class. + +### Security schema `petstore_auth` +> Important! To make OAuth authentication work you need to extend [\OpenAPIServer\Auth\AbstractAuthenticator](./lib/Auth/AbstractAuthenticator.php) class by [\OpenAPIServer\Auth\OAuthAuthenticator](./src/Auth/OAuthAuthenticator.php) class. + +Scope list: +* `write:pets` - modify pets in your account *_/ ' \" =end -- \\r\\n \\n \\r +* `read:pets` - read your pets *_/ ' \" =end -- \\r\\n \\n \\r + +### Advanced middleware configuration +Ref to used Slim Token Middleware [dyorg/slim-token-authentication](https://github.com/dyorg/slim-token-authentication/tree/1.x#readme) diff --git a/samples/server/petstore-security-test/php-slim/composer.json b/samples/server/petstore-security-test/php-slim/composer.json new file mode 100644 index 00000000000..91d25bb9cb3 --- /dev/null +++ b/samples/server/petstore-security-test/php-slim/composer.json @@ -0,0 +1,38 @@ +{ + "minimum-stability": "RC", + "repositories": [ + { + "type": "github", + "url": "https://github.com/ybelenko/slim-token-authentication" + } + ], + "require": { + "php": "^7.0", + "slim/slim": "3.*", + "dyorg/slim-token-authentication": "dev-per_route_apply" + }, + "require-dev": { + "phpunit/phpunit": "^6.0 || ^7.0", + "overtrue/phplint": "^1.0", + "squizlabs/php_codesniffer": "^3.0" + }, + "autoload": { + "psr-4": { "OpenAPIServer\\": [ + "lib/", + "src/" + ]} + }, + "autoload-dev": { + "psr-4": { "OpenAPIServer\\": "test/" } + }, + "scripts": { + "test": [ + "@test-apis", + "@test-models" + ], + "test-apis": "phpunit --testsuite Apis", + "test-models": "phpunit --testsuite Models", + "phpcs": "phpcs", + "phplint": "phplint ./ --exclude=vendor" + } +} diff --git a/samples/server/petstore-security-test/php-slim/index.php b/samples/server/petstore-security-test/php-slim/index.php new file mode 100644 index 00000000000..767a9340c0e --- /dev/null +++ b/samples/server/petstore-security-test/php-slim/index.php @@ -0,0 +1,110 @@ + '1.1', + + /** + * Size of each chunk read from the Response body when sending to the browser. + * Default: 4096 + */ + // 'responseChunkSize' => 4096, + + /** + * If false, then no output buffering is enabled. If 'append' or 'prepend', then + * any echo or print statements are captured and are either appended or prepended + * to the Response returned from the route callable. + * Default: 'append' + */ + // 'outputBuffering' => 'append', + + /** + * When true, the route is calculated before any middleware is executed. This + * means that you can inspect route parameters in middleware if you need to. + * Default: false + */ + // 'determineRouteBeforeAppMiddleware' => false, + + /** + * When true, additional information about exceptions are displayed by the default + * error handler. + * Default: false + */ + // 'displayErrorDetails' => false, + + /** + * When true, Slim will add a Content-Length header to the response. If you are using + * a runtime analytics tool, such as New Relic, then this should be disabled. + * Default: true + */ + // 'addContentLengthHeader' => true, + + /** + * Filename for caching the FastRoute routes. Must be set to to a valid filename within + * a writeable directory. If the file does not exist, then it is created with the correct + * cache information on first run. + * Set to false to disable the FastRoute cache system. + * Default: false + */ + // 'routerCacheFile' => false, +]; + +/** + * Token Middleware 1.x Options + * Options `header`, `regex`, `parameter`, `cookie`, `attribute`, `path`, `except`, `authenticator` + * are handled by SlimRouter class. These options are ignored by app and they omitted from current + * example. + * Ref: https://github.com/dyorg/slim-token-authentication/tree/1.x + */ +$config['tokenAuthenticationOptions'] = [ + /** + * Tokens are essentially passwords. You should treat them as such and you should always + * use HTTPS. If the middleware detects insecure usage over HTTP it will return unathorized + * with a message Required HTTPS for token authentication. This rule is relaxed for requests + * on localhost. To allow insecure usage you must enable it manually by setting secure to + * false. + * Default: true + */ + // 'secure' => true, + + /** + * Alternatively you can list your development host to have relaxed security. + * Default: ['localhost', '127.0.0.1'] + */ + // 'relaxed' => ['localhost', '127.0.0.1'], + + /** + * By default on ocurred a fail on authentication, is sent a response on json format with a + * message (`Invalid Token` or `Not found Token`) and with the token (if found), with status + * `401 Unauthorized`. You can customize it by setting a callable function on error option. + * Default: null + */ + // 'error' => null, +]; + +$router = new SlimRouter($config); +$app = $router->getSlimApp(); +$app->run(); diff --git a/samples/server/petstore-security-test/php-slim/lib/Api/AbstractFakeApi.php b/samples/server/petstore-security-test/php-slim/lib/Api/AbstractFakeApi.php new file mode 100644 index 00000000000..2c1606445ae --- /dev/null +++ b/samples/server/petstore-security-test/php-slim/lib/Api/AbstractFakeApi.php @@ -0,0 +1,79 @@ +container = $container; + } + + + /** + * PUT testCodeInjectEndRnNR + * Summary: To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * Notes: To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * + * @param ServerRequestInterface $request Request + * @param ResponseInterface $response Response + * @param array|null $args Path arguments + * + * @return ResponseInterface + * @throws Exception to force implementation class to override this method + */ + public function testCodeInjectEndRnNR(ServerRequestInterface $request, ResponseInterface $response, array $args) + { + $testCodeInjectEndRnNR = $request->getParsedBodyParam('test code inject */ ' " =end -- \r\n \n \r'); + $message = "How about implementing testCodeInjectEndRnNR as a PUT method in OpenAPIServer\Api\FakeApi class?"; + throw new Exception($message); + + return $response->write($message)->withStatus(501); + } +} diff --git a/samples/server/petstore-security-test/php-slim/lib/Auth/AbstractAuthenticator.php b/samples/server/petstore-security-test/php-slim/lib/Auth/AbstractAuthenticator.php new file mode 100644 index 00000000000..faaf4d4b704 --- /dev/null +++ b/samples/server/petstore-security-test/php-slim/lib/Auth/AbstractAuthenticator.php @@ -0,0 +1,109 @@ +container = $container; + $this->requiredScope = $requiredScope; + } + + /** + * Makes the api key validation of your application + * + * Just an example of implementation. Override this method to fit your needs + * + * @param ServerRequestInterface $request HTTP request + * @param TokenSearch $tokenSearch Middleware instance which contains api key in token + * + * @return bool Must return either true or false + * @throws UnauthorizedExceptionInterface when cannot parse token + */ + public function __invoke(ServerRequestInterface &$request, TokenSearch $tokenSearch) + { + /** + * Try find authorization token via header, parameters, cookie or attribute + * If token not found, return response with status 401 (unauthorized) + */ + $token = $tokenSearch->getToken($request); + + /** + * Verify if token is valid on database + * If token isn't valid, expired or has insufficient scope must throw an UnauthorizedExceptionInterface + */ + $user = $this->getUserByToken($token); + + /** + * Set authenticated user at attributes + */ + $request = $request->withAttribute('authenticated_user', $user); + + return true; + } +} diff --git a/samples/server/petstore-security-test/php-slim/lib/Model/ModelReturn.php b/samples/server/petstore-security-test/php-slim/lib/Model/ModelReturn.php new file mode 100644 index 00000000000..20dea2a7d5f --- /dev/null +++ b/samples/server/petstore-security-test/php-slim/lib/Model/ModelReturn.php @@ -0,0 +1,30 @@ + 'PUT', + 'basePathWithoutHost' => '/%20%27%20%22%20%3Dend%20--%20%5C%5Cr%5C%5Cn%20%5C%5Cn%20%5C%5Cr/v2%20*_/%20%27%20%22%20%3Dend%20--%20%5C%5Cr%5C%5Cn%20%5C%5Cn%20%5C%5Cr', + 'path' => '/fake', + 'apiPackage' => 'OpenAPIServer\Api', + 'classname' => 'AbstractFakeApi', + 'userClassname' => 'FakeApi', + 'operationId' => 'testCodeInjectEndRnNR', + 'authMethods' => [ + ], + ], + ]; + + /** + * Class constructor + * + * @param ContainerInterface|array $container Either a ContainerInterface or an associative array of app settings + * + * @throws InvalidArgumentException When no container is provided that implements ContainerInterface + * @throws Exception When implementation class doesn't exists + */ + public function __construct($container = []) + { + $this->slimApp = new App($container); + + $authPackage = 'OpenAPIServer\Auth'; + $basicAuthenticator = function (ServerRequestInterface &$request, TokenSearch $tokenSearch) use ($authPackage) { + $message = "How about extending AbstractAuthenticator class by {$authPackage}\BasicAuthenticator?"; + throw new Exception($message); + }; + $apiKeyAuthenticator = function (ServerRequestInterface &$request, TokenSearch $tokenSearch) use ($authPackage) { + $message = "How about extending AbstractAuthenticator class by {$authPackage}\ApiKeyAuthenticator?"; + throw new Exception($message); + }; + $oAuthAuthenticator = function (ServerRequestInterface &$request, TokenSearch $tokenSearch) use ($authPackage) { + $message = "How about extending AbstractAuthenticator class by {$authPackage}\OAuthAuthenticator?"; + throw new Exception($message); + }; + + foreach ($this->operations as $operation) { + $callback = function ($request, $response, $arguments) use ($operation) { + $message = "How about extending {$operation['classname']} by {$operation['apiPackage']}\\{$operation['userClassname']} class implementing {$operation['operationId']} as a {$operation['httpMethod']} method?"; + throw new Exception($message); + return $response->withStatus(501)->write($message); + }; + $middlewares = []; + + if (class_exists("\\{$operation['apiPackage']}\\{$operation['userClassname']}")) { + $callback = "\\{$operation['apiPackage']}\\{$operation['userClassname']}:{$operation['operationId']}"; + } + + foreach ($operation['authMethods'] as $authMethod) { + switch ($authMethod['type']) { + case 'http': + $authenticatorClassname = "\\{$authPackage}\\BasicAuthenticator"; + if (class_exists($authenticatorClassname)) { + $basicAuthenticator = new $authenticatorClassname($container); + } + + $middlewares[] = new TokenAuthentication($this->getTokenAuthenticationOptions([ + 'authenticator' => $basicAuthenticator, + 'regex' => '/Basic\s+(.*)$/i', + 'header' => 'Authorization', + 'parameter' => null, + 'cookie' => null, + 'argument' => null, + ])); + break; + case 'apiKey': + $authenticatorClassname = "\\{$authPackage}\\ApiKeyAuthenticator"; + if (class_exists($authenticatorClassname)) { + $apiKeyAuthenticator = new $authenticatorClassname($container); + } + + $middlewares[] = new TokenAuthentication($this->getTokenAuthenticationOptions([ + 'authenticator' => $apiKeyAuthenticator, + 'regex' => '/^(.*)$/i', + 'header' => $authMethod['isKeyInHeader'] ? $authMethod['keyParamName'] : null, + 'parameter' => $authMethod['isKeyInQuery'] ? $authMethod['keyParamName'] : null, + 'cookie' => $authMethod['isKeyInCookie'] ? $authMethod['keyParamName'] : null, + 'argument' => null, + ])); + break; + case 'oauth2': + $authenticatorClassname = "\\{$authPackage}\\OAuthAuthenticator"; + if (class_exists($authenticatorClassname)) { + $oAuthAuthenticator = new $authenticatorClassname($container, $authMethod['scopes']); + } + + $middlewares[] = new TokenAuthentication($this->getTokenAuthenticationOptions([ + 'authenticator' => $oAuthAuthenticator, + 'regex' => '/Bearer\s+(.*)$/i', + 'header' => 'Authorization', + 'parameter' => null, + 'cookie' => null, + 'argument' => null, + ])); + break; + default: + throw new Exception('Unknown authorization schema type'); + } + } + + $this->addRoute( + [$operation['httpMethod']], + "{$operation['basePathWithoutHost']}{$operation['path']}", + $callback, + $middlewares + )->setName($operation['operationId']); + } + } + + /** + * Merges user defined options with dynamic params + * + * @param array $options Params which need to merge into user options + * + * @return array Merged array + */ + private function getTokenAuthenticationOptions(array $options) + { + if (is_array($this->slimApp->getContainer()['tokenAuthenticationOptions']) === false) { + return $options; + } + + return array_merge($this->slimApp->getContainer()['tokenAuthenticationOptions'], $options); + } + + /** + * Add route with multiple methods + * + * @param string[] $methods Numeric array of HTTP method names + * @param string $pattern The route URI pattern + * @param callable|string $callable The route callback routine + * @param array|null $middlewares List of middlewares + * + * @return RouteInterface + * + * @throws InvalidArgumentException If the route pattern isn't a string + */ + public function addRoute(array $methods, string $pattern, $callable, $middlewares = []) + { + $route = $this->slimApp->map($methods, $pattern, $callable); + foreach ($middlewares as $middleware) { + $route->add($middleware); + } + return $route; + } + + /** + * Returns Slim Framework instance + * + * @return App + */ + public function getSlimApp() + { + return $this->slimApp; + } +} diff --git a/samples/server/petstore-security-test/php-slim/phpcs.xml.dist b/samples/server/petstore-security-test/php-slim/phpcs.xml.dist new file mode 100644 index 00000000000..744c14c40a4 --- /dev/null +++ b/samples/server/petstore-security-test/php-slim/phpcs.xml.dist @@ -0,0 +1,31 @@ + + + PHP_CodeSniffer config for OpenAPI Petstore *_/ ' \" =end -- \\r\\n \\n \\r + + + ./ + + + ./vendor + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/server/petstore-security-test/php-slim/phpunit.xml.dist b/samples/server/petstore-security-test/php-slim/phpunit.xml.dist new file mode 100644 index 00000000000..5804ff4945e --- /dev/null +++ b/samples/server/petstore-security-test/php-slim/phpunit.xml.dist @@ -0,0 +1,27 @@ + + + + + ./test/Api + + + ./test/Model + + + + + ./lib/Api + ./lib/Model + + + \ No newline at end of file diff --git a/samples/server/petstore-security-test/php-slim/test/Api/FakeApiTest.php b/samples/server/petstore-security-test/php-slim/test/Api/FakeApiTest.php new file mode 100644 index 00000000000..aab077bfa98 --- /dev/null +++ b/samples/server/petstore-security-test/php-slim/test/Api/FakeApiTest.php @@ -0,0 +1,81 @@ + + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L] + \ No newline at end of file diff --git a/samples/server/petstore-security-test/silex/SwaggerServer/.openapi-generator-ignore b/samples/server/petstore-security-test/silex/SwaggerServer/.openapi-generator-ignore new file mode 100644 index 00000000000..7484ee590a3 --- /dev/null +++ b/samples/server/petstore-security-test/silex/SwaggerServer/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore-security-test/silex/SwaggerServer/.openapi-generator/VERSION b/samples/server/petstore-security-test/silex/SwaggerServer/.openapi-generator/VERSION new file mode 100644 index 00000000000..afa63656064 --- /dev/null +++ b/samples/server/petstore-security-test/silex/SwaggerServer/.openapi-generator/VERSION @@ -0,0 +1 @@ +4.0.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore-security-test/silex/SwaggerServer/README.md b/samples/server/petstore-security-test/silex/SwaggerServer/README.md new file mode 100644 index 00000000000..03f2825681d --- /dev/null +++ b/samples/server/petstore-security-test/silex/SwaggerServer/README.md @@ -0,0 +1,10 @@ +# OpenAPI generated server + +## Overview +This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the +[OpenAPI-Spec](https://www.openapis.org/) from a remote server, you can easily generate a server stub. This +is an example of building a PHP server. + +This example uses the [Silex](http://silex.sensiolabs.org/) micro-framework. To see how to make this your own, please take a look at the template here: + +[TEMPLATES](https://github.com/openapitools/openapi-generator/tree/master/modules/openapi-generator/src/main/resources/silex/) diff --git a/samples/server/petstore-security-test/silex/SwaggerServer/composer.json b/samples/server/petstore-security-test/silex/SwaggerServer/composer.json new file mode 100644 index 00000000000..466cd3fbc77 --- /dev/null +++ b/samples/server/petstore-security-test/silex/SwaggerServer/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "silex/silex": "~1.2" + } +} \ No newline at end of file diff --git a/samples/server/petstore-security-test/silex/SwaggerServer/index.php b/samples/server/petstore-security-test/silex/SwaggerServer/index.php new file mode 100644 index 00000000000..f5e5b498f5d --- /dev/null +++ b/samples/server/petstore-security-test/silex/SwaggerServer/index.php @@ -0,0 +1,17 @@ +PUT('/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r/fake', function(Application $app, Request $request) { + $test_code_inject_*/_'_"_=end____\r\n_\n_\r = $request->get('test_code_inject_*/_'_"_=end____\r\n_\n_\r'); + return new Response('How about implementing testCodeInject */ ' " =end \r\n \n \r as a PUT method ?'); + }); + + +$app->run();