Merge pull request #1 from nextcloud/data-request-buttons

initial feature set
This commit is contained in:
blizzz 2018-05-22 22:58:40 +02:00 committed by GitHub
commit 989c4ac38a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 901 additions and 2 deletions

24
.drone.yml Normal file
View File

@ -0,0 +1,24 @@
clone:
git:
image: plugins/git
depth: 1
pipeline:
signed-off-check:
image: nextcloudci/php7.0:php7.0-2
environment:
- APP_NAME=data_request
- CORE_BRANCH=master
- DB=sqlite
commands:
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server
- php ./build/signed-off-checker.php
secrets: [ github_token ]
when:
matrix:
TESTS: signed-off-check
matrix:
include:
- TESTS: signed-off-check

118
.scrutinizer.yml Normal file
View File

@ -0,0 +1,118 @@
filter:
excluded_paths:
- 'tests/*'
- 'doc/*'
tools:
sensiolabs_security_checker: true
php_sim: true
php_pdepend: true
php_analyzer: true
checks:
php:
line_length:
max_length: '100'
verify_access_scope_valid: true
require_scope_for_methods: true
no_underscore_prefix_in_methods: true
missing_arguments: true
method_calls_on_non_object: true
deprecated_code_usage: true
no_eval: true
parameter_doc_comments: true
return_doc_comments: true
fix_doc_comments: true
return_doc_comments: true
parameter_doc_comments: true
more_specific_types_in_doc_comments: true
code_rating: true
duplication: true
variable_existence: true
useless_calls: true
use_statement_alias_conflict: true
unused_variables: true
unused_properties: true
unused_parameters: true
unused_methods: true
unreachable_code: true
sql_injection_vulnerabilities: true
security_vulnerabilities: true
precedence_mistakes: true
precedence_in_conditions: true
parameter_non_unique: true
no_property_on_interface: true
no_non_implemented_abstract_methods: true
deprecated_code_usage: true
closure_use_not_conflicting: true
closure_use_modifiable: true
avoid_useless_overridden_methods: true
avoid_conflicting_incrementers: true
assignment_of_null_return: true
php5_style_constructor: true
one_class_per_file: true
require_php_tag_first: true
uppercase_constants: true
require_braces_around_control_structures: true
psr2_switch_declaration: true
psr2_control_structure_declaration: true
properties_in_camelcaps: true
parameters_in_camelcaps: true
optional_parameters_at_the_end: true
no_underscore_prefix_in_properties: true
no_space_inside_cast_operator: true
no_space_before_semicolon: true
no_short_open_tag: true
no_goto: true
lowercase_php_keywords: true
lowercase_basic_constants: true
function_in_camel_caps: true
classes_in_camel_caps: true
avoid_space_indentation: true
overriding_private_members: true
no_unnecessary_function_call_in_for_loop: true
simplify_boolean_return: true
javascript:
wrap_iife: true
no_process_exit: true
no_process_env: true
no_extra_semi: true
no_extra_bind: true
no_eval: true
no_else_return: true
dot_notation: true
camelcase: true
wrap_regex: true
valid_typeof: true
no_wrap_func: true
no_use_before_define: true
no_unreachable: true
no_undefined: true
no_trailing_spaces: true
no_reserved_keys: true
no_redeclare: true
no_obj_calls: true
no_loop_func: true
no_lonely_if: true
no_lone_blocks: true
no_inner_declarations: true
no_floating_decimal: true
no_extra_boolean_cast: true
no_empty: true
no_dupe_keys: true
coding_style:
php:
indentation:
general:
use_tabs: true
size: 4
spaces:
within:
brackets: false
other:
after_type_cast: false
braces:
classes_functions:
class: end-of-line

View File

@ -633,8 +633,8 @@ the "copyright" line and a pointer to where the full notice is found.
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,

157
Makefile Normal file
View File

@ -0,0 +1,157 @@
# This file is licensed under the Affero General Public License version 3 or
# later. See the COPYING file.
# @author Bernhard Posselt <dev@bernhard-posselt.com>
# @copyright Bernhard Posselt 2016
# Generic Makefile for building and packaging a Nextcloud app which uses npm and
# Composer.
#
# Dependencies:
# * make
# * which
# * curl: used if phpunit and composer are not installed to fetch them from the web
# * tar: for building the archive
# * npm: for building and testing everything JS
#
# If no composer.json is in the app root directory, the Composer step
# will be skipped. The same goes for the package.json which can be located in
# the app root or the js/ directory.
#
# The npm command by launches the npm build script:
#
# npm run build
#
# The npm test command launches the npm test script:
#
# npm run test
#
# The idea behind this is to be completely testing and build tool agnostic. All
# build tools and additional package managers should be installed locally in
# your project, since this won't pollute people's global namespace.
#
# The following npm scripts in your package.json install and update the bower
# and npm dependencies and use gulp as build system (notice how everything is
# run from the node_modules folder):
#
# "scripts": {
# "test": "node node_modules/gulp-cli/bin/gulp.js karma",
# "prebuild": "npm install && node_modules/bower/bin/bower install && node_modules/bower/bin/bower update",
# "build": "node node_modules/gulp-cli/bin/gulp.js"
# },
app_name=$(notdir $(CURDIR))
build_tools_directory=$(CURDIR)/build/tools
source_build_directory=$(CURDIR)/build/artifacts/source
source_package_name=$(source_build_directory)/$(app_name)
appstore_build_directory=$(CURDIR)/build/artifacts/appstore
appstore_package_name=$(appstore_build_directory)/$(app_name)
npm=$(shell which npm 2> /dev/null)
composer=$(shell which composer 2> /dev/null)
all: build
# Fetches the PHP and JS dependencies and compiles the JS. If no composer.json
# is present, the composer step is skipped, if no package.json or js/package.json
# is present, the npm step is skipped
.PHONY: build
build:
ifneq (,$(wildcard $(CURDIR)/composer.json))
make composer
endif
ifneq (,$(wildcard $(CURDIR)/package.json))
make npm
endif
ifneq (,$(wildcard $(CURDIR)/js/package.json))
make npm
endif
# Installs and updates the composer dependencies. If composer is not installed
# a copy is fetched from the web
.PHONY: composer
composer:
ifeq (, $(composer))
@echo "No composer command available, downloading a copy from the web"
mkdir -p $(build_tools_directory)
curl -sS https://getcomposer.org/installer | php
mv composer.phar $(build_tools_directory)
php $(build_tools_directory)/composer.phar install --prefer-dist
php $(build_tools_directory)/composer.phar update --prefer-dist
else
composer install --prefer-dist
composer update --prefer-dist
endif
# Installs npm dependencies
.PHONY: npm
npm:
ifeq (,$(wildcard $(CURDIR)/package.json))
cd js && $(npm) run build
else
npm run build
endif
# Removes the appstore build
.PHONY: clean
clean:
rm -rf ./build
# Same as clean but also removes dependencies installed by composer, bower and
# npm
.PHONY: distclean
distclean: clean
rm -rf vendor
rm -rf node_modules
rm -rf js/vendor
rm -rf js/node_modules
# Builds the source and appstore package
.PHONY: dist
dist:
make source
make appstore
# Builds the source package
.PHONY: source
source:
rm -rf $(source_build_directory)
mkdir -p $(source_build_directory)
tar cvzf $(source_package_name).tar.gz ../$(app_name) \
--exclude-vcs \
--exclude="../$(app_name)/build" \
--exclude="../$(app_name)/js/node_modules" \
--exclude="../$(app_name)/node_modules" \
--exclude="../$(app_name)/*.log" \
--exclude="../$(app_name)/js/*.log" \
# Builds the source package for the app store, ignores php and js tests
.PHONY: appstore
appstore:
rm -rf $(appstore_build_directory)
mkdir -p $(appstore_build_directory)
tar cvzf $(appstore_package_name).tar.gz ../$(app_name) \
--exclude-vcs \
--exclude="../$(app_name)/build" \
--exclude="../$(app_name)/tests" \
--exclude="../$(app_name)/Makefile" \
--exclude="../$(app_name)/*.log" \
--exclude="../$(app_name)/phpunit*xml" \
--exclude="../$(app_name)/composer.*" \
--exclude="../$(app_name)/js/node_modules" \
--exclude="../$(app_name)/js/tests" \
--exclude="../$(app_name)/js/test" \
--exclude="../$(app_name)/js/*.log" \
--exclude="../$(app_name)/js/package.json" \
--exclude="../$(app_name)/js/bower.json" \
--exclude="../$(app_name)/js/karma.*" \
--exclude="../$(app_name)/js/protractor.*" \
--exclude="../$(app_name)/package.json" \
--exclude="../$(app_name)/bower.json" \
--exclude="../$(app_name)/karma.*" \
--exclude="../$(app_name)/protractor\.*" \
--exclude="../$(app_name)/.*" \
--exclude="../$(app_name)/js/.*" \
.PHONY: test
test: composer
$(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.xml
$(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml

21
appinfo/info.xml Normal file
View File

@ -0,0 +1,21 @@
<?xml version="1.0"?>
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>data_request</id>
<name>Data Request</name>
<summary>Request your data from the admins</summary>
<description><![CDATA[Enable your users to request an export or deletion of their data. According options are added to the personal settings section. Administrations will be notified by email about the request.]]></description>
<version>1.0.0</version>
<licence>agpl</licence>
<author mail="blizzz@arthur-schiwon.de" homepage="https://nextcloud.com">Arthur Schiwon</author>
<namespace>DataRequest</namespace>
<category>tools</category>
<bugs>https://github.com/nextcloud/data_request/issues</bugs>
<dependencies>
<nextcloud min-version="13" max-version="13"/>
</dependencies>
<settings>
<personal>OCA\DataRequest\Settings\Personal</personal>
</settings>
</info>

29
appinfo/routes.php Normal file
View File

@ -0,0 +1,29 @@
<?php
/**
* @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
return [
'ocs' => [
['name' => 'DataRequest#export', 'url' => '/api/v1/export', 'verb' => 'POST'],
['name' => 'DataRequest#deletion', 'url' => '/api/v1/deletion', 'verb' => 'POST'],
]
];

7
css/style.scss Normal file
View File

@ -0,0 +1,7 @@
#data-request * button {
min-width: 225px;
}
#data-request-deletion {
border-color: $color-error;
}

56
img/app.svg Normal file
View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="32"
width="32"
version="1"
viewBox="0 0 32 32"
id="svg4"
sodipodi:docname="app.svg"
inkscape:version="0.92.1 r">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="789"
inkscape:window-height="480"
id="namedview6"
showgrid="false"
inkscape:zoom="7.375"
inkscape:cx="-8.3389831"
inkscape:cy="16"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="0"
inkscape:current-layer="svg4" />
<path
d="M13.733 0a.915.915 0 0 0-.933.934V3.6c-1.182.304-2.243.794-3.267 1.4L7.6 3.068a.93.93 0 0 0-1.334 0l-3.2 3.2a.93.93 0 0 0 0 1.334L5 9.535c-.607 1.024-1.097 2.085-1.4 3.267H.933a.915.915 0 0 0-.933.934v4.533c0 .53.403.934.933.934H3.6c.303 1.182.793 2.243 1.4 3.267l-1.934 1.935a.93.93 0 0 0 0 1.333l3.2 3.2a.93.93 0 0 0 1.333 0L9.532 27c1.024.61 2.085 1.097 3.266 1.4v2.667c0 .53.402.933.932.933h4.534c.53 0 .933-.403.933-.935V28.4c1.18-.305 2.24-.795 3.265-1.4L24.4 28.93a.93.93 0 0 0 1.332 0l3.2-3.2a.93.93 0 0 0 0-1.333L27 22.465c.607-1.024 1.096-2.085 1.4-3.266h2.665a.915.915 0 0 0 .935-.933v-4.534a.915.915 0 0 0-.934-.933H28.4c-.304-1.182-.792-2.243-1.4-3.267L28.932 7.6a.93.93 0 0 0 0-1.334l-3.2-3.2a.93.93 0 0 0-1.333 0L22.465 5c-1.024-.607-2.084-1.097-3.266-1.4V.933A.915.915 0 0 0 18.267 0zM16 8.87A7.134 7.134 0 0 1 23.13 16 7.134 7.134 0 0 1 16 23.133c-3.936 0-7.13-3.196-7.13-7.132S12.063 8.87 16 8.87z"
display="block"
fill="#fff"
id="path2"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

76
js/app.js Normal file
View File

@ -0,0 +1,76 @@
/**
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
'use strict';
/** global: OCA */
/** global: OC */
(function(OC, OCA) {
OCA.DataRequest = OCA.DataRequest || {};
OCA.DataRequest.App = {
init: function() {
$('#data-request button').on('click', function() {
OCA.DataRequest.App.request($(this));
});
},
request: function ($context) {
if(OC.PasswordConfirmation.requiresPasswordConfirmation()) {
var self = this;
OC.PasswordConfirmation.requirePasswordConfirmation(function () {
self._doRequest($context);
});
return;
}
this._doRequest($context);
},
_doRequest($context) {
$context.prop('disabled', 'disabled');
$context.addClass('loading');
$context.siblings('span.warning').addClass('hidden').html('');
$.ajax({
type: 'POST',
url: OC.linkToOCS('apps/data_request/api/v1', 2) + $context.data('request'),
dataType: 'json',
beforeSend: function (request) {
request.setRequestHeader('Accept', 'application/json');
},
success: function () {
$context.html($context.html() + ' ' + t('data_request', 'sent!'));
$context.removeClass('loading');
},
error: function (response) {
$context.prop('disabled', '');
$context.removeClass('loading');
if(response.responseJSON && response.responseJSON.ocs.data.error) {
$context.siblings('span.warning')
.removeClass('hidden')
.html(response.responseJSON.ocs.data.error);
}
}
});
}
};
})(OC, OCA);

27
js/init.js Normal file
View File

@ -0,0 +1,27 @@
/**
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
'use strict';
/** global: OCA */
$(document).ready(function() {
OCA.DataRequest.App.init();
});

View File

@ -0,0 +1,81 @@
<?php
/**
* @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\DataRequest\Controller;
use OCA\DataRequest\Exceptions\HintedRuntime;
use OCA\DataRequest\Services\Request;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\IRequest;
class DataRequestController extends OCSController {
/** @var Request */
private $dataRequest;
public function __construct(
$appName,
IRequest $request,
$corsMethods = 'PUT, POST, GET, DELETE, PATCH',
$corsAllowedHeaders = 'Authorization, Content-Type, Accept',
$corsMaxAge = 1728000,
Request $dataRequest
) {
parent::__construct($appName, $request, $corsMethods, $corsAllowedHeaders, $corsMaxAge);
$this->dataRequest = $dataRequest;
}
/**
* @NoAdminRequired
* @PasswordConfirmationRequired
*/
public function export() {
try {
$this->dataRequest->sendExportRequest();
return new DataResponse();
} catch(HintedRuntime $e) {
return new DataResponse(
['error' => $e->getHint()],
Http::STATUS_INTERNAL_SERVER_ERROR
);
}
}
/**
* @NoAdminRequired
* @PasswordConfirmationRequired
*/
public function deletion() {
try {
$this->dataRequest->sendDeleteRequest();
return new DataResponse();
} catch(HintedRuntime $e) {
return new DataResponse(
['error' => $e->getHint()],
Http::STATUS_INTERNAL_SERVER_ERROR
);
}
}
}

View File

@ -0,0 +1,45 @@
<?php
/**
* @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\DataRequest\Exceptions;
use Throwable;
class HintedRuntime extends \RuntimeException {
/** @var string */
protected $hint;
public function __construct($message = '', $hint = '', $code = 0, Throwable $previous = null) {
parent::__construct($message, $code, $previous);
$this->hint = $hint;
}
public function getHint() {
if (empty($this->hint)) {
return $this->message;
}
return $this->hint;
}
}

161
lib/Services/Request.php Normal file
View File

@ -0,0 +1,161 @@
<?php
/**
* @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\DataRequest\Services;
use OCA\DataRequest\Exceptions\HintedRuntime;
use OCP\Defaults;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IL10N;
use OCP\IUser;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use OCP\Mail\IEMailTemplate;
use OCP\Mail\IMailer;
use OCP\Util;
class Request {
/** @var string */
protected $defaultLanguage;
/** @var IGroupManager */
private $groupManager;
/** @var IMailer */
private $mailer;
/** @var IFactory */
private $l10nFactory;
/** @var IConfig */
private $config;
/** @var IUser */
private $requester;
/** @var IL10N */
private $l;
public function __construct(IGroupManager $groupManager, IMailer $mailer, IFactory $l10nFactory, IConfig $config, IUserSession $userSession, IL10N $l) {
$this->groupManager = $groupManager;
$this->mailer = $mailer;
$this->l10nFactory = $l10nFactory;
$this->config = $config;
$this->requester = $userSession->getUser();
$this->l = $l;
}
public function sendExportRequest() {
$this->sendRequest(function (IUser $r) {return $this->getExportTemplate($r); });
}
public function sendDeleteRequest() {
$this->sendRequest(function (IUser $r) {return $this->getDeletionTemplate($r); });
}
protected function sendRequest(callable $templateGenerator) {
$admins = $this->getAdmins();
$oneMailSent = false;
foreach ($admins as $admin) {
$template = $templateGenerator($admin);
if($this->craftEmailTo($admin, $template) === true) {
$oneMailSent = true;
}
}
if(!$oneMailSent) {
throw new HintedRuntime(
'No mail was sent successfully',
$this->l->t('No administrator could have been contacted.')
);
}
}
protected function getDefaultLang() {
if($this->defaultLanguage === null) {
$this->defaultLanguage = $this->config->getSystemValue('default_language', 'en');
}
return $this->defaultLanguage;
}
protected function craftEmailTo(IUser $admin, IEMailTemplate $template) {
$defaults = new Defaults();
$senderAddress = $this->requester->getEMailAddress() ?: Util::getDefaultEmailAddress('no-reply');
$senderName = $this->requester->getEMailAddress() ? $this->requester->getDisplayName() : $defaults->getName();
$message = $this->mailer->createMessage();
$message->setTo([$admin->getEMailAddress() => $admin->getDisplayName()]);
$message->setSubject($template->renderSubject());
$message->setHtmlBody($template->renderHtml());
$message->setPlainBody($template->renderText());
$message->setFrom([$senderAddress => $senderName]);
try {
$this->mailer->send($message);
} catch (\Exception $e) {
return $e;
}
return true;
}
protected function getExportTemplate(IUser $admin) {
$l = $this->l10nFactory->get('data_request', $this->config->getUserValue($admin->getUID(), 'core', 'lang', $this->getDefaultLang()));
$template = $this->mailer->createEMailTemplate('data_request.Export', []);
$template->setSubject($l->t('Personal data export request'));
$template->addHeader();
$template->addHeading($l->t('Hello %s,',[$admin->getDisplayName()]));
$template->addBodyText($l->t('The user %s, identified by user id "%s", has requested an export of his personal data. Please take action accordingly.', [$this->requester->getDisplayName(), $this->requester->getUID()]));
$template->addFooter();
return $template;
}
protected function getDeletionTemplate(IUser $admin) {
$l = $this->l10nFactory->get('data_request', $this->config->getUserValue($admin->getUID(), 'core', 'lang', $this->getDefaultLang()));
$template = $this->mailer->createEMailTemplate('data_request.Deletion', []);
$template->setSubject($l->t('Account deletion request'));
$template->addHeader();
$template->addHeading($l->t('Hello %s,',[$admin->getDisplayName()]));
$template->addBodyText($l->t('The user %s, identified by user id "%s", has requested to delete the account. Please take action accordingly.', [$this->requester->getDisplayName(), $this->requester->getUID()]));
$template->addFooter();
return $template;
}
protected function getAdmins() {
$admins = $this->groupManager->get('admin')->searchUsers('');
$admins = array_filter($admins, function(IUser $admin) {
return $admin->getEMailAddress() !== null;
});
if(empty($admins)) {
throw new HintedRuntime(
'No admin has entered an email address',
$this->l->t('No administrator has set an email address')
);
}
return $admins;
}
}

58
lib/Settings/Personal.php Normal file
View File

@ -0,0 +1,58 @@
<?php
/**
* @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\DataRequest\Settings;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Settings\ISettings;
class Personal implements ISettings {
/**
* @return TemplateResponse returns the instance with all parameters set, ready to be rendered
* @since 9.1
*/
public function getForm() {
return new TemplateResponse('data_request', 'Settings/personal', [], '');
}
/**
* @return string the section ID, e.g. 'sharing'
* @since 9.1
*/
public function getSection() {
return 'personal-info';
}
/**
* @return int whether the form should be rather on the top or bottom of
* the admin section. The forms are arranged in ascending order of the
* priority values. It is required to return a value between 0 and 100.
*
* E.g.: 70
* @since 9.1
*/
public function getPriority() {
return 80;
}
}

View File

@ -0,0 +1,39 @@
<?php
/**
* @copyright Copyright (c) 2018 Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
style('data_request', 'style');
script('data_request', ['init', 'app']);
?>
<div id="data-request" class="section">
<h2><?php p($l->t('Account')); ?></h2>
<p class="settings-hint"><?php p($l->t('You can request an export of your data or account deletion from the system administrator. This can take up to 30 days.')); ?></p>
<div>
<button id="data-request-export" data-request="export" class="button"><?php p($l->t('Request data export')); ?></button><span class="warning hidden"></span>
</div>
<div>
<button id="data-request-deletion" data-request="deletion" class="button"><?php p($l->t('Request account deletion')); ?></button><span class="warning hidden"></span>
</div>
</div>