Add QLocalAuth class.
This commit is contained in:
1
include/QHttpEngine/QLocalAuth
Normal file
1
include/QHttpEngine/QLocalAuth
Normal file
@@ -0,0 +1 @@
|
||||
#include "qlocalauth.h"
|
||||
101
include/QHttpEngine/qlocalauth.h
Normal file
101
include/QHttpEngine/qlocalauth.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Nathan Osman
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef QHTTPENGINE_QLOCALAUTH_H
|
||||
#define QHTTPENGINE_QLOCALAUTH_H
|
||||
|
||||
#include <QVariantMap>
|
||||
|
||||
#include <QHttpEngine/QHttpMiddleware>
|
||||
|
||||
#include "qhttpengine_global.h"
|
||||
|
||||
class QHTTPENGINE_EXPORT QLocalAuthPrivate;
|
||||
|
||||
/**
|
||||
* @brief Middleware for local file-based authentication
|
||||
*
|
||||
* This class is intended for authenticating applications running under the
|
||||
* same user account as the server. QLocalFile is used to expose a token to
|
||||
* connecting applications. The client passes the token in a special header
|
||||
* and the request is permitted.
|
||||
*
|
||||
* The file consists of a JSON object in the following format:
|
||||
*
|
||||
* @code
|
||||
* {
|
||||
* "token": "{8a34d0f0-29d0-4e54-b3aa-ce8f8ad65527}"
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* Additional data can be added to the object using the setData() method.
|
||||
*/
|
||||
class QHTTPENGINE_EXPORT QLocalAuth : public QHttpMiddleware
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Initialize local authentication
|
||||
*
|
||||
* To determine whether the local file was created successfully, call the
|
||||
* exists() method.
|
||||
*/
|
||||
explicit QLocalAuth(QObject *parent = Q_NULLPTR);
|
||||
|
||||
/**
|
||||
* @brief Determine whether the file exists
|
||||
*/
|
||||
bool exists() const;
|
||||
|
||||
/**
|
||||
* @brief Retrieve the name of the file used for storing the token
|
||||
*/
|
||||
QString filename() const;
|
||||
|
||||
/**
|
||||
* @brief Set additional data to include with the token
|
||||
*/
|
||||
void setData(const QVariantMap &data);
|
||||
|
||||
/**
|
||||
* @brief Set the name of the custom header used for confirming the token
|
||||
*
|
||||
* The default value is "X-Auth-Token".
|
||||
*/
|
||||
void setHeaderName(const QByteArray &name);
|
||||
|
||||
/**
|
||||
* @brief Process the request
|
||||
*
|
||||
* If the token supplied by the client matches, the request is allowed.
|
||||
* Otherwise, an HTTP 403 error is returned.
|
||||
*/
|
||||
virtual bool process(QHttpSocket *socket);
|
||||
|
||||
private:
|
||||
|
||||
QLocalAuthPrivate *const d;
|
||||
};
|
||||
|
||||
#endif // QHTTPENGINE_QLOCALAUTH_H
|
||||
@@ -12,6 +12,7 @@ set(SRC
|
||||
qhttpserver.cpp
|
||||
qhttpsocket.cpp
|
||||
qiodevicecopier.cpp
|
||||
qlocalauth.cpp
|
||||
qlocalfile.cpp
|
||||
qobjecthandler.cpp
|
||||
)
|
||||
|
||||
84
src/qlocalauth.cpp
Normal file
84
src/qlocalauth.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Nathan Osman
|
||||
*
|
||||
* 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 <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QUuid>
|
||||
|
||||
#include <QHttpEngine/QHttpSocket>
|
||||
#include <QHttpEngine/QLocalAuth>
|
||||
|
||||
#include "qlocalauth_p.h"
|
||||
|
||||
QLocalAuthPrivate::QLocalAuthPrivate(QObject *parent)
|
||||
: QObject(parent),
|
||||
tokenHeader("X-Auth-Token"),
|
||||
token(QUuid::createUuid().toString())
|
||||
{
|
||||
updateFile();
|
||||
}
|
||||
|
||||
void QLocalAuthPrivate::updateFile()
|
||||
{
|
||||
if (file.open()) {
|
||||
file.write(QJsonDocument(QJsonObject::fromVariantMap(data)).toJson());
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
QLocalAuth::QLocalAuth(QObject *parent)
|
||||
: QHttpMiddleware(parent),
|
||||
d(new QLocalAuthPrivate(this))
|
||||
{
|
||||
}
|
||||
|
||||
bool QLocalAuth::exists() const
|
||||
{
|
||||
return d->file.exists();
|
||||
}
|
||||
|
||||
QString QLocalAuth::filename() const
|
||||
{
|
||||
return d->file.fileName();
|
||||
}
|
||||
|
||||
void QLocalAuth::setData(const QVariantMap &data)
|
||||
{
|
||||
d->data = data;
|
||||
d->data.insert("token", d->token);
|
||||
d->updateFile();
|
||||
}
|
||||
|
||||
void QLocalAuth::setHeaderName(const QByteArray &name)
|
||||
{
|
||||
d->tokenHeader = name;
|
||||
}
|
||||
|
||||
bool QLocalAuth::process(QHttpSocket *socket)
|
||||
{
|
||||
if (socket->headers().value(d->tokenHeader) != d->token) {
|
||||
socket->writeError(QHttpSocket::Forbidden);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
47
src/qlocalauth_p.h
Normal file
47
src/qlocalauth_p.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Nathan Osman
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef QHTTPENGINE_QLOCALAUTHPRIVATE_H
|
||||
#define QHTTPENGINE_QLOCALAUTHPRIVATE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
#include <QHttpEngine/QLocalFile>
|
||||
|
||||
class QLocalAuthPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit QLocalAuthPrivate(QObject *parent);
|
||||
|
||||
void updateFile();
|
||||
|
||||
QLocalFile file;
|
||||
QVariantMap data;
|
||||
QByteArray tokenHeader;
|
||||
QString token;
|
||||
};
|
||||
|
||||
#endif // QHTTPENGINE_QLOCALAUTHPRIVATE_H
|
||||
@@ -13,6 +13,7 @@ set(TESTS
|
||||
TestQHttpSocket
|
||||
TestQIByteArray
|
||||
TestQIODeviceCopier
|
||||
TestQLocalAuth
|
||||
TestQLocalFile
|
||||
TestQObjectHandler
|
||||
)
|
||||
|
||||
79
tests/TestQLocalAuth.cpp
Normal file
79
tests/TestQLocalAuth.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Nathan Osman
|
||||
*
|
||||
* 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 <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QTest>
|
||||
#include <QVariantMap>
|
||||
|
||||
#include <QHttpEngine/QHttpSocket>
|
||||
#include <QHttpEngine/QLocalAuth>
|
||||
|
||||
#include "common/qsimplehttpclient.h"
|
||||
#include "common/qsocketpair.h"
|
||||
|
||||
const QByteArray HeaderName = "X-Test";
|
||||
const QByteArray CustomName = "Name";
|
||||
const QByteArray CustomData = "Data";
|
||||
|
||||
class TestQLocalAuth : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
void testAuth();
|
||||
};
|
||||
|
||||
void TestQLocalAuth::testAuth()
|
||||
{
|
||||
QSocketPair pair;
|
||||
QTRY_VERIFY(pair.isConnected());
|
||||
|
||||
QSimpleHttpClient client(pair.client());
|
||||
QHttpSocket socket(pair.server(), &pair);
|
||||
|
||||
QLocalAuth localAuth;
|
||||
localAuth.setData(QVariantMap{
|
||||
{CustomName, CustomData}
|
||||
});
|
||||
localAuth.setHeaderName(HeaderName);
|
||||
QVERIFY(localAuth.exists());
|
||||
|
||||
QFile file(localAuth.filename());
|
||||
QVERIFY(file.open(QIODevice::ReadOnly));
|
||||
|
||||
QVariantMap data = QJsonDocument::fromJson(file.readAll()).object().toVariantMap();
|
||||
QVERIFY(data.contains("token"));
|
||||
QCOMPARE(data.value(CustomName).toByteArray(), CustomData);
|
||||
|
||||
client.sendHeaders("GET", "/", QHttpSocket::HeaderMap{
|
||||
{HeaderName, data.value("token").toByteArray()}
|
||||
});
|
||||
QTRY_VERIFY(socket.isHeadersParsed());
|
||||
|
||||
QVERIFY(localAuth.process(&socket));
|
||||
}
|
||||
|
||||
QTEST_MAIN(TestQLocalAuth)
|
||||
#include "TestQLocalAuth.moc"
|
||||
Reference in New Issue
Block a user