Browse Source

Refactor QGrpcCredentials API

- Make definition and roles of channel/call credentialls bit more
  explicit
- Update Ssl credentials usage
- Add reference User/Password credentials
- Update existing tests
TODO: Need to implement explicit unit tests for credentials
Alexey Edelev 5 years ago
parent
commit
235de7d2ac

+ 4 - 12
examples/addressbook/addressbookengine.cpp

@@ -29,8 +29,8 @@
 #include "addressbook_grpc.pb.h"
 
 #include <QGrpcHttp2Channel>
-#include <InsecureCredentials>
-#include <SslCredentials>
+#include <QGrpcUserPasswordCredentials>
+#include <QGrpcSslCredentials>
 
 #include <QDebug>
 #include <QFile>
@@ -39,14 +39,6 @@
 
 using namespace qtprotobuf::examples;
 
-class AuthCredentials : public QtProtobuf::CallCredentials
-{
-public:
-    AuthCredentials(const QString &userName, const QString &password) :
-        CallCredentials(CredentialMap{{QLatin1String("user-name"), QVariant::fromValue(userName)},
-                                      {QLatin1String("user-password"), QVariant::fromValue(password)}}) {}
-};
-
 AddressBookEngine::AddressBookEngine() : QObject()
   , m_client(new AddressBookClient)
   , m_contacts(new ContactsListModel({}, this))
@@ -61,8 +53,8 @@ AddressBookEngine::AddressBookEngine() : QObject()
     conf.setProtocol(QSsl::TlsV1_2);
     conf.setAllowedNextProtocols({QSslConfiguration::ALPNProtocolHTTP2});
 
-    std::shared_ptr<QtProtobuf::QAbstractGrpcChannel> channel(new QtProtobuf::QGrpcHttp2Channel(QUrl("https://localhost:65001"), QtProtobuf::SslCredentials(conf) |
-                                                                                      AuthCredentials("authorizedUser", QCryptographicHash::hash("test", QCryptographicHash::Md5).toHex())));
+    std::shared_ptr<QtProtobuf::QAbstractGrpcChannel> channel(new QtProtobuf::QGrpcHttp2Channel(QUrl("https://localhost:65001"), QtProtobuf::QGrpcSslCredentials(conf) |
+                                                                                      QtProtobuf::QGrpcUserPasswordCredentials<>("authorizedUser", QCryptographicHash::hash("test", QCryptographicHash::Md5).toHex())));
     m_client->attachChannel(channel);
     m_client->subscribeContactsUpdates(ListFrame());
     connect(m_client, &AddressBookClient::contactsUpdated, this, [this](const Contacts &contacts) {

+ 4 - 13
examples/simplechat/simplechatengine.cpp

@@ -28,8 +28,8 @@
 #include "simplechat_grpc.pb.h"
 
 #include <QGrpcHttp2Channel>
-#include <InsecureCredentials>
-#include <SslCredentials>
+#include <QGrpcUserPasswordCredentials>
+#include <QGrpcSslCredentials>
 
 #include <QDebug>
 #include <QFile>
@@ -45,14 +45,6 @@
 
 using namespace qtprotobuf::examples;
 
-class AuthCredentials : public QtProtobuf::CallCredentials
-{
-public:
-    AuthCredentials(const QString &userName, const QString &password) :
-        CallCredentials(CredentialMap{{QLatin1String("user-name"), QVariant::fromValue(userName)},
-    {QLatin1String("user-password"), QVariant::fromValue(password)}}) {}
-};
-
 SimpleChatEngine::SimpleChatEngine(QObject *parent) : QObject(parent), m_client(new SimpleChatClient)
   , m_clipBoard(QGuiApplication::clipboard())
 {
@@ -77,8 +69,8 @@ void SimpleChatEngine::login(const QString &name, const QString &password)
     conf.setAllowedNextProtocols({QSslConfiguration::ALPNProtocolHTTP2});
 
     QUrl url("https://localhost:65002");
-    std::shared_ptr<QtProtobuf::QAbstractGrpcChannel> channel(new QtProtobuf::QGrpcHttp2Channel(url, QtProtobuf::SslCredentials(conf) |
-                                                                                      AuthCredentials(name, QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Md5).toHex())));
+    std::shared_ptr<QtProtobuf::QAbstractGrpcChannel> channel(new QtProtobuf::QGrpcHttp2Channel(url, QtProtobuf::QGrpcSslCredentials(conf) |
+                                                                                      QtProtobuf::QGrpcUserPasswordCredentials<>(name, QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Md5).toHex())));
 
     m_client->attachChannel(channel);
     m_client->subscribeMessageListUpdates(None());
@@ -162,4 +154,3 @@ QString SimpleChatEngine::getImageThumbnail(const QByteArray &data) const
     img.save(&buffer, "PNG");
     return getImage(scaledData);
 }
-

+ 9 - 6
src/grpc/CMakeLists.txt

@@ -19,18 +19,21 @@ file(GLOB SOURCES qgrpcasyncreply.cpp
     qabstractgrpcchannel.cpp
     qgrpchttp2channel.cpp
     qabstractgrpcclient.cpp
-    abstractcredentials.cpp
-    sslcredentials.cpp
-    insecurecredentials.cpp)
+    qgrpccredentials.cpp
+    qgrpcsslcredentials.cpp
+    qgrpcinsecurecredentials.cpp
+    qgrpcuserpasswordcredentials.cpp)
 
 file(GLOB HEADERS qgrpcasyncreply.h
     qgrpcstatus.h
     qabstractgrpcchannel.h
     qgrpchttp2channel.h
     qabstractgrpcclient.h
-    abstractcredentials.h
-    sslcredentials.h
-    insecurecredentials.h
+    qabstractgrpccredentials.h
+    qgrpccredentials.h
+    qgrpcsslcredentials.h
+    qgrpcinsecurecredentials.h
+    qgrpcuserpasswordcredentials.h
     qtgrpcglobal.h)
 
 protobuf_generate_qt_headers(PUBLIC_HEADERS ${HEADERS} COMPONENT ${TARGET})

+ 0 - 148
src/grpc/abstractcredentials.h

@@ -1,148 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
- *
- * This file is part of QtProtobuf project https://git.semlanik.org/semlanik/qtprotobuf
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this
- * software and associated documentation files (the "Software"), to deal in the Software
- * without restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
- * to permit persons to whom the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies
- * or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
- * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
- * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#pragma once //AbstractCredentials
-
-#include <QString>
-#include <QHash>
-#include <QVariant>
-
-#include <functional>
-#include <memory>
-
-#include "qtgrpcglobal.h"
-
-namespace QtProtobuf {
-/*!
-*  \addtogroup QtGrpc
-*  \{
-*/
-
-class CallCredentials;
-class ChannelCredentials;
-
-using CredentialMap = QHash<QLatin1String, QVariant>;
-
-//! \private
-class QGrpcAbstractCredentials {
-public:
-    virtual CredentialMap callCredentials() = 0;
-    virtual CredentialMap channelCredentials() = 0;
-};
-
-/*!
- * \brief The CallCredentials class
- */
-class Q_GRPC_EXPORT CallCredentials
-{
-public:
-    CallCredentials() = default;
-    virtual ~CallCredentials();
-};
-
-/*!
- * \brief The ChannelCredentials class
- */
-class Q_GRPC_EXPORT ChannelCredentials
-{
-public:
-    ChannelCredentials() = default;
-    virtual ~ChannelCredentials();
-};
-
-
-/*!
- * \brief The QGrpcCredentials class
- */
-template<typename Call, typename Channel,
-         typename std::enable_if_t<std::is_base_of<QtProtobuf::CallCredentials, Call>::value
-                                   && std::is_base_of<QtProtobuf::ChannelCredentials, Channel>::value, int> = 0>
-class Q_GRPC_EXPORT QGrpcCredentials : public QGrpcAbstractCredentials
-{
-public:
-    static QtProtobuf::QGrpcAbstractCredentials *withCredentials(const Call &call, const Channel &channel)
-    {
-        return new QGrpcCredentials<Call, Channel>(call, channel);
-    }
-    static QtProtobuf::QGrpcAbstractCredentials *withCallCredentials(const Call &call) {
-        return new QGrpcCredentials<Call, Channel>(call);
-    }
-    static QtProtobuf::QGrpcAbstractCredentials *withChannelCredentials(const Channel &channel) {
-        return new QGrpcCredentials<Call, Channel>(channel);
-    }
-
-    CredentialMap callCredentials() {
-        return mCall();
-    }
-
-    CredentialMap channelCredentials() {
-        return mChannel();
-    }
-
-public:
-    QGrpcCredentials(const Call &call, const Channel &channel) :
-        mCall(call)
-      , mChannel(channel)
-    {
-    }
-
-    QGrpcCredentials(const Call &call) :
-        mCall(call)
-    {
-    }
-
-    QGrpcCredentials(const Channel &channel) :
-        mChannel(channel)
-    {
-    }
-
-protected:
-    QGrpcCredentials() = default;
-
-private:
-    Call mCall;
-    Channel mChannel;
-};
-
-/*! \} */
-}
-
-//! \private
-template<typename Call, typename Channel,
-         typename std::enable_if_t<std::is_base_of<QtProtobuf::CallCredentials, Call>::value
-                                   && std::is_base_of<QtProtobuf::ChannelCredentials, Channel>::value, int> = 0>
-std::unique_ptr<QtProtobuf::QGrpcAbstractCredentials> operator |(const Call &call, const Channel &channel)
-{
-    return std::unique_ptr<QtProtobuf::QGrpcAbstractCredentials>(QtProtobuf::QGrpcCredentials<Call, Channel>::withCredentials(call, channel));
-}
-
-//! \private
-template<typename Call, typename Channel,
-         typename std::enable_if_t<std::is_base_of<QtProtobuf::CallCredentials, Call>::value
-                                   && std::is_base_of<QtProtobuf::ChannelCredentials, Channel>::value, int> = 0>
-std::unique_ptr<QtProtobuf::QGrpcAbstractCredentials> operator |(const Channel &channel, const Call &call)
-{
-    return std::unique_ptr<QtProtobuf::QGrpcAbstractCredentials>(new QtProtobuf::QGrpcCredentials<Call, Channel>(call, channel));
-}

+ 1 - 0
src/grpc/qabstractgrpcchannel.h

@@ -31,6 +31,7 @@
 #include <memory>
 
 #include "qgrpcstatus.h"
+#include "qgrpccredentials.h"
 #include "qtgrpcglobal.h"
 
 namespace QtProtobuf {

+ 0 - 1
src/grpc/qabstractgrpcclient.cpp

@@ -111,4 +111,3 @@ QAbstractProtobufSerializer *QAbstractGrpcClient::serializer() const
 {
     return d_ptr->serializer.get();
 }
-

+ 13 - 13
src/grpc/insecurecredentials.h → src/grpc/qabstractgrpccredentials.h

@@ -23,23 +23,23 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#pragma once //InsecureCredentials
-
-#include "abstractcredentials.h"
+#pragma once
 
 #include "qtgrpcglobal.h"
 
+#include <QHash>
+#include <QString>
+#include <QVariant>
+
 namespace QtProtobuf {
-/*!
- * \ingroup QtGrpc
- * \brief The InsecureCredentials class
- */
-class Q_GRPC_EXPORT InsecureCredentials : public ChannelCredentials
-{
+
+using QGrpcCredentialMap = QHash<QLatin1String, QVariant>;
+
+//! \private
+class Q_GRPC_EXPORT QAbstractGrpcCredentials {
 public:
-    InsecureCredentials() = default;
-    CredentialMap operator()() {
-        return CredentialMap{};
-    }
+    virtual ~QAbstractGrpcCredentials() = default;
+    virtual QGrpcCredentialMap callCredentials() = 0;
+    virtual QGrpcCredentialMap channelCredentials() = 0;
 };
 }

+ 2 - 3
src/grpc/abstractcredentials.cpp → src/grpc/qgrpccredentials.cpp

@@ -23,9 +23,8 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "abstractcredentials.h"
+#include "qgrpccredentials.h"
 
 using namespace QtProtobuf;
 
-CallCredentials::~CallCredentials() = default;
-ChannelCredentials::~ChannelCredentials() = default;
+const char *QtProtobuf::SslConfigCredential = "sslConfig";

+ 113 - 0
src/grpc/qgrpccredentials.h

@@ -0,0 +1,113 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of QtProtobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once //QGrpcCredentials
+
+#include "qtgrpcglobal.h"
+#include "qabstractgrpccredentials.h"
+
+#include <memory>
+
+namespace QtProtobuf {
+/*!
+*  \addtogroup QtGrpc
+*  \{
+*/
+
+/*!
+ * \brief The QGrpcCallCredentials class
+ */
+class Q_GRPC_EXPORT QGrpcCallCredentials {};
+
+/*!
+ * \brief The QGrpcChannelCredentials class
+ */
+class Q_GRPC_EXPORT QGrpcChannelCredentials {};
+
+/*!
+ * \brief The QGrpcCredentials class
+ */
+template<typename Call, typename Channel,
+         typename std::enable_if_t<std::is_base_of<QtProtobuf::QGrpcCallCredentials, Call>::value &&
+                                   std::is_base_of<QtProtobuf::QGrpcChannelCredentials, Channel>::value, int> = 0>
+class QGrpcCredentials final : public QAbstractGrpcCredentials
+{
+public:
+    QGrpcCredentials(const Call &call, const Channel &channel) :
+        mCall(call)
+      , mChannel(channel)
+    {
+    }
+
+    QGrpcCredentials(const Call &call) :
+        mCall(call)
+    {
+    }
+
+    QGrpcCredentials(const Channel &channel) :
+        mChannel(channel)
+    {
+    }
+
+    QGrpcCredentialMap callCredentials() override {
+        return mCall();
+    }
+
+    QGrpcCredentialMap channelCredentials() override {
+        return mChannel.channelCredentials();
+    }
+
+private:
+    QGrpcCredentials() = default;
+
+    Call mCall;
+    Channel mChannel;
+};
+
+/*!
+ * \brief SslConfigCredential
+ */
+extern Q_GRPC_EXPORT const char *SslConfigCredential;
+
+/*! \} */
+}
+
+//! \private
+template<typename Call, typename Channel,
+         typename std::enable_if_t<std::is_base_of<QtProtobuf::QGrpcCallCredentials, Call>::value &&
+                                   std::is_base_of<QtProtobuf::QGrpcChannelCredentials, Channel>::value, int> = 0>
+std::unique_ptr<QtProtobuf::QAbstractGrpcCredentials> operator |(const Call &call, const Channel &channel)
+{
+    return std::unique_ptr<QtProtobuf::QAbstractGrpcCredentials>(new QtProtobuf::QGrpcCredentials<Call, Channel>(call, channel));
+}
+
+//! \private
+template<typename Call, typename Channel,
+         typename std::enable_if_t<std::is_base_of<QtProtobuf::QGrpcCallCredentials, Call>::value &&
+                                   std::is_base_of<QtProtobuf::QGrpcChannelCredentials, Channel>::value, int> = 0>
+std::unique_ptr<QtProtobuf::QAbstractGrpcCredentials> operator |(const Channel &channel, const Call &call)
+{
+    return std::unique_ptr<QtProtobuf::QAbstractGrpcCredentials>(new QtProtobuf::QGrpcCredentials<Call, Channel>(call, channel));
+}

+ 9 - 9
src/grpc/qgrpchttp2channel.cpp

@@ -37,7 +37,7 @@
 
 #include "qgrpcasyncreply.h"
 #include "qabstractgrpcclient.h"
-#include "abstractcredentials.h"
+#include "qgrpccredentials.h"
 #include "qprotobufserializerregistry_p.h"
 #include "qtprotobuflogging.h"
 
@@ -104,7 +104,7 @@ struct QGrpcHttp2ChannelPrivate {
 
     QUrl url;
     QNetworkAccessManager nm;
-    std::unique_ptr<QGrpcAbstractCredentials> credentials;
+    std::unique_ptr<QAbstractGrpcCredentials> credentials;
     QSslConfiguration sslConfig;
     std::unordered_map<QNetworkReply *, ExpectedData> activeStreamReplies;
 
@@ -119,7 +119,7 @@ struct QGrpcHttp2ChannelPrivate {
         request.setRawHeader(AcceptEncodingHeader, "identity,gzip");
         request.setRawHeader(TEHeader, "trailers");
         request.setSslConfiguration(sslConfig);
-        CredentialMap callCredentials = credentials->callCredentials();
+        QGrpcCredentialMap callCredentials = credentials->callCredentials();
         for (auto i = callCredentials.begin(); i != callCredentials.end(); ++i) {
             request.setRawHeader(i.key().data(), i.value().toString().toUtf8());
         }
@@ -127,7 +127,7 @@ struct QGrpcHttp2ChannelPrivate {
         request.setAttribute(QNetworkRequest::Http2DirectAttribute, true);
 
         QByteArray msg(GrpcMessageSizeHeaderSize, '\0');
-        *(int *)(msg.data() + 1) = qToBigEndian(args.size());
+        *reinterpret_cast<int *>(msg.data() + 1) = qToBigEndian(args.size());
         msg += args;
         qProtoDebug() << "SEND: " << msg.size();
 
@@ -172,22 +172,22 @@ struct QGrpcHttp2ChannelPrivate {
         return networkReply->readAll().mid(GrpcMessageSizeHeaderSize);
     }
 
-    QGrpcHttp2ChannelPrivate(const QUrl &_url, std::unique_ptr<QGrpcAbstractCredentials> _credentials)
+    QGrpcHttp2ChannelPrivate(const QUrl &_url, std::unique_ptr<QAbstractGrpcCredentials> _credentials)
         : url(_url)
         , credentials(std::move(_credentials))
     {
         if (url.scheme() == "https") {
-            if (!credentials->channelCredentials().contains(QLatin1String("sslConfig"))) {
+            if (!credentials->channelCredentials().contains(QLatin1String(SslConfigCredential))) {
                 throw std::invalid_argument("Https connection requested but not ssl configuration provided.");
             }
-            sslConfig = credentials->channelCredentials().value(QLatin1String("sslConfig")).value<QSslConfiguration>();
+            sslConfig = credentials->channelCredentials().value(QLatin1String(SslConfigCredential)).value<QSslConfiguration>();
         } else if (url.scheme().isEmpty()) {
             url.setScheme("http");
         }
     }
 
     static int getExpectedDataSize(const QByteArray &container) {
-        return qFromBigEndian(*(int *)(container.data() + 1)) + GrpcMessageSizeHeaderSize;
+        return qFromBigEndian(*reinterpret_cast<const int *>(container.data() + 1)) + GrpcMessageSizeHeaderSize;
     }
 
     QObject lambdaContext;
@@ -195,7 +195,7 @@ struct QGrpcHttp2ChannelPrivate {
 
 }
 
-QGrpcHttp2Channel::QGrpcHttp2Channel(const QUrl &url, std::unique_ptr<QGrpcAbstractCredentials> credentials) : QAbstractGrpcChannel()
+QGrpcHttp2Channel::QGrpcHttp2Channel(const QUrl &url, std::unique_ptr<QAbstractGrpcCredentials> credentials) : QAbstractGrpcChannel()
   , d_ptr(std::make_unique<QGrpcHttp2ChannelPrivate>(url, std::move(credentials)))
 {
 }

+ 2 - 2
src/grpc/qgrpchttp2channel.h

@@ -32,7 +32,7 @@
 
 namespace QtProtobuf {
 
-class QGrpcAbstractCredentials;
+class QAbstractGrpcCredentials;
 struct QGrpcHttp2ChannelPrivate;
 /*!
  * \ingroup QtGrpc
@@ -41,7 +41,7 @@ struct QGrpcHttp2ChannelPrivate;
 class Q_GRPC_EXPORT QGrpcHttp2Channel final : public QAbstractGrpcChannel
 {
 public:
-    QGrpcHttp2Channel(const QUrl &url, std::unique_ptr<QGrpcAbstractCredentials> credentials);
+    QGrpcHttp2Channel(const QUrl &url, std::unique_ptr<QAbstractGrpcCredentials> credentials);
     ~QGrpcHttp2Channel();
 
     QGrpcStatus call(const QString &method, const QString &service, const QByteArray &args, QByteArray &ret) override;

+ 1 - 1
src/grpc/insecurecredentials.cpp → src/grpc/qgrpcinsecurecredentials.cpp

@@ -23,4 +23,4 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "insecurecredentials.h"
+#include "qgrpcinsecurecredentials.h"

+ 59 - 0
src/grpc/qgrpcinsecurecredentials.h

@@ -0,0 +1,59 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of QtProtobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once //QGrpcInsecureCredentials
+
+#include "qgrpccredentials.h"
+#include "qtgrpcglobal.h"
+
+namespace QtProtobuf {
+/*!
+ * \ingroup QtGrpc
+ * \brief The QGrpcInsecureCallCredentials class is dummy implementation of
+ * QGrpcCallCredentials. It doesn't provides any extra information to channel.
+ *
+ * Use it when you don't need any call credentials.
+ */
+class Q_GRPC_EXPORT QGrpcInsecureCallCredentials final : public QGrpcCallCredentials {
+public:
+    QGrpcCredentialMap operator()() const {
+        return QGrpcCredentialMap{};
+    }
+};
+
+/*!
+ * \ingroup QtGrpc
+ * \brief The QGrpcInsecureChannelCredentials class is dummy implementation of
+ * QGrpcChannelCredentials. It doesn't provides any extra information to channel.
+ *
+ * Use it when you don't need any channel credentials.
+ */
+class Q_GRPC_EXPORT QGrpcInsecureChannelCredentials final : public QGrpcChannelCredentials {
+public:
+    QGrpcCredentialMap channelCredentials() const {
+        return QGrpcCredentialMap{};
+    }
+};
+}

+ 1 - 1
src/grpc/sslcredentials.cpp → src/grpc/qgrpcsslcredentials.cpp

@@ -23,4 +23,4 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "sslcredentials.h"
+#include "qgrpcsslcredentials.h"

+ 12 - 10
src/grpc/sslcredentials.h → src/grpc/qgrpcsslcredentials.h

@@ -23,30 +23,32 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#pragma once //SslCredentials
+#pragma once //QGrpcSslCredentials
 
-#include "abstractcredentials.h"
+#include "qgrpccredentials.h"
+#include "qtgrpcglobal.h"
 
 #include <QSslConfiguration>
 
-#include "qtgrpcglobal.h"
-
 namespace QtProtobuf {
+
 /*!
  * \ingroup QtGrpc
- * \brief The SslCredentials class
+ * \brief The QGrpcSslCredentials class
  */
-class Q_GRPC_EXPORT SslCredentials : public ChannelCredentials
+class Q_GRPC_EXPORT QGrpcSslCredentials final : public QGrpcChannelCredentials
 {
 public:
-    SslCredentials(const QSslConfiguration &configuation) :
-        m_map(CredentialMap{{QLatin1String("sslConfig"),
+    QGrpcSslCredentials(const QSslConfiguration &configuation) :
+        m_map(QGrpcCredentialMap{{QLatin1String(SslConfigCredential),
               QVariant::fromValue<QSslConfiguration>(configuation)}})
     {}
-    CredentialMap operator()() {
+
+    QGrpcCredentialMap channelCredentials() const {
         return m_map;
     }
 private:
-    CredentialMap m_map;
+	QGrpcSslCredentials() = default;
+    QGrpcCredentialMap m_map;
 };
 }

+ 26 - 0
src/grpc/qgrpcuserpasswordcredentials.cpp

@@ -0,0 +1,26 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of QtProtobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "qgrpcuserpasswordcredentials.h"

+ 52 - 0
src/grpc/qgrpcuserpasswordcredentials.h

@@ -0,0 +1,52 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of QtProtobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once //QGrpcUserPasswordCredentials
+
+#include "qgrpccredentials.h"
+
+namespace QtProtobuf {
+
+constexpr char defaultUserFieldName[] = "user-name";
+constexpr char defaultPasswordFieldName[] = "user-password";
+
+template<const char *UserFieldName = defaultUserFieldName,
+         const char *PasswordFieldName = defaultPasswordFieldName>
+class QGrpcUserPasswordCredentials final : public QGrpcCallCredentials
+{
+public:
+    QGrpcUserPasswordCredentials(const QString &userName, const QString &password) :
+        m_map(QtProtobuf::QGrpcCredentialMap{{QLatin1String(UserFieldName), QVariant::fromValue(userName)},
+                                      {QLatin1String(PasswordFieldName), QVariant::fromValue(password)}})
+	{}
+
+	QtProtobuf::QGrpcCredentialMap operator()() {
+		return m_map;
+	}
+private:
+	QGrpcUserPasswordCredentials() = default;
+    QtProtobuf::QGrpcCredentialMap m_map;
+};
+}

+ 1 - 1
src/protobuf/qtprotobuftypes.h

@@ -224,7 +224,7 @@ using DoubleList = QList<double>;
  * \brief registerTypes
  * This method should be called in all applications that supposed to use QtProtobuf
  */
-Q_PROTOBUF_EXPORT extern void qRegisterProtobufTypes();
+extern Q_PROTOBUF_EXPORT void qRegisterProtobufTypes();
 
 /*! \} */
 }

+ 17 - 20
tests/test_grpc/clienttest.cpp

@@ -25,16 +25,13 @@
 
 #include "testservice_grpc.pb.h"
 #include "qtprotobuf_global.pb.h"
-
-#include "qgrpchttp2channel.h"
-#include "insecurecredentials.h"
-
-#include <sslcredentials.h>
+#include <QGrpcHttp2Channel>
+#include <QGrpcCredentials>
+#include <QGrpcInsecureCredentials>
 
 #include <QTimer>
 #include <QFile>
 #include <QCryptographicHash>
-#include <QSslConfiguration>
 
 #include <QCoreApplication>
 #include <gtest/gtest.h>
@@ -64,7 +61,7 @@ TEST_F(ClientTest, CheckMethodsGeneration)
 {
     //Dummy compile time check of functions generation and interface compatibility
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(QUrl(), InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(QUrl(), QGrpcInsecureChannelCredentials() | QGrpcInsecureCallCredentials()));
     SimpleStringMessage request;
     QPointer<SimpleStringMessage> result(new SimpleStringMessage);
     testClient.testMethod(request, result);
@@ -76,7 +73,7 @@ TEST_F(ClientTest, CheckMethodsGeneration)
 TEST_F(ClientTest, StringEchoTest)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureChannelCredentials() | QGrpcInsecureCallCredentials()));
     SimpleStringMessage request;
     QPointer<SimpleStringMessage> result(new SimpleStringMessage);
     request.setTestFieldString("Hello beach!");
@@ -88,7 +85,7 @@ TEST_F(ClientTest, StringEchoTest)
 TEST_F(ClientTest, StringEchoAsyncTest)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureChannelCredentials() | QGrpcInsecureCallCredentials()));
     SimpleStringMessage request;
     SimpleStringMessage result;
     request.setTestFieldString("Hello beach!");
@@ -107,7 +104,7 @@ TEST_F(ClientTest, StringEchoAsyncTest)
 TEST_F(ClientTest, StringEchoAsync2Test)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));
     SimpleStringMessage result;
     SimpleStringMessage request;
     request.setTestFieldString("Hello beach!");
@@ -124,7 +121,7 @@ TEST_F(ClientTest, StringEchoAsync2Test)
 TEST_F(ClientTest, StringEchoImmediateAsyncAbortTest)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));
     SimpleStringMessage result;
     SimpleStringMessage request;
     request.setTestFieldString("sleep");
@@ -160,7 +157,7 @@ TEST_F(ClientTest, StringEchoImmediateAsyncAbortTest)
 TEST_F(ClientTest, StringEchoDeferredAsyncAbortTest)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));
     SimpleStringMessage result;
     SimpleStringMessage request;
     request.setTestFieldString("sleep");
@@ -190,7 +187,7 @@ TEST_F(ClientTest, StringEchoDeferredAsyncAbortTest)
 TEST_F(ClientTest, StringEchoStreamTest)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));
     SimpleStringMessage result;
     SimpleStringMessage request;
     request.setTestFieldString("Stream");
@@ -220,7 +217,7 @@ TEST_F(ClientTest, StringEchoStreamTest)
 TEST_F(ClientTest, StringEchoStreamTestRetUpdates)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));
     SimpleStringMessage request;
     QPointer<SimpleStringMessage> result(new SimpleStringMessage);
 
@@ -247,7 +244,7 @@ TEST_F(ClientTest, StringEchoStreamTestRetUpdates)
 TEST_F(ClientTest, HugeBlobEchoStreamTest)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));
     BlobMessage result;
     BlobMessage request;
     QFile testFile("testfile");
@@ -274,7 +271,7 @@ TEST_F(ClientTest, HugeBlobEchoStreamTest)
 TEST_F(ClientTest, StatusMessageAsyncTest)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));
     SimpleStringMessage request(QString{"Some status message"});
     QGrpcStatus::StatusCode asyncStatus = QGrpcStatus::StatusCode::Ok;
     QEventLoop waiter;
@@ -296,7 +293,7 @@ TEST_F(ClientTest, StatusMessageAsyncTest)
 TEST_F(ClientTest, StatusMessageClientAsyncTest)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));
     SimpleStringMessage request(QString{"Some status message"});
     QGrpcStatus::StatusCode asyncStatus = QGrpcStatus::StatusCode::Ok;
     QEventLoop waiter;
@@ -319,7 +316,7 @@ TEST_F(ClientTest, StatusMessageClientAsyncTest)
 TEST_F(ClientTest, StatusMessageClientSyncTest)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));
     SimpleStringMessage request(QString{"Some status message"});
     QPointer<SimpleStringMessage> ret(new SimpleStringMessage);
     QGrpcStatus::StatusCode asyncStatus = QGrpcStatus::StatusCode::Ok;
@@ -343,7 +340,7 @@ TEST_F(ClientTest, StatusMessageClientSyncTest)
 TEST_F(ClientTest, StatusMessageClientSyncTestReturnedStatus)
 {
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));
     SimpleStringMessage request(QString{"Some status message"});
     QPointer<SimpleStringMessage> ret(new SimpleStringMessage);
     QEventLoop waiter;
@@ -396,7 +393,7 @@ TEST_F(ClientTest, AsyncReplySubscribeTest)
 {
     QTimer callTimeout;
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, InsecureCredentials()));
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(m_echoServerAddress, QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));
     SimpleStringMessage request(QString{"Some status message"});
     QGrpcStatus::StatusCode asyncStatus = QGrpcStatus::StatusCode::Ok;
     QEventLoop waiter;

+ 5 - 5
tests/test_grpc/sslclienttest.cpp

@@ -24,10 +24,10 @@
  */
 
 #include "testservice_grpc.pb.h"
-//#include "testserviceclient.h"
-#include "qgrpchttp2channel.h"
-//#include "blobmessage.h"
-#include <sslcredentials.h>
+
+#include <QGrpcHttp2Channel>
+#include <QGrpcSslCredentials>
+#include <QGrpcInsecureCredentials>
 
 #include <QTimer>
 #include <QFile>
@@ -67,7 +67,7 @@ TEST_F(ClientTest, IncorrectSecureCredentialsTest)
     //  conf.setCaCertificates({QSslCertificate(cert)});
 
     TestServiceClient testClient;
-    testClient.attachChannel(std::make_shared<QtProtobuf::QGrpcHttp2Channel>(QUrl("https://localhost:60051", QUrl::StrictMode), QtProtobuf::SslCredentials(conf)));
+    testClient.attachChannel(std::make_shared<QtProtobuf::QGrpcHttp2Channel>(QUrl("https://localhost:60051", QUrl::StrictMode), QtProtobuf::QGrpcInsecureCallCredentials()|QtProtobuf::QGrpcSslCredentials(conf)));
 
     std::unique_ptr<SimpleStringMessage> result = std::make_unique<SimpleStringMessage>();
     EXPECT_FALSE(testClient.testMethod(SimpleStringMessage{"Hello beach!"}, result.get()) == QGrpcStatus::Ok);