Skip to content

Commit

Permalink
Merge extensions repository (open-eid#1226)
Browse files Browse the repository at this point in the history
IB-7385

Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma authored Jan 23, 2024
1 parent 74a7239 commit 0ae519a
Show file tree
Hide file tree
Showing 36 changed files with 1,764 additions and 5 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ jobs:
-DCMAKE_TOOLCHAIN_FILE=${{ env.RUNVCPKG_VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake `
"-DLibDigiDocpp_ROOT=libs/libdigidocpp"
cmake --build build --target msi
cmake --build build --target msishellext
cmake --build build --target appx
- name: Archive artifacts
uses: actions/upload-artifact@v3
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,3 @@
[submodule "common"]
path = common
url = ../qt-common
[submodule "extensions"]
path = extensions
url = ../digidoc-extensions
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ include(CPack)
if(APPLE)
add_subdirectory(extensions/DigiDocQL)
elseif(WIN32)
add_subdirectory(extensions/windows EXCLUDE_FROM_ALL)
add_subdirectory(extensions/windows)
elseif(UNIX)
option(ENABLE_KDE "Install KDE service menu (default: TRUE)" TRUE)
option(ENABLE_NAUTILUS_EXTENSION "Build Nautilus extension (default: TRUE)" TRUE)
Expand Down
1 change: 0 additions & 1 deletion extensions
Submodule extensions deleted from d428a8
24 changes: 24 additions & 0 deletions extensions/DigiDocQL/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
set( RESOURCES ../../client/mac/Resources/asic.icns )
add_library( DigiDocQL MODULE
${RESOURCES}
Info.plist
main.c
GenerateThumbnailForURL.c
GeneratePreviewForURL.mm
)
set_source_files_properties( GeneratePreviewForURL.mm PROPERTIES COMPILE_FLAGS "-fobjc-arc" )
set_source_files_properties( Info.plist PROPERTIES MACOSX_PACKAGE_LOCATION . )
set_target_properties( DigiDocQL PROPERTIES
BUNDLE YES
BUNDLE_EXTENSION qlgenerator
RESOURCE "${RESOURCES}"
XCODE_ATTRIBUTE_WRAPPER_EXTENSION qlgenerator
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
AUTOMOC OFF
INCLUDE_DIRECTORIES "${LIBDIGIDOCPP_INCLUDE_DIR}"
COMPILE_FLAGS "-Wno-unused-parameter"
LINK_LIBRARIES "-framework QuickLook;-framework digidocpp;-framework Cocoa"
LINK_FLAGS "-F/Library/Frameworks -fobjc-arc"
BUILD_WITH_INSTALL_RPATH YES
INSTALL_RPATH "@loader_path/../../../../../Frameworks"
)
201 changes: 201 additions & 0 deletions extensions/DigiDocQL/GeneratePreviewForURL.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*
* QEstEidClient
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/

// https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/Quicklook_Programming_Guide/Introduction/Introduction.html

#include <digidocpp/Container.h>
#include <digidocpp/DataFile.h>
#include <digidocpp/Signature.h>
#include <digidocpp/Exception.h>
#include <digidocpp/XmlConf.h>

#include <Foundation/Foundation.h>
#include <QuickLook/QuickLook.h>

using namespace digidoc;

QL_EXTERN_C_BEGIN
OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview,
CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
void CancelPreviewGeneration(void * /*thisInterface*/, QLPreviewRequestRef /*preview*/) {}
QL_EXTERN_C_END

@interface NSString (Digidoc)
+ (NSString*)stdstring:(const std::string&)str;
+ (NSString*)fileSize:(unsigned long)bytes;
+ (void)parseException:(const Exception&)e result:(NSMutableArray *)result;
@end

@implementation NSString (Digidoc)
+ (NSString*)stdstring:(const std::string&)str
{
return str.empty() ? [NSString string] : [NSString stringWithUTF8String:str.c_str()];
}

+ (NSString*)htmlEntityEncode:(NSString*)str
{
str = [str stringByReplacingOccurrencesOfString:@"&" withString:@"&amp;"];
str = [str stringByReplacingOccurrencesOfString:@"\"" withString:@"&quot;"];
str = [str stringByReplacingOccurrencesOfString:@"'" withString:@"&apos;"];
str = [str stringByReplacingOccurrencesOfString:@"<" withString:@"&lt;"];
str = [str stringByReplacingOccurrencesOfString:@">" withString:@"&gt;"];
return str;
}

+ (NSString*)fileSize:(unsigned long)bytes
{
enum {
kb = 1UL << 1,
mb = 1UL << 2,
gb = 1UL << 3
};
if (bytes >= gb)
return [NSString stringWithFormat:@"%1.2f GB", double(bytes) / gb];
if (bytes >= mb)
return [NSString stringWithFormat:@"%1.2f MB", double(bytes) / mb];
if (bytes >= kb)
return [NSString stringWithFormat:@"%1.1f KB", double(bytes) / kb];
return [NSString stringWithFormat:@"%lu bytes", bytes];
}

+ (void)parseException:(const Exception&)e result:(NSMutableArray *)result
{
[result addObject:[self stdstring:e.msg()]];
for (const Exception &i : e.causes()) {
[self parseException:i result:result];
}
}
@end

class DigidocConf: public digidoc::XmlConfCurrent
{
public:
bool TSLAutoUpdate() const final { return false; }
bool TSLOnlineDigest() const final { return false; }
std::string TSLCache() const final
{
std::string home = "~";
if(char *var = getenv("HOME"))
home = var;
return home + "/Library/Containers/ee.ria.qdigidoc4/Data/Library/Application Support/RIA/qdigidoc4/";
}
};

OSStatus GeneratePreviewForURL(void */*thisInterface*/, QLPreviewRequestRef preview,
CFURLRef url, CFStringRef /*contentTypeUTI*/, CFDictionaryRef /*options*/)
{
@autoreleasepool {
NSMutableString *h = [NSMutableString string];
[h appendString:@"<html><head><style>"];
[h appendString:@"* { font-family: 'Lucida Sans Unicode', 'Lucida Grande', sans-serif };"];
[h appendString:@"body { font-size: 10pt };"];
[h appendString:@"h2 { padding-left: 50px; background: url(cid:asic.icns); background-size: 42px 42px; background-repeat:no-repeat; };"];
[h appendString:@"font, dt { color: #808080 };"];
[h appendString:@"dt { float: left; clear: left; margin-left: 30px; margin-right: 10px };"];
[h appendString:@"dl { margin-bottom: 10px };"];
[h appendString:@"</style></head><body>"];
[h appendFormat:@"<h2>%@<hr size='1' /></h2>", [NSString htmlEntityEncode:[(__bridge NSURL*)url lastPathComponent]]];
try
{
digidoc::Conf::init( new DigidocConf );
digidoc::initialize();
std::unique_ptr<Container> d(Container::openPtr([(__bridge NSURL*)url path].UTF8String));

[h appendString:@"<font>Files</font><ol>"];
for (const DataFile *doc : d->dataFiles()) {
[h appendFormat:@"<li>%@</li>", [NSString htmlEntityEncode:[NSString stdstring:doc->fileName()]]];
}
[h appendString:@"</ol>"];

[h appendString:@"<font>Signatures</font>"];
for (const Signature *s : d->signatures()) {
[h appendFormat:@"<dl><dt>Signer</dt><dd>%@</dd>", [NSString htmlEntityEncode:[NSString stdstring:s->signedBy()]]];

NSString *date = [NSString stdstring:s->trustedSigningTime()];
[date stringByReplacingOccurrencesOfString:@"Z" withString:@"-0000"];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate *formateddate = [df dateFromString:date];
[df setTimeZone: [NSTimeZone defaultTimeZone]];
[df setDateFormat:@"YYYY-MM-dd HH:mm:ss z"];
[h appendFormat:@"<dt>Time</dt><dd>%@</dd>", [df stringFromDate:formateddate]];

Signature::Validator v(s);
NSString *status = @"not valid";
switch(v.status())
{
case Signature::Validator::Valid: status = @"valid"; break;
case Signature::Validator::Warning: status = @"valid with warnings"; break;
case Signature::Validator::NonQSCD: status = @"valid with limitations"; break;
case Signature::Validator::Test: status = @"valid test signature"; break;
case Signature::Validator::Invalid: status = @"invalid"; break;
case Signature::Validator::Unknown: status = @"unknown"; break;
}
[h appendFormat:@"<dt>Validity</dt><dd>Signature is %@</dd>", status];

NSMutableArray *roles = [NSMutableArray array];
for (const std::string &role : s->signerRoles()) {
if( !role.empty() ) {
[roles addObject:[NSString htmlEntityEncode:[NSString stdstring:role]]];
}
}
if( [roles count] > 0 ) {
[h appendFormat:@"<dt>Role</dt><dd>%@&nbsp;</dd>", [NSString htmlEntityEncode:[roles componentsJoinedByString:@" / "]]];
}
if (!s->countryName().empty()) {
[h appendFormat:@"<dt>Country</dt><dd>%@&nbsp;</dd>", [NSString htmlEntityEncode:[NSString stdstring:s->countryName()]]];
}
if (!s->city().empty()) {
[h appendFormat:@"<dt>City</dt><dd>%@&nbsp;</dd>", [NSString htmlEntityEncode:[NSString stdstring:s->city()]]];
}
if (!s->stateOrProvince().empty()) {
[h appendFormat:@"<dt>State</dt><dd>%@&nbsp;</dd>", [NSString htmlEntityEncode:[NSString stdstring:s->stateOrProvince()]]];
}
if (!s->postalCode().empty()) {
[h appendFormat:@"<dt>Postal code</dt><dd>%@&nbsp;</dd>", [NSString htmlEntityEncode:[NSString stdstring:s->postalCode()]]];
}
[h appendString:@"</dl>"];
}
digidoc::terminate();
} catch (const Exception &e) {
NSMutableArray *err = [NSMutableArray array];
[NSString parseException:e result:err];
[h appendFormat:@"Failed to load document:<br />%@", [err componentsJoinedByString:@"<br />"]];
}
[h appendString:@"</body></html>"];

NSBundle *bundle = [NSBundle bundleWithIdentifier:@"ee.ria.DigiDocQL"];
NSData *image = [NSData dataWithContentsOfFile:[bundle pathForResource:@"asic" ofType:@"icns"]];
NSDictionary *props = @{
(__bridge id)kQLPreviewPropertyTextEncodingNameKey : @"UTF-8",
(__bridge id)kQLPreviewPropertyMIMETypeKey : @"text/html",
(__bridge id)kQLPreviewPropertyWidthKey : [[bundle infoDictionary] valueForKey:@"QLPreviewWidth"],
(__bridge id)kQLPreviewPropertyHeightKey : [[bundle infoDictionary] valueForKey:@"QLPreviewHeight"],
(__bridge id)kQLPreviewPropertyAttachmentsKey : @{
@"asic.icns" : @{
(__bridge id)kQLPreviewPropertyMIMETypeKey : @"image/icns",
(__bridge id)kQLPreviewPropertyAttachmentDataKey : image
}
}
};
QLPreviewRequestSetDataRepresentation(preview,
(__bridge CFDataRef)[h dataUsingEncoding:NSUTF8StringEncoding], kUTTypeHTML, (__bridge CFDictionaryRef)props);
}
return noErr;
}
30 changes: 30 additions & 0 deletions extensions/DigiDocQL/GenerateThumbnailForURL.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* QEstEidClient
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/

#include <QuickLook/QuickLook.h>

OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail,
CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize)
{
return noErr;
}

void CancelThumbnailGeneration(void *thisInterface, QLThumbnailRequestRef thumbnail)
{
}
62 changes: 62 additions & 0 deletions extensions/DigiDocQL/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>QLGenerator</string>
<key>LSItemContentTypes</key>
<array>
<string>ee.ria.bdoc</string>
<string>ee.ria.asics</string>
</array>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>DigiDocQL</string>
<key>CFBundleIdentifier</key>
<string>ee.ria.DigiDocQL</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>DigiDocQL</string>
<key>CFBundleShortVersionString</key>
<string>1</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFPlugInDynamicRegisterFunction</key>
<string></string>
<key>CFPlugInDynamicRegistration</key>
<string>NO</string>
<key>CFPlugInFactories</key>
<dict>
<key>60213CB1-91F9-43A6-BEF5-9DE58A2B6C52</key>
<string>QuickLookGeneratorPluginFactory</string>
</dict>
<key>CFPlugInTypes</key>
<dict>
<key>5E2D9680-5022-40FA-B806-43349622E5B9</key>
<array>
<string>60213CB1-91F9-43A6-BEF5-9DE58A2B6C52</string>
</array>
</dict>
<key>CFPlugInUnloadFunction</key>
<string></string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2012-2023 Estonian Information System's Authority. All rights reserved.</string>
<key>QLNeedsToBeRunInMainThread</key>
<false/>
<key>QLPreviewHeight</key>
<integer>600</integer>
<key>QLPreviewWidth</key>
<integer>500</integer>
<key>QLSupportsConcurrentRequests</key>
<false/>
<key>QLThumbnailMinimumSize</key>
<real>17</real>
</dict>
</plist>
2 changes: 2 additions & 0 deletions extensions/DigiDocQL/en.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

Loading

0 comments on commit 0ae519a

Please sign in to comment.