mirror of
https://github.com/QRouland/UTPass.git
synced 2025-01-02 13:48:45 +00:00
UP
This commit is contained in:
parent
c26443b6f8
commit
c044cefc26
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,14 +1,14 @@
|
|||||||
# Builds dirs
|
# Builds dirs
|
||||||
cmake-build-*
|
build*
|
||||||
build
|
|
||||||
|
|
||||||
|
# IDE & Devs tools
|
||||||
# IDE
|
|
||||||
.clickable
|
.clickable
|
||||||
.idea
|
.idea
|
||||||
*.project
|
*.project
|
||||||
*.workspace
|
*.workspace
|
||||||
.codelite
|
.codelite
|
||||||
|
*.kdev4
|
||||||
|
*swp
|
||||||
|
|
||||||
# Third parties ouput dir
|
# Third parties ouput dir
|
||||||
third/local
|
third/local
|
||||||
|
@ -3,6 +3,10 @@ cmake_minimum_required(VERSION 3.5.1)
|
|||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||||
|
|
||||||
|
option(TEST_RUNNER "Run Test" OFF)
|
||||||
|
if(${TEST_RUNNER})
|
||||||
|
add_definitions(-DTEST_RUNNER)
|
||||||
|
endif()
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND dpkg-architecture -qDEB_HOST_ARCH
|
COMMAND dpkg-architecture -qDEB_HOST_ARCH
|
||||||
@ -16,6 +20,7 @@ execute_process(
|
|||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
find_package(Qt5Core)
|
find_package(Qt5Core)
|
||||||
find_package(Qt5Qml)
|
find_package(Qt5Qml)
|
||||||
find_package(Qt5Quick)
|
find_package(Qt5Quick)
|
||||||
@ -36,7 +41,13 @@ set(DESKTOP_FILE_NAME ${PROJECT_NAME}.desktop)
|
|||||||
|
|
||||||
add_executable(${PROJECT_NAME} main.cpp)
|
add_executable(${PROJECT_NAME} main.cpp)
|
||||||
|
|
||||||
qt5_use_modules(${PROJECT_NAME} Gui Qml Quick)
|
if(${TEST_RUNNER})
|
||||||
|
find_package(Qt5QuickTest)
|
||||||
|
qt5_use_modules(${PROJECT_NAME} Gui Qml Quick QuickTest)
|
||||||
|
else()
|
||||||
|
qt5_use_modules(${PROJECT_NAME} Gui Qml Quick)
|
||||||
|
endif()
|
||||||
|
|
||||||
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
|
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||||
|
|
||||||
configure_file(manifest.json.in ${CMAKE_CURRENT_BINARY_DIR}/manifest.json)
|
configure_file(manifest.json.in ${CMAKE_CURRENT_BINARY_DIR}/manifest.json)
|
||||||
@ -45,12 +56,15 @@ install(FILES ${PROJECT_NAME}.apparmor DESTINATION ${DATA_DIR})
|
|||||||
install(DIRECTORY qml DESTINATION ${DATA_DIR})
|
install(DIRECTORY qml DESTINATION ${DATA_DIR})
|
||||||
install(DIRECTORY assets DESTINATION ${DATA_DIR})
|
install(DIRECTORY assets DESTINATION ${DATA_DIR})
|
||||||
file(GLOB_RECURSE BIN_FILES
|
file(GLOB_RECURSE BIN_FILES
|
||||||
"third/local/bin/${ARCH_TRIPLET}/*")
|
"third/local/${ARCH_TRIPLET}/bin/*")
|
||||||
install(
|
install(
|
||||||
FILES ${BIN_FILES}
|
FILES ${BIN_FILES}
|
||||||
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||||
DESTINATION ${BIN_DIR}
|
DESTINATION ${BIN_DIR}
|
||||||
)
|
)
|
||||||
|
if(${TEST_RUNNER})
|
||||||
|
install(DIRECTORY tests DESTINATION ${DATA_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
file(GLOB_RECURSE I18N_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/po qml/*.qml qml/*.js)
|
file(GLOB_RECURSE I18N_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/po qml/*.qml qml/*.js)
|
||||||
@ -77,3 +91,4 @@ add_subdirectory(po)
|
|||||||
add_subdirectory(plugins)
|
add_subdirectory(plugins)
|
||||||
|
|
||||||
add_custom_target(${PROJECT_NAME}_FILES ALL SOURCES ${PROJECT_SRC_FILES})
|
add_custom_target(${PROJECT_NAME}_FILES ALL SOURCES ${PROJECT_SRC_FILES})
|
||||||
|
|
||||||
|
79
FEATURES.MD
Normal file
79
FEATURES.MD
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
# Features
|
||||||
|
|
||||||
|
## Pass
|
||||||
|
|
||||||
|
- [ ] pass init [--path=subfolder,-p subfolder] gpg-id...
|
||||||
|
Initialize new password storage and use gpg-id for encryption.
|
||||||
|
Selectively reencrypt existing passwords using new gpg-id.
|
||||||
|
- [ ] Interactive dialog to init a new password storage
|
||||||
|
- [ ] Support subfolder
|
||||||
|
- [ ] Support reencrypt
|
||||||
|
---
|
||||||
|
- [x] pass [ls] [subfolder]
|
||||||
|
List passwords.
|
||||||
|
- [x] UI allowing to navigate through the password store showing the available passwords
|
||||||
|
---
|
||||||
|
- [ ] pass find pass-names...
|
||||||
|
List passwords that match pass-names
|
||||||
|
- [ ] Search bar allowing searchs by pass-names
|
||||||
|
---
|
||||||
|
- [ ] pass [show] [--clip[=line-number],-c[line-number]] pass-name
|
||||||
|
Show existing password and optionally put it on the clipboard.
|
||||||
|
If put on the clipboard, it will be cleared in 45 seconds.
|
||||||
|
- [ ] Click on a pass show the password
|
||||||
|
- [ ] Add option to put the password to the clipboard
|
||||||
|
- [ ] Clearing clipboard after 45 secs
|
||||||
|
- [ ] Line number option ???
|
||||||
|
---
|
||||||
|
- [ ] pass grep search-string
|
||||||
|
Search for password files containing search-string when decrypted.
|
||||||
|
- [ ] TBD
|
||||||
|
---
|
||||||
|
- [ ] pass insert [--echo,-e | --multiline,-m] [--force,-f] pass-name
|
||||||
|
Insert new password. Optionally, echo the password back to the console
|
||||||
|
during entry. Or, optionally, the entry may be multiline. Prompt before
|
||||||
|
overwriting existing password unless forced.
|
||||||
|
- [ ] TBD
|
||||||
|
---
|
||||||
|
- [ ] pass edit pass-name
|
||||||
|
Insert a new password or edit an existing password using editor.
|
||||||
|
- [ ] TBD
|
||||||
|
---
|
||||||
|
- [ ] pass generate [--no-symbols,-n] [--clip,-c] [--in-place,-i | --force,-f] pass-name [pass-length]
|
||||||
|
Generate a new password of pass-length (or 25 if unspecified) with optionally no symbols.
|
||||||
|
Optionally put it on the clipboard and clear board after 45 seconds.
|
||||||
|
Prompt before overwriting existing password unless forced.
|
||||||
|
Optionally replace only the first line of an existing file with a new password.
|
||||||
|
- [ ] TBD
|
||||||
|
---
|
||||||
|
- [ ] pass rm [--recursive,-r] [--force,-f] pass-name
|
||||||
|
Remove existing password or directory, optionally forcefully.
|
||||||
|
- [ ] TBD
|
||||||
|
---
|
||||||
|
- [ ] pass mv [--force,-f] old-path new-path
|
||||||
|
Renames or moves old-path to new-path, optionally forcefully, selectively reencrypting.
|
||||||
|
- [ ] TBD
|
||||||
|
---
|
||||||
|
- [ ] pass cp [--force,-f] old-path new-path
|
||||||
|
Copies old-path to new-path, optionally forcefully, selectively reencrypting.
|
||||||
|
|
||||||
|
- [ ] TBD
|
||||||
|
---
|
||||||
|
- [ ] pass git git-command-args...
|
||||||
|
If the password store is a git repository, execute a git command
|
||||||
|
specified by git-command-args.
|
||||||
|
- [ ] TBD
|
||||||
|
---
|
||||||
|
- [ ] pass help
|
||||||
|
Show this text.
|
||||||
|
|
||||||
|
- [ ] TBD
|
||||||
|
---
|
||||||
|
- [ ] pass version
|
||||||
|
Show version information.
|
||||||
|
- [ ] TBD
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gpg
|
||||||
|
|
||||||
|
TODO
|
90
README.md
90
README.md
@ -18,6 +18,20 @@ For more options/details see the [clickable documentation](http://clickable.bhdo
|
|||||||
* ```clickable third_clean ``` : clean third parties
|
* ```clickable third_clean ``` : clean third parties
|
||||||
* ```clickable style ``` : reformat the code (Required [astyle](astyle.sourceforge.ne) & [qmlfmt](https://github.com/jesperhh/qmlfmt) installed)
|
* ```clickable style ``` : reformat the code (Required [astyle](astyle.sourceforge.ne) & [qmlfmt](https://github.com/jesperhh/qmlfmt) installed)
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
To switch to the tests build you need to add the following arguments to the build command : -DTEST_RUNNER=ON.
|
||||||
|
|
||||||
|
To do so with clickable you need to use the following commands:
|
||||||
|
```
|
||||||
|
export CLICKABLE_BUILD_ARGS='-DTEST_RUNNER=ON'
|
||||||
|
clickable
|
||||||
|
```
|
||||||
|
To comeback to the app build unset the environnment variable :
|
||||||
|
```
|
||||||
|
unset CLICKABLE_BUILD_ARGS
|
||||||
|
```
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
Any contributions are welcome using the github issue & pull request system.
|
Any contributions are welcome using the github issue & pull request system.
|
||||||
@ -25,80 +39,8 @@ Please respect the code style format by running ```clickable style``` before com
|
|||||||
|
|
||||||
# Features
|
# Features
|
||||||
|
|
||||||
The goal is to be closest possible of the features offer by [ZX2C4’s pass command line application](https://www.passwordstore.org/):
|
The goal is to be closest possible of the features offer by [ZX2C4’s pass command line application](https://www.passwordstore.org/).
|
||||||
|
See to the FEATURES.MD file for detailed comparison.
|
||||||
---
|
|
||||||
- [ ] pass init [--path=subfolder,-p subfolder] gpg-id...
|
|
||||||
Initialize new password storage and use gpg-id for encryption.
|
|
||||||
Selectively reencrypt existing passwords using new gpg-id.
|
|
||||||
- [ ] Interactive dialog to init a new password storage
|
|
||||||
- [ ] Support subfolder
|
|
||||||
- [ ] Support reencrypt
|
|
||||||
---
|
|
||||||
- [x] pass [ls] [subfolder]
|
|
||||||
List passwords.
|
|
||||||
- [x] UI allowing to navigate through the password store showing the available passwords
|
|
||||||
---
|
|
||||||
- [ ] pass find pass-names...
|
|
||||||
List passwords that match pass-names
|
|
||||||
- [ ] Search bar allowing searchs by pass-names
|
|
||||||
---
|
|
||||||
- [ ] pass [show] [--clip[=line-number],-c[line-number]] pass-name
|
|
||||||
Show existing password and optionally put it on the clipboard.
|
|
||||||
If put on the clipboard, it will be cleared in 45 seconds.
|
|
||||||
- [ ] Click on a pass show the password
|
|
||||||
- [ ] Add option to put the password to the clipboard
|
|
||||||
- [ ] Clearing clipboard after 45 secs
|
|
||||||
- [ ] Line number option ???
|
|
||||||
---
|
|
||||||
- [ ] pass grep search-string
|
|
||||||
Search for password files containing search-string when decrypted.
|
|
||||||
- [ ] TBD
|
|
||||||
---
|
|
||||||
- [ ] pass insert [--echo,-e | --multiline,-m] [--force,-f] pass-name
|
|
||||||
Insert new password. Optionally, echo the password back to the console
|
|
||||||
during entry. Or, optionally, the entry may be multiline. Prompt before
|
|
||||||
overwriting existing password unless forced.
|
|
||||||
- [ ] TBD
|
|
||||||
---
|
|
||||||
- [ ] pass edit pass-name
|
|
||||||
Insert a new password or edit an existing password using editor.
|
|
||||||
- [ ] TBD
|
|
||||||
---
|
|
||||||
- [ ] pass generate [--no-symbols,-n] [--clip,-c] [--in-place,-i | --force,-f] pass-name [pass-length]
|
|
||||||
Generate a new password of pass-length (or 25 if unspecified) with optionally no symbols.
|
|
||||||
Optionally put it on the clipboard and clear board after 45 seconds.
|
|
||||||
Prompt before overwriting existing password unless forced.
|
|
||||||
Optionally replace only the first line of an existing file with a new password.
|
|
||||||
- [ ] TBD
|
|
||||||
---
|
|
||||||
- [ ] pass rm [--recursive,-r] [--force,-f] pass-name
|
|
||||||
Remove existing password or directory, optionally forcefully.
|
|
||||||
- [ ] TBD
|
|
||||||
---
|
|
||||||
- [ ] pass mv [--force,-f] old-path new-path
|
|
||||||
Renames or moves old-path to new-path, optionally forcefully, selectively reencrypting.
|
|
||||||
- [ ] TBD
|
|
||||||
---
|
|
||||||
- [ ] pass cp [--force,-f] old-path new-path
|
|
||||||
Copies old-path to new-path, optionally forcefully, selectively reencrypting.
|
|
||||||
|
|
||||||
- [ ] TBD
|
|
||||||
---
|
|
||||||
- [ ] pass git git-command-args...
|
|
||||||
If the password store is a git repository, execute a git command
|
|
||||||
specified by git-command-args.
|
|
||||||
- [ ] TBD
|
|
||||||
---
|
|
||||||
- [ ] pass help
|
|
||||||
Show this text.
|
|
||||||
|
|
||||||
- [ ] TBD
|
|
||||||
---
|
|
||||||
- [ ] pass version
|
|
||||||
Show version information.
|
|
||||||
- [ ] TBD
|
|
||||||
---
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"third_build": "clickable run 'cd third && ./clean.sh && mkdir build && cd build && cmake .. && make'",
|
"third_build": "clickable run 'cd third && ./clean.sh && mkdir build && cd build && cmake .. && make'",
|
||||||
"third_build_d": "clickable run 'cd third && ./clean.sh && mkdir build && cd build && cmake .. && make' --arch amd64 ",
|
"third_build_d": "clickable run 'cd third && ./clean.sh && mkdir build && cd build && cmake .. && make' --arch amd64 ",
|
||||||
"third_clean": "cd third && ./clean.sh",
|
"third_clean": "cd third && rm -rf local && ./clean.sh",
|
||||||
"style": "astyle --options=.astylerc \"plugins/*.cpp,*.h\" && qmlfmt -w tests && qmlfmt -w qml"
|
"style": "astyle --options=.astylerc 'plugins/*.cpp,*.h' && qmlfmt -w tests && qmlfmt -w qml"
|
||||||
},
|
},
|
||||||
"dependencies_build": [
|
"dependencies_build": [
|
||||||
"texinfo",
|
"texinfo",
|
||||||
|
19
main.cpp
19
main.cpp
@ -5,16 +5,27 @@
|
|||||||
#include <QQuickView>
|
#include <QQuickView>
|
||||||
#include <QtQml>
|
#include <QtQml>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TEST_RUNNER
|
||||||
|
#include <QtQuickTest/quicktest.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
new QGuiApplication(argc, argv);
|
#ifndef TEST_RUNNER
|
||||||
QGuiApplication::setApplicationName("utpass.qrouland");
|
|
||||||
|
|
||||||
qDebug() << "Starting app from main.cpp";
|
qDebug() << "Starting app from main.cpp";
|
||||||
|
new QGuiApplication(argc, argv);
|
||||||
|
|
||||||
|
QGuiApplication::setApplicationName("utpass.qrouland");
|
||||||
|
|
||||||
auto *view = new QQuickView();
|
auto *view = new QQuickView();
|
||||||
view->setSource(QUrl(QStringLiteral("qml/Main.qml")));
|
view->setSource(QUrl(QStringLiteral("qml/Main.qml")));
|
||||||
view->show();
|
view->show();
|
||||||
|
|
||||||
return QGuiApplication::exec();
|
return QGuiApplication::exec();
|
||||||
|
#else
|
||||||
|
qDebug() << "Starting tests from main.cpp";
|
||||||
|
return quick_test_main(argc, argv, "Tests", "tests/unit");
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
add_subdirectory(Gpg)
|
|
||||||
add_subdirectory(Pass)
|
add_subdirectory(Pass)
|
||||||
|
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
|
||||||
set(PLUGIN "Gpg")
|
|
||||||
|
|
||||||
set(
|
|
||||||
SRC
|
|
||||||
plugin.cpp
|
|
||||||
gpg.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
|
||||||
|
|
||||||
add_library(${PLUGIN} MODULE ${SRC})
|
|
||||||
set_target_properties(${PLUGIN} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN})
|
|
||||||
qt5_use_modules(${PLUGIN} Qml Quick DBus)
|
|
||||||
|
|
||||||
set(EXTERNAL_LIBS "${CMAKE_SOURCE_DIR}/third/local/${ARCH_TRIPLET}")
|
|
||||||
set(THIRD_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(${EXTERNAL_LIBS}/include)
|
|
||||||
|
|
||||||
add_library(GpgError STATIC IMPORTED)
|
|
||||||
set_property(TARGET GpgError PROPERTY IMPORTED_LOCATION "${EXTERNAL_LIBS}/lib/libgpg-error.a")
|
|
||||||
|
|
||||||
add_library(GpgAssuan STATIC IMPORTED)
|
|
||||||
set_property(TARGET GpgAssuan PROPERTY IMPORTED_LOCATION "${EXTERNAL_LIBS}/lib/libassuan.a")
|
|
||||||
|
|
||||||
add_library(Gpgme STATIC IMPORTED)
|
|
||||||
set_property(TARGET Gpgme PROPERTY IMPORTED_LOCATION "${EXTERNAL_LIBS}/lib/libgpgme.a")
|
|
||||||
|
|
||||||
add_library(Gpgmepp STATIC IMPORTED)
|
|
||||||
set_property(TARGET Gpgmepp PROPERTY IMPORTED_LOCATION "${EXTERNAL_LIBS}/lib/libgpgmepp.a")
|
|
||||||
|
|
||||||
add_library(QGpgme STATIC IMPORTED)
|
|
||||||
set_property(TARGET QGpgme PROPERTY IMPORTED_LOCATION "${EXTERNAL_LIBS}/lib/libqgpgme.a")
|
|
||||||
|
|
||||||
target_link_libraries(${PLUGIN} QGpgme Gpgmepp Gpgme GpgAssuan GpgError)
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
|
|
||||||
OUTPUT_VARIABLE ARCH_TRIPLET
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
|
|
||||||
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")
|
|
||||||
|
|
||||||
install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/)
|
|
||||||
install(FILES qmldir DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/)
|
|
@ -1,24 +0,0 @@
|
|||||||
#ifndef PASS_H
|
|
||||||
#define PASS_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
class Gpg : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
Gpg();
|
|
||||||
~Gpg() override = default;
|
|
||||||
|
|
||||||
Q_INVOKABLE void listDir();
|
|
||||||
Q_INVOKABLE QString getKeyId(QString uid);
|
|
||||||
Q_INVOKABLE QStringList getAllKeysId();
|
|
||||||
Q_INVOKABLE bool importKey(QString path);
|
|
||||||
Q_INVOKABLE QString decrypt(QByteArray plainText);
|
|
||||||
Q_INVOKABLE QString decryptFile(QString path);
|
|
||||||
Q_INVOKABLE QByteArray encrypt(QString str);
|
|
||||||
Q_INVOKABLE bool encryptFile(QString str, QString path);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,10 +0,0 @@
|
|||||||
#include <QtQml>
|
|
||||||
|
|
||||||
#include "plugin.h"
|
|
||||||
#include "gpg.h"
|
|
||||||
|
|
||||||
void GpgPlugin::registerTypes(const char *uri)
|
|
||||||
{
|
|
||||||
//@uri Pass
|
|
||||||
qmlRegisterSingletonType<Gpg>(uri, 1, 0, "Gpg", [](QQmlEngine *, QJSEngine *) -> QObject * { return new Gpg; });
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
#ifndef GPGPLUGIN_H
|
|
||||||
#define GPGPLUGIN_H
|
|
||||||
|
|
||||||
#include <QQmlExtensionPlugin>
|
|
||||||
|
|
||||||
class GpgPlugin : public QQmlExtensionPlugin
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PLUGIN_METADATA(IID
|
|
||||||
"org.qt-project.Qt.QQmlExtensionInterface")
|
|
||||||
|
|
||||||
public:
|
|
||||||
void registerTypes(const char *uri);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,2 +0,0 @@
|
|||||||
module Gpg
|
|
||||||
plugin Gpg
|
|
@ -5,21 +5,48 @@ set(
|
|||||||
SRC
|
SRC
|
||||||
plugin.cpp
|
plugin.cpp
|
||||||
pass.cpp
|
pass.cpp
|
||||||
|
gpg.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
|
||||||
add_library(${PLUGIN} MODULE ${SRC})
|
|
||||||
set_target_properties(${PLUGIN} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN})
|
|
||||||
qt5_use_modules(${PLUGIN} Qml Quick DBus)
|
|
||||||
|
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
|
COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
|
||||||
OUTPUT_VARIABLE ARCH_TRIPLET
|
OUTPUT_VARIABLE ARCH_TRIPLET
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(ARCH_TRIPLET STREQUAL "")
|
||||||
|
set(ARCH_TRIPLET x86_64-linux-gnu)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(${PLUGIN} MODULE ${SRC})
|
||||||
|
set_target_properties(${PLUGIN} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN})
|
||||||
|
qt5_use_modules(${PLUGIN} Qml Quick DBus)
|
||||||
|
|
||||||
|
set(EXTERNAL_LIBS "${CMAKE_SOURCE_DIR}/third/local/${ARCH_TRIPLET}")
|
||||||
|
set(THIRD_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(${EXTERNAL_LIBS}/include)
|
||||||
|
|
||||||
|
add_library(GpgError STATIC IMPORTED)
|
||||||
|
set_property(TARGET GpgError PROPERTY IMPORTED_LOCATION "${EXTERNAL_LIBS}/lib/libgpg-error.a")
|
||||||
|
|
||||||
|
add_library(GpgAssuan STATIC IMPORTED)
|
||||||
|
set_property(TARGET GpgAssuan PROPERTY IMPORTED_LOCATION "${EXTERNAL_LIBS}/lib/libassuan.a")
|
||||||
|
|
||||||
|
add_library(Gpgme STATIC IMPORTED)
|
||||||
|
set_property(TARGET Gpgme PROPERTY IMPORTED_LOCATION "${EXTERNAL_LIBS}/lib/libgpgme.a")
|
||||||
|
|
||||||
|
add_library(Gpgmepp STATIC IMPORTED)
|
||||||
|
set_property(TARGET Gpgmepp PROPERTY IMPORTED_LOCATION "${EXTERNAL_LIBS}/lib/libgpgmepp.a")
|
||||||
|
|
||||||
|
add_library(QGpgme STATIC IMPORTED)
|
||||||
|
set_property(TARGET QGpgme PROPERTY IMPORTED_LOCATION "${EXTERNAL_LIBS}/lib/libqgpgme.a")
|
||||||
|
|
||||||
|
target_link_libraries(${PLUGIN} QGpgme Gpgmepp Gpgme GpgAssuan GpgError)
|
||||||
|
|
||||||
|
|
||||||
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")
|
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")
|
||||||
|
|
||||||
install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/)
|
install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QtCore/QStandardPaths>
|
#include <QtCore/QStandardPaths>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "gpg.h"
|
#include "gpg.h"
|
||||||
#include "gpgme++/global.h"
|
#include "gpgme++/global.h"
|
||||||
@ -13,6 +14,7 @@
|
|||||||
#include "qgpgme/importjob.h"
|
#include "qgpgme/importjob.h"
|
||||||
#include "gpgme++/importresult.h"
|
#include "gpgme++/importresult.h"
|
||||||
#include "qgpgme/decryptjob.h"
|
#include "qgpgme/decryptjob.h"
|
||||||
|
#include "qgpgme/encryptjob.h"
|
||||||
|
|
||||||
using namespace GpgME;
|
using namespace GpgME;
|
||||||
using namespace QGpgME;
|
using namespace QGpgME;
|
||||||
@ -26,13 +28,7 @@ Gpg::Gpg()
|
|||||||
qFatal("GpgME init fail");
|
qFatal("GpgME init fail");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString gnuhome = QStandardPaths::writableLocation(
|
setGpghome();
|
||||||
QStandardPaths::AppDataLocation).append("/gpghome");
|
|
||||||
QDir dir(gnuhome);
|
|
||||||
if (!dir.exists())
|
|
||||||
dir.mkpath(".");
|
|
||||||
qputenv("GNUPGHOME", gnuhome.toStdString().c_str());
|
|
||||||
qDebug() << "GNUPGHOME is :" << qgetenv("GNUPGHOME");
|
|
||||||
|
|
||||||
error = checkEngine(OpenPGP);
|
error = checkEngine(OpenPGP);
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -43,86 +39,99 @@ Gpg::Gpg()
|
|||||||
qDebug() << "GpgME Engine Version :" << engineInfo(OpenPGP).version();
|
qDebug() << "GpgME Engine Version :" << engineInfo(OpenPGP).version();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gpg::listDir()
|
bool Gpg::setGpghome(QString path)
|
||||||
{
|
{
|
||||||
qDebug() << "hello world!";
|
QFileInfo file(path);
|
||||||
|
if (file.isFile()) {
|
||||||
|
qWarning() << "Not a directory GNUPGHOME not change";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (file.isDir() and !file.isWritable()) {
|
||||||
|
qWarning() << "Not a writable directory GNUPGHOME not change";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QDir dir(path);
|
||||||
|
if (!dir.exists()) {
|
||||||
|
dir.mkpath(".");
|
||||||
|
}
|
||||||
|
m_gpghome = dir;
|
||||||
|
qputenv("GNUPGHOME", m_gpghome.absolutePath().toStdString().c_str());
|
||||||
|
qDebug() << "GNUPGHOME is :" << qgetenv("GNUPGHOME");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Gpg::decrypt(const QByteArray cipherText)
|
QString Gpg::decrypt(const QByteArray cipherText)
|
||||||
{
|
{
|
||||||
/*auto decJob = openpgp()->decryptJob();
|
/*
|
||||||
auto ctx = DecryptJob::context(decJob);*/
|
auto decJob = openpgp()->decryptJob();
|
||||||
|
auto ctx = DecryptJob::context(decJob);
|
||||||
|
|
||||||
/* TODO
|
|
||||||
* TestPassphraseProvider provider;
|
TestPassphraseProvider provider;
|
||||||
ctx->setPassphraseProvider(&provider);
|
ctx->setPassphraseProvider(&provider);
|
||||||
ctx->setPinentryMode(Context::PinentryLoopback);*/
|
ctx->setPinentryMode(Context::PinentryLoopback);
|
||||||
|
|
||||||
/*QByteArray plainText;
|
QByteArray plainText;
|
||||||
decJob->exec(cipherText, plainText);
|
decJob->exec(cipherText, plainText);
|
||||||
|
|
||||||
return QString::fromUtf8(plainText);*/
|
return QString::fromUtf8(plainText);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Gpg::decryptFile(QString path)
|
QString Gpg::decryptFromFile(QString path)
|
||||||
{
|
{
|
||||||
/*QFile file(path);
|
QFile file(path);
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
qErrnoWarning("Can't open the File");
|
qWarning() << "Can't open the File";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
QByteArray plainText = file.readAll();
|
QByteArray plainText = file.readAll();
|
||||||
return this->decrypt(plainText);*/
|
return decrypt(plainText);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray Gpg::encrypt(const QString str)
|
QByteArray Gpg::encrypt(QString str, QString uid, bool ascii_armor, bool text_mode)
|
||||||
{
|
{
|
||||||
/*auto listjob = openpgp()->keyListJob(false, false, false);
|
qDebug() << "Encrypt to QByteArray";
|
||||||
std::vector<Key> keys;
|
|
||||||
auto keylistresult = listjob->exec(QStringList() << QStringLiteral("alfa@example.net"), false, keys);
|
auto keys = getKeys(uid);
|
||||||
|
|
||||||
auto job = openpgp()
|
auto job = openpgp()
|
||||||
->encryptJob(
|
->encryptJob(
|
||||||
true, //ASCII Armor
|
ascii_armor,
|
||||||
true //Textmode
|
text_mode
|
||||||
);
|
);
|
||||||
QByteArray cipherText;
|
QByteArray cipherText;
|
||||||
auto result = job->exec(keys, QStringLiteral("Hello World").toUtf8(), Context::AlwaysTrust, cipherText);
|
//auto result = job->exec(keys, str.toUtf8(), Context::AlwaysTrust, cipherText);
|
||||||
return cipherText;*/
|
return cipherText;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Gpg::encryptFile(QString str, QString path)
|
bool Gpg::encryptToFile(QString str, QString path, const QString uid, bool ascii_armor,
|
||||||
|
bool text_mode)
|
||||||
{
|
{
|
||||||
/*QFile file(path);
|
qDebug() << "Encrypt to file " << path;
|
||||||
|
QFile file(path);
|
||||||
if (!file.open(QIODevice::WriteOnly)) {
|
if (!file.open(QIODevice::WriteOnly)) {
|
||||||
qErrnoWarning("Can't open the File");
|
qWarning() << "Can't open the file to write it" ;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
file.write(Pass::encrypt(str));
|
file.write(encrypt(str, uid, ascii_armor, text_mode));
|
||||||
return true;*/
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Gpg::getKeyId(QString uid)
|
std::vector<Key> Gpg::getKeys(QString pattern_uid, bool remote, bool include_sigs, bool validate)
|
||||||
{
|
{
|
||||||
qDebug() << "Getting the key id " << uid;
|
qDebug() << "Getting the key " << pattern_uid;
|
||||||
auto *job = openpgp()->keyListJob(false, false, false);
|
auto *job = openpgp()->keyListJob(remote, include_sigs, validate);
|
||||||
|
|
||||||
std::vector<Key> keys;
|
std::vector<Key> keys;
|
||||||
auto result = job->exec(QStringList() << uid, false, keys);
|
auto result = job->exec(QStringList() << pattern_uid, false, keys);
|
||||||
delete job;
|
delete job;
|
||||||
|
|
||||||
if (keys.empty()) {
|
return keys;
|
||||||
qDebug() << "No key found for" << uid;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
const QString kId = QLatin1String(keys.front().keyID());
|
|
||||||
qDebug() << "Id key for " << uid << "is : " << kId;
|
|
||||||
return kId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList Gpg::getAllKeysId()
|
QStringList Gpg::getAllKeysId(bool remote, bool include_sigs, bool validate)
|
||||||
{
|
{
|
||||||
qDebug() << "Show all available key";
|
qDebug() << "Show all available key";
|
||||||
auto job = openpgp()->keyListJob(false, false, false);
|
auto job = openpgp()->keyListJob(remote, remote, validate);
|
||||||
std::vector<Key> keys;
|
std::vector<Key> keys;
|
||||||
auto result = job->exec(QStringList(""), false, keys);
|
auto result = job->exec(QStringList(""), false, keys);
|
||||||
delete job;
|
delete job;
|
||||||
@ -140,7 +149,7 @@ QStringList Gpg::getAllKeysId()
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Gpg::importKey(QString path)
|
bool Gpg::importKeyFromFile(QString path)
|
||||||
{
|
{
|
||||||
qDebug() << "Importing the key file" << path;
|
qDebug() << "Importing the key file" << path;
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
@ -159,15 +168,5 @@ bool Gpg::importKey(QString path)
|
|||||||
qWarning() << "Import go wrong";
|
qWarning() << "Import go wrong";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return result.imports().size() == 1;
|
||||||
qDebug() << "Key imported" << result.numImported();
|
}
|
||||||
qDebug() << "Key not imported" << result.notImported();
|
|
||||||
qDebug() << "Key unchanged" << result.numUnchanged();
|
|
||||||
qDebug() << "Result null" << result.isNull();
|
|
||||||
qDebug() << "newUserIDs" << result.newUserIDs();
|
|
||||||
|
|
||||||
for (const auto &key : result.imports())
|
|
||||||
qDebug() << "Key" << key.fingerprint();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
38
plugins/Pass/gpg.h
Normal file
38
plugins/Pass/gpg.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef GPG_H
|
||||||
|
#define GPG_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "gpgme++/key.h"
|
||||||
|
|
||||||
|
class Gpg
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Gpg();
|
||||||
|
QDir m_gpghome;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~Gpg();
|
||||||
|
static std::shared_ptr<Gpg> instance()
|
||||||
|
{
|
||||||
|
static std::shared_ptr<Gpg> s{new Gpg};
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
Gpg(Gpg const &) = delete;
|
||||||
|
void operator=(Gpg const &) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
QString decrypt(QByteArray plainText);
|
||||||
|
QString decryptFromFile(QString path);
|
||||||
|
QByteArray encrypt(QString str, QString uid, bool ascii_armor = true, bool text_mode = true);
|
||||||
|
bool encryptToFile(QString str, QString path, const QString uid, bool ascii_armor = true,
|
||||||
|
bool text_mode = true);
|
||||||
|
bool importKeyFromFile(QString path);
|
||||||
|
std::vector<GpgME::Key> getKeys(QString pattern_uid, bool remote = false, bool include_sigs = false,
|
||||||
|
bool validate = false);
|
||||||
|
QStringList getAllKeysId(bool remote = false, bool include_sigs = false, bool validate = false);
|
||||||
|
|
||||||
|
bool setGpghome(QString path = QStandardPaths::writableLocation(
|
||||||
|
QStandardPaths::AppDataLocation).append("/gpghome"));
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -4,17 +4,30 @@
|
|||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
|
|
||||||
#include "pass.h"
|
#include "pass.h"
|
||||||
|
#include "gpg.h"
|
||||||
|
|
||||||
Pass::Pass(){
|
|
||||||
pass_store = QStandardPaths::writableLocation(
|
Pass::Pass()
|
||||||
QStandardPaths::AppDataLocation).append("/.password-store");
|
{
|
||||||
QDir dir(pass_store);
|
m_password_store = QStandardPaths::writableLocation(
|
||||||
|
QStandardPaths::AppDataLocation).append("/.password-store");
|
||||||
|
QDir dir(m_password_store);
|
||||||
if (!dir.exists())
|
if (!dir.exists())
|
||||||
dir.mkpath(".");
|
dir.mkpath(".");
|
||||||
qDebug() << "Password Store is :" << pass_store;
|
qDebug() << "Password Store is :" << m_password_store;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pass::speak()
|
bool Pass::gpgImportKeyFromFile(QString path)
|
||||||
{
|
{
|
||||||
qDebug() << "Starting app from main.cpp";
|
return Gpg::instance()->importKeyFromFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList Pass::gpgListAllKeys()
|
||||||
|
{
|
||||||
|
return Gpg::instance()->getAllKeysId();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Pass::gpgSetGpghome(QString path)
|
||||||
|
{
|
||||||
|
return Gpg::instance()->setGpghome(path);
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,19 @@
|
|||||||
#define PASS_H
|
#define PASS_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class Pass : public QObject
|
class Pass : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
QString pass_store;
|
QString m_password_store;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Pass();
|
Pass();
|
||||||
~Pass() override = default;
|
~Pass() override = default;
|
||||||
|
Q_INVOKABLE bool gpgImportKeyFromFile(QString path);
|
||||||
Q_INVOKABLE void speak();
|
Q_INVOKABLE QStringList gpgListAllKeys();
|
||||||
|
Q_INVOKABLE bool gpgSetGpghome(QString path);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: utpass.qrouland\n"
|
"Project-Id-Version: utpass.qrouland\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2019-03-22 16:39+0000\n"
|
"POT-Creation-Date: 2019-03-23 19:50+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -17,10 +17,6 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=CHARSET\n"
|
"Content-Type: text/plain; charset=CHARSET\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: ../qml/pages/Settings.qml:8 ../qml/pages/headers/MainHeader.qml:49
|
|
||||||
msgid "Settings"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../qml/pages/PasswordList.qml:16
|
#: ../qml/pages/PasswordList.qml:16
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -29,7 +25,21 @@ msgstr ""
|
|||||||
msgid "No password found in the current folder"
|
msgid "No password found in the current folder"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../qml/pages/Info.qml:10 ../qml/pages/headers/MainHeader.qml:56
|
#: ../qml/pages/Settings.qml:8 ../qml/pages/headers/MainHeader.qml:49
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../qml/pages/headers/MainHeader.qml:8 ../qml/pages/headers/StackHeader.qml:8
|
||||||
|
#: UTPass.desktop.in.h:1
|
||||||
|
msgid "UTPass"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../qml/pages/headers/MainHeader.qml:23
|
||||||
|
#: ../qml/pages/headers/MainHeader.qml:38
|
||||||
|
msgid "Search"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../qml/pages/headers/MainHeader.qml:56 ../qml/pages/Info.qml:10
|
||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -56,13 +66,3 @@ msgstr ""
|
|||||||
#: ../qml/pages/Info.qml:75
|
#: ../qml/pages/Info.qml:75
|
||||||
msgid "<font size=\"2\">Released under the terms of the GNU GPL v3</font>"
|
msgid "<font size=\"2\">Released under the terms of the GNU GPL v3</font>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../qml/pages/headers/MainHeader.qml:8 ../qml/pages/headers/StackHeader.qml:8
|
|
||||||
#: UTPass.desktop.in.h:1
|
|
||||||
msgid "UTPass"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: ../qml/pages/headers/MainHeader.qml:23
|
|
||||||
#: ../qml/pages/headers/MainHeader.qml:38
|
|
||||||
msgid "Search"
|
|
||||||
msgstr ""
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
import Ubuntu.Components 1.3
|
import Ubuntu.Components 1.3
|
||||||
import Gpg 1.0
|
|
||||||
|
|
||||||
import "components"
|
import "components"
|
||||||
|
|
||||||
@ -23,7 +22,6 @@ MainView {
|
|||||||
"pages/PasswordList.qml")))
|
"pages/PasswordList.qml")))
|
||||||
}
|
}
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
Gpg.importKey("password-store/public.key")
|
|
||||||
Gpg.getAllKeysId()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,30 +2,30 @@ pragma Singleton
|
|||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: manifest
|
id: manifest
|
||||||
property string name : ""
|
property string name: ""
|
||||||
property string description : ""
|
property string description: ""
|
||||||
property string architecture : ""
|
property string architecture: ""
|
||||||
property string title : ""
|
property string title: ""
|
||||||
property string version : ""
|
property string version: ""
|
||||||
property string maintainer : ""
|
property string maintainer: ""
|
||||||
property string framework : ""
|
property string framework: ""
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
var xhr = new XMLHttpRequest;
|
var xhr = new XMLHttpRequest
|
||||||
xhr.open("GET", "../../manifest.json");
|
xhr.open("GET", "../../manifest.json")
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onreadystatechange = function () {
|
||||||
if (xhr.readyState == XMLHttpRequest.DONE) {
|
if (xhr.readyState == XMLHttpRequest.DONE) {
|
||||||
var mJson = JSON.parse(xhr.responseText);
|
var mJson = JSON.parse(xhr.responseText)
|
||||||
manifest.name = mJson.name
|
manifest.name = mJson.name
|
||||||
manifest.description = mJson.description
|
manifest.description = mJson.description
|
||||||
manifest.architecture = mJson.architecture
|
manifest.architecture = mJson.architecture
|
||||||
manifest.title = mJson.title
|
manifest.title = mJson.title
|
||||||
manifest.version = mJson.version
|
manifest.version = mJson.version
|
||||||
manifest.maintainer = mJson.maintainer
|
manifest.maintainer = mJson.maintainer
|
||||||
manifest.framework = mJson.framework
|
manifest.framework = mJson.framework
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
xhr.send();
|
xhr.send()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,16 +19,17 @@ Page {
|
|||||||
Flow {
|
Flow {
|
||||||
spacing: units.gu(3)
|
spacing: units.gu(3)
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: units.gu(1)
|
height: units.gu(1)
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: units.gu(4)
|
height: units.gu(4)
|
||||||
text: i18n.tr('<b><font size="6">%1</font></b>').arg(Manifest.title)
|
text: i18n.tr('<b><font size="6">%1</font></b>').arg(
|
||||||
|
Manifest.title)
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@ -40,40 +41,44 @@ Page {
|
|||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: units.gu(6)
|
height: units.gu(6)
|
||||||
text: i18n.tr('<font size="4">Maintainer<br>%1</font>').arg(Manifest.maintainer)
|
text: i18n.tr('<font size="4">Maintainer<br>%1</font>').arg(
|
||||||
|
Manifest.maintainer)
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: units.gu(6)
|
height: units.gu(6)
|
||||||
text: i18n.tr('<font size="4">Version<br>%1</font><br>%2@%3').arg(Manifest.version).arg(Manifest.framework).arg(Manifest.architecture)
|
text: i18n.tr(
|
||||||
|
'<font size="4">Version<br>%1</font><br>%2@%3').arg(
|
||||||
|
Manifest.version).arg(Manifest.framework).arg(
|
||||||
|
Manifest.architecture)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Flow {
|
Flow {
|
||||||
spacing: 2
|
spacing: 2
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
Link {
|
Link {
|
||||||
url: "https://github.com/QRouland/UTPass/issues"
|
url: "https://github.com/QRouland/UTPass/issues"
|
||||||
text: i18n.tr('Suggest improvement(s) or report a bug(s)')
|
text: i18n.tr('Suggest improvement(s) or report a bug(s)')
|
||||||
}
|
}
|
||||||
Link {
|
Link {
|
||||||
url: "https://github.com/QRouland/UTPass"
|
url: "https://github.com/QRouland/UTPass"
|
||||||
text: i18n.tr('Access to the source code')
|
text: i18n.tr('Access to the source code')
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: units.gu(3)
|
height: units.gu(3)
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
text: i18n.tr('<font size="2">Released under the terms of the GNU GPL v3</font>')
|
text: i18n.tr(
|
||||||
|
'<font size="2">Released under the terms of the GNU GPL v3</font>')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
tests/unit/assets/not.key
Normal file
1
tests/unit/assets/not.key
Normal file
@ -0,0 +1 @@
|
|||||||
|
This not a key file
|
30
tests/unit/assets/public1.key
Normal file
30
tests/unit/assets/public1.key
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
mQENBFyNdOEBCADl2oWeYkmVBDWoWgZdkpbV5VRJJFATLsu5aHBuQO/C1mn2RlL2
|
||||||
|
jIpIzI5mwviAw9RN0KnLdHvp3n3JkJPZ8tB3Sk9SD8qhr6ae2DbIpySMscYC9+Go
|
||||||
|
t0mrGyB3w+Y5etfZ/1dRNx6/vYaWYIG6bKfJettt/zLJcjpkIKcrN4OKyN2wXz3y
|
||||||
|
EiAiJvMntdgLslURl93RyNuVR6UaE4TchtDqRc2KvXAxrf6NUYd4KxvUgUd0TFPs
|
||||||
|
s3SRs+cAcRmTzxv/c40sBw3z0B9rBB7T7oPgGUA6NhErvBwpF9MLN+6ucZ1HHLLH
|
||||||
|
dmCd7q2OT7wZ9L6zILmKvJcK13V4FyO9zOALABEBAAG0I1Rlc3QgKFRlc3QgZ3Bn
|
||||||
|
IGtleSkgPHRlc3RAdGVzdC5vcmc+iQFOBBMBCAA4FiEE6JXydyCXAQnkfMmTuV1W
|
||||||
|
R67EDnIFAlyNdOECGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQuV1WR67E
|
||||||
|
DnIchAgAvV5q4/Hktlu3RIgo8KkGksMOS5XhJrr6fZ8bUgqpwL3oEfZ3Se5aS7yN
|
||||||
|
5M7NT8foB2zK2moBICMYpxBxQoGjxFosv94FqX9+XMiRc2Di6MwLwKkWfu0HoPEi
|
||||||
|
e701iTo53r6K84TIKNrRsKyg6C/pRqNNwSp1YcvG11eUnG5teZMcb1xsMfx4O2/s
|
||||||
|
mcrySo0ZjAfYnh2poxf4yy9xTryPrDnaY/EFj+4uBMLH8jG3QQiAH1N6wHhi/vwj
|
||||||
|
FaaaBtRxcVU/obGDg2LHTVxItv81xzSbLf8JdIGOKjwFed+DjaoSlEzPnuaEZf/M
|
||||||
|
7mE6fiGbIhFgUlwEGomptZDC1fg3M7kBDQRcjXThAQgAmuSsbRoLfiSoij5CWiP4
|
||||||
|
UUvhIEt5d4KkMRRvuWXkJo4FWs2tmNWIb1tiXuKhX+puLjP06LwfEyNT1jz75pgO
|
||||||
|
tSQ0Yz55Hn25CWOcyWF/iIoIjjw3WhQ0a59Ajk8tVdVrTEhlcQ+m7dH1igyMO1vv
|
||||||
|
iH1eTu+TXqWDF1+oYTZH0iTMYreCNbz2RcFHZQKdWK8GI1DE/qeKLHf+XYGTVQH4
|
||||||
|
fRnGaX7T5DdnklHKVGi4iILOKn5aofTIg14roS9yfDMK6vmNr7BkzqAe9+WfYC0K
|
||||||
|
TU3hX1z5SrjnYnBb531MaaCotUEI3DbNeoNsuH3Hx0WLHR1Q55Hh+KAxhMUKTR4P
|
||||||
|
uwARAQABiQE2BBgBCAAgFiEE6JXydyCXAQnkfMmTuV1WR67EDnIFAlyNdOECGwwA
|
||||||
|
CgkQuV1WR67EDnKjKwgA3yexUAoTe9sDRKO710MSWhPAn3DZ8qMo8EqmNegG86PO
|
||||||
|
/mD6BPKo9503pqGGXYoFBcqsmFX07uvy0evCsqO15xuDWwOhNX5fm2LeSsNEkhhC
|
||||||
|
2wvJVQPdekj9KmOrRRRcr6DlR0Yl7+BJX1+zF8tYwtU4tiY+bCOVRoa1KvTXUwcy
|
||||||
|
sRTQ9xWguCP8Ai1GyZS0P8lEU0nCS2KrgU/XKQVW7o2OtBiywJbmVCDw15vIq3kN
|
||||||
|
akRrU5DvYCelUjjzgj+HC3MEE5fV4UsuFLKw3QMmekzFfa6OagRb/FYYZ5ZL+tGI
|
||||||
|
cf2W57AJOHpgYvxqrY5M1UfKLf8kCYPt3AG0XiD5mw==
|
||||||
|
=OHyE
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
@ -1,10 +1,39 @@
|
|||||||
import QtTest 1.0
|
import QtTest 1.0
|
||||||
import Ubuntu.Test 1.0
|
import Ubuntu.Test 1.0
|
||||||
import Gpg 1.0
|
import Pass 1.0
|
||||||
|
|
||||||
UbuntuTestCase {
|
UbuntuTestCase {
|
||||||
name: "GpgTests"
|
name: "GpgTests"
|
||||||
function test_empty_gnuhome() {
|
function initTestCase() {
|
||||||
Gpg::getListIds().empty()
|
Pass.gpgSetGpghome("tests/tmp/gnuhome")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_empty_gnuhome() {
|
||||||
|
var listKeys = Pass.gpgListAllKeys()
|
||||||
|
verify(listKeys.length == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_import_key_form_file_data() {
|
||||||
|
return [{
|
||||||
|
"tag": "public1.key",
|
||||||
|
"path": "tests/unit/assets/public1.key",
|
||||||
|
"answer": true
|
||||||
|
}, {
|
||||||
|
"tag": "private1.key",
|
||||||
|
"path": "tests/unit/assets/private1.key",
|
||||||
|
"answer": true
|
||||||
|
}, {
|
||||||
|
"tag": "bad path",
|
||||||
|
"path": "this/is/a/bad/path",
|
||||||
|
"answer": false
|
||||||
|
}, {
|
||||||
|
"tag": "bad key",
|
||||||
|
"path": "tests/unit/assets/not.key",
|
||||||
|
"answer": false
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_import_key_form_file(data) {
|
||||||
|
compare(Pass.gpgImportKeyFromFile(data.path), data.answer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,4 +62,4 @@ ExternalProject_Add(
|
|||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
BUILD_COMMAND make
|
BUILD_COMMAND make
|
||||||
INSTALL_COMMAND make install
|
INSTALL_COMMAND make install
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user