commit 444c69672fe7fb0667cda8d11bf403a7b370f4e4 Author: philipp lang Date: Wed Mar 22 00:23:34 2023 +0100 Initial commit diff --git a/Plugin.php b/Plugin.php new file mode 100644 index 0000000..ebc8eff --- /dev/null +++ b/Plugin.php @@ -0,0 +1,104 @@ + 'zoomyboy.owncloud::lang.plugin.name', + 'description' => 'zoomyboy.owncloud::lang.plugin.description', + 'author' => 'zoomyboy', + 'icon' => 'icon-leaf', + ]; + } + + /** + * Register method, called when the plugin is first registered. + */ + public function register(): void + { + } + + /** + * Boot method, called right before the request route. + */ + public function boot(): void + { + } + + /** + * Registers any frontend components implemented in this plugin. + */ + public function registerComponents(): array + { + return [ + Form::class => 'owncloud_form', + Confirm::class => 'owncloud_confirm', + ]; + } + + /** + * Registers any backend permissions used by this plugin. + */ + public function registerPermissions(): array + { + return []; // Remove this line to activate + + return [ + 'zoomyboy.owncloud.some_permission' => [ + 'tab' => 'zoomyboy.owncloud::lang.plugin.name', + 'label' => 'zoomyboy.owncloud::lang.permissions.some_permission', + 'roles' => [UserRole::CODE_DEVELOPER, UserRole::CODE_PUBLISHER], + ], + ]; + } + + /** + * Registers backend navigation items for this plugin. + */ + public function registerNavigation(): array + { + return []; // Remove this line to activate + + return [ + 'owncloud' => [ + 'label' => 'zoomyboy.owncloud::lang.plugin.name', + 'url' => Backend::url('zoomyboy/owncloud/mycontroller'), + 'icon' => 'icon-leaf', + 'permissions' => ['zoomyboy.owncloud.*'], + 'order' => 500, + ], + ]; + } + + public function registerSettings(): array + { + return [ + 'settings' => [ + 'label' => 'Owncloud Settings', + 'description' => 'Owncloud Zugangsdaten', + 'category' => 'Services', + 'icon' => 'icon-cog', + 'class' => Settings::class, + 'order' => 500, + 'keywords' => 'owncloud api', + 'permissions' => [], + ], + ]; + } +} diff --git a/assets/eventregistration.js b/assets/eventregistration.js new file mode 100644 index 0000000..bc2d698 --- /dev/null +++ b/assets/eventregistration.js @@ -0,0 +1,67 @@ +var toastedOptions = { + position: "bottom-right", + duration: 3000, + fitToScreen: false, + fullWidth: false, + theme: "material", +}; + +export default function (toasted) { + var toasted = new toasted(toastedOptions); + + return { + loading: false, + data: { + firstname: "", + lastname: "", + username: "", + email: "", + group: null, + function: '', + oc_groups: [], + }, + oc_groups: [], + finished: false, + submitRequest: null, + errorFields: [], + groups: [ + { id: "Gallier", name: "Gallier (Wuppertal)" }, + { id: "Gandalf", name: "Gandalf (SG-Mangenberg)" }, + { id: "Gravenrode", name: "Gravenrode (SG-Gräfrath)" }, + { id: "Lennep", name: "Lennep (RS-Lennep)" }, + { id: "Silva", name: "Silva (SG-Wald)" }, + { id: "Sugambrer", name: "Sugambrer (SG-Höhscheid)" }, + { id: "Tenkterer", name: "Tenkterer (SG-Löhdorf)" }, + { id: "von Berg", name: "von Berg (SG-Ohligs)" }, + ], + submit() { + var _self = this; + this.loading = true; + var promise = fetch(window.location.href, { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "X-WINTER-REQUEST-HANDLER": this.submitRequest, + "X-WINTER-REQUEST-PARTIALS": [], + "X-Requested-With": "XMLHttpRequest", + }, + body: JSON.stringify(this.data), + }); + + promise.then(function (response) { + _self.loading = false; + if (response.status === 422) { + response.json().then((errors) => { + Object.keys(errors).forEach((field) => { + toasted.error(errors[field].join("
")); + }); + }); + } + if (response.status === 201) { + _self.finished = true; + } + }); + }, + }; +} diff --git a/components/Confirm.php b/components/Confirm.php new file mode 100644 index 0000000..32b0a05 --- /dev/null +++ b/components/Confirm.php @@ -0,0 +1,67 @@ + 'Confirm Component', + 'description' => 'No description provided yet...', + ]; + } + + public function onRun(): void + { + $b = base64_decode($this->property('payload')); + + if (!$b) { + return; + } + + $b = json_decode($b, true); + + if (!$b) { + return; + } + + $password = str_random(32); + $auth = base64_encode(Settings::get('username').':'.Settings::get('password')); + $client = new Client(['base_uri' => Settings::get('url'), 'headers' => ['Authorization' => 'Basic '.$auth, 'Content-Type' => 'application/x-www-form-urlencoded']]); + $client->post('/ocs/v1.php/cloud/users', [ + 'form_params' => [ + 'groups' => array_merge($b['oc_groups'], Settings::get('force_groups')), + 'userid' => $b['username'], + 'password' => $password, + ], + ]); + + Mail::send('owncloud_confirm', [ + 'password' => $password, + 'payload' => $b, + ], function ($message) use ($b) { + $message->to($b['email'], $b['firstname'].' '.$b['lastname']); + }); + } + + /** + * Returns the properties provided by the component. + */ + public function defineProperties() + { + return [ + 'payload' => [ + 'label' => 'Payload', + ], + ]; + } +} diff --git a/components/Form.php b/components/Form.php new file mode 100644 index 0000000..1a11bb5 --- /dev/null +++ b/components/Form.php @@ -0,0 +1,118 @@ + 'Form Component', + 'description' => 'No description provided yet...', + ]; + } + + /** + * Returns the properties provided by the component. + */ + public function defineProperties() + { + return []; + } + + public function onRun(): void + { + $groups = Cache::remember('oc_groupsa', 1, function () { + return $this->getGroups(); + }); + $this->groups = collect($groups) + ->filter(fn ($g) => !in_array($g, Settings::get('force_groups'))) + ->filter(fn ($g) => !in_array($g, Settings::get('disallowed_groups'))) + ->map(fn ($group) => ['id' => $group, 'name' => $group]) + ->toArray(); + } + + public function onSubmit() + { + $rules = [ + 'firstname' => 'required|string|max:255', + 'lastname' => 'required|string|max:255', + 'username' => ['required', 'string', 'max:255', 'regex:/^[a-zA-Z0-9]+$/', Rule::notIn($this->getUsers())], + 'email' => 'required|email|string|max:255', + 'group' => 'required|string|max:255', + 'function' => 'required|string|max:255', + 'oc_groups' => 'present|array', + 'oc_groups.*' => 'string', + ]; + $validator = Validator::make(Input::all(), $rules, [ + 'username.not_in' => 'OwnCloud Nutzername wird bereits verwendet.', + 'username.regex' => 'OwnCloud Nutzername darf nur aus Buchstaben und Zahlen bestehen', + ], Lang::get('zoomyboy.owncloud::validation.attributes')); + + if ($validator->fails()) { + return response()->json($validator->errors(), 422); + } + + $payload = base64_encode(json_encode($validator->validated())); + Mail::send('owncloud_request', [ + 'link' => url('/owncloud-confirm/'.$payload), + 'payload' => $validator->validated(), + ], function ($message) { + foreach (Settings::get('admins') as $admin) { + $message->to($admin); + } + }); + + dd('I'); + + return response()->json([], 201); + } + + private function getGroups(): array + { + $response = $this->getClient()->get('/ocs/v1.php/cloud/groups'); + + $r = []; + $xml = simplexml_load_string((string) $response->getBody()); + foreach ($xml->xpath('/ocs/data/groups/element') as $element) { + $r[] = (string) $element; + } + + return $r; + } + + private function getUsers(): array + { + $response = $this->getClient()->get('/ocs/v1.php/cloud/users'); + + $r = []; + $xml = simplexml_load_string((string) $response->getBody()); + foreach ($xml->xpath('/ocs/data/users/element') as $element) { + $r[] = (string) $element; + } + + return $r; + } + + private function getClient(): Client + { + $auth = base64_encode(Settings::get('username').':'.Settings::get('password')); + + return new Client(['base_uri' => Settings::get('url'), 'headers' => ['Authorization' => 'Basic '.$auth]]); + } +} diff --git a/components/confirm/default.htm b/components/confirm/default.htm new file mode 100644 index 0000000..3cd9fe7 --- /dev/null +++ b/components/confirm/default.htm @@ -0,0 +1 @@ +Zugang wurde erstellt. diff --git a/components/form/default.htm b/components/form/default.htm new file mode 100644 index 0000000..6e023d4 --- /dev/null +++ b/components/form/default.htm @@ -0,0 +1,3 @@ +

This is the default markup for component Form

+ +You can delete this file if you want diff --git a/lang/de/lang.php b/lang/de/lang.php new file mode 100644 index 0000000..78b7350 --- /dev/null +++ b/lang/de/lang.php @@ -0,0 +1,22 @@ + [ + 'name' => 'owncloud', + 'description' => 'No description provided yet...', + ], + 'permissions' => [ + 'some_permission' => 'Some permission', + ], + 'models' => [ + 'general' => [ + 'id' => 'ID', + 'created_at' => 'Created At', + 'updated_at' => 'Updated At', + ], + 'request' => [ + 'label' => 'Request', + 'label_plural' => 'Requests', + ], + ], +]; diff --git a/lang/en/validation.php b/lang/en/validation.php new file mode 100644 index 0000000..149d35c --- /dev/null +++ b/lang/en/validation.php @@ -0,0 +1,12 @@ + [ + 'firstname' => 'Vorname', + 'username' => 'OwnCloud Nutzername', + 'lastname' => 'Nachname', + 'email' => 'E-Mail-Adresse', + 'group' => 'Stamm', + 'function' => 'Funktion', + ], +]; diff --git a/models/Request.php b/models/Request.php new file mode 100644 index 0000000..e4faf11 --- /dev/null +++ b/models/Request.php @@ -0,0 +1,74 @@ + + + {{label}} {% if required %} * {% endif %} + +{% endmacro %} +{% macro textarea(context, name, label, required, type) %} + +{% endmacro %} +{% macro select(context, name, label, required, options) %} + +{% endmacro %} +{% macro radio(context, name, label, required, options) %} +
+ {{label}} {% if required %} * {% endif %} +
+ +
+
+{% endmacro %} +{% macro yesno(context, name, label, required) %} +
+
+ +
+
+{% endmacro %} +{% macro checkboxes(context, name, label, required, options, settings) %} +
+ {{label}} {% if required %} * {% endif %} +
+ +
+
+{% endmacro %}