「Qtの基礎 - 管理者権限」の版間の差分

ナビゲーションに移動 検索に移動
47行目: 47行目:
<br>
<br>
<u>次に、<code>cmake</code>コマンド、または、パッケージ管理システムからインストールした<code>qmake-qt5</code>を使用して、Qtプロジェクトをビルドする必要がある。</u><br>
<u>次に、<code>cmake</code>コマンド、または、パッケージ管理システムからインストールした<code>qmake-qt5</code>を使用して、Qtプロジェクトをビルドする必要がある。</u><br>
  qmake-qt5 xxx.pro
# qmakeコマンドを使用する場合
  # または
mkdir build && cd build
  cmake .
  qmake-qt5 <Qtプロジェクトファイル名>.pro  または  qmake <Qtプロジェクトファイル名>.pro
  make -j $(nproc)
  make install
   
   
# cmakeコマンドを使用する場合
mkdir build && cd build
cmake ..
make -j $(nproc)
make install
<br><br>
== PolKit-Qt-1を使用した開発例 ==
==== 開発例に挙げるソフトウェア ====
実行ファイルの画面にあるボタンを押下する時、任意のディレクトリにroot権限でテキストファイルを作成または書き込みするソフトウェアを例に挙げる。<br>
<br>
開発するプロジェクトを以下に示す。<br>
* Sample
*: 主となるGUIソフトウェア
* SampleHelper
*: 管理者権限でファイル操作を行うヘルパー実行ファイル
* PolKitポリシーファイル
*: ファイルの場所 : /usr/share/polkit-1/actions
*: .policy拡張子
*: ファイル名を、org.qt.policykit.examples.policyファイルとする。
* D-Busインターフェースファイル
*: ファイルの場所 : /usr/share/dbus-1/interfaces
*: .xml拡張子
*: ファイル名を、org.qt.policykit.examples.xmlファイルとする。
* D-Busポリシーファイル
*: ファイルの場所 :
*:: 優先順位 1 : /etc/dbus-1/system-local.conf (新規作成)
*:: 優先順位 2 : /etc/dbus-1/system.d
*:: 優先順位 3 : /usr/share/dbus-1/system.d
*: .conf拡張子
*: ファイル名を、org.qt.policykit.examples.confファイルとする。
* D-Busサービスファイル(D-Busアクティベーションファイル)
*: ファイルの場所 : /usr/share/dbus-1/system-services
*: .service拡張子
*: ファイル名を、org.qt.policykit.examples.serviceファイルとする。
<br>
==== ヘルパー実行ファイルの開発 ====
# SampleHelper.proファイル
QT -= gui
QT += core dbus
CONFIG += c++17
CONFIG -= app_bundle
# PolKit-Qt-1 Install directory
isEmpty(polqt_dir) {
    polqt_dir = /usr
}
unix:!macx: LIBS += \
        -L$${polqt_dir}/lib64 -lpolkit-qt5-core-1 \
        -L$${polqt_dir}/lib64 -lpolkit-qt5-agent-1 \
        -L$${polqt_dir}/lib64 -lpolkit-qt5-gui-1
INCLUDEPATH += \
        $${polqt_dir}/include
SOURCES += \
        SampleHelper.cpp \
        SamplesAdaptor.cpp \
        main.cpp
HEADERS += \
      SampleHelper.h \
      SamplesAdaptor.h
# Config Install directory
isEmpty(prefix) {
    prefix = $${PWD}/$${TARGET}
}
target.path = $${prefix}
INSTALLS += target
<br>
<syntaxhighlight lang="c++">
// main.cppファイル
#include <QCoreApplication>
#include "SampleHelper.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    SampleHelper helper(argc, argv);
    return a.exec();
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// SampleHelper.hファイル
#ifndef SAMPLE_HELPER_H
#define SAMPLE_HELPER_H
#include <QDBusContext>
#include <QDBusMessage>
#include <QCoreApplication>
class SampleHelper : public QCoreApplication, protected QDBusContext
{
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "org.qt.policykit.examples")
public:
    SampleHelper(int &argc, char **argv);
    ~SampleHelper() override;
public Q_SLOTS:
    bool write(const QString &action);
    bool writeValue(const QString &action);
};
#endif
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// SampleHelper.cppファイル
#include "SampleHelper.h"
#include "SamplesAdaptor.h"
#include <polkit-qt5-1/polkitqt1-authority.h>
#include <QDBusConnection>
#include <QTimer>
#include <QDebug>
#include <QFile>
#define MINUTE 60000
using namespace PolkitQt1;
SampleHelper::SampleHelper(int &argc, char **argv) : QCoreApplication(argc, argv)
{
    qDebug() << "Creating Helper";
    (void) new ExamplesAdaptor(this);
    // Register the DBus service
    if (!QDBusConnection::systemBus().registerService("org.qt.policykit.examples"))
    {
      qDebug() << QDBusConnection::systemBus().lastError().message();;
      QTimer::singleShot(0, this, SLOT(quit()));
      return;
    }
    if (!QDBusConnection::systemBus().registerObject("/", this))
    {
      qDebug() << "unable to register service interface to dbus";
      QTimer::singleShot(0, this, SLOT(quit()));
      return;
    }
    // Normally you will set a timeout so your application can free some resources of the poor client machine
    QTimer::singleShot(MINUTE, this, SLOT(quit()));
}
SampleHelper::~SampleHelper()
{
    qDebug() << "Destroying Helper";
}
bool SampleHelper::write(const QString &action)
{
    // message().service() is the service name of the caller.
    // We can check if the caller is authorized to the following action.
    Authority::Result result;
    PolkitQt1::SystemBusNameSubject subject(message().service());
    result = Authority::instance()->checkAuthorizationSync("org.qt.policykit.examples.write", subject, Authority::AllowUserInteraction);
    if (result == Authority::Yes)
    {  // Caller is authorized so we can perform the action
      return writeValue(action);
    }
    else
    {  // Caller is not authorized so the action can't be performed
      return false;
    }
}
bool SampleHelper::writeValue(const QString &action)
{
    // This action must be authorized first. It will set the implicit authorization for the Shout action by editing the .policy file.
    QFileInfo FileInfo("/opt/sample.txt");
    QFile File("/opt/sample.txt");
    if(!File.open(QIODevice::WriteOnly))
    {
      QString strErrMsg = "File(" + FileInfo.fileName() + ") Open Error: " + File.errorString();
      qDebug() << strErrMsg;
      return -1;
    }
    QTextStream OutStream(&File);
    OutStream << "foo bar";
    File.close();
    return true;
}
</syntaxhighlight>
<br>
ここで、SamplesAdaptor.cppファイル、および、SamplesAdaptor.hファイルは、Qt Creator付属の<code>qdbusxml2cpp</code>コマンドを実行することにより自動生成される。<br>
自動生成された上記の2つのファイルをインクルードすることにより、ヘルパー実行ファイルが完成する。<br>
# mocファイルはインクルードしない場合
qdbusxml2cpp -a <自動生成するヘルパークラス名> -i <対象となるクラスを記述しているヘッダファイル> -l <対象となるクラス名> <D-Busインターフェースファイルのパス>
例. qdbusxml2cpp -a SamplesAdaptor -i SampleHelper.h -l SampleHelper org.qt.policykit.examples.xml
# mocファイルもインクルードする場合
qdbusxml2cpp -m -a <自動生成するヘルパークラス名> -i <対象となるクラスを記述しているヘッダファイル> -l <対象となるクラス名> <D-Busインターフェースファイルのパス>
例. qdbusxml2cpp -m -a SamplesAdaptor -i SampleHelper.h -l SampleHelper org.qt.policykit.examples.xml
<br>
自動生成されたヘルパーファイルを、Qtプロジェクト等に追加する。<br>
<br>
最後に、<code>cmake</code>コマンド、または、パッケージ管理システムからインストールした<code>qmake-qt5</code>を使用して、Qtプロジェクトをビルドする。<br>
# qmakeコマンドを使用する場合
mkdir build && cd build
qmake-qt5 <ヘルパープロジェクトファイル名>.pro  または  qmake <ヘルパープロジェクトファイル名>.pro
make -j $(nproc)
make install
# cmakeコマンドを使用する場合
mkdir build && cd build
cmake ..
  make -j $(nproc)
  make -j $(nproc)
  make install
  make install

案内メニュー