Merge pull request #1 from nextcloud/data-request-buttons
initial feature set
This commit is contained in:
commit
989c4ac38a
|
@ -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
|
|
@ -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
|
|
@ -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,
|
|
@ -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
|
|
@ -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>
|
|
@ -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'],
|
||||
]
|
||||
];
|
|
@ -0,0 +1,7 @@
|
|||
#data-request * button {
|
||||
min-width: 225px;
|
||||
}
|
||||
|
||||
#data-request-deletion {
|
||||
border-color: $color-error;
|
||||
}
|
|
@ -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 |
|
@ -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);
|
|
@ -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();
|
||||
});
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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>
|
Loading…
Reference in New Issue