/* Transit - Remote procedure calls made simple Copyright (c) 2012 Ulrich Hilger This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package de.uhilger.transit.web; import java.util.List; import java.util.Map; import de.uhilger.baselink.GenericRecord; import de.uhilger.baselink.PersistenceManager; import de.uhilger.baselink.Record; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; /** * Die Klasse RechteDb implementiert die Schnittstelle RechtePruefer * auf der Grundlage von Benutzerinformationen in einer Datenbank. * * @author Copyright (c) Ulrich Hilger, http://uhilger.de * @author Published under the terms and conditions of * the GNU Affero General Public License * * @version 1, September 16, 2012 */ public class RechteDb extends PersistenceManager implements RechtePruefer { /** Der Name des Datenbanktreibers, der verwendet werden soll, falls keiner angegeben wurde */ public static final String DEFAULT_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver"; /** * Ein Objekt der Klasse RechteDb erzeugen. * * Beim Aufruf dieses Konstruktors muss anschliessend eine der folgenden * Methoden gerufen werden: * setDatabase(DEFAULT_DRIVER, url); * setDatabase(driverName, url); * setDataSourceName(dsName); */ public RechteDb() { super(); } /** * Ein Objekt der Klasse RechteDb erzeugen. * * @param driverName Name des Datenbanktreibers * @param url der Datenbank */ public RechteDb(String driverName, String url) { this(driverName, null, url); } /** * Ein Objekt der Klasse RechteDb erzeugen. * * @param dsName Name der DataSource */ public RechteDb(String dsName) { this(null, dsName, null); } /** * Ein Objekt der Klasse RechteDb erzeugen. * * @param driverName * Name des Datenbanktreibers fuer den Fall dass keine DataSource * verwendet werden soll, sonst kann dieser Parameter null sein * * @param dsName * Name der JDBC DataSource, wie er im Kontext des Servlet Containers * erscheint, z.B. jdbc/AuthorityDB * * @param url * der JDBC connect string, fuer den Fall dass keine DataSource * verwendet werden soll, sonst kann dieser Parameter null sein */ @SuppressWarnings("rawtypes") private RechteDb(String driverName, String dsName, String url) { //super(productionMode, dsName, url); super(); try { if (url != null && !url.isEmpty()) { Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).finest("setting url to " + url); if(driverName == null) { setDatabase(DEFAULT_DRIVER, url); } else { setDatabase(driverName, url); } } else { Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).finest("setting data source to " + dsName); setDataSourceName(dsName); } } catch (Exception ex) { Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, ex.getMessage(), ex); } } /* select m.* from app.user_roles as ur, app.methoden_rechte as mr, app.methoden as m where ur.role_name = mr.role_name and mr.mt_id = m.mt_id and ur.user_name = [name] gibt eine Tabelle mit folgenden Spalten zurueck: mt_id, mt_klasse, mt_name die alle Methoden des Benutzers enthaelt */ /** * Die Rechte eines Benutzers ermitteln * * @param Name des Benutzers * @return eine Liste mit Berechtigungen des Benutzers */ @SuppressWarnings("rawtypes") public List getRechte(String benutzerName) { StringBuffer sql = new StringBuffer(); sql.append("select m.* from app.user_roles as ur"); sql.append(", app.methoden_rechte as mr, app.methoden as m"); sql.append(" where ur.role_name = mr.role_name"); sql.append(" and mr.mt_id = m.mt_id"); sql.append(" and ur.user_name = '"); sql.append(benutzerName); sql.append("'"); List rechte = select(sql.toString()); return rechte; } /** * Pruefen ob ein Methodenaufruf erlaubt ist * * @param klasse vollstaendiger Name der Klasse, die die auszufuehrende Methode enthaelt * @param methode Name der Methode, die ausgefuehrt werden soll * @param benutzerName Name des Benutzerkontos, dessen Benutzer die Methode ausfuehren moechte * * @return true, wenn der Benutzer die Methode ausfuehren darf, false wenn nicht */ @SuppressWarnings("unchecked") public boolean istErlaubt(ServletRequest request, ServletResponse response, String klasse, String methode, String benutzerName) { boolean erlaubt = false; List rechte = getRechte(benutzerName); if(rechte != null) { for(int i = 0; i < rechte.size() && !erlaubt; i++) { String rKlasse = (String) rechte.get(i).get("MT_KLASSE"); String rMethode = (String) rechte.get(i).get("MT_NAME"); /* Verwendung von Regular Expressions, ein Muster fuer eine Klasse ist z.B. de.uhilger..* eine Methode koennte so lauten .* oder get.* Der Punkt steht fuer ein beliebiges Zeichen, das * steht fuer kein Mal oder beliebig oft das davor befindliche Zeichen .* bedeutet 'ab dieser Stelle keinmal oder beliebig oft ein beliebiges Zeichen' + bedeutet stattdessen ein oder mehrmals das davor befindliche Zeichen */ erlaubt = klasse.matches(rKlasse) && methode.matches(rMethode); } } return erlaubt; } }