From 48a649c8e6fca04a0a7de20110e6a8427e9da659 Mon Sep 17 00:00:00 2001
From: ulrich <undisclosed>
Date: Thu, 06 Apr 2017 15:26:35 +0000
Subject: [PATCH] Profil hinzugefuegt

---
 src/java/de/uhilger/um/api/Profil.java |   75 +++++++++
 web/WEB-INF/web.xml                    |   33 ++++
 web/ui/index.html                      |    1 
 src/java/logging.properties            |   68 ++++++++
 web/WEB-INF/sql.properties             |    3 
 web/profil/stile.css                   |   42 +++++
 web/profil/index.html                  |   72 +++++++++
 web/profil/ui.js                       |  129 ++++++++++++++++
 web/WEB-INF/create_database.sql        |    1 
 9 files changed, 424 insertions(+), 0 deletions(-)

diff --git a/src/java/de/uhilger/um/api/Profil.java b/src/java/de/uhilger/um/api/Profil.java
new file mode 100644
index 0000000..e89992f
--- /dev/null
+++ b/src/java/de/uhilger/um/api/Profil.java
@@ -0,0 +1,75 @@
+/*
+ *  Nutzerverwaltung - User and role management in your browser
+ *  Copyright (C) 2011-2017 Ulrich Hilger, http://uhilger.de
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see http://www.gnu.org/licenses/
+ */
+
+
+package de.uhilger.um.api;
+
+import de.uhilger.baselink.PersistenceManager;
+import de.uhilger.baselink.Record;
+import de.uhilger.um.Digester;
+import static de.uhilger.um.api.UserMgr.MP_USER;
+import static de.uhilger.um.api.UserMgr.P_DIGESTER;
+import de.uhilger.um.daten.User;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * API-Methoden fuer die Aenderung der eigenen Nutzerdaten
+ */
+public class Profil extends Api {
+  private static final Logger logger = Logger.getLogger(Profil.class.getName());
+  
+  public static final String SQL_GET_USER = "getUser";
+
+  public String setUserPw(String userId, String currentPw, String newPw) {
+    String result = "Kennwort nicht geändert";
+    try {
+    
+      String digesterClassName = getServletContext().getInitParameter(P_DIGESTER);
+      Digester digester = (Digester) Class.forName(digesterClassName).newInstance();
+      /*
+      MD5 geht nicht mehr,
+      vgl. http://stackoverflow.com/questions/39967289/how-to-use-digest-authentication-in-tomcat-8-5
+      */
+      String digestedCurrentPw = digester.digest(currentPw, Digester.SHA256, null);
+      PersistenceManager pm = getDb();
+      logger.fine(getSql(SQL_GET_USER));
+      List list = pm.select(getSql(SQL_GET_USER), getMapper(MP_USER), Record.WITHOUT_BLOBS, userId);
+      if(list != null && list.size() > 0) {
+        Object o = list.get(0);
+        if(o instanceof User) {
+          User u = (User) o;
+          if(u.getPw().equals(digestedCurrentPw)) {
+            String digestedNewPw = digester.digest(newPw, Digester.SHA256, null);
+            u.setPw(digestedNewPw);
+            pm.update(u, getMapper(MP_USER));
+            result = "Kennwort geaendert";
+          } else {
+            result = "Das Kennwort ist falsch";
+          }
+        }
+      } else {
+        result = "Benutzer " + userId + " nicht gefunden";
+      }
+    } catch (ClassNotFoundException|InstantiationException|IllegalAccessException ex) {
+      logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
+    }
+    return result;
+  }
+}
diff --git a/src/java/logging.properties b/src/java/logging.properties
new file mode 100644
index 0000000..374ff88
--- /dev/null
+++ b/src/java/logging.properties
@@ -0,0 +1,68 @@
+############################################################
+#      Default Logging Configuration File
+#
+# You can use a different file by specifying a filename
+# with the java.util.logging.config.file system property.  
+# For example java -Djava.util.logging.config.file=myfile
+############################################################
+
+############################################################
+#  	Global properties
+############################################################
+
+# "handlers" specifies a comma separated list of log Handler 
+# classes.  These handlers will be installed during VM startup.
+# Note that these classes must be on the system classpath.
+# By default we only configure a ConsoleHandler, which will only
+# show messages at the INFO and above levels.
+# handlers= java.util.logging.ConsoleHandler
+
+# To also add the FileHandler, use the following line instead.
+handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
+
+# Default global logging level.
+# This specifies which kinds of events are logged across
+# all loggers.  For any given facility this global level
+# can be overriden by a facility specific level
+# Note that the ConsoleHandler also has a separate level
+# setting to limit messages printed to the console.
+# .level= FINE
+.level = OFF
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+# default file output is in user's home directory.
+# java.util.logging.FileHandler.pattern = %h/java%u.log
+# java.util.logging.FileHandler.pattern = /media/extmirror/tomcat747/logs/tv_%u.log
+java.util.logging.FileHandler.pattern = ${catalina.base}/logs/um_%u.log
+java.util.logging.FileHandler.limit = 50000
+# java.util.logging.FileHandler.count = 1
+java.util.logging.FileHandler.count = 2
+# java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
+java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
+java.util.logging.FileHandler.level = FINER
+
+# Limit the message that are printed on the console to INFO and above.
+# java.util.logging.ConsoleHandler.level = INFO
+java.util.logging.ConsoleHandler.level = FINER
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+# Example to customize the SimpleFormatter output format 
+# to print one-line log message like this:
+#     <level>: <log message> [<date/time>]
+#
+# java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
+
+############################################################
+# Facility specific properties.
+# Provides extra control for each logger.
+############################################################
+
+# For example, set the com.xyz.foo logger to only log SEVERE
+# messages:
+# com.xyz.foo.level = SEVERE
+de.uhilger.um.handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
+de.uhilger.um.level = FINER
diff --git a/web/WEB-INF/create_database.sql b/web/WEB-INF/create_database.sql
index 4f1be1b..5258a34 100644
--- a/web/WEB-INF/create_database.sql
+++ b/web/WEB-INF/create_database.sql
@@ -19,6 +19,7 @@
 );
 insert into APP.USER_ROLES (user_name, role_name) values ('admin', 'manager-script');
 insert into APP.USER_ROLES (user_name, role_name) values ('admin', 'nutzerAdmin');
+insert into APP.USER_ROLES (user_name, role_name) values ('admin', 'nutzerProfil');
 insert into APP.USER_ROLES (user_name, role_name) values ('admin', 'wbxAdmin');
 insert into APP.USER_ROLES (user_name, role_name) values ('admin', 'ownFileAdmin');
 insert into APP.USER_ROLES (user_name, role_name) values ('admin', 'sqlKonsole');
diff --git a/web/WEB-INF/sql.properties b/web/WEB-INF/sql.properties
index b94548e..7613271 100644
--- a/web/WEB-INF/sql.properties
+++ b/web/WEB-INF/sql.properties
@@ -41,6 +41,9 @@
   <entry key="getUserData">
     select user_name,user_first,user_last,user_email from app.users where user_name = ?
   </entry>
+  <entry key="getUser">
+    select * from app.users where user_name = ?
+  </entry>
   <entry key="getDateList">
     select substr(or_zeit,1,8) as tag, count(*) as anz from app.orte as orte 
     where or_pers_id = ?  
diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml
index 6f037ac..f6dc948 100644
--- a/web/WEB-INF/web.xml
+++ b/web/WEB-INF/web.xml
@@ -37,6 +37,14 @@
             <param-value>de.uhilger.um.pub</param-value>
         </init-param>
     </servlet>
+    <servlet>
+        <servlet-name>ProfilDienst</servlet-name>
+        <servlet-class>de.uhilger.transit.web.TransitServlet</servlet-class>
+        <init-param>
+            <param-name>klassen</param-name>
+            <param-value>de.uhilger.um.api.Profil</param-value>
+        </init-param>
+    </servlet>
     <servlet-mapping>
         <servlet-name>TransitServlet</servlet-name>
         <url-pattern>/api</url-pattern>
@@ -44,6 +52,10 @@
     <servlet-mapping>
         <servlet-name>PublicTransit</servlet-name>
         <url-pattern>/pub</url-pattern>
+    </servlet-mapping>
+    <servlet-mapping>
+        <servlet-name>ProfilDienst</servlet-name>
+        <url-pattern>/prf</url-pattern>
     </servlet-mapping>
     <session-config>
         <session-timeout>
@@ -56,12 +68,29 @@
             <web-resource-name>nutzerAdmin</web-resource-name>
             <description>Nutzer-Administration</description>
             <url-pattern>/ui/*</url-pattern>
+            <url-pattern>/ui*</url-pattern>
             <url-pattern>/svc/*</url-pattern>
+            <url-pattern>/svc*</url-pattern>
             <url-pattern>/api/*</url-pattern>
+            <url-pattern>/api*</url-pattern>
         </web-resource-collection>
         <auth-constraint>
             <description>nutzerAdminAuthContraint</description>
             <role-name>nutzerAdmin</role-name>
+        </auth-constraint>
+    </security-constraint>
+    <security-constraint>
+        <display-name>nutzerProfilConstraint</display-name>
+        <web-resource-collection>
+            <web-resource-name>nutzerProfil</web-resource-name>
+            <description>Nutzerprofil</description>
+            <url-pattern>/prf*</url-pattern>
+            <url-pattern>/prf/*</url-pattern>
+            <url-pattern>/profil/*</url-pattern>
+        </web-resource-collection>
+        <auth-constraint>
+            <description>nutzerProfilAuthContraint</description>
+            <role-name>nutzerProfil</role-name>
         </auth-constraint>
     </security-constraint>
     <login-config>
@@ -75,4 +104,8 @@
         <description/>
         <role-name>nutzerAdmin</role-name>
     </security-role>
+    <security-role>
+        <description/>
+        <role-name>nutzerProfil</role-name>
+    </security-role>
 </web-app>
diff --git a/web/profil/index.html b/web/profil/index.html
new file mode 100644
index 0000000..9919174
--- /dev/null
+++ b/web/profil/index.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Benutzer</title>
+    <link rel="stylesheet" type="text/css" href="/jslib/bootstrap/css/bootstrap.min.css">
+    <link rel="stylesheet" type="text/css" href="stile.css">
+    <script id="tpl-list" type="x-tmpl-mustache">
+      {{#List}}
+      {{#List}}
+        <option value="{{ String }}">{{ String }}</option>'
+      {{/List}}
+      {{/List}}
+    </script>
+  </head>
+  <body>
+    <div id="inhalt">
+      <ul class="nav">
+        <li class="nav-item dropdown">
+          <a id="userMenu" class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Dropdown</a>
+          <div class="dropdown-menu">
+            <a class="dropdown-item" href="/data/dok/wbx/Bedienung.htmi">Hilfe</a>
+            <a class="dropdown-item" href="/">Zur Hauptseite der WebBox wechseln</a>
+            <div class="dropdown-divider"></div>
+            <a class="dropdown-item" href="/wbx/mng">Apps verwalten</a>
+            <a class="dropdown-item" href="/um/ui">Benutzer verwalten</a>
+            <a class="dropdown-item" href="/file-cms/ui">Dateien verwalten</a>
+            <a class="dropdown-item" href="/wbx-dbcon/ui">Datenbanken verwalten</a>
+            <div class="dropdown-divider"></div>
+            <a id="profil" class="dropdown-item disabled" href="/um/profil">Profil</a>
+            <a id="logout" class="dropdown-item" href="#">Abmelden</a>
+          </div>
+        </li>
+      </ul>
+      <!-- <h1>Benutzer</h1> -->
+      <div class="bg-warning p-3" id="meldung-box">
+        <button type="button" class="close" aria-label="Close" id="mldg-x">
+          <span aria-hidden="true">&times;</span>
+        </button>
+        <div class="meldung"></div>
+      </div>
+      <div id="user-form">
+        <label class="pl-3" id="anmeldename">id</label>
+        <!-- <input class="form-control eingabe" type="text" size="20" maxlength="30" placeholder="Anmeldename" name="anmeldename" id="anmeldename"> -->
+        <input class="form-control eingabe" type="password" size="20" maxlength="30" placeholder="Kennwort" name="kennwort" id="kennwort">
+        <input class="form-control eingabe" type="password" size="20" maxlength="30" placeholder="Neues Kennwort" name="kennwortneu" id="kennwortNeu">
+        <input class="form-control eingabe" type="password" size="20" maxlength="30" placeholder="Wiederholung" name="kennwortw" id="kennwortw">
+        <input class="form-control eingabe" type="text" size="20" maxlength="250" placeholder="Vorname" name="vorname" id="vorname">
+        <input class="form-control eingabe" type="text" size="20" maxlength="250" placeholder="Name" name="nachname" id="nachname">
+        <!--<button class="user-cancel-btn">Abbrechen</button>-->
+        <button class="user-save-btn btn btn-primary eingabe">Speichern</button>
+      </div>
+      
+      <!--
+      <div id="nav">
+        <button id="nav-back-btn" class="btn btn-secondary">zur&uuml;ck</button>
+      </div>
+      -->
+    </div>
+    <script src="/jslib/jquery/jquery.min.js"></script>
+    <script src="/jslib/bootstrap/js/bootstrap.min.js"></script>
+    <script src="/jslib/mustache/mustache.min.js"></script>
+    <script src="ui.js"></script>
+    <script type="text/javascript" charset="utf-8">
+      //var ui;
+      $(document).ready(function() {
+        um_prf_init();
+      });
+    </script>
+  </body>
+</html>
diff --git a/web/profil/stile.css b/web/profil/stile.css
new file mode 100644
index 0000000..f990909
--- /dev/null
+++ b/web/profil/stile.css
@@ -0,0 +1,42 @@
+
+
+#inhalt {
+  margin-top: 0.5em;
+  margin-left: 0.5em;
+  margin-right: 0.5em;
+}
+
+#nutzerliste {
+  height: 10em;
+  width: 80%
+}
+
+#nutzerrollen {
+  height: 5em;
+  width: 80%
+}
+
+#rollen {
+  height: 5em;
+  width: 80%
+}
+
+#nav {
+  margin-top: 1em;
+}
+
+#role-form {
+  margin-top: 1em;
+}
+
+#user-role-form {
+  margin-top: 1em;
+}
+
+.eingabe {
+  margin-top: 0.5em;
+}
+
+.role-select {
+  margin-bottom: 0.5em;
+}
\ No newline at end of file
diff --git a/web/profil/ui.js b/web/profil/ui.js
new file mode 100644
index 0000000..aba8469
--- /dev/null
+++ b/web/profil/ui.js
@@ -0,0 +1,129 @@
+
+
+function um_prf_init() {
+  $('#meldung-box').hide();
+  $('#anmeldename').hide();
+  $('.user-save-btn').click(um_prf_user_save);
+  $('#logout').click(um_prf_apicall_logout);
+  um_prf_apicall_get_login();
+}
+
+function um_prf_user_form_fuellen(resp) {
+  $('#anmeldename').text(resp.UserData.id);
+  $('#vorname').val(resp.UserData.firstName);
+  $('#nachname').val(resp.UserData.lastName);
+}
+
+function um_prf_user_save() {
+  var uid = $('#anmeldename').text();
+  var aktKennwort = $('#kennwort').val();
+  var neuKennwort = $('#kennwortNeu').val();
+  var wKennwort = $('#kennwortw').val();
+  if(neuKennwort === '' || wKennwort === '') {
+    um_prf_meldung_anzeigen('Das neue Kennwort darf nicht leer sein.');
+  } else if(neuKennwort !== wKennwort) {
+    um_prf_meldung_anzeigen('Kennworte stimmen nicht überein');
+  } else if(aktKennwort === neuKennwort) {
+    um_prf_meldung_anzeigen('Altes und neues Kennwort müssen sich unterscheiden');
+  } else {
+    um_prf_apicall_kennwort_aendern(uid, aktKennwort, neuKennwort);
+  }
+}
+
+function um_prf_meldung_anzeigen(msg) {
+  $('#meldung-box').show();
+  $("#mldg-x").on('click', function() {
+    $("#mldg-x").attr('onclick','').unbind('click');
+    $('.meldung').slideUp('fast', function() {
+      $('#meldung-box').hide();
+    });
+  });
+  $('.meldung').empty();
+  $('.meldung').text(msg);
+  $('.meldung').slideDown('fast', function(){
+    //
+  });
+}
+
+
+function um_prf_apicall_get_login() {
+  var m = '?c=de.uhilger.um.pub.SessionManager&m=getSessionUser';
+  var u = '../pub' + m;
+  $.ajax({
+    url: u,
+    type: "GET",
+    dataType : "json",
+    success: function( resp ) {
+      $('#userMenu').text(resp.UserData.firstName);
+      um_prf_user_form_fuellen(resp);
+    },
+    error: function( xhr, status, errorThrown ) {
+      $('#fehler').html("Error: " + errorThrown + " Status: " + status);
+    },
+    complete: function( xhr, status ) {
+      //alert( "The request is complete!" );
+    }
+  });      
+  
+}
+function um_prf_apicall_get_user() {
+  var m = '?c=de.uhilger.um.api.Profil&m=getUser';
+  var u = '../prf' + m;
+  $.ajax({
+    url: u,
+    type: "GET",
+    dataType : "json",
+    success: function( resp ) {
+      um_prf_user_form_fuellen(resp);
+    },
+    error: function( xhr, status, errorThrown ) {
+      $('#fehler').html("Error: " + errorThrown + " Status: " + status);
+    },
+    complete: function( xhr, status ) {
+      //alert( "The request is complete!" );
+    }
+  });      
+}
+
+function um_prf_apicall_kennwort_aendern(userId, aktKw, neuKw) {
+  var m = '?c=de.uhilger.um.api.Profil&m=setUserPw&p=' + userId + '&p=' + aktKw + '&p=' + neuKw;
+  var u = '../prf' + m;
+  $.ajax({
+    url: u,
+    type: "GET",
+    dataType : "text",
+    success: function( resp ) {
+      um_prf_meldung_anzeigen(resp);
+    },
+    error: function( xhr, status, errorThrown ) {
+      $('#fehler').html("Error: " + errorThrown + " Status: " + status);
+    },
+    complete: function( xhr, status ) {
+      //alert( "The request is complete!" );
+    }
+  });      
+}
+
+function um_prf_apicall_logout() {
+  var m = '?c=de.uhilger.um.pub.SessionManager&m=expireSession';
+  var u = '../pub' + m;
+  $.ajax({
+    url: u,
+    type: "GET",
+    dataType : "text",
+    success: function( resp ) {
+      $('#userMenu').text('nicht angemeldet');
+      window.location.href = '../logout.html';
+    },
+    error: function( xhr, status, errorThrown ) {
+      $('#fehler').html("Error: " + errorThrown + " Status: " + status);
+    },
+    complete: function( xhr, status ) {
+      //alert( "The request is complete!" );
+    }
+  });      
+}
+
+
+
+
diff --git a/web/ui/index.html b/web/ui/index.html
index f210d5f..f11ade7 100644
--- a/web/ui/index.html
+++ b/web/ui/index.html
@@ -28,6 +28,7 @@
             <a class="dropdown-item" href="/file-cms/ui">Dateien verwalten</a>
             <a class="dropdown-item" href="/wbx-dbcon/ui">Datenbanken verwalten</a>
             <div class="dropdown-divider"></div>
+            <a id="profil" class="dropdown-item" href="/um/profil">Profil</a>
             <a id="logout" class="dropdown-item" href="#">Abmelden</a>
           </div>
         </li>

--
Gitblit v1.9.3