mirror of
https://github.com/QuasarApp/qca.git
synced 2025-04-26 19:44:32 +00:00
Documentation update.
Improve API documentation for Event related classes, and add an example/demo of how to use Event together with EventHandler, PasswordAsker and TokenAsker. svn path=/trunk/kdesupport/qca/; revision=644098
This commit is contained in:
parent
44b03f499e
commit
3507ede288
4
Doxyfile
4
Doxyfile
@ -495,12 +495,16 @@ EXAMPLE_PATH = examples/aes-cmac \
|
||||
examples/certtest \
|
||||
examples/ciphertest \
|
||||
examples/cms \
|
||||
examples/eventhandlerdemo \
|
||||
examples/hashtest \
|
||||
examples/hextest \
|
||||
examples/mactest \
|
||||
examples/providertest \
|
||||
examples/publickeyexample \
|
||||
examples/randomtest \
|
||||
examples/rsatest \
|
||||
examples/saslservtest \
|
||||
examples/sasltest \
|
||||
examples/ssltest \
|
||||
examples/sslservtest
|
||||
|
||||
|
@ -3,6 +3,7 @@ add_subdirectory(base64test)
|
||||
add_subdirectory(certtest)
|
||||
add_subdirectory(ciphertest)
|
||||
add_subdirectory(cms)
|
||||
add_subdirectory(eventhandlerdemo)
|
||||
add_subdirectory(hashtest)
|
||||
add_subdirectory(hextest)
|
||||
add_subdirectory(mactest)
|
||||
|
8
examples/eventhandlerdemo/CMakeLists.txt
Normal file
8
examples/eventhandlerdemo/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
set(eventhandlerdemo_bin_SRCS eventhandlerdemo.cpp)
|
||||
|
||||
MY_AUTOMOC( eventhandlerdemo_bin_SRCS)
|
||||
|
||||
add_executable(eventhandlerdemo ${eventhandlerdemo_bin_SRCS})
|
||||
|
||||
target_link_libraries( eventhandlerdemo qca ${QT_QTCORE_LIBRARY})
|
||||
|
138
examples/eventhandlerdemo/eventhandlerdemo.cpp
Normal file
138
examples/eventhandlerdemo/eventhandlerdemo.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
Copyright (C) 2007 Brad Hards <bradh@frogmouth.net>
|
||||
|
||||
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 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.
|
||||
*/
|
||||
|
||||
// QtCrypto has the declarations for all of QCA
|
||||
#include <QtCrypto>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
We need a class on the client side to handle password requests.
|
||||
*/
|
||||
class ClientPassphraseHandler: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ClientPassphraseHandler(QObject *parent = 0) : QObject( parent )
|
||||
{
|
||||
// When the PasswordAsker or TokenAsker needs to interact
|
||||
// with the user, it raises a signal. We connect that to a
|
||||
// local slot to get the required information.
|
||||
connect( &m_handler, SIGNAL( eventReady(int, const QCA::Event &) ),
|
||||
SLOT( my_eventReady(int, const QCA::Event &) ) );
|
||||
|
||||
// Now that we are set up, we can start the EventHandler. Nothing
|
||||
// will happen if you don't call this method.
|
||||
m_handler.start();
|
||||
}
|
||||
|
||||
private slots:
|
||||
// This slot gets called when the provider needs a token inserted,
|
||||
// or to get a passphrase / password / PIN.
|
||||
void my_eventReady(int id, const QCA::Event &event)
|
||||
{
|
||||
// We can sanity check the event
|
||||
if ( event.isNull() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Events can be associated with a a keystore or a file/bytearray
|
||||
// You can tell which by looking at the Source
|
||||
if ( event.source() == QCA::Event::KeyStore ) {
|
||||
std::cout << "Event is associated with a key store operation" << std::endl;
|
||||
} else if ( event.source() == QCA::Event::Data ) {
|
||||
std::cout << "Event is associated with a file or some other data" << std::endl;
|
||||
// if the event comes from a file type operation, you can get the
|
||||
// name / label using fileName()
|
||||
std::cout << " Filename: " << qPrintable( event.fileName() ) << std::endl;
|
||||
} else {
|
||||
std::cout << "Unexpected Source for Event" << std::endl;
|
||||
}
|
||||
|
||||
// There are different kinds of events.
|
||||
if ( event.type() == QCA::Event::Token ) {
|
||||
// You would typically ask the user to insert the token here
|
||||
std::cout << "Request for token" << std::endl;
|
||||
// we just fake it for this demo.
|
||||
m_handler.tokenOkay( id );
|
||||
// you could use m_handler.reject( id ) to refuse the token request
|
||||
|
||||
} else if ( event.type() == QCA::Event::Password ) {
|
||||
std::cout << "Request for password, passphrase or PIN" << std::endl;
|
||||
// and within the Password type, we have a few different styles.
|
||||
if ( event.passwordStyle() == QCA::Event::StylePassword ) {
|
||||
std::cout << " [Password request]" << std::endl;
|
||||
} else if ( event.passwordStyle() == QCA::Event::StylePassphrase ) {
|
||||
std::cout << " [Passphrase request]" << std::endl;
|
||||
} else if ( event.passwordStyle() == QCA::Event::StylePIN ){
|
||||
std::cout << " [PIN request]" << std::endl;
|
||||
} else {
|
||||
std::cout << " [unexpect request style]" << std::endl;
|
||||
}
|
||||
// You would typically request the password/PIN/passphrase.
|
||||
// again, we just fake it.
|
||||
m_handler.submitPassword( id, QSecureArray( "hello" ) );
|
||||
|
||||
} else {
|
||||
std::cout << "Unexpected event type" << std::endl;
|
||||
}
|
||||
}
|
||||
private:
|
||||
QCA::EventHandler m_handler;
|
||||
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QCoreApplication exampleApp(argc, argv);
|
||||
|
||||
// the Initializer object sets things up, and
|
||||
// also does cleanup when it goes out of scope
|
||||
QCA::Initializer init;
|
||||
|
||||
ClientPassphraseHandler cph;
|
||||
|
||||
QCA::PasswordAsker pwAsker;
|
||||
|
||||
pwAsker.ask( QCA::Event::StylePassword, "foo.tmp", 0 );
|
||||
|
||||
pwAsker.waitForResponse();
|
||||
|
||||
std::cout << "Password was: " << pwAsker.password().toByteArray().data() << std::endl;
|
||||
|
||||
std::cout << std::endl << "Now do token:" << std::endl;
|
||||
|
||||
QCA::TokenAsker tokenAsker;
|
||||
|
||||
tokenAsker.ask( QString( "Entry 3" ), 0 );
|
||||
|
||||
tokenAsker.waitForResponse();
|
||||
|
||||
if ( tokenAsker.accepted() ) {
|
||||
std::cout << "Token was accepted" << std::endl;
|
||||
} else {
|
||||
std::cout << "Token was not accepted" << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "eventhandlerdemo.moc"
|
7
examples/eventhandlerdemo/eventhandlerdemo.pro
Normal file
7
examples/eventhandlerdemo/eventhandlerdemo.pro
Normal file
@ -0,0 +1,7 @@
|
||||
TEMPLATE = app
|
||||
CONFIG += thread console
|
||||
QT -= gui
|
||||
TARGET = eventhandlerdemo
|
||||
|
||||
SOURCES += eventhandlerdemo.cpp
|
||||
include(../examples.pri)
|
@ -14,7 +14,7 @@ There are three important parts to this:
|
||||
|
||||
/** \example base64test.cpp
|
||||
|
||||
The code below shows some simple operations on a Base64 object, converting
|
||||
The code below shows some simple operations on a QCA::Base64 object, converting
|
||||
between QSecureArray and QString.
|
||||
|
||||
*/
|
||||
@ -29,45 +29,59 @@ PEM encoded file collection.
|
||||
|
||||
/** \example ciphertest.cpp
|
||||
|
||||
The code below shows the normal way to use the Cipher class.
|
||||
The code below shows the normal way to use the QCA::Cipher class.
|
||||
|
||||
*/
|
||||
|
||||
/** \example cmsexample.cpp
|
||||
|
||||
The code below shows the normal way to use the CMS class.
|
||||
The code below shows the normal way to use the QCA::CMS class.
|
||||
|
||||
*/
|
||||
|
||||
/** \example eventhandlerdemo.cpp
|
||||
|
||||
The code below shows to implement a client side handler for
|
||||
password / passphrase / PIN and token requests from QCA and any
|
||||
associated providers.
|
||||
|
||||
*/
|
||||
|
||||
/** \example hashtest.cpp
|
||||
|
||||
The code below shows how to use the Hash class
|
||||
The code below shows how to use the QCA::Hash class
|
||||
|
||||
*/
|
||||
|
||||
/** \example hextest.cpp
|
||||
|
||||
The code below shows some simple operations on a Hex object, converting
|
||||
The code below shows some simple operations on a QCA::Hex object, converting
|
||||
between QSecureArray and QString.
|
||||
|
||||
*/
|
||||
|
||||
/** \example mactest.cpp
|
||||
|
||||
The code below shows how to usethe MessageAuthenticationCode class
|
||||
The code below shows how to use the QCA::MessageAuthenticationCode class
|
||||
|
||||
*/
|
||||
|
||||
/** \example providertest.cpp
|
||||
|
||||
The code below shows some simple operations on a Provider object, including
|
||||
The code below shows some simple operations on a QCA::Provider object, including
|
||||
use of iterators and some member functions.
|
||||
|
||||
*/
|
||||
|
||||
/** \example publickeyexample.cpp
|
||||
|
||||
The code below shows how to do public key encryption, decryption,
|
||||
signing and verification.
|
||||
*/
|
||||
|
||||
/** \example randomtest.cpp
|
||||
|
||||
The code below shows the normal way to use the Random class.
|
||||
The code below shows the normal way to use the QCA::Random class.
|
||||
|
||||
*/
|
||||
|
||||
@ -79,6 +93,18 @@ to a file, using PEM encoding.
|
||||
|
||||
*/
|
||||
|
||||
/** \example saslservtest.cpp
|
||||
|
||||
The code below shows how to create a SASL server.
|
||||
|
||||
*/
|
||||
|
||||
/** \example sasltest.cpp
|
||||
|
||||
The code below shows how to create a SASL client.
|
||||
|
||||
*/
|
||||
|
||||
/** \example ssltest.cpp
|
||||
|
||||
The code below shows how to create an SSL client
|
||||
|
@ -70,12 +70,13 @@
|
||||
- SSL/TLS (QCA::TLS)
|
||||
- X509 certificates (QCA::Certificate and QCA::CertificateCollection)
|
||||
- X509 certificate revocation lists (QCA::CRL)
|
||||
- Built-in support for operating system root storage (QCA::systemStore)
|
||||
- Built-in support for operating system certificate root storage (QCA::systemStore)
|
||||
- Simple Authentication and Security Layer (SASL) (QCA::SASL)
|
||||
- Cryptographic Message Syntax (e.g., for S/MIME) (QCA::CMS)
|
||||
- PGP messages (QCA::OpenPGP)
|
||||
- Unified PGP/CMS API (QCA::SecureMessage)
|
||||
- Subsystem for managing Smart Cards and PGP keyrings (QCA::KeyStore)
|
||||
- Simple but flexible logging system (QCA::Logger)
|
||||
- RSA (QCA::RSAPrivateKey and QCA::RSAPublicKey)
|
||||
- DSA (QCA::DSAPrivateKey and QCA::DSAPublicKey)
|
||||
- Diffie-Hellman (QCA::DHPrivateKey and QCA::DHPublicKey)
|
||||
|
@ -1047,30 +1047,53 @@ namespace QCA
|
||||
|
||||
/**
|
||||
An asynchronous event
|
||||
|
||||
Events are produced in response to the library's need for some user
|
||||
intervention, such as entering a pin or password, or inserting a cryptographic
|
||||
token.
|
||||
|
||||
Event is an abstraction, so you can handle this need in a way that makes sense
|
||||
for your application.
|
||||
*/
|
||||
class QCA_EXPORT Event
|
||||
{
|
||||
public:
|
||||
/**
|
||||
type of event
|
||||
%Type of event
|
||||
|
||||
\sa type()
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
Password, ///< Asking for a password
|
||||
Password, ///< Asking for a password, PIN or passphrase.
|
||||
Token ///< Asking for a token
|
||||
};
|
||||
|
||||
/**
|
||||
source of event
|
||||
%Source of the event
|
||||
|
||||
Events are associated with access to a KeyStore, or access to
|
||||
a file (or bytearray/stream or equivalent). This tells you the
|
||||
type of source that caused the Event.
|
||||
|
||||
\sa source()
|
||||
\sa fileName() for the name, if source is Event::Data
|
||||
\sa keyStoreId() and keyStoreEntryId for the keystore and entry, if
|
||||
the source is Event::KeyStore
|
||||
*/
|
||||
enum Source
|
||||
{
|
||||
KeyStore, ///< KeyStore generated the event
|
||||
Data ///< File/bytearray generated the event
|
||||
Data ///< File or bytearray generated the event
|
||||
};
|
||||
|
||||
/**
|
||||
password variation
|
||||
|
||||
If the Type of Event is Password, PasswordStyle tells you whether
|
||||
it is a PIN, passphrase or password.
|
||||
|
||||
\sa passwordStyle()
|
||||
*/
|
||||
enum PasswordStyle
|
||||
{
|
||||
@ -1119,20 +1142,34 @@ namespace QCA
|
||||
Source source() const;
|
||||
|
||||
/**
|
||||
the style of password required
|
||||
the style of password required.
|
||||
|
||||
This is not meaningful unless the Type is Event::Password.
|
||||
|
||||
\sa PasswordStyle
|
||||
*/
|
||||
PasswordStyle passwordStyle() const;
|
||||
|
||||
/**
|
||||
The id of the KeyStore associated with this event
|
||||
|
||||
This is not meaningful unless the Source is KeyStore.
|
||||
*/
|
||||
QString keyStoreId() const;
|
||||
|
||||
/**
|
||||
The id of the KeyStoreEntry associated with this event
|
||||
|
||||
This is not meaningful unless the Source is KeyStore.
|
||||
*/
|
||||
QString keyStoreEntryId() const;
|
||||
|
||||
/**
|
||||
Name or other identifier for the file or byte array
|
||||
associated with this event.
|
||||
|
||||
This is not meaningful unless the Source is Data.
|
||||
*/
|
||||
QString fileName() const;
|
||||
|
||||
/**
|
||||
@ -1143,9 +1180,11 @@ namespace QCA
|
||||
/**
|
||||
Set the values for this Event
|
||||
|
||||
\param pstyle the style of password required
|
||||
\param keyStoreId
|
||||
\param keyStoreEntryId
|
||||
This creates a Password type event, for a keystore.
|
||||
|
||||
\param pstyle the style of information required (e.g. PIN, password or passphrase)
|
||||
\param keyStoreId the keystore that the information is required for
|
||||
\param keyStoreEntryId the entry in the keystore that the information is required for
|
||||
\param ptr opaque data
|
||||
*/
|
||||
void setPasswordKeyStore(PasswordStyle pstyle, const QString &keyStoreId, const QString &keyStoreEntryId, void *ptr);
|
||||
@ -1153,12 +1192,22 @@ namespace QCA
|
||||
/**
|
||||
Set the values for this Event
|
||||
|
||||
\param pstyle
|
||||
\param fileName
|
||||
This creates a Password type event, for a file.
|
||||
|
||||
\param pstyle the style of information required (e.g. PIN, password or passphrase)
|
||||
\param fileName the name of the file (or other identifier) that the information is required for
|
||||
\param ptr opaque data
|
||||
*/
|
||||
void setPasswordData(PasswordStyle pstyle, const QString &fileName, void *ptr);
|
||||
|
||||
/**
|
||||
Set the values for this Event
|
||||
|
||||
This creates a Token type event.
|
||||
|
||||
\param keyStoreEntryId the entry in the keystore that the token is required for
|
||||
\param ptr opaque data
|
||||
*/
|
||||
void setToken(const QString &keyStoreEntryId, void *ptr);
|
||||
|
||||
private:
|
||||
@ -1173,20 +1222,79 @@ namespace QCA
|
||||
class TokenAskerPrivate;
|
||||
class AskerItem;
|
||||
|
||||
/**
|
||||
Interface class for password / passphrase / PIN and token handlers
|
||||
|
||||
This class is used on client side applications to handle
|
||||
the provision of passwords, passphrases and PINs by users, and
|
||||
to indicate that tokens have been correctly inserted.
|
||||
|
||||
The concept behind this class is that the library can raise
|
||||
events (typically using PasswordAsker or TokenAsker), which
|
||||
may (or may not) be handled by the application using a
|
||||
handler object (that has-a EventHandler, or possibly is-a
|
||||
EventHandler) that is connected to the eventReady() signal.
|
||||
*/
|
||||
class QCA_EXPORT EventHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
Constructor
|
||||
|
||||
\param parent the parent object for this object
|
||||
*/
|
||||
EventHandler(QObject *parent = 0);
|
||||
~EventHandler();
|
||||
|
||||
/**
|
||||
mandatory function to call after connecting the
|
||||
signal to a slot in your application specific password
|
||||
/ passphrase / PIN or token handler
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
function to call to return the user provided
|
||||
password, passphrase or PIN.
|
||||
|
||||
\param id the id corresponding to the password request
|
||||
\param password the user-provided password, passphrase or PIN.
|
||||
|
||||
\note the id parameter is the same as that provided in the
|
||||
eventReady() signal.
|
||||
*/
|
||||
void submitPassword(int id, const QSecureArray &password);
|
||||
|
||||
/**
|
||||
function to call to indicate that the token has been inserted
|
||||
by the user.
|
||||
|
||||
\param id the id corresponding to the password request
|
||||
|
||||
\note the id parameter is the same as that provided in the
|
||||
eventReady() signal.
|
||||
*/
|
||||
void tokenOkay(int id);
|
||||
|
||||
/**
|
||||
function to call to indicate that the user declined to
|
||||
provide a password, passphrase, PIN or token.
|
||||
|
||||
\param id the id corresponding to the password request
|
||||
|
||||
\note the id parameter is the same as that provided in the
|
||||
eventReady() signal.
|
||||
*/
|
||||
void reject(int id);
|
||||
|
||||
signals:
|
||||
/**
|
||||
signal emitted when an Event requires attention.
|
||||
|
||||
You typically need to connect this signal to
|
||||
a compatible slot in your callback handler
|
||||
*/
|
||||
void eventReady(int id, const QCA::Event &context);
|
||||
|
||||
private:
|
||||
@ -1199,22 +1307,79 @@ namespace QCA
|
||||
friend class AskerItem;
|
||||
};
|
||||
|
||||
/**
|
||||
User password / passphrase / PIN handler
|
||||
|
||||
This class is used to obtain a password from a user.
|
||||
*/
|
||||
class QCA_EXPORT PasswordAsker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
Construct a new asker
|
||||
|
||||
\param parent the parent object for this QObject
|
||||
*/
|
||||
PasswordAsker(QObject *parent = 0);
|
||||
~PasswordAsker();
|
||||
|
||||
/**
|
||||
queue a password / passphrase request associated with a key store
|
||||
|
||||
\param pstyle the type of information required (e.g. PIN, passphrase or password)
|
||||
\param keyStoreId the key store that the information is required for
|
||||
\param keyStoreEntryId the item in the key store that the information is required for
|
||||
\param ptr opaque data
|
||||
*/
|
||||
void ask(Event::PasswordStyle pstyle, const QString &keyStoreId, const QString &keyStoreEntryId, void *ptr);
|
||||
|
||||
/**
|
||||
queue a password / passphrase request associated with a file
|
||||
|
||||
\param pstyle the type of information required (e.g. PIN, passphrase or password)
|
||||
\param fileName the name of the file that the information is required for
|
||||
\param ptr opaque data
|
||||
*/
|
||||
void ask(Event::PasswordStyle pstyle, const QString &fileName, void *ptr);
|
||||
|
||||
/**
|
||||
Cancel the pending password / passphrase request
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
Block until the password / passphrase request is
|
||||
completed
|
||||
|
||||
You can use the responseReady signal instead of
|
||||
blocking, if appropriate.
|
||||
*/
|
||||
void waitForResponse();
|
||||
|
||||
/**
|
||||
Determine whether the password / passphrase was accepted or not
|
||||
|
||||
In this context, returning true is indicative of the user clicking "Ok"
|
||||
or equivalent; and returning false indicates that either the user
|
||||
clicked "Cancel" or equivalent, or that the cancel() function was
|
||||
called, or that the request is still pending.
|
||||
*/
|
||||
bool accepted() const;
|
||||
|
||||
/**
|
||||
The password / passphrase / PIN provided by the user in response to
|
||||
the asker request. This may be empty.
|
||||
*/
|
||||
QSecureArray password() const;
|
||||
|
||||
signals:
|
||||
/**
|
||||
Emitted when the asker process has been completed.
|
||||
|
||||
You should check whether the user accepted() the response
|
||||
prior to relying on the password().
|
||||
*/
|
||||
void responseReady();
|
||||
|
||||
private:
|
||||
@ -1224,20 +1389,58 @@ namespace QCA
|
||||
friend class AskerItem;
|
||||
};
|
||||
|
||||
/**
|
||||
User token handler
|
||||
|
||||
This class is used to request the user to insert a token.
|
||||
*/
|
||||
class QCA_EXPORT TokenAsker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
Construct a new asker
|
||||
|
||||
\param parent the parent object for this QObject
|
||||
*/
|
||||
TokenAsker(QObject *parent = 0);
|
||||
~TokenAsker();
|
||||
|
||||
/**
|
||||
queue a token request associated with a key store
|
||||
|
||||
\param keyStoreEntryId the item in the key store that the information is required for
|
||||
\param ptr opaque data
|
||||
*/
|
||||
void ask(const QString &keyStoreEntryId, void *ptr);
|
||||
|
||||
/**
|
||||
Cancel the pending password / passphrase request
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
Block until the token request is completed
|
||||
|
||||
You can use the responseReady signal instead of
|
||||
blocking, if appropriate.
|
||||
*/
|
||||
void waitForResponse();
|
||||
|
||||
/**
|
||||
Test if the token request was accepted or not.
|
||||
|
||||
\return true if the token request was accepted
|
||||
*/
|
||||
bool accepted() const;
|
||||
|
||||
signals:
|
||||
/**
|
||||
Emitted when the asker process has been completed.
|
||||
|
||||
You should check whether the user accepted() the response
|
||||
prior to relying on token being present.
|
||||
*/
|
||||
void responseReady();
|
||||
|
||||
private:
|
||||
|
Loading…
x
Reference in New Issue
Block a user