first commit
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/.vscode/
|
||||||
|
*/.vscode/
|
||||||
|
/.theia/
|
||||||
|
*/.theia/
|
||||||
|
*/*.deb
|
||||||
|
*.deb
|
||||||
131
createapp.pl
Normal file
131
createapp.pl
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Data::Printer;
|
||||||
|
use File::Find;
|
||||||
|
use File::Copy;
|
||||||
|
use Cwd;
|
||||||
|
use File::Slurp;
|
||||||
|
|
||||||
|
my $secret = `openssl rand -base64 48`;
|
||||||
|
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
|
||||||
|
$year = $year+1900;
|
||||||
|
|
||||||
|
chomp $secret;
|
||||||
|
|
||||||
|
my $rc = system('git --version');
|
||||||
|
if ( $rc < 0) {
|
||||||
|
print STDOUT "GIT scheint nicht installiert zu sein, Programm wird geschlossen\n";
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
print "Wie soll das neue Programm heißen: ";
|
||||||
|
chomp( my $name = <ARGV> );
|
||||||
|
|
||||||
|
if ( $name !~ /^[a-z]*$/ ) {
|
||||||
|
print STDOUT "Programmname muss existieren und darf nur kleinbuchstaben beinhalten, Programm wird geschlossen\n";
|
||||||
|
exit 0;
|
||||||
|
} elsif ( $name eq 'xxx' ) {
|
||||||
|
print STDOUT "Programmname darf nicht xxx heißen, Programm wird geschlossen\n";
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
print "Wohin soll das neue Programm kopiert werden ( $ENV{'HOME'}/mojo ): ";
|
||||||
|
chomp( my $wohin = <ARGV> );
|
||||||
|
|
||||||
|
if ( $wohin eq "" ) {
|
||||||
|
$wohin = "$ENV{'HOME'}/mojo";
|
||||||
|
};
|
||||||
|
if ( !-d $wohin ) {
|
||||||
|
print STDOUT "Ordner existiert nicht, Programm wird geschlossen\n";
|
||||||
|
exit 0;
|
||||||
|
} elsif ( $wohin =~ /create_mojo_app/ ) {
|
||||||
|
print STDOUT "Ordner mit create_mojo_app im Namen sind nicht erlaubt, Programm wird geschlossen\n";
|
||||||
|
exit 0;
|
||||||
|
} elsif ( !-w $wohin ) {
|
||||||
|
print STDOUT "in Ordner $wohin kann nicht geschrieben werden, Programm wird geschlossen\n";
|
||||||
|
exit 0;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
$wohin = $wohin =~ s/\/*$//r; # letztes / entfernen
|
||||||
|
|
||||||
|
my $lname = lcfirst $name;
|
||||||
|
my $uname = ucfirst $name;
|
||||||
|
|
||||||
|
print "Wofür ist $lname: ";
|
||||||
|
chomp( my $wofuer = <ARGV> );
|
||||||
|
|
||||||
|
print "auf welchem Port soll $uname laufen (Default 3000): ";
|
||||||
|
chomp( my $port = <ARGV> );
|
||||||
|
if ( $port eq "" ) { $port = 3000 }
|
||||||
|
|
||||||
|
my $dir = getcwd;
|
||||||
|
|
||||||
|
# Ordner und Dateinamen in xxx durchgehen und XXX mit neuen Appnamen ersetzen
|
||||||
|
find( \&files, 'xxx' );
|
||||||
|
|
||||||
|
sub files {
|
||||||
|
my $str = $File::Find::name;
|
||||||
|
$str =~ s/Xxx/$uname/g;
|
||||||
|
$str =~ s/xxx/$lname/g;
|
||||||
|
|
||||||
|
if (-d) {
|
||||||
|
mkdir $wohin . '/' . $str;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
copy( $dir . '/' . $File::Find::name, $wohin . '/' . $str )
|
||||||
|
or die "The move operation failed: $!";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Dateien in neuen Appordner durchgehen und Werte mit neuen ersetzen
|
||||||
|
find( \&newfiles, "$wohin/$lname" );
|
||||||
|
|
||||||
|
sub newfiles {
|
||||||
|
|
||||||
|
if (-f) {
|
||||||
|
|
||||||
|
#print "File: $dir/$File::Find::name\n";
|
||||||
|
if ( $File::Find::name !~ m/.png/g ) {
|
||||||
|
my @lines = read_file($File::Find::name);
|
||||||
|
write_file($File::Find::name, '');
|
||||||
|
|
||||||
|
for my $line (@lines) {
|
||||||
|
$line =~ s/mojocreateyear/$year/g;
|
||||||
|
$line =~ s/Xxx/$uname/g;
|
||||||
|
$line =~ s/xxx/$lname/g;
|
||||||
|
$line =~ s/mojoappsecret/$secret/g;
|
||||||
|
$line =~ s/hypnotoadport/$port/g;
|
||||||
|
$line =~ s/wofuer/$wofuer/g;
|
||||||
|
append_file($File::Find::name, $line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rechte der Datei ändern
|
||||||
|
|
||||||
|
chmod( 0755, "$wohin/$lname/app/morbo.sh" );
|
||||||
|
chmod( 0755, "$wohin/$lname/app/test.sh" );
|
||||||
|
chmod( 0755, "$wohin/$lname/deb/DEBIAN/postinst" );
|
||||||
|
chmod( 0755, "$wohin/$lname/deb/DEBIAN/prerm" );
|
||||||
|
chmod( 0755, "$wohin/$lname/deb/pbuild.sh" );
|
||||||
|
|
||||||
|
print "App: $uname erstellt\n";
|
||||||
|
chdir "$wohin/$lname/";
|
||||||
|
system( "git init" );
|
||||||
|
system( "git add ." );
|
||||||
|
system( "git commit -m 'initialer Commit'" );
|
||||||
|
system( "git remote add origin git\@git:WebApps/$uname.git" );
|
||||||
|
|
||||||
|
system( "$wohin/$lname/deb/pbuild.sh" ) == 0
|
||||||
|
or die "Bash Script failed";
|
||||||
|
1;
|
||||||
|
|
||||||
|
system( "$wohin/$lname/app/morbo.sh" ) == 0
|
||||||
|
or die "Bash Script failed";
|
||||||
|
1;
|
||||||
116
xxx/app/lib/XxxApp.pm
Normal file
116
xxx/app/lib/XxxApp.pm
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
package XxxApp;
|
||||||
|
use Mojo::Base 'Mojolicious';
|
||||||
|
use Time::localtime;
|
||||||
|
|
||||||
|
# This method will run once at server start
|
||||||
|
sub startup {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# einlesen der lokalen Config
|
||||||
|
my $config = $self->plugin('Config');
|
||||||
|
# $self->plugin('Config', 'file' => $config->{zus_config}); # hier und in der konfig zus_config aktivieren
|
||||||
|
|
||||||
|
$self->secrets([ $config->{secret}]);
|
||||||
|
|
||||||
|
$config->{version} = '__VERSION__';
|
||||||
|
$config->{prefix} = '';
|
||||||
|
|
||||||
|
# Logging mit Log4perl
|
||||||
|
$self->plugin('steffen::MojoPlug::Syslog' => $config->{logging} );
|
||||||
|
$self->app->log->info(sprintf('%s v%s (Perl %s, Mojolicious v%s) started', 'Xxx', $config->{version}, $^V, $Mojolicious::VERSION));
|
||||||
|
|
||||||
|
# Authentication & Authorization
|
||||||
|
$self->sessions->cookie_name('Xxx');
|
||||||
|
$self->sessions->default_expiration(3600);
|
||||||
|
$self->sessions->samesite('Strict');
|
||||||
|
delete $self->app->static->extra->{'favicon.ico'};
|
||||||
|
push @{$self->app->static->paths}, $config->{htlib};
|
||||||
|
|
||||||
|
# Kompression
|
||||||
|
$self->app->renderer->compress(1);
|
||||||
|
|
||||||
|
# Authorisation
|
||||||
|
$self->plugin('steffen::MojoPlug::Authorization' => { verbose => 1 });
|
||||||
|
|
||||||
|
# Menu über config
|
||||||
|
$self->plugin('Config', file => 'navigation.conf');
|
||||||
|
$self->plugin('steffen::MojoPlug::NavHelper' => { verbose => 1, bs => 5 });
|
||||||
|
|
||||||
|
# deaktivierte Plugins
|
||||||
|
# $self->plugin('RenderFile');
|
||||||
|
# mysql
|
||||||
|
# $self->plugin('steffen::MojoPlug::Mysql' => { db => $config->{db} });
|
||||||
|
# $config->{test} = $self->dbxxx->{dsn} =~ m/dbs-test/gxms;
|
||||||
|
|
||||||
|
# Local Helpers
|
||||||
|
$self->plugin('XxxApp::Helpers' => { verbose => 1 });
|
||||||
|
|
||||||
|
# https://editor.swagger.io/?url=https://petstore.swagger.io/v2/swagger.yaml
|
||||||
|
$self->plugin('OpenAPI' => {
|
||||||
|
#route => $self->app->routes->under("/api")->to("api#auth"),
|
||||||
|
url => $self->app->home->rel_file("openapi.json"),
|
||||||
|
schema => 'v3',
|
||||||
|
security => {
|
||||||
|
BasicAuth => sub {
|
||||||
|
my ($c, $definition, $scopes, $cb) = @_;
|
||||||
|
my $haspriv;
|
||||||
|
for my $sc ( @{$scopes} ) {
|
||||||
|
$haspriv = 1 if $c->has_priv($sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $haspriv ) {
|
||||||
|
return $c->$cb()
|
||||||
|
} else {
|
||||||
|
return $c->$cb('no permission')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$self->plugin( 'steffen::MojoPlug::SwaggerUI' => {
|
||||||
|
route => $self->app->routes()->any('/rfc'),
|
||||||
|
url => "/api",
|
||||||
|
title => "Xxx",
|
||||||
|
favicon => "/images/favicon.png"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$self->hook(
|
||||||
|
'before_dispatch' => sub {
|
||||||
|
my $c = shift;
|
||||||
|
$c->req->url->base->path('');
|
||||||
|
$config->{prefix} = '';
|
||||||
|
if (!!$c->req->headers->header('Mojo-RP-Location')) {
|
||||||
|
$c->req->url->base->path( $c->req->headers->header('Mojo-RP-Location') );
|
||||||
|
$config->{prefix} = '/'.$c->req->headers->header('Mojo-RP-Location');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
# Hook für CORS
|
||||||
|
$self->hook(
|
||||||
|
'after_dispatch' => sub {
|
||||||
|
my $c = shift;
|
||||||
|
$c->res->headers->header('Access-Control-Allow-Origin' => '*');
|
||||||
|
$c->res->headers->remove('Server');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
# Router
|
||||||
|
my $r = $self->routes;
|
||||||
|
|
||||||
|
# Normal route to controller
|
||||||
|
$r->get('/') ->to('main#main', title => 'Xxx');
|
||||||
|
$r->get('/jstreetemplate') ->to('menu#jstreetemplate', title => 'JStree Template'); # Beispiel kann gelöscht werden
|
||||||
|
|
||||||
|
$r->get('/xxx') ->to('main#xxx', title => 'Xxx');
|
||||||
|
$r->get('/about') ->to('main#about', title => 'Über Xxx');
|
||||||
|
$r->get('/login') ->to('main#loginform');
|
||||||
|
$r->post('/login') ->to('main#login');
|
||||||
|
$r->get('/userinfo') ->to('main#userinfo');
|
||||||
|
$r->get('/getoff') ->to('main#getoff');
|
||||||
|
|
||||||
|
# API über OpenAPI Plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
376
xxx/app/lib/XxxApp/Controller/Api/Jstreetemplate.pm
Normal file
376
xxx/app/lib/XxxApp/Controller/Api/Jstreetemplate.pm
Normal file
@@ -0,0 +1,376 @@
|
|||||||
|
package XxxApp::Controller::Api::Jstreetemplate;
|
||||||
|
use Mojo::Base 'Mojolicious::Controller';
|
||||||
|
use Data::Printer;
|
||||||
|
|
||||||
|
my @liste = qw|Anstand
|
||||||
|
Aufmerksamkeit
|
||||||
|
Auftrieb
|
||||||
|
Ausgelassenheit
|
||||||
|
Ausgewogenheit
|
||||||
|
Auszeichnung
|
||||||
|
Bedeutung
|
||||||
|
Begeisterung
|
||||||
|
Beglückung
|
||||||
|
Behaglichkeit
|
||||||
|
Beherztheit
|
||||||
|
Belohnung
|
||||||
|
Bereicherung
|
||||||
|
Bewunderung
|
||||||
|
Chance
|
||||||
|
Charisma
|
||||||
|
Charme
|
||||||
|
Dankbarkeit
|
||||||
|
Daseinsfreude
|
||||||
|
Ehrlichkeit
|
||||||
|
Einfallsreichtum
|
||||||
|
Einigkeit
|
||||||
|
Empfehlung
|
||||||
|
Energie
|
||||||
|
Engagement
|
||||||
|
Entspannung
|
||||||
|
Erfolg
|
||||||
|
Erfüllung
|
||||||
|
Ermutigung
|
||||||
|
Faszination
|
||||||
|
Freiheit
|
||||||
|
Freude
|
||||||
|
Freunde
|
||||||
|
Freundlichkeit
|
||||||
|
Fröhlichkeit
|
||||||
|
Fülle
|
||||||
|
Füreinandereintreten
|
||||||
|
Gabe
|
||||||
|
Geduld
|
||||||
|
Gegenseitigkeit
|
||||||
|
Gemeinschaftsgeist
|
||||||
|
Geschenk
|
||||||
|
Geschlossenheit
|
||||||
|
Gesundheit
|
||||||
|
Glück
|
||||||
|
Glückseligkeit
|
||||||
|
Glückwunsch
|
||||||
|
Großzügigkeit
|
||||||
|
Güte
|
||||||
|
Harmonie
|
||||||
|
Hauptgewinn
|
||||||
|
Heiterkeit
|
||||||
|
Herzenswärme
|
||||||
|
Herzensgüte
|
||||||
|
Herzlichkeit
|
||||||
|
Hilfsbereitschaft
|
||||||
|
Hinwendung
|
||||||
|
Hochgefühl
|
||||||
|
Hoffnung
|
||||||
|
Höflichkeit
|
||||||
|
Idealismus
|
||||||
|
Intuition
|
||||||
|
Ideenreichtum
|
||||||
|
Idylle
|
||||||
|
Inspiration
|
||||||
|
Interesse
|
||||||
|
Jubel
|
||||||
|
Jugendlichkeit
|
||||||
|
Kompliment
|
||||||
|
Köstlichkeit
|
||||||
|
Kraft
|
||||||
|
Kreativität
|
||||||
|
Lächeln
|
||||||
|
Lachen
|
||||||
|
Leben
|
||||||
|
Lebenslust
|
||||||
|
Lebendigkeit
|
||||||
|
Lebensfreude
|
||||||
|
Lebhaftigkeit
|
||||||
|
Leichtigkeit
|
||||||
|
Leidenschaft
|
||||||
|
Liebe
|
||||||
|
Liebenswürdigkeit
|
||||||
|
Luxus
|
||||||
|
Munterkeit
|
||||||
|
Mut
|
||||||
|
Nähe
|
||||||
|
Offenheit
|
||||||
|
Optimismus
|
||||||
|
Originalität
|
||||||
|
Pracht
|
||||||
|
Prestige
|
||||||
|
Problemlösung
|
||||||
|
Pünktlichkeit
|
||||||
|
Reichhaltigkeit
|
||||||
|
Reichtum
|
||||||
|
Respekt
|
||||||
|
Richtigkeit
|
||||||
|
Rücksicht
|
||||||
|
Rücksichtnahme
|
||||||
|
Schönheit
|
||||||
|
Schutz
|
||||||
|
Seelenverwandtschaft
|
||||||
|
Selbstachtung
|
||||||
|
Selbstbestimmung
|
||||||
|
Selbstliebe
|
||||||
|
Selbstlosigkeit
|
||||||
|
Selbstsicherheit
|
||||||
|
Selbstwertgefühl
|
||||||
|
Selbstzufriedenheit
|
||||||
|
Seligkeit
|
||||||
|
Sicherheit
|
||||||
|
Solidarität
|
||||||
|
Sorgfalt
|
||||||
|
Spaß
|
||||||
|
Spontanität
|
||||||
|
Stärke
|
||||||
|
Sympathie
|
||||||
|
Toleranz
|
||||||
|
Treue
|
||||||
|
Überfluss
|
||||||
|
Überraschung
|
||||||
|
Überschwang
|
||||||
|
Überzeugung
|
||||||
|
Überzeugungskraft
|
||||||
|
Unbeschwertheit
|
||||||
|
Unterstützung
|
||||||
|
Verbesserung
|
||||||
|
Verbundenheit
|
||||||
|
Verehrung
|
||||||
|
Verlockung
|
||||||
|
Verspieltheit
|
||||||
|
Verständnis
|
||||||
|
Vertrauen
|
||||||
|
Vertrauenswürdigkeit
|
||||||
|
Vertrautheit
|
||||||
|
Vertraulichkeit
|
||||||
|
Vielfalt
|
||||||
|
Vielseitigkeit
|
||||||
|
Wahrhaftigkeit
|
||||||
|
Wärme
|
||||||
|
Willenskraft
|
||||||
|
Willkommen
|
||||||
|
Wohlbefinden
|
||||||
|
Wohlgefallen
|
||||||
|
Wohlstand
|
||||||
|
Wohltat
|
||||||
|
Wonne
|
||||||
|
Würde
|
||||||
|
Wunder
|
||||||
|
Zauber
|
||||||
|
Zufriedenheit
|
||||||
|
Zuneigung
|
||||||
|
Zusammengehörigkeit
|
||||||
|
Zusammenhalt
|
||||||
|
Zuverlässigkeit
|
||||||
|
Zuwendung|;
|
||||||
|
|
||||||
|
sub jstreedata {
|
||||||
|
my $c = shift->openapi->valid_input or return;
|
||||||
|
|
||||||
|
my ($src, $tab ) = _generatetestdata();
|
||||||
|
|
||||||
|
my @tree;
|
||||||
|
push @tree, @{$src};
|
||||||
|
push @tree, @{$tab};
|
||||||
|
|
||||||
|
return $c->render(json => { rc => 0, msg => 'OK', data => \@tree} );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _generatetestdata {
|
||||||
|
my ( $liste ) = @_;
|
||||||
|
my $src;
|
||||||
|
my $tab;
|
||||||
|
my $cnt = @liste;
|
||||||
|
|
||||||
|
my $first = int(rand( 10));
|
||||||
|
$first ++;
|
||||||
|
my $second = int(rand( 10));
|
||||||
|
$second ++;
|
||||||
|
my $third = int(rand( 10));
|
||||||
|
$third ++;
|
||||||
|
|
||||||
|
for my $f ( 1..$first ) {
|
||||||
|
my $word = int(rand( $cnt ));
|
||||||
|
push @{$src}, { parent => '#', id => $f, text => $liste[$word] };
|
||||||
|
|
||||||
|
for my $s ( 1..$second ) {
|
||||||
|
my $fs = $f * 10 + $s;
|
||||||
|
my $wordchild = int(rand( $cnt ));
|
||||||
|
push @{$tab}, { parent => $f, id => $fs, text => $liste[$wordchild] };
|
||||||
|
|
||||||
|
for my $t ( 1..$third ) {
|
||||||
|
my $fst = $fs * 10 + $t;
|
||||||
|
my $wordchild2 = int(rand( $cnt ));
|
||||||
|
push @{$tab}, { parent => $fs, id => $fst, text => $liste[$wordchild2] },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($src, $tab );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub datatablesdata {
|
||||||
|
my $c = shift->openapi->valid_input or return;
|
||||||
|
my $cnt = @liste;
|
||||||
|
|
||||||
|
my $rows = int(rand( 1000));
|
||||||
|
$rows ++;
|
||||||
|
my @data;
|
||||||
|
|
||||||
|
for my $d ( 0..$rows ) {
|
||||||
|
my $col1 = int(rand( $cnt ));
|
||||||
|
my $col2 = int(rand( $cnt ));
|
||||||
|
my $col3 = int(rand( $cnt ));
|
||||||
|
my $col4 = int(rand( $cnt ));
|
||||||
|
my $col5 = int(rand( $cnt ));
|
||||||
|
my $col6 = int(rand( $cnt ));
|
||||||
|
my $col7 = int(rand( $cnt ));
|
||||||
|
my $col8 = int(rand( $cnt ));
|
||||||
|
my $col9 = int(rand( $cnt ));
|
||||||
|
|
||||||
|
push @data, { col1 => $liste[$col1], col2 => $liste[$col2], col3 => $liste[$col3], col4 => $liste[$col4], col5 => $liste[$col5], col6 => $liste[$col6], col7 => $liste[$col7], col8 => $liste[$col8], col9 => $liste[$col9] };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return $c->render(json => { rc => 0, msg => 'OK', data => \@data} );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
sub listfiles {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $id = $self->stash('todoid');
|
||||||
|
|
||||||
|
my $sql = "SELECT idma,
|
||||||
|
size,
|
||||||
|
created,
|
||||||
|
info,
|
||||||
|
type,
|
||||||
|
name
|
||||||
|
FROM todo_master_files
|
||||||
|
WHERE id = ? and deleted = 0";
|
||||||
|
|
||||||
|
my ( $rc, $msg, $data ) = $self->dbxxx->query_hash_array( $sql, $id );
|
||||||
|
|
||||||
|
return $self->render( json => { rc => $rc, msg => $msg, data => $data} );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub blob {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $dbh = $self->dbxxx->get;
|
||||||
|
return (1, "kein DB-Handle bekommen") if !defined $dbh;
|
||||||
|
|
||||||
|
my $cursor = $dbh->prepare("SELECT file, type FROM todo_master_files where idma = ?");
|
||||||
|
$cursor->execute($self->stash('idma'));
|
||||||
|
my @data = $cursor->fetchrow;
|
||||||
|
$cursor->finish;
|
||||||
|
|
||||||
|
my $blob;
|
||||||
|
|
||||||
|
if ( defined $data[0]) {
|
||||||
|
$blob = encode_base64($data[0]);
|
||||||
|
} else {
|
||||||
|
$blob = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->dbxxx->free($dbh);
|
||||||
|
return $self->render( json => { blob => $blob, type => $data[1] });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub update {
|
||||||
|
# update eines eintrages der Mastertabelle
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $todoid = $self->stash('todoid');
|
||||||
|
return $self->render( json => { rc => 1, msg => "Die todoid fehlt"} ) if ( $todoid eq "" ) ;
|
||||||
|
|
||||||
|
my $daten = $self->req->json;
|
||||||
|
|
||||||
|
return $self->render( json => { rc => 1, msg => 'Programmname fehlt'} ) if ( !defined $daten->{name} or $daten->{name} eq "" );
|
||||||
|
return $self->render( json => { rc => 1, msg => 'Verantwortlichkeit zuweisen'} ) if ( !defined $daten->{who} or $daten->{who} eq "" );
|
||||||
|
return $self->render( json => { rc => 1, msg => 'Prozesszuweisung fehlt'} ) if ( !defined $daten->{prozess} or $daten->{prozess} eq "" );
|
||||||
|
return $self->render( json => { rc => 1, msg => 'Festellung definieren'} ) if ( !defined $daten->{todoinfo} or $daten->{todoinfo} eq "" );
|
||||||
|
return $self->render( json => { rc => 1, msg => 'ext fehlt'} ) if ( !defined $daten->{ext} );
|
||||||
|
|
||||||
|
my $sql = "UPDATE todo_master set
|
||||||
|
name = ?,
|
||||||
|
who = ?,
|
||||||
|
prozess = ?,
|
||||||
|
todoinfo = ?,
|
||||||
|
status = ?,
|
||||||
|
finishdate = ?,
|
||||||
|
closed = ?,
|
||||||
|
notes_master = ?,
|
||||||
|
targetdate_master = ?,
|
||||||
|
ext = ?
|
||||||
|
WHERE id = ?";
|
||||||
|
|
||||||
|
my ($rc, $msg ) = $self->dbxxx->query_res( $sql, $daten->{'name'},
|
||||||
|
$daten->{'who'},
|
||||||
|
$daten->{'prozess'},
|
||||||
|
$daten->{'todoinfo'},
|
||||||
|
$daten->{'status'},
|
||||||
|
$daten->{'finishdate'},
|
||||||
|
$daten->{'closed'},
|
||||||
|
$daten->{'notes_master'},
|
||||||
|
$daten->{'targetdate_master'},
|
||||||
|
$daten->{'ext'},
|
||||||
|
$todoid);
|
||||||
|
return $self->render(json => { rc => $rc, msg => $msg });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub insert_file {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $file = $self->param("file");
|
||||||
|
my $todoid = $self->param("id");
|
||||||
|
my $info = $self->param("info");
|
||||||
|
|
||||||
|
return $self->render(json => { rc => 1, msg => "Die todoid fehlt"} ) if ( $todoid eq "" ) ;
|
||||||
|
return $self->render(json => { rc => 1, msg => "Die Info fehlt"} ) if ( $info eq "" ) ;
|
||||||
|
return $self->render(json => { rc => 1, msg => 'file'}) if (!defined $file->asset->slurp or $file->asset->slurp eq "");
|
||||||
|
return $self->render(json => { rc => 1, msg => 'name'}) if (!defined $file->filename or $file->filename eq "");
|
||||||
|
return $self->render(json => { rc => 1, msg => 'type'}) if (!defined $file->headers->content_type or $file->headers->content_type eq "");
|
||||||
|
return $self->render(json => { rc => 1, msg => 'size'}) if (!defined $file->size or $file->size eq "");
|
||||||
|
|
||||||
|
my $sql = "INSERT INTO todo_master_files (id, file, type, name, size, info) VALUES (?,?,?,?,?,?)";
|
||||||
|
|
||||||
|
my ($rc, $msg ) = $self->dbxxx->query_res( $sql, $todoid, $file->asset->slurp, $file->headers->content_type, $file->filename, $file->size, $info );
|
||||||
|
|
||||||
|
return $self->render(template => 'main/todo_main');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub insert_datei {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $daten = $self->req->json;
|
||||||
|
my $id = $self->stash("todoid");
|
||||||
|
|
||||||
|
return $self->render(json => { rc => 1, msg => "Die ID fehlt"} ) if ( $id eq "" ) ;
|
||||||
|
my $filebase64 = $daten->{file};
|
||||||
|
$filebase64 =~ s/data:$daten->{type};base64//;
|
||||||
|
|
||||||
|
my $file = decode_base64($filebase64);
|
||||||
|
|
||||||
|
my $sql = "INSERT INTO todo_master_files (id, file, type, name, size, info) VALUES (?,?,?,?,?,?)";
|
||||||
|
|
||||||
|
my ($rc, $msg ) = $self->dbxxx->query_res( $sql, $id, $file, $daten->{type}, $daten->{name}, $daten->{size}, $daten->{info});
|
||||||
|
# oder mit der zurückgegebenen id
|
||||||
|
# my ($rc, $msg, $insid ) = $self->dbkoma->query_inserted_id( $sql, $id, $file, $daten->{type}, $daten->{name}, $daten->{size}, $daten->{info});
|
||||||
|
|
||||||
|
return $self->render(json => { rc => $rc, msg => $msg });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub deletefile {
|
||||||
|
my $self = shift;
|
||||||
|
my $id = $self->stash('idma');
|
||||||
|
return $self->render(json => { rc => 1, msg => "Die idma fehlt"}) if ( $id eq "" ) ;
|
||||||
|
|
||||||
|
my ($rc, $msg) = $self->dbxxx->query_res( "DELETE FROM todo_master_files WHERE idma = ?", $id);
|
||||||
|
return $self->render( json => { rc => $rc, msg => $msg });
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
10
xxx/app/lib/XxxApp/Controller/Menu.pm
Normal file
10
xxx/app/lib/XxxApp/Controller/Menu.pm
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package XxxApp::Controller::Menu;
|
||||||
|
use Mojo::Base 'Mojolicious::Controller';
|
||||||
|
|
||||||
|
sub jstreetemplate {
|
||||||
|
my $c = shift;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
30
xxx/app/lib/XxxApp/Helpers.pm
Normal file
30
xxx/app/lib/XxxApp/Helpers.pm
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package XxxApp::Helpers;
|
||||||
|
use Mojo::Base 'Mojolicious::Plugin';
|
||||||
|
|
||||||
|
sub register {
|
||||||
|
my ($self, $app, $args) = @_;
|
||||||
|
|
||||||
|
$app->helper('trim' => \&_trim);
|
||||||
|
$app->helper('debuglog' => \&_debuglog);
|
||||||
|
|
||||||
|
$app->log->info(sprintf('REGISTERED: %s', __PACKAGE__)) if !!$args->{verbose};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Führende und nachfolgende Leerzeichen entfernen
|
||||||
|
sub _trim {
|
||||||
|
my ($c, $str) = @_;
|
||||||
|
$str =~ s/^\s+|\s+$//g;
|
||||||
|
return $str;
|
||||||
|
};
|
||||||
|
|
||||||
|
sub _debuglog {
|
||||||
|
my ($c, $info) = @_;
|
||||||
|
if ( $c->config->{logging}->{level} =~ /trace|debug/ ) {
|
||||||
|
$c->log->debug($info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
53
xxx/app/lib/XxxApp/Main.pm
Normal file
53
xxx/app/lib/XxxApp/Main.pm
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package XxxApp::Main;
|
||||||
|
use Mojo::Base 'Mojolicious::Controller';
|
||||||
|
|
||||||
|
sub main {
|
||||||
|
my $self = shift;
|
||||||
|
return $self->render( template => 'main/main', title => 'Xxx', msg => '' );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub login {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# Grab the request parameters
|
||||||
|
my $username = $self->param('username');
|
||||||
|
my $password = $self->param('password');
|
||||||
|
|
||||||
|
my $developer = ($username eq 'developer' and $password eq 'wbdfgmnjke834dshf89w7rsdfsdjf' and $self->app->mode =~ /development/xms ) ? 1 : 0;
|
||||||
|
|
||||||
|
if ( $developer or $self->authenticate( $username, $password )) {
|
||||||
|
$self->session->{msg} = 'Login erfolgreich!';
|
||||||
|
push @{$self->session->{privs}}, 'user';
|
||||||
|
} else {
|
||||||
|
$self->logoff();
|
||||||
|
$self->session->{url} = '/login';
|
||||||
|
$self->session->{msg} = 'Fehler, das Login wurde abgewiesen!';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $self->redirect_to( defined $self->session->{url} ? $self->session->{url} : "/" );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub loginform {
|
||||||
|
my $self = shift;
|
||||||
|
return $self->render( title => 'xxx: Main', msg => '', sess => $self->session);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub userinfo {
|
||||||
|
my $self = shift;
|
||||||
|
return $self->render( title => 'xxx: Userinfo', sess => $self->session, msg => 'Du besitzt folgende Rechte:');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub getoff {
|
||||||
|
my $self = shift;
|
||||||
|
$self->logoff();
|
||||||
|
delete $self->session->{privs};
|
||||||
|
$self->session->{url} = '/';
|
||||||
|
$self->session->{msg} = 'bye, bye ...';
|
||||||
|
return $self->redirect_to( "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
1;
|
||||||
4
xxx/app/morbo.sh
Normal file
4
xxx/app/morbo.sh
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd "${0%/*}"
|
||||||
|
morbo -l http://*:hypnotoadport script/XxxApp -w templates -w lib -w *.conf -w *.json
|
||||||
39
xxx/app/navigation.conf
Normal file
39
xxx/app/navigation.conf
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
navigation => {
|
||||||
|
menu => [
|
||||||
|
# {
|
||||||
|
# text => 'QS',
|
||||||
|
# dropdown => [
|
||||||
|
# { text => 'Arbeitsvorrat', href => '/rech/qs' },
|
||||||
|
# ]
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# text => 'Recherchen',
|
||||||
|
# dropdown => [
|
||||||
|
# { text => 'Was steht zum Transport bereit?', href => '/rech/dropd' },
|
||||||
|
# { text => 'Was wird gerade transportiert?', href => '/rech/taken' },
|
||||||
|
# { text => 'Was wurde bereits transportiert?', href => '/rech/done' },
|
||||||
|
# ]
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# text => 'Auswertungen',
|
||||||
|
# dropdown => [
|
||||||
|
# { text => 'Transportstatistik', href => '/rept/statistik/0' },
|
||||||
|
# { text => 'QS-Statistik', href => '/rept/statistik/1' },
|
||||||
|
# ]
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# text => 'Konfiguration',
|
||||||
|
# priv => 'admin',
|
||||||
|
# dropdown => [
|
||||||
|
# { text => 'Standort festlegen', href => '/conf/stdort' },
|
||||||
|
# ]
|
||||||
|
# },
|
||||||
|
{
|
||||||
|
priv => 'user',
|
||||||
|
text => 'JSTree Template',
|
||||||
|
href => '/jstreetemplate',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
};
|
||||||
209
xxx/app/openapi.json
Normal file
209
xxx/app/openapi.json
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.0.0",
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "/api"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"version": "1.0",
|
||||||
|
"title": "Steffens Xxx API"
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"/jstreedata": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BasicAuth": [
|
||||||
|
"user"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Jstreetemplate"
|
||||||
|
],
|
||||||
|
"operationId": "jstreedata",
|
||||||
|
"x-mojo-name": "jstreetemplate_jstreedata",
|
||||||
|
"x-mojo-to": "api-jstreetemplate#jstreedata",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Daten für das JSTree",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/mls_default_response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/jstreedataupdate": {
|
||||||
|
"post": {
|
||||||
|
"summary": "nicht funktionierende UPDATE Route Controller existiert nicht",
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BasicAuth": [
|
||||||
|
"user"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Jstreetemplate"
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"description": "ident zum update",
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
},
|
||||||
|
"kat_id": {
|
||||||
|
"description": "Kategorie ident zum update",
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "Name der Kategorie",
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 3,
|
||||||
|
"maxLength": 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"operationId": "jstreedataupdate",
|
||||||
|
"x-mojo-name": "jstreetemplate_jstreedataupdate",
|
||||||
|
"x-mojo-to": "api-jstreetemplate#jstreedataupdate",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Daten für das JSTree",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/mls_default_response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/jstree/{id}/{kat_id}": {
|
||||||
|
"get": {
|
||||||
|
"summary": "nicht funktionierende GET Path Route Controller existiert nicht",
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BasicAuth": [
|
||||||
|
"user"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Jstreetemplate"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"name": "kat_id",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"operationId": "jstree",
|
||||||
|
"x-mojo-name": "jstreetemplate_jstree",
|
||||||
|
"x-mojo-to": "api-jstreetemplate#jstree",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Daten für das JSTree",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/mls_default_response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/datatablesdata": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BasicAuth": [
|
||||||
|
"user"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Jstreetemplate"
|
||||||
|
],
|
||||||
|
"operationId": "datatablesdata",
|
||||||
|
"x-mojo-name": "jstreetemplate_datatablesdata",
|
||||||
|
"x-mojo-to": "api-jstreetemplate#datatablesdata",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Daten für die Tabelle",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/mls_default_response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"securitySchemes": {
|
||||||
|
"BasicAuth": {
|
||||||
|
"type": "http",
|
||||||
|
"scheme": "basic"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schemas": {
|
||||||
|
"mls_default_response": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"rc": {
|
||||||
|
"type": "integer",
|
||||||
|
"enum": [
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"description": "0 - alles gut | 1 - Fehler"
|
||||||
|
},
|
||||||
|
"msg": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
34
xxx/app/public/css/jstreetemplate.css
Normal file
34
xxx/app/public/css/jstreetemplate.css
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
.jstree-anchor,
|
||||||
|
.jstree-ocl {
|
||||||
|
line-height: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jstree-anchor,
|
||||||
|
.vakata-context {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jstree-ocl {
|
||||||
|
margin-top: -2px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jstree-icon {
|
||||||
|
line-height: 16px !important;
|
||||||
|
transform: scale(1.4) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jstree-node {
|
||||||
|
min-height: 20px !important;
|
||||||
|
line-height: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.treedetail {
|
||||||
|
border: 0.5px black solid;
|
||||||
|
overflow: auto;
|
||||||
|
box-shadow: 0 0 5px #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table td,
|
||||||
|
.table th {
|
||||||
|
vertical-align: inherit;
|
||||||
|
}
|
||||||
1
xxx/app/public/css/jstreetemplate.min.css
vendored
Normal file
1
xxx/app/public/css/jstreetemplate.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.jstree-anchor,.jstree-ocl{line-height:20px!important}.jstree-anchor,.vakata-context{font-size:16px}.jstree-ocl{margin-top:-2px!important}.jstree-icon{line-height:16px!important;transform:scale(1.4)!important}.jstree-node{min-height:20px!important;line-height:20px!important}.treedetail{border:.5px #000 solid;overflow:auto;box-shadow:0 0 5px #ccc}.table td,.table th{vertical-align:inherit}
|
||||||
23
xxx/app/public/css/xxx.css
Normal file
23
xxx/app/public/css/xxx.css
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0px;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-brand {
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 2px;
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
1
xxx/app/public/css/xxx.min.css
vendored
Normal file
1
xxx/app/public/css/xxx.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
body{width:100%;overflow:hidden;min-height:0;line-height:1.1}.navbar{padding-top:0;padding-bottom:0;height:50px}.navbar-brand{padding-top:0;padding-bottom:0}.footer{position:fixed;bottom:2px;right:0}
|
||||||
BIN
xxx/app/public/images/powered.png
Normal file
BIN
xxx/app/public/images/powered.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
148
xxx/app/public/images/xxx.svg
Normal file
148
xxx/app/public/images/xxx.svg
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
sodipodi:docname="test.svg"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
id="svg8"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 84.957652 83.999998"
|
||||||
|
height="84mm"
|
||||||
|
width="84.957649mm"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient2657"
|
||||||
|
inkscape:swatch="solid">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#1d1c3a;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop2655" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient2651"
|
||||||
|
inkscape:swatch="solid">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop2649" />
|
||||||
|
</linearGradient>
|
||||||
|
<inkscape:perspective
|
||||||
|
sodipodi:type="inkscape:persp3d"
|
||||||
|
inkscape:vp_x="141.38559 : 23.558402 : 1"
|
||||||
|
inkscape:vp_y="0 : 1000 : 0"
|
||||||
|
inkscape:vp_z="84.423113 : 12.065813 : 1"
|
||||||
|
inkscape:persp3d-origin="42.478826 : 27.999999 : 1"
|
||||||
|
id="perspective1152" />
|
||||||
|
<rect
|
||||||
|
id="rect1932"
|
||||||
|
height="157.42708"
|
||||||
|
width="145.8988"
|
||||||
|
y="37.230656"
|
||||||
|
x="21.922619" />
|
||||||
|
<rect
|
||||||
|
id="rect1925"
|
||||||
|
height="154.78125"
|
||||||
|
width="152.5134"
|
||||||
|
y="30.994047"
|
||||||
|
x="18.331844" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2657"
|
||||||
|
id="linearGradient2653"
|
||||||
|
x1="127.3954"
|
||||||
|
y1="76.994209"
|
||||||
|
x2="193.25467"
|
||||||
|
y2="76.994209"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="1076"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-height="1017"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:current-layer="text1919"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:cy="147.98735"
|
||||||
|
inkscape:cx="168.44294"
|
||||||
|
inkscape:zoom="1.979899"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<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>
|
||||||
|
<g
|
||||||
|
transform="translate(-32.673336,-72.980634)"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Ebene 1">
|
||||||
|
<g
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:50.8px;line-height:1.25;font-family:Gazzarelli;-inkscape-font-specification:Gazzarelli;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||||
|
id="text1919"
|
||||||
|
aria-label="Ko Ma">
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:44.3654px;line-height:1.65;font-family:'Gill Sans MT';-inkscape-font-specification:'Gill Sans MT';letter-spacing:0px;word-spacing:0px;stroke-width:0.0700042"
|
||||||
|
x="36.218472"
|
||||||
|
y="147.49475"
|
||||||
|
id="text422"
|
||||||
|
transform="scale(1.0102584,0.98984575)"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan420"
|
||||||
|
style="font-size:44.3654px;stroke-width:0.0700042"
|
||||||
|
x="36.218472"
|
||||||
|
y="147.49475">SVG</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:19.7556px;line-height:1.65;font-family:'Gill Sans MT';-inkscape-font-specification:'Gill Sans MT';letter-spacing:0px;word-spacing:0px;stroke-width:0.0700042"
|
||||||
|
x="37.413837"
|
||||||
|
y="98.903824"
|
||||||
|
id="text426"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan424"
|
||||||
|
style="font-size:19.7556px;stroke-width:0.0700042"
|
||||||
|
x="37.413837"
|
||||||
|
y="98.903824">xxx</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2653);stroke-width:1.229;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.2;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="rect1300"
|
||||||
|
width="83.504608"
|
||||||
|
height="82.438667"
|
||||||
|
x="33.447392"
|
||||||
|
y="73.72715"
|
||||||
|
rx="7.6999998"
|
||||||
|
ry="9.1999989" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
style="font-size:9.87778px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1925)"
|
||||||
|
id="text1923" />
|
||||||
|
<text
|
||||||
|
style="font-size:9.87778px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1932)"
|
||||||
|
id="text1930"
|
||||||
|
xml:space="preserve" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 5.1 KiB |
174
xxx/app/public/js/jstreetemplate.js
Normal file
174
xxx/app/public/js/jstreetemplate.js
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
var tblmeta, nodeid, nodeselect, tree, table;
|
||||||
|
var w = {
|
||||||
|
autoclose: false,
|
||||||
|
type: 'danger',
|
||||||
|
top: false,
|
||||||
|
rc0: {
|
||||||
|
top: false,
|
||||||
|
slide: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var g = {
|
||||||
|
autoclose: false,
|
||||||
|
top: false,
|
||||||
|
rc0: {
|
||||||
|
top: false,
|
||||||
|
slide: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var option = '';
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
listtree();
|
||||||
|
// JQuery Tooltips aktivieren
|
||||||
|
$('[data-toggle="tooltip"]').tooltip({
|
||||||
|
delay: {
|
||||||
|
show: 1000,
|
||||||
|
hide: 100
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function listtree() {
|
||||||
|
$("#tree").jstree("destroy");
|
||||||
|
|
||||||
|
$.get($('#base_url').val() + '/api/jstreedata/', function (res) {
|
||||||
|
//if ($.popyrc1(res, w)) return;
|
||||||
|
$('#tree')
|
||||||
|
.on('changed.jstree', function (e, data) {
|
||||||
|
// klick auf einen Node und holen der Mitglieder
|
||||||
|
if (data.node !== undefined) {
|
||||||
|
nodeselect = data.node;
|
||||||
|
treecklick(data);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.jstree({
|
||||||
|
'core': {
|
||||||
|
"check_callback": function (operation, node, node_parent, node_position, more) {
|
||||||
|
// unterbinden des droppen wenn man nicht owner ist und wenn externe sachen gedropt werden
|
||||||
|
if (more && more.dnd && operation == 'move_node') {
|
||||||
|
if (treelock || ogsidstochange[node_parent.id] == undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"keyboard": false,
|
||||||
|
"cache": false,
|
||||||
|
'data': res.data
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"wholerow", "sort", "html_data"
|
||||||
|
],
|
||||||
|
}).on('ready.jstree', function (d) {
|
||||||
|
$('.baum').show();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.treedetail').css('height', 'calc(100vh - 130px)');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function treecklick(data) {
|
||||||
|
$('.words').hide();
|
||||||
|
if (data.node.parent != '#') {
|
||||||
|
$('.words').show();
|
||||||
|
gettabledata(data.node.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function gettabledata() {
|
||||||
|
|
||||||
|
table = $('#tbl-worlds').DataTable({
|
||||||
|
ajax: {
|
||||||
|
"type": "GET",
|
||||||
|
"url": $('#base_url').val() + '/api/datatablesdata',
|
||||||
|
dataSrc: function (json) {
|
||||||
|
return json.data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// fixedHeader: {
|
||||||
|
// header: true,
|
||||||
|
// },
|
||||||
|
// responsive: {
|
||||||
|
// details: false
|
||||||
|
// },
|
||||||
|
// scrollCollapse: true,
|
||||||
|
searching: true,
|
||||||
|
destroy: true,
|
||||||
|
deferRender: true,
|
||||||
|
// createdRow: function (row, data, index) {
|
||||||
|
// if (data.hidden == 1) {
|
||||||
|
// $(row).css('opacity', 0.2)
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
fixedColumns: {
|
||||||
|
left: 1,
|
||||||
|
right: 1
|
||||||
|
},
|
||||||
|
select: true,
|
||||||
|
// "stateSave": true,
|
||||||
|
// "stateLoadParams": function (settings, data) {
|
||||||
|
// console.log(settings)
|
||||||
|
// for (var i in data.columns) {
|
||||||
|
// data.columns[i].regex = false;
|
||||||
|
// data.columns[i].search = '';
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
data: 'col1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'col2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'col3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'col4',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'col5',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'col6',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'col7',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'col8',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'col9',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
info: true,
|
||||||
|
scrollX: true,
|
||||||
|
// bLengthChange: false,
|
||||||
|
scroller: true,
|
||||||
|
scrollY: 'calc(100vh - 320px)', // Höhe der Tabelle
|
||||||
|
"sDom": 'Bfrti',
|
||||||
|
language: {
|
||||||
|
sLoadingRecords: "Lade Wörter...",
|
||||||
|
sInfo: '_START_ bis _END_ von _TOTAL_ Wörter',
|
||||||
|
sInfoEmpty: '',
|
||||||
|
infoFiltered: '(gefiltert von _MAX_ Wörter)',
|
||||||
|
searchPlaceholder: 'Suche',
|
||||||
|
sZeroRecords: 'Keine Wörter vorhanden.',
|
||||||
|
sSearch: '',
|
||||||
|
oPaginate: {
|
||||||
|
sFirst: 'Erste',
|
||||||
|
sPrevious: '<',
|
||||||
|
sNext: '>',
|
||||||
|
sLast: 'Letzte'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
init();
|
||||||
|
});
|
||||||
1
xxx/app/public/js/jstreetemplate.min.js
vendored
Normal file
1
xxx/app/public/js/jstreetemplate.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
function init(){listtree(),$('[data-toggle="tooltip"]').tooltip({delay:{show:1e3,hide:100}})}function listtree(){$("#tree").jstree("destroy"),$.get($("#base_url").val()+"/api/jstreedata/",function(e){$("#tree").on("changed.jstree",function(e,t){void 0!==t.node&&(nodeselect=t.node,treecklick(t))}).jstree({core:{check_callback:function(e,t,a,o,r){if(r&&r.dnd&&"move_node"==e)return!treelock&&null!=ogsidstochange[a.id]},keyboard:!1,cache:!1,data:e.data},plugins:["wholerow","sort","html_data"]}).on("ready.jstree",function(e){$(".baum").show()}),$(".treedetail").css("height","calc(100vh - 130px)")})}function treecklick(e){$(".words").hide(),"#"!=e.node.parent&&($(".words").show(),gettabledata(e.node.id))}function gettabledata(){table=$("#tbl-worlds").DataTable({ajax:{type:"GET",url:$("#base_url").val()+"/api/datatablesdata",dataSrc:function(e){return e.data}},searching:!0,destroy:!0,deferRender:!0,fixedColumns:{left:1,right:1},select:!0,columns:[{data:"col1"},{data:"col2"},{data:"col3"},{data:"col4"},{data:"col5"},{data:"col6"},{data:"col7"},{data:"col8"},{data:"col9"}],info:!0,scrollX:!0,scroller:!0,scrollY:"calc(100vh - 320px)",sDom:"Bfrti",language:{sLoadingRecords:"Lade Wörter...",sInfo:"_START_ bis _END_ von _TOTAL_ Wörter",sInfoEmpty:"",infoFiltered:"(gefiltert von _MAX_ Wörter)",searchPlaceholder:"Suche",sZeroRecords:"Keine Wörter vorhanden.",sSearch:"",oPaginate:{sFirst:"Erste",sPrevious:"<",sNext:">",sLast:"Letzte"}}})}var tblmeta,nodeid,nodeselect,tree,table,w={autoclose:!1,type:"danger",top:!1,rc0:{top:!1,slide:!0}},g={autoclose:!1,top:!1,rc0:{top:!1,slide:!0}},option="";$(document).ready(function(){init()});
|
||||||
7
xxx/app/public/js/xxx.js
Normal file
7
xxx/app/public/js/xxx.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
function xxx() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
new xxx();
|
||||||
|
});
|
||||||
11
xxx/app/script/XxxApp
Normal file
11
xxx/app/script/XxxApp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use FindBin;
|
||||||
|
BEGIN { unshift @INC, "$FindBin::Bin/../lib" }
|
||||||
|
use Mojolicious::Commands;
|
||||||
|
|
||||||
|
# Start command line interface for application
|
||||||
|
Mojolicious::Commands->start_app('XxxApp');
|
||||||
108
xxx/app/t/01_routes.t
Normal file
108
xxx/app/t/01_routes.t
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
|
||||||
|
print "Test: $0\n";
|
||||||
|
|
||||||
|
use Mojo::Base -strict;
|
||||||
|
use Mojo::JSON qw(decode_json);
|
||||||
|
use Modern::Perl;
|
||||||
|
use Test::More;
|
||||||
|
use Test::Mojo;
|
||||||
|
use DBI;
|
||||||
|
use Data::Printer;
|
||||||
|
|
||||||
|
#my $dbh = DBI->connect('DBI:mysql:prod:ares', '', '') or die ('Fehler beim Verbinden mit der Datenbank');
|
||||||
|
my $t = Test::Mojo->new('XxxApp');
|
||||||
|
|
||||||
|
$t->app->log->level('info');
|
||||||
|
$t->app->ua->max_redirects(1);
|
||||||
|
|
||||||
|
subtest 'prod konfig test' => sub {
|
||||||
|
my $konf = do '../deb/prod/xxx_app.conf';
|
||||||
|
|
||||||
|
is exists $konf->{secret}, 1, 'secret = exists';
|
||||||
|
is $konf->{htlib}, "/var/local/htlib", 'htlib = /var/local/htlib';
|
||||||
|
|
||||||
|
is $konf->{hypnotoad}->{pid_file}, "/run/xxx.pid", 'hypnotoad->pid_file = /run/xxx.pid';
|
||||||
|
is $konf->{hypnotoad}->{workers}, 4, 'hypnotoad->workers = 4';
|
||||||
|
is $konf->{hypnotoad}->{proxy}, 1, 'hypnotoad->proxy = 1';
|
||||||
|
|
||||||
|
is $konf->{logging}->{enable}, 1, 'logging->enable = 1';
|
||||||
|
is $konf->{logging}->{facility}, 'local7', 'logging->facility = local7';
|
||||||
|
is $konf->{logging}->{ident}, 'xxx', 'logging->ident = xxx';
|
||||||
|
is $konf->{logging}->{level}, 'info', 'logging->level = info';
|
||||||
|
is $konf->{logging}->{only_syslog}, 1, 'logging->only_syslog = 1';
|
||||||
|
};
|
||||||
|
|
||||||
|
subtest 'Routes', sub {
|
||||||
|
note '/';
|
||||||
|
$t->get_ok('/')
|
||||||
|
->status_is(200)
|
||||||
|
->content_like(qr'<img class="mypic" src="\/images\/xxx.svg">', 'SVG is availble')
|
||||||
|
->header_isnt('Server' => 'Mojolicious');
|
||||||
|
|
||||||
|
note '/login';
|
||||||
|
$t->get_ok('/login')
|
||||||
|
->status_is(200)
|
||||||
|
->content_like(qr'placeholder="Anmeldename"', 'Anmeldename is availble')
|
||||||
|
->content_like(qr'placeholder="Passwort"', 'Passwort is availble');
|
||||||
|
|
||||||
|
note '/api/jstreedata no permission';
|
||||||
|
$t->get_ok('/api/jstreedata')
|
||||||
|
->status_is(401);
|
||||||
|
|
||||||
|
note '/api/datatablesdata no permission';
|
||||||
|
$t->get_ok('/api/datatablesdata')
|
||||||
|
->status_is(401);
|
||||||
|
|
||||||
|
# on this point we have a session
|
||||||
|
note 'with Login no AD';
|
||||||
|
$t->post_ok(
|
||||||
|
'/login' => form => { username => 'developer', password => 'wbdfgmnjke834dshf89w7rsdfsdjf' }
|
||||||
|
);
|
||||||
|
$t->status_is(302);
|
||||||
|
|
||||||
|
note '/api/jstreedata';
|
||||||
|
$t->get_ok('/api/jstreedata')
|
||||||
|
->status_is(200)
|
||||||
|
->json_is( '/msg' => 'OK', 'msg: OK' )
|
||||||
|
->json_is( '/rc' => 0, 'rc: 0' );
|
||||||
|
my $res = $t->tx->res->json;
|
||||||
|
is ref $res->{data}, 'ARRAY', 'data is ARRAY reference';
|
||||||
|
is exists $res->{data}[0]->{id}, 1, 'data has id';
|
||||||
|
is exists $res->{data}[0]->{parent}, 1, 'data has firstname';
|
||||||
|
is exists $res->{data}[0]->{text}, 1, 'data has name';
|
||||||
|
|
||||||
|
note '/api/datatablesdata';
|
||||||
|
$t->get_ok('/api/datatablesdata')
|
||||||
|
->status_is(200)
|
||||||
|
->json_is( '/msg' => 'OK', 'msg: OK' )
|
||||||
|
->json_is( '/rc' => 0, 'rc: 0' );
|
||||||
|
$res = $t->tx->res->json;
|
||||||
|
is ref $res->{data}, 'ARRAY', 'data is ARRAY reference';
|
||||||
|
is exists $res->{data}[0]->{col1}, 1, 'data has col1';
|
||||||
|
is exists $res->{data}[0]->{col2}, 1, 'data has col2';
|
||||||
|
is exists $res->{data}[0]->{col3}, 1, 'data has col3';
|
||||||
|
is exists $res->{data}[0]->{col4}, 1, 'data has col4';
|
||||||
|
is exists $res->{data}[0]->{col5}, 1, 'data has col5';
|
||||||
|
is exists $res->{data}[0]->{col6}, 1, 'data has col6';
|
||||||
|
is exists $res->{data}[0]->{col7}, 1, 'data has col7';
|
||||||
|
is exists $res->{data}[0]->{col8}, 1, 'data has col8';
|
||||||
|
is exists $res->{data}[0]->{col9}, 1, 'data has col9';
|
||||||
|
is exists $res->{data}[0]->{col10}, '', 'data has no col10';
|
||||||
|
};
|
||||||
|
|
||||||
|
subtest 'POST requestBody required must True', sub {
|
||||||
|
$t->get_ok('/api');
|
||||||
|
$t->status_is(200);
|
||||||
|
|
||||||
|
my $res = $t->tx->res->json;
|
||||||
|
|
||||||
|
for my $path ( keys %{$res->{paths}} ) {
|
||||||
|
my $pa = $res->{paths}->{$path};
|
||||||
|
if ( $pa->{post}->{requestBody} ) {
|
||||||
|
is $pa->{post}->{requestBody}->{required}, 1, $path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
done_testing();
|
||||||
119
xxx/app/templates/layouts/index.html.ep
Normal file
119
xxx/app/templates/layouts/index.html.ep
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title><%= $title %></title>
|
||||||
|
|
||||||
|
%= stylesheet '/htlib/bootstrap/5.3.3/css/bootstrap.min.css'
|
||||||
|
%= stylesheet '/htlib/fontawesome/6.4.0/css/all.min.css'
|
||||||
|
%= stylesheet '/htlib/jquery-datatables/2.1.8/css/dataTables.bootstrap4.min.css'
|
||||||
|
%= stylesheet '/htlib/jquery-datatables/extensions/Buttons/3.1.2/css/buttons.dataTables.min.css'
|
||||||
|
%= stylesheet '/htlib/jquery-datatables/extensions/Scroller/2.4.3/css/scroller.bootstrap4.min.css'
|
||||||
|
%= stylesheet '/htlib/jquery-datatables/extensions/FixedColumns/5.0.3/css/fixedColumns.dataTables.min.css'
|
||||||
|
%= stylesheet '/htlib/jquery-ui/1.13.2/jquery-ui.min.css'
|
||||||
|
%= stylesheet '/css/xxx.min.css'
|
||||||
|
|
||||||
|
<style>
|
||||||
|
% if ( $self->config->{test} ) { # einfärben der Kopfzeile wenn Programm im Developermodus läuft
|
||||||
|
.navbar {
|
||||||
|
background-color: rgb(255, 215, 215) !important;
|
||||||
|
}
|
||||||
|
% }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Standard-Navbar -->
|
||||||
|
|
||||||
|
<nav class="navbar navbar-expand-sm navbar-light bg-light">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="navbar-brand" href="<%= $self->config->{mlandshome} %>">
|
||||||
|
<img src="<%= url_for('/htlib/mlands/img/mlands.svg') %>">
|
||||||
|
</a>
|
||||||
|
<a class="navbar-brand ukraine" href="/" style="margin-right: 0.5rem;">
|
||||||
|
<img src="<%= url_for('/images/xxx.svg') %>" width="40px">
|
||||||
|
</a>
|
||||||
|
<a class="navbar-brand" style="font-size: 1.4rem;" href="<%= url_for('/') %>">Xxx</a>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarText">
|
||||||
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||||
|
<%== nav($self->config->{navigation}->{menu}) %>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
|
||||||
|
<ul class="navbar-nav nav">
|
||||||
|
% if ( $self->session->{auth_data}) {
|
||||||
|
% my $username = $self->session->{auth_data} =~ s/@[^@]*$//r;
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a aria-expanded="false" aria-haspopup="true" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" id="navbarDropdown" role="button">
|
||||||
|
%== $username
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<ul class="dropdown-menu dropdown-menu-lg-right">
|
||||||
|
%# Benutzerinformatioen
|
||||||
|
<li><a href="<%= url_for('/userinfo') %>" class="dropdown-item">
|
||||||
|
<span class="fas fa-user-circle" style="color:#777;"></span>
|
||||||
|
Info
|
||||||
|
</a></li>
|
||||||
|
<li class="dropdown-divider"></li>
|
||||||
|
%# Abmelden
|
||||||
|
<li><a class="dropdown-item"href="<%= url_for('/getoff') %>">
|
||||||
|
<span class="fas fa-cloud-moon" style="color:#777;"></span>
|
||||||
|
Abmelden
|
||||||
|
</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
% } else {
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="<%= url_for('/login') %>" class="nav-link">
|
||||||
|
Anmelden
|
||||||
|
<span class="fas fa-lock" style="color:#777;"></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
% }
|
||||||
|
<li>
|
||||||
|
<a href="<%= url_for('/about') %>" class="nav-link">
|
||||||
|
über
|
||||||
|
<span class="fas fa-info-sign" style="color:#777;"></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- externe Bibliotheken -->
|
||||||
|
%= javascript '/htlib/jquery/3.7.1/jquery.min.js'
|
||||||
|
%= javascript '/htlib/jquery-ui/1.13.2/jquery-ui.min.js'
|
||||||
|
%= javascript '/htlib/bootstrap/5.3.3/js/bootstrap.bundle.min.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/2.1.8/js/dataTables.min.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/2.1.8/js/dataTables.bootstrap4.min.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/extensions/Select/2.1.0/js/dataTables.select.min.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/extensions/Select/2.1.0/js/select.bootstrap4.min.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/extensions/Buttons/3.1.2/js/dataTables.buttons.min.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/extensions/Buttons/3.1.2/js/buttons.colVis.min.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/extensions/JSZip/3.10.1/jszip.min.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/extensions/pdfmake/0.2.7/pdfmake.min.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/extensions/pdfmake/0.2.7/vfs_fonts.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/extensions/Buttons/3.1.2/js/buttons.html5.min.js'
|
||||||
|
%= javascript "/htlib/jquery-datatables/extensions/FixedColumns/5.0.3/js/dataTables.fixedColumns.min.js"
|
||||||
|
%= javascript '/htlib/jquery-datatables/extensions/Scroller/2.4.3/js/dataTables.scroller.min.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/extensions/Scroller/2.4.3/js/scroller.bootstrap4.min.js'
|
||||||
|
%= javascript '/htlib/jquery-datatables/date-de/date-de.min.js'
|
||||||
|
|
||||||
|
%= javascript "/htlib/mlands/js/popy.min.js"
|
||||||
|
|
||||||
|
<%= content %>
|
||||||
|
|
||||||
|
<input type="hidden" id="base_url" value="<%= $self->config->{prefix} %>">
|
||||||
|
<input type="hidden" id="koma-urlbase" value="<%= $self->config->{base}->{koma}->{url} %>">
|
||||||
|
<!-- FOOTER -->
|
||||||
|
<footer class="footer">
|
||||||
|
% use POSIX qw(strftime);
|
||||||
|
% my $year = strftime('%Y', localtime);
|
||||||
|
<div class="container-fluid text-muted text-right">
|
||||||
|
<small>Xxx v<%= $self->config->{version} %> • © 2003-<%= $year %> ml&s Gmbh & Co. KG</small>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
16
xxx/app/templates/main/about.html.ep
Normal file
16
xxx/app/templates/main/about.html.ep
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
% layout 'index';
|
||||||
|
|
||||||
|
<div class="container pt-3">
|
||||||
|
<div class="jumbotron">
|
||||||
|
<p>Entwickler: <br></p>
|
||||||
|
<h4><p></p>
|
||||||
|
<p>Version <%= $self->config->{version} %><p>
|
||||||
|
<p>powered by</p>
|
||||||
|
<img src="<%= url_for('/images/powered.png') %>"><br>
|
||||||
|
<p><a href="https://mojolicious.org/" target="_blank">Mojolicious</a> <%== 'V'.$Mojolicious::VERSION .', <a href="https://perl.org/" target="_blank">Perl</a> '.ucfirst $^V .', ' %><span id="version"></span></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$('#version').html('<a href="https://jquery.com/" target="_blank">jQuery</a> V' + $().jquery + ', <a href="https://datatables.net/" target="_blank">Datatables</a> V' + $.fn.dataTable.version + ', <a href="https://getbootstrap.com/docs/3.3/" target="_blank">Bootstrap</a> V' + bootstrap.Tooltip.VERSION );
|
||||||
|
</script>
|
||||||
35
xxx/app/templates/main/loginform.html.ep
Normal file
35
xxx/app/templates/main/loginform.html.ep
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
% layout 'index';
|
||||||
|
|
||||||
|
<title>Xxx: Login</title>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
%= form_for '/login' => {format => 'txt'} => (method => 'POST', class => 'form-horizontal', id => 'form_login') => begin
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<div class="row" style="margin-top:25vh;">
|
||||||
|
<div class="col-4" style="margin:0 auto 0 auto;float:none;">
|
||||||
|
% if ( defined $self->session->{msg} ) {
|
||||||
|
<h4>
|
||||||
|
% if ( $self->session->{msg} =~ /Fehler|Sorry/ ) {
|
||||||
|
<span class="text-danger">
|
||||||
|
% } else {
|
||||||
|
<span class="text-info">
|
||||||
|
% }
|
||||||
|
<%= $self->session->{msg} %>
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
% }
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-group-text"><i class="fas fa-user"></i></div>
|
||||||
|
<input autocomplete="off" autofocus="" class="form-control" id="id_username" name="username" placeholder="Anmeldename" required="" type="text">
|
||||||
|
</div>
|
||||||
|
<div class="input-group pt-3">
|
||||||
|
<div class="input-group-text"><i class="fas fa-lock"></i></div>
|
||||||
|
<input class="form-control" id="id_password" name="password" placeholder="Passwort" required="" type="password" value="">
|
||||||
|
</div>
|
||||||
|
<div class="pt-3"><input class="btn btn-lg btn-primary btn-block" type="submit" value="Anmelden"></div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
% end
|
||||||
|
|
||||||
|
</div>
|
||||||
16
xxx/app/templates/main/main.html.ep
Normal file
16
xxx/app/templates/main/main.html.ep
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
% layout 'index';
|
||||||
|
<style>
|
||||||
|
.mypic {
|
||||||
|
height: calc(100vh - 180px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card m-2">
|
||||||
|
<div class="row p-3">
|
||||||
|
<div>Willkommen bei</div>
|
||||||
|
</div>
|
||||||
|
<div class="text-center pb-3">
|
||||||
|
<img class="mypic" src="/images/xxx.svg">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
23
xxx/app/templates/main/userinfo.html.ep
Normal file
23
xxx/app/templates/main/userinfo.html.ep
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
% layout 'index';
|
||||||
|
|
||||||
|
<title>*Temp*::Userinfo</title>
|
||||||
|
|
||||||
|
<div class="jumbotron" style="margin-top:5vh;">
|
||||||
|
|
||||||
|
% if ( defined $msg ) {
|
||||||
|
<h2>
|
||||||
|
% if ( $msg =~ /Fehler|Sorry/ ) {
|
||||||
|
<span class="text-danger">
|
||||||
|
% } else {
|
||||||
|
<span class="text-info">
|
||||||
|
% }
|
||||||
|
<%= $msg %></span></h2>
|
||||||
|
% }
|
||||||
|
|
||||||
|
% if ( defined $sess->{privs} ) {
|
||||||
|
% foreach my $s ( @{$sess->{privs} } ) {
|
||||||
|
<p> Gruppe: <%= $s %></p>
|
||||||
|
% }
|
||||||
|
% }
|
||||||
|
|
||||||
|
</div>
|
||||||
43
xxx/app/templates/menu/jstreetemplate.html.ep
Normal file
43
xxx/app/templates/menu/jstreetemplate.html.ep
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
% layout 'index';
|
||||||
|
|
||||||
|
%= stylesheet '/htlib/jquery-jstree/3.3.17/themes/default/style.min.css'
|
||||||
|
%= stylesheet '/css/jstreetemplate.min.css'
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row p-2">
|
||||||
|
<div class="col-3">
|
||||||
|
<label class="col-form-label text-right">Daten:</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row pr-3 baum" style="display: none">
|
||||||
|
<div class="col-3">
|
||||||
|
<div class="treedetail" id="tree"></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-9 treedetail">
|
||||||
|
<div class="words" style="display: none">
|
||||||
|
<div class="row p-3">
|
||||||
|
<label class="col-form-label pb-0">Wörter</label>
|
||||||
|
</div>
|
||||||
|
<table class="table table-bordered table-sm" width="100%" id="tbl-worlds">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-center">Spalte1</th>
|
||||||
|
<th class="text-center">Spalte 2</th>
|
||||||
|
<th class="text-center">Spalte 3</th>
|
||||||
|
<th class="text-center">Spalte 4</th>
|
||||||
|
<th class="text-center">Spalte 5</th>
|
||||||
|
<th class="text-center">Spalte 6</th>
|
||||||
|
<th class="text-center">Spalte 7</th>
|
||||||
|
<th class="text-center">Spalte 8</th>
|
||||||
|
<th class="text-center">Spalte 9</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
%= javascript '/htlib/jquery-jstree/3.3.17/jstree.min.js'
|
||||||
|
%= javascript "/js/jstreetemplate.min.js?v=". $self->config->{version}
|
||||||
13
xxx/app/test.sh
Normal file
13
xxx/app/test.sh
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#export PERL5LIB=`pwd`
|
||||||
|
|
||||||
|
if [[ $1 == "all" ]]; then
|
||||||
|
prove -l t/*.t
|
||||||
|
else
|
||||||
|
if [[ -f t/$1.t ]]; then
|
||||||
|
prove -l -v t/$1.t
|
||||||
|
else
|
||||||
|
prove -l -v t/*.t
|
||||||
|
fi
|
||||||
|
fi
|
||||||
35
xxx/app/xxx_app.conf
Normal file
35
xxx/app/xxx_app.conf
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
# zus_config => '/etc/mlands/configs/xxx.conf', # um externe konfigs mit Passwörtern zu laden
|
||||||
|
|
||||||
|
htlib => '/var/local/htlib',
|
||||||
|
mlandshome => 'http://intranet.mlands.com:9673/Z/',
|
||||||
|
komaurl => 'http://intra/koma',
|
||||||
|
smtpserver => 'mail.mlands.com',
|
||||||
|
mail => 'Xxx@mlands.com',
|
||||||
|
|
||||||
|
secret => 'mojoappsecret',
|
||||||
|
|
||||||
|
# DB Pools
|
||||||
|
# db => {
|
||||||
|
# xxx => {
|
||||||
|
# dsn => 'DBI:mysql:test:localhost',
|
||||||
|
# username => '',
|
||||||
|
# password => '',
|
||||||
|
# verbose => 0,
|
||||||
|
# },
|
||||||
|
# },
|
||||||
|
|
||||||
|
privileges => {
|
||||||
|
# user => wird bei erfolgreicher Anmeldung den Privs hinzugefügt
|
||||||
|
},
|
||||||
|
|
||||||
|
logging => {
|
||||||
|
level => 'debug',
|
||||||
|
facility => 'local7',
|
||||||
|
enable => 1,
|
||||||
|
only_syslog => 0,
|
||||||
|
#access_log => 'v1', #bisher nicht änderbar
|
||||||
|
ident => 'xxx',
|
||||||
|
#color => 1, #erst ab Mojolicious 9.01
|
||||||
|
}
|
||||||
|
}
|
||||||
1
xxx/deb/DEBIAN/conffiles
Normal file
1
xxx/deb/DEBIAN/conffiles
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/opt/xxx/app/xxx_app.conf
|
||||||
10
xxx/deb/DEBIAN/control
Normal file
10
xxx/deb/DEBIAN/control
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Package: steffen-xxx
|
||||||
|
Version: __VERSION__
|
||||||
|
Section: unknown
|
||||||
|
Priority: optional
|
||||||
|
Architecture: all
|
||||||
|
Depends: libmojolicious-perl >= (9.39), libev-perl, libsteffen-mojoplug-authorization-perl, libsteffen-mojoplug-navhelper-perl, libsteffen-mojoplug-syslog-perl, libmojolicious-plugin-openapi-perl, libsteffen-mojoplug-swaggerui-perl
|
||||||
|
Installed-Size: __VERSION__
|
||||||
|
Maintainer: Steffen Junge <steffen.junge@gmx.de>
|
||||||
|
Description: wofuer
|
||||||
|
A HTTP Daemon for the steffen xxx Webservice.
|
||||||
7
xxx/deb/DEBIAN/postinst
Normal file
7
xxx/deb/DEBIAN/postinst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Startskript aktivieren
|
||||||
|
systemctl daemon-reload
|
||||||
|
/bin/systemd-sysusers
|
||||||
|
/bin/systemd-tmpfiles --create
|
||||||
|
systemctl enable --now steffen-xxx.service
|
||||||
6
xxx/deb/DEBIAN/prerm
Normal file
6
xxx/deb/DEBIAN/prerm
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
# Daemon stoppen und deaktivieren
|
||||||
|
systemctl stop steffen-xxx.service || true
|
||||||
|
systemctl disable steffen-xxx.service || true
|
||||||
52
xxx/deb/pbuild.sh
Normal file
52
xxx/deb/pbuild.sh
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
cd "${0%/*}" || exit
|
||||||
|
SCRIPTPATH=$(pwd)
|
||||||
|
cd ../app || exit
|
||||||
|
rc=0
|
||||||
|
prove -l -v t/*.t
|
||||||
|
rc=$?
|
||||||
|
cd "$SCRIPTPATH" || exit
|
||||||
|
|
||||||
|
if [ $rc -eq 0 ] ; then
|
||||||
|
# Jahr in dem das Programm begonnen wurde
|
||||||
|
createyear=mojocreateyear
|
||||||
|
currentyear=$(date +'%Y')
|
||||||
|
major=$((currentyear-createyear))
|
||||||
|
minor=$(date +'%m')
|
||||||
|
|
||||||
|
progpfad="opt/xxx/"
|
||||||
|
apppfad="app/lib/XxxApp.pm"
|
||||||
|
workdir=/tmp/$USER_$(pwd | sed 's/^.*\///')
|
||||||
|
rm -Rf "${workdir:?}/*"
|
||||||
|
mkdir -p "$workdir"
|
||||||
|
# Daten in workdir sysnchronisieren
|
||||||
|
rsync -Ca ./DEBIAN "$workdir/"
|
||||||
|
rsync -Ca ./usr "$workdir/"
|
||||||
|
mkdir -p "$workdir/opt"
|
||||||
|
rsync -Ca ../app "$workdir/$progpfad"
|
||||||
|
|
||||||
|
# Test entfernen
|
||||||
|
rm -r "$workdir/$progpfad/app/t"
|
||||||
|
rm "$workdir/$progpfad/app/test.sh"
|
||||||
|
|
||||||
|
# config aus prod ordner kopieren
|
||||||
|
cp -ar ./prod/* "$workdir/$progpfad/app"
|
||||||
|
|
||||||
|
# Revision holen
|
||||||
|
REV=$(git rev-list --count --all)
|
||||||
|
VER="$major.$minor.$REV"
|
||||||
|
|
||||||
|
# Version in die startup app.pm und control eintragen
|
||||||
|
sed -i "s@__VERSION__@$VER@g" "$workdir/DEBIAN/control"
|
||||||
|
sed -i "s@__VERSION__@$VER@g" "$workdir/$progpfad/$apppfad"
|
||||||
|
|
||||||
|
SIZE=$(du -h -k --max-depth=0 "$workdir" | cut -d '/' -f1)
|
||||||
|
sed -i "s@__SIZE__@$SIZE@g" "$workdir/DEBIAN/control"
|
||||||
|
echo "Version: $VER, Size: $SIZE"
|
||||||
|
|
||||||
|
chmod -R g-s "$workdir"
|
||||||
|
# paket erstellen
|
||||||
|
fakeroot dpkg-deb -b "$workdir" ./
|
||||||
|
else
|
||||||
|
echo "TESTs failed no package created"
|
||||||
|
fi
|
||||||
40
xxx/deb/prod/xxx_app.conf
Normal file
40
xxx/deb/prod/xxx_app.conf
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
# zus_config => '/etc/mlands/configs/xxx.conf', # um externe konfigs mit Passwörtern zu laden
|
||||||
|
|
||||||
|
htlib => '/var/local/htlib',
|
||||||
|
|
||||||
|
secret => 'mojoappsecret',
|
||||||
|
|
||||||
|
# dieser Teil wandert in die Datei unter zus_config
|
||||||
|
# DB Pools
|
||||||
|
# db => {
|
||||||
|
# xxx => {
|
||||||
|
# dsn => 'DBI:mysql:test:ares',
|
||||||
|
# username => '',
|
||||||
|
# password => '',
|
||||||
|
# verbose => 0,
|
||||||
|
# },
|
||||||
|
# },
|
||||||
|
|
||||||
|
hypnotoad => {
|
||||||
|
listen => ['http://*:hypnotoadport'],
|
||||||
|
workers => 4,
|
||||||
|
pid_file => '/run/xxx.pid',
|
||||||
|
proxy => 1
|
||||||
|
},
|
||||||
|
|
||||||
|
privileges => {
|
||||||
|
# user => wird bei erfolgreicher Anmeldung den Privs hinzugefügt
|
||||||
|
# admin => 'xxx_admin::xgroups',
|
||||||
|
},
|
||||||
|
|
||||||
|
logging => {
|
||||||
|
level => 'info',
|
||||||
|
facility => 'local7',
|
||||||
|
enable => 1,
|
||||||
|
only_syslog => 1,
|
||||||
|
#access_log => 'v1', #bisher nicht änderbar
|
||||||
|
ident => 'xxx',
|
||||||
|
#color => 1, #erst ab Mojolicious 9.01
|
||||||
|
}
|
||||||
|
}
|
||||||
41
xxx/deb/usr/lib/systemd/system/steffen-xxx.service
Normal file
41
xxx/deb/usr/lib/systemd/system/steffen-xxx.service
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=steffen Xxx/Rfs Webservice
|
||||||
|
After=network.target syslog.socket
|
||||||
|
StartLimitBurst=5
|
||||||
|
StartLimitIntervalSec=10
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
User=steffen-xxx
|
||||||
|
Group=webapps
|
||||||
|
WorkingDirectory=/opt/xxx/app
|
||||||
|
ExecStart=/usr/bin/hypnotoad ./script/XxxApp
|
||||||
|
ExecReload=/usr/bin/hypnotoad ./script/XxxApp
|
||||||
|
Restart=on-failure
|
||||||
|
PIDFile=/run/xxx.pid
|
||||||
|
KillMode=process
|
||||||
|
|
||||||
|
# Optional hardening to improve security
|
||||||
|
ReadWritePaths=/opt/xxx
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
MemoryDenyWriteExecute=true
|
||||||
|
PrivateDevices=yes
|
||||||
|
PrivateTmp=yes
|
||||||
|
ProtectHome=yes
|
||||||
|
#ProtectSystem=strict
|
||||||
|
ProtectControlGroups=true
|
||||||
|
#RestrictSUIDSGID=true
|
||||||
|
RestrictRealtime=true
|
||||||
|
LockPersonality=true
|
||||||
|
#ProtectKernelLogs=true
|
||||||
|
ProtectKernelTunables=true
|
||||||
|
#ProtectHostname=true
|
||||||
|
ProtectKernelModules=true
|
||||||
|
PrivateUsers=true
|
||||||
|
#ProtectClock=true
|
||||||
|
SystemCallArchitectures=native
|
||||||
|
SystemCallErrorNumber=EPERM
|
||||||
|
SystemCallFilter=@system-service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
5
xxx/deb/usr/lib/sysusers.d/steffen-xxx.conf
Normal file
5
xxx/deb/usr/lib/sysusers.d/steffen-xxx.conf
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# see https://www.freedesktop.org/software/systemd/man/latest/sysusers.d.html
|
||||||
|
# Type Name ID GECOS Home Shell
|
||||||
|
g webapps - -
|
||||||
|
u steffen-xxx - "steffen Xxx" /opt/xxx -
|
||||||
|
m steffen-xxx webapps
|
||||||
3
xxx/deb/usr/lib/tmpfiles.d/steffen-xxx.conf
Normal file
3
xxx/deb/usr/lib/tmpfiles.d/steffen-xxx.conf
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# see https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html
|
||||||
|
# Type Path Mode User Group Age Argument
|
||||||
|
Z /opt/xxx - steffen-xxx steffen-xxx
|
||||||
Reference in New Issue
Block a user