X-Git-Url: https://vaikene.ee/gitweb/gitweb.cgi?p=evaf;a=blobdiff_plain;f=www%2Fpswgen03.html;fp=www%2Fpswgen03.html;h=056da8e42145a4b3c1f15656e206c67b8cb92497;hp=0000000000000000000000000000000000000000;hb=368818c22af812ac35f5ff69423522dbd54d37ed;hpb=3352f7acc232104985807b9f470cb12bcb2b47c2 diff --git a/www/pswgen03.html b/www/pswgen03.html new file mode 100644 index 0000000..056da8e --- /dev/null +++ b/www/pswgen03.html @@ -0,0 +1,334 @@ + + + +
+ +In this section we write the Generator module. According to the specification, the Generator module has to + generate strong passwords in such a way that by feeding the module with the same input data we always get the + same password.
+ +We start by defining the interface for the module. For this create the file igenerator.h in the + src/apps/pswGen/Generator directory:
+ +/** + * @file src/apps/PswGen/Generator/igenerator.h + */ +#ifndef __PSWGEN_GENERATOR_IGENERATOR_H +# define __PSWGEN_GENERATOR_IGENERATOR_H + +#endif // igenerator.h+ +
The interface class needs to be derived from QObject and we also need QString for input + data and generated passwords:
+ +#include <QObject> +#include <QString>+ +
To avoid potential name collisions with other existing or future modules, we use the eVaf::PswGen + namespace for this application:
+ +namespace eVaf { +namespace PswGen { + +} // namespace eVaf::PswGen +} // namespace eVaf+ +
We call the interface class iGenerator: + +
class iGenerator : public QObject +{ + Q_OBJECT +public: +};+ +
All the interface classes need a default constructor and an empty virtual destructor. Do not perform any actions + in these constructors and destructors. Instead, leave it up to the class that implements the interface.
+/// Interface constructor +iGenerator() : QObject() {} + +/// Empty virtual destructor +virtual ~iGenerator() {}+ +
Now we add the functionality to the interface and according to the specification we need two functions -- one that + generates passwords and another that returns the maximum length of the password:
+ +virtual QString generatePassword(QString const & name, QString const & masterPassword, int length, uint flags = 0) const = 0; + +virtual int maxLength() const = 0;+ +
I am training myself to use the style of writing declarations like "QString const &", which refers to a non-mutable QString object similar to "int maxLength() const", which is a function that does not modify the object's data members. Feel free to use the traditional way of writing "const QString &" if this looks weird to you.
+ +The iGenerator interface needs to be visible for other modules and marked for export. We do this by creating the src/apps/PswGen/Generator/lib.h file, which defines the PSWGEN_GENERATOR_EXPORT macro:
+/** + * @file src/apps/PswGen/Generator/lib.h + */ +#ifndef __PSWGEN_GENERATOR_LIB_H +# define __PSWGEN_GENERATOR_LIB_H + +#include <QtCore/qglobal.h> + +#if defined(PSWGEN_GENERATOR_LIBRARY) +# define PSWGEN_GENERATOR_EXPORT Q_DECL_EXPORT +#else +# define PSWGEN_GENERATOR_EXPORT Q_DECL_IMPORT +#endif +#endif // libgen.h+ +
Then we include this new header file in our interface header file and modify the iGenerator class definition by adding + the PSWGEN_GENERATOR_EXPORT macro to it:
+#include "lib.h" + +/// ... + +class PSWGEN_GENERATOR_EXPORT iGenerator : public QObject+ +
This is pretty much all we need to add to the iGenerator interface and here is the final file:
+ +/** + * @file src/apps/PswGen/Generator/igenerator.h + */ + +#ifndef __PSWGEN_GENERATOR_IGENERATOR_H +# define __PSWGEN_GENERATOR_IGENERATOR_H + +#include "lib.h" + +#include <QObject> +#include <QString> + +namespace eVaf { +namespace PswGen { + +/// Password generator interface. +class PSWGEN_GENERATOR_EXPORT iGenerator : public QObject +{ + Q_OBJECT + +public: + + /// Interface constructor + iGenerator() : QObject() {} + + /// Empty virtual destructor + virtual ~iGenerator() {} + + /// Generates a strong password + virtual QString generatePassword(QString const & name, QString const & masterPassword, int length, uint flags = 0) const = 0; + + /// Returns the maximum length of generated passwords + virtual int maxLength() const = 0; + +}; + +} // namespace eVaf::PswGen +} // namespace eVaf + +#endif // igenerator.h ++ +
As a final touch, we create a file called iGenerator with the following content:
+#include "igenerator.h"+ +
With this file in place other modules can use #include "Generator/iGenerator" instead of #include "Generator/igenerator.h" similar to other eVaf and Qt include files.
+ +Now we write the Generator module itself. The module class has to be derived from the Plugins::iPlugin interface class + with or without the Plugins::iPluginFactory factory class.
+ +The Plugins::iPluginFactory factory class should be used when more than one plugins are implemented by the same + module. The factory class takes care of creating individual plugins whenever they are instantiated. This module implements only + one plugin and we opt to the implementation without the factory class.
+ +Create the module.h header file in the src/apps/PswGen/Generator directory:
+ +/** + * @file src/apps/PswGen/Generator/module.h + */ +#ifndef __PSWGEN_GENERATOR_MODULE_H +# define __PSWGEN_GENERATOR_MODULE_H + +#endif // module.h+ +
As this is a simple module, we define all our class in this single header file. This includes the implementation + of the iGenerator interface and also the plugin itself. Se we need to include header files for the + iGenerator and iPlugin interfaces:
+ +#include "igenerator.h" +#include <Plugins/iPlugin>+ +
We are going to put every public class in this module into the eVaf::PswGen::Generator namespace and private + classes into the eVaf::PswGen::Generator::Private namespace:
+ +namespace eVaf { +namespace PswGen { + +/// Module that generates strong passwords using cryptographic methods +namespace Generator { + +/// Internal implementation of the Generator module +namespace Internal { + +} // namespace eVaf::PswGen::Generator::Internal +} // namespace eVaf::PswGen::Generator +} // namespace eVaf::PswGen +} // namespace eVaf+ +
We call the class that implements the module simply Module. This is a public class and goes into the + eVaf::PswGen::Generator namespace. We however, do not need to export it as we did with the iGenerator + interface class, as this will be done by Qt.
+ +class Module : public Plugins::iPlugin +{ + Q_OBJECT + +public: + + Module(); + + virtual ~Module(); + +}+ +
The iPlugin interface has three abstract methods that we need to implement in our class -- init(), + done() and isReady(). Since this simple module is always ready, we can return true in the + isReady() function. More complex modules can use a private mReady variable, which they set to true + once all the initialization is done. + +
virtual bool init(QString const & args); + +virtual void done(); + +virtual bool isReady() const { return true; }+ +
We need the iGenerator interface object in this module and add it to the private members section: + +
private: // Members + + /// iGenerator interface instance + Internal::GeneratorImpl * mGenerator;+ +
As the Internal::GeneratorImpl class is not declared yet, we need to add this forward declaration before the + Module class:
+ +namespace Internal { + class GeneratorImpl; +} // namespace eVaf::PswGen::Generator::Internal+ +
Then we can move forward and implement the iGenerator interface, which we already happened to call + GeneratorImpl. This class goes into the eVaf::PswGen::Generator::Internal namespace:
+ +class GeneratorImpl : public iGenerator +{ + Q_OBJECT + +public: + + GeneratorImpl(); + + virtual ~GeneratorImpl(); + + virtual QString generatePassword(QString const & name, QString const & masterPassword, int length, uint flags = 0) const; + + virtual int maxLength() const; +};+ +
Here is the final module.h file:
+ +/** + * @file src/apps/PswGen/Generator/module.h + */ + +#ifndef __PSWGEN_GENERATOR_MODULE_H +# define __PSWGEN_GENERATOR_MODULE_H + +#include "igenerator.h" + +#include <Plugins/iPlugin> + +#include <QObject> +#include <QString> + +namespace eVaf { +namespace PswGen { + +/// Module that generates strong passwords using cryptographic methods +namespace Generator { + +/// Internal implementation of the Generator module +namespace Internal { + class GeneratorImpl; +} // namespace eVaf::PswGen::Generator::Internal + +/// Plugins/iPlugin interface implementation. +class Module : public Plugins::iPlugin +{ + Q_OBJECT + +public: + + Module(); + + virtual ~Module(); + + virtual bool init(QString const & args); + + virtual void done(); + + virtual bool isReady() const { return true; } + + +private: // Members + + /// iGenerator interface instance + Internal::GeneratorImpl * mGenerator; + +}; + +namespace Internal { + + /// iGenerator interface implementation. +class GeneratorImpl : public iGenerator +{ + Q_OBJECT + +public: + + GeneratorImpl(); + + virtual ~GeneratorImpl(); + + virtual QString generatePassword(QString const & name, QString const & masterPassword, int length, uint flags = 0) const; + + virtual int maxLength() const; + +}; + +} // namespace eVaf::PswGen::Generator::Internal +} // namespace eVaf::PswGen::Generator +} // namespace eVaf::PswGen +} // namespace eVaf + +#endif // module.h+ +
Continue implementing the Generator Module.
+ + + +