diff --git a/include/pistache/description.h b/include/pistache/description.h index 775b3d831..612d48f9f 100644 --- a/include/pistache/description.h +++ b/include/pistache/description.h @@ -143,6 +143,45 @@ struct InfoBuilder { Info *info_; }; +#define AUTHENTICATION_TYPES \ + AUTH_TYPE(ApiKey, "apiKey") + +enum class AuthenticationType { +#define AUTH_TYPE(name, _) name, + AUTHENTICATION_TYPES +#undef AUTH_TYPE +}; + +#define AUTHENTICATION_LOCATIONS \ + AUTH_LOC(Header, "header") \ + AUTH_LOC(Query, "query") + +enum class AuthenticationLocation { +#define AUTH_LOC(name, _) name, + AUTHENTICATION_LOCATIONS +#undef AUTH_LOC +}; + +struct Authentication { + Authentication(std::string title); + + std::string title; + AuthenticationType type; + AuthenticationLocation location; + std::string name; +}; + +struct AuthenticationBuilder { + explicit AuthenticationBuilder(Authentication *auth); + + AuthenticationBuilder &type(AuthenticationType type); + AuthenticationBuilder &location(AuthenticationLocation loc); + AuthenticationBuilder &name(std::string name); + +private: + Authentication *auth_; +}; + struct DataType { virtual const char *typeName() const = 0; virtual const char *format() const = 0; @@ -380,6 +419,7 @@ class Description { std::string description = ""); Schema::InfoBuilder info(); + Schema::AuthenticationBuilder authentication(std::string title); Description &host(std::string value); Description &basePath(std::string value); @@ -423,6 +463,7 @@ class Description { std::string description); Schema::Info rawInfo() const { return info_; } + std::vector rawAuthenticationSchemas() const { return authenticationSchemes_; } std::string rawHost() const { return host_; } std::string rawBasePath() const { return basePath_; } std::vector rawSchemes() const { return schemes_; } @@ -431,6 +472,7 @@ class Description { private: Schema::Info info_; + std::vector authenticationSchemes_; std::string host_; std::string basePath_; std::vector schemes_; diff --git a/include/pistache/thirdparty/serializer/rapidjson.h b/include/pistache/thirdparty/serializer/rapidjson.h index 02bfbd4e2..97dceab84 100644 --- a/include/pistache/thirdparty/serializer/rapidjson.h +++ b/include/pistache/thirdparty/serializer/rapidjson.h @@ -16,6 +16,31 @@ namespace Pistache { namespace Rest { namespace Serializer { + +const char *authenticationTypeString(Schema::AuthenticationType type) { + switch (type) { +#define AUTH_TYPE(e, str) \ + case Schema::AuthenticationType::e: \ + return str; + AUTHENTICATION_TYPES +#undef AUTH_TYPE + } + + return nullptr; +} + +const char *authenticationLocationString(Schema::AuthenticationLocation location) { + switch (location) { +#define AUTH_LOC(e, str) \ + case Schema::AuthenticationLocation::e: \ + return str; + AUTHENTICATION_LOCATIONS +#undef AUTH_LOC + } + + return nullptr; +} + template void serializeInfo(Writer &writer, const Schema::Info &info) { writer.String("swagger"); @@ -38,6 +63,40 @@ void serializeInfo(Writer &writer, const Schema::Info &info) { } writer.EndObject(); } +template +void serializeAuthenticationSchemas(Writer &writer, const std::vector &authenticationSchemas) { + if (authenticationSchemas.empty()) return; + + writer.String("securityDefinitions"); + writer.StartObject(); + for (auto &schema: authenticationSchemas){ + writer.String(schema.title.c_str()); + writer.StartObject(); + { + writer.String("type"); + writer.String(authenticationTypeString(schema.type)); + writer.String("in"); + writer.String(authenticationLocationString(schema.location)); + writer.String("name"); + writer.String(schema.name.c_str()); + } + writer.EndObject(); + } + writer.EndObject(); + + writer.String("security"); + writer.StartArray(); + for (auto &schema: authenticationSchemas) { + writer.StartObject(); + { + writer.String(schema.title.c_str()); + writer.StartArray(); + writer.EndArray(); + } + writer.EndObject(); + } + writer.EndArray(); +} template void serializePC(Writer &writer, const Schema::ProduceConsume &pc) { @@ -175,6 +234,7 @@ void serializeDescription(Writer &writer, const Description &desc) { writer.StartObject(); { serializeInfo(writer, desc.rawInfo()); + serializeAuthenticationSchemas(writer, desc.rawAuthenticationSchemas()); auto host = desc.rawHost(); auto basePath = desc.rawBasePath(); auto schemes = desc.rawSchemes(); diff --git a/src/common/description.cc b/src/common/description.cc index fa2a251c5..0c2307be0 100644 --- a/src/common/description.cc +++ b/src/common/description.cc @@ -213,6 +213,28 @@ InfoBuilder &InfoBuilder::license(std::string name, std::string url) { return *this; } +Authentication::Authentication(std::string title) : title(std::move(title)) {} + +AuthenticationBuilder::AuthenticationBuilder(Authentication *auth) : auth_(auth) {} + +AuthenticationBuilder &AuthenticationBuilder::type(AuthenticationType type) +{ + auth_->type = type; + return *this; +} + +AuthenticationBuilder &AuthenticationBuilder::location(AuthenticationLocation loc) +{ + auth_->location = loc; + return *this; +} + +AuthenticationBuilder &AuthenticationBuilder::name(std::string name) +{ + auth_->name = std::move(name); + return *this; +} + } // namespace Schema Description::Description(std::string title, std::string version, @@ -225,6 +247,12 @@ Schema::InfoBuilder Description::info() { return builder; } +Schema::AuthenticationBuilder Description::authentication(std::string title) +{ + auto it = authenticationSchemes_.emplace(authenticationSchemes_.end(), std::move(title)); + return Schema::AuthenticationBuilder(&*it); +} + Description &Description::host(std::string value) { host_ = std::move(value); return *this;