diff --git a/info.textgrid.middleware.tgauth.rbac/documentation/install.pdf b/info.textgrid.middleware.tgauth.rbac/documentation/install.pdf new file mode 100644 index 0000000000000000000000000000000000000000..47943dffb569de13e916476cc40a36a7b4a07396 Binary files /dev/null and b/info.textgrid.middleware.tgauth.rbac/documentation/install.pdf differ diff --git a/info.textgrid.middleware.tgauth.rbac/documentation/install.tex b/info.textgrid.middleware.tgauth.rbac/documentation/install.tex index 0c763bc644cd7835b2142a29d4a2c55569011312..ad2f9bcff321e7060f9690e4ae0b3015378ab930 100644 --- a/info.textgrid.middleware.tgauth.rbac/documentation/install.tex +++ b/info.textgrid.middleware.tgauth.rbac/documentation/install.tex @@ -1,14 +1,15 @@ -\documentclass[a4paper,12pt,twoside]{article} -\usepackage[ngerman]{babel} +\documentclass[a4paper,11pt,twoside]{article} +%\usepackage[ngerman]{babel} \usepackage[OT1]{fontenc} \usepackage[latin1]{inputenc} \usepackage[top=2.5cm,bottom=2.5cm,left=3cm,right=2.5cm]{geometry} \usepackage{amssymb} \usepackage{amsmath} \usepackage{graphicx} -\usepackage{bibgerm} +%\usepackage{bibgerm} \usepackage{setspace} \usepackage{ifthen} +\usepackage{hyperref} \graphicspath{{graphics/}} % % @@ -16,20 +17,773 @@ % % \author{Markus Widmer} -\title{Role Based Access Control mit OpenLDAP\\ (Anwendung im TextGrid-Projekt)} -\date{SS 2007} +\title{openRBAC installation guide} +\date{04.04.2008} % % -\pagenumbering{roman} +\pagenumbering{arabic} \parindent=0mm % % \begin{document} % \begin{abstract} -In this document you will find a quick installation and configuration guide for the openRBAC software. This software is implemented in PHP5 and is available under the LGPL (Limited Gnu Public License). +In this document you will find a quick installation and configuration guide for the openRBAC software. This software is implemented in PHP5 and is available under the LGPL (Lesser Gnu Public License). As backend database it uses one or more LDAP servers. The configuration of these servers is not part of this guide. \end{abstract} % \tableofcontents % +% -------------------------------------------------------------------------- +\section{Introduction} +\label{sec:intro} +% -------------------------------------------------------------------------- +This software is an implementation of the RBAC Standard\cite{rbac2004}. This standard defines the minimum of functionality for role based access control systems. If you are interested in details about RBAC or the RBAC Standard, please read the accompanying openRBAC documentation. +% +% +% -------------------------------------------------------------------------- +\section{Installation} +\label{sec:inst} +% -------------------------------------------------------------------------- +% +% +% -------------------------------------------------------------------------- +\subsection{Requirements} +\label{subsec:inst:requirements} +% -------------------------------------------------------------------------- +Because this software is written in PHP5 you need an PHP5 interpreter. It has to be compiled with XSL and XML support. If you plan to use RBAC in combination with SOAP services, you have to add SOAP support as well, but you do \emph{not} need to install PEAR to run openRBAC on your PHP5 installation. Further you need one or more LDAP servers that are ready to accept connections from openRBAC which will read and store its data there. If you don not have an LDAP server yet, consider to use openLDAP. You can download it from the project page\footnote{http://www.openldap.org} and you will also find an installation guide there. If you want to use openRBAC with Active Directory as data storage, you have to add LDAPS support to the underlying LDAP class by yourself, which offers only TLS support at the moment. +% +% +% -------------------------------------------------------------------------- +\subsection{Platform} +\label{subsec:inst:platform} +% -------------------------------------------------------------------------- +The software was developed and tested on openSuSE Linux 10.1. So if you use a Linux on your machine, you shouldn't have any problems. It has not been tested on other platforms, but if you have a PHP5 interpreter running properly on your system, it should work as well. +% +% +% -------------------------------------------------------------------------- +\subsection{Getting the code} +\label{subsec:inst:gettingthecode} +% -------------------------------------------------------------------------- +This project is rather young, so at the moment you can only download the code via a SVN client. The software consists of two parts that are required for openRBAC to run: +\begin{description} +\item[mwlib] This part is a collection of rather small classes that provide general functionality, as for example parsing and reading XML files, or encapsulate LDAP commands. The openRBAC software only needs the following files: +\begin{itemize} +\item iNode.interface.php +\item iXML.interface.php +\item iLDAP.interface.php +\item iHelper.interface.php +\item Node.class.php +\item XML.class.php +\item LDAP.class.php +\item Helper.class.php +\end{itemize} +All other files could be deleted or simply left where they are, because they do no harm as long as you do not include them. +\item[openRBAC] This part is the RBAC implementation. It is split into multiple files, each containing one class or interface. +\end{description} +You have to download both parts. To make it easier to get updates and patches via SVN, it is recommended that you make an SVN checkout rather then an SVN export. But if you do so, make sure you download \emph{mwlib} and \emph{openRBAC} into two separate directories. Otherwise you will get an error from your SVN client. If you use the Linux subversion client, you can go to your target directory and run the following commands (don't forget the single dot at the end of line 4 and 6!):\\ +\begin{verbatim} +mkdir rbac +mkdir lib +cd rbac +svn checkout svn://markus-widmer.de/openRBAC/trunk/ . +cd ../lib +svn checkout svn://markus-widmer.de/mwlib/trunk/ . +\end{verbatim} +Now you have installed openRBAC on your system. Continue with section \ref{subsec:inst:configuration} to learn how to configure the software or read more about the different possibilities using the software in section \ref{subsec:inst:makeadecision}. +% +% +% -------------------------------------------------------------------------- +\subsection{Make a decision} +\label{subsec:inst:makeadecision} +% -------------------------------------------------------------------------- +Before you start to configure openRBAC, you should think about your requirements. You can use all of the software or only parts of it. The differences are described below. +% +% +% -------------------------------------------------------------------------- +\subsubsection{The RBAC Framework} +\label{subsubsec:inst:configuration:therbacframework} +% -------------------------------------------------------------------------- +You can decide whether you want to use the RBAC Framework or not. It is wrapped around the RBAC libraries and allows you not only to include the required classes from the \emph{mwlib} via a configuration file, but also to use the SSD and/or DSD extension for openRBAC or to write custom extensions. An extension allows you to modify the behaviour of the software in a way it is needed for your application. RBAC, for example, does not know any public resources. So you would have to work around this by implementing the ''is public'' statement directly into your application. Using an extension for the \emph{checkAccess} function is the other way. You can write your own code that decides when you wish to grant access although RBAC would not.\\ +Using the RBAC Framework gives you a lot more flexibility, but of cores it makes a higher complexity. +% +% +% -------------------------------------------------------------------------- +\subsubsection{Core RBAC} +\label{subsubsec:inst:configuration:corerbac} +% -------------------------------------------------------------------------- +This library contains the core features of RBAC as defined in the standard. It allows you to add and delete users, roles and sessions as well as managing their rights. This library can be used within the RBAC Framework or can be included directly into your application. The configuration is almost independent of your decision. +% +% +% -------------------------------------------------------------------------- +\subsubsection{Hierarchical RBAC} +\label{subsubsec:inst:configuration:hierarchicalrbac} +% -------------------------------------------------------------------------- +This library contains the functionality of limited hierarchical RBAC as defined in the standard. It is derived from Core RBAC and allows you to manage role hierarchies and redefines some of the functions from Core RBAC. This library can be used within the RBAC Framework or can be included directly into your application. The configuration is almost independent of your decision. +% +% +% -------------------------------------------------------------------------- +\subsection{Preparing the LDAP server} +\label{subsec:inst:preparingtheldapserver} +% -------------------------------------------------------------------------- +Before you start to configure openRBAC, you should prepare your LDAP server. If you have it running, it is recommended that you create a subtree for each of the different parts of RBAC, for example: +\begin{description} +\item[users] Usually the users in a LDAP server are stored under the RDN\footnote{RDN: Relative Distinguished Name} ''ou=people''. If you ask openRBAC to add a user via the \emph{addUser} function, it will create it there. Respectively openRBAC will search for users under that subtree. If you already have your users defined somewhere else, you should use this DN, of course. +\item[roles] RBAC is based on roles. It grants permissions to roles and therefore uses roles to make access decisions. To make it possible for openRBAC to store and manage roles, you have to create a subtree, for example ''ou=roles'' in your LDAP server. If you have an LDAP server where there are already groups defined, you could also try to re-use them as roles and configure the RBAC library respectively. But unless you are familiar with the differences between roles and groups and how openRBAC creates, deletes and manages roles, you should be careful. +\item[sessions] The RBAC standard defines sessions as continous context for a user. Therefore openRBAC needs a place to store session information in the LDAP server, for example a subtree named ''ou=sessions''. +\item[resources] The RBAC standard does not define any functionality to manage resources. Nevertheless you have to create a subtree in your LDAP server where openRBAC can find your resources. To learn more about how to create a resource in your LDAP directory, please read the accompanying documentation of openRBAC. +\item[SSD/DSD sets] If you decided to use SSD/DSD (Static/Dynamic Separation of Duty) sets in your application, you have to create a subtree for each of them. openRBAC will store and read informations about restrictions there. You could create subtrees ''ou=dsd'' as the case may be ''ou=ssd''. +\end{description} +% +% +% -------------------------------------------------------------------------- +\subsection{Configuration} +\label{subsec:inst:configuration} +% -------------------------------------------------------------------------- +% +% +% -------------------------------------------------------------------------- +\subsubsection{Configuring the RBAC Framework} +\label{subsubsec:inst:configuration:configuringtherbacframework} +% -------------------------------------------------------------------------- +In the ''rbac/conf/'' directory, you will find two configuration files. You are free to rename them if you wish to. +\begin{description} +\item[rbac.conf.dist] This is an example configuration for the RBAC library. Here you configure the connections to the LDAP server(s) and details about your attributes used in these servers. This file will further be referred as ''rbac.conf'' (see appendix \ref{subsec:appendix:configurationfiles:rbacconfdist}). +\item[system.conf.dist] This is an example configuration for the RBAC Framework. Here you configure the path to the rbac.conf, the paths of the files you have to include and the extensions you want to use. This file will further be referred as ''system.conf'' (see appendix \ref{subsec:appendix:configurationfiles:systemconfdist}). +\end{description} +Please start by editing rbac.conf. The file is split into sections each containing multiple variables. For each of the sections ''user'', ''role'', ''session'' and ''resource'' you have to define the appropriate LDAP parameters: +\begin{description} +\item[host] The hostname where the LDAP server is installed on +\item[port] The port on which the LDAP server is listening +\item[version] The version to use to talk to the LDAP server +\item[tls] If you want to use TLS for the connection say 'yes', otherwise say 'no' +\item[base] The base-DN where the RBAC library starts searching for an entry +\item[binddn] The DN with which the RBAC library binds to the LDAP server +\item[password] The password corresponding to the binddn parameter +\item[filter] A basic filter that is used in every search +\item[namingattribute] The naming attribute of an entry (f.e. ''uid' for a user entry) +\end{description} +For the role section there is the additional ''assignedattribute'' parameter. In this attribute the RBAC library stores the users assigned to a role.\\ +For the resource section there is the additional ''aliasattribute'' parameter. If you specify an attribute different from the ''namingattribute'', the RBAC library searches for both when searching for a resource.\\ +The ssd and dsd sections are only needed if you decide to use one of these extensions. Otherwise you can ignore them.\\ +The ''errorCode'' and ''errorDescription'' sections can be left untouched unless you want to change the output messages the RBAC library should give.\\ +Please edit the system.conf next. There you find various configuration parameters you have to adapt to your installation. Please keep in mind that every path has to be either absolut or relative to your application that is using openRBAC. +\begin{description} +\item[configuration] This parameter tells the RBAC Framework where to find the configuration file for the RBAC library that you have already modified. +\item[rbac] The ''class'' attribute defines which RBAC library you wish to use. Possible values are ''RBACcore'' and ''RBAClimitedHirarchical''. As child nodes you see a lot of ''require'' statements. As mentioned in section \ref{subsec:inst:gettingthecode} the code consists of two parts. You now have to tell the RBAC Framework where it can find all needed classes and interfaces. Depending on how you decided where to store the code, you have to adapt the pathes. +\item[extension] If you want to use extensions, you have to configure them. For each extension class you have to define an ''extension'' statement. The ''class'' attribute contains the name of the class and the ''file'' attribute contains the path and filename in which the class is defined. +\end{description} +A simple example on how to integrate the RBAC Framework into your application could be: +\begin{verbatim} +<?php +require_once( "RBAC.class.php" ); + +$rbac = new RBAC( "../conf/system.conf", "./", "../lib" ); +$rbac->createSession( "martin.haase@daasi.de", Array(), "abc" ); +?> +\end{verbatim} +% +% +% -------------------------------------------------------------------------- +\subsubsection{Configuring openRBAC without the RBAC Framework} +\label{subsubsec:inst:configuration:configuringopenrbacwithouttherbacframework} +% -------------------------------------------------------------------------- +If you want to use the Core RBAC or limited hierarchical RBAC \emph{without} the RBAC Framework, you have to adapt the rbac.conf as described in section \ref{subsubsec:inst:configuration:configuringtherbacframework}, but you can omit the part that describes the adaption of system.conf. Because the RBAC Framework now does not include the required classes and interfaces, you have to define the paths via constants in your application so that the RBAC library can do this on its own: +\begin{description} +\item[RBAC\_LIB\_PATH] This constant has to contain the path to the mwlib files either absolute or relative to your application. +\item[RBAC\_PATH] This constant has to contain the path to the openRBAC files either absolute or relative to your application. +\end{description} +You have to define these constants in your application before you include the RBAC library! A simple example on how to integrate the Core RBAC into your application could be: +\begin{verbatim} +<?php +define( "RBAC_LIB_PATH", "../lib" ); +define( "RBAC_PATH", "./" ); +require_once( "RBACcore.class.php" ); + +$rbac = new RBACcore( "conf/rbac.conf" ); +$rbac->createSession( "jondoe", Array( "student", "hiwi,staff" ), "s13243355a46" ); +?> +\end{verbatim} +% +% +% -------------------------------------------------------------------------- +\subsection{Closing words} +\label{subsec:inst:closingwords} +% -------------------------------------------------------------------------- +You now have installed openRBAC. Remember that openRBAC is just a library and cannot replace an application. Even if you just want to have a graphical interface that maps the RBAC functionality defined in the standard, you have to write it on your own. It is not an ''out-of-the-box'' management tool. +% +% +% -------------------------------------------------------------------------- +\section{RBAC with XACML via SOAP} +\label{sec:xacmlsoap} +% -------------------------------------------------------------------------- +Additional to the RBAC library and RBAC Framework, you will find a SOAP\cite{soap} server and client in the \emph{SOAP} directory. Both use the SAML 2.0 profile of XACML v2.0\cite{xacmlsaml2005} to communicate with each other. The clients gives you the possibility to call the RBAC function \emph{checkAccess} via a SOAP service. SOAP transports a SAML Request and Response adapted to XACML. An example SOAP request is given in App. \ref{sec:appendix:rbacwithxacmlviasoap:soaprequest} and an appropriate SOAP response is given in App. \ref{sec:appendix:rbacwithxacmlviasoap:soapresponse}. +% +% +% -------------------------------------------------------------------------- +\subsection{Preparations} +\label{subsec:xacmlsoap:preparations} +% -------------------------------------------------------------------------- +To use RBAC with SOAP you have to have a webserver like Apache having PHP5 module included. You than have to configure Apache to serve the content of the \emph{SOAP} directory. Make sure that it is possible for {xacml.php} to include all of the RBAC library and RBAC Framework. +% +% +% -------------------------------------------------------------------------- +\subsection{Configuration} +\label{subsec:xacmlsoap:configuration} +% -------------------------------------------------------------------------- +At this point it is possible to reach the file \emph{xacml.php} over the HTTP protocol using a browser or something similar. Now you have to edit three files and replace the placeholders within them: +\begin{description} +\item[xacml.wsdl] Go to the end of the file. In the section \emph{Servicedefinition} you will find the placeholder \emph{$<$YOUR\_LOCATION$>$}. Replace it with the path where a client will be able to call your \emph{xacml.php}. +\item[xacml.php] At the top of the file you will find the placeholder \emph{$<$PATH\_TO\_RBAC$>$}. Replace it with a relative or absolute path to your RBAC Framework. This value will be used twice in \emph{xacml.php}. First it is used to include the RBAC Framework and second to tell the RBAC Framework where it is located. Afer having set this, you need to replace the placeholder \emph{$<$PATH\_TO\_WSDL$>$} in the same file. Set the path to the WSDL file you have just edited to fit your installation. +\item[xacmlCheckAccess.php] This is the client. If you want to use it you have to replace the placeholder \emph{$<$PATH\_TO\_WSDL$>$} as you did in \emph{xacml.php}. +\emph{Notice}: If you have a close look at the WSDL file (see App. \ref{sec:appendix:xacmlwsdl}), you might recognice that the imported XML schema is not located at the OASIS web page but at the web page of DAASI International GmbH. The reason for this is, that the XML schema you can download at OASIS is flawed and cannot be used for an XSD import. To verify this, download the files from OASIS and make a \emph{diff} between the corresponding files served at the DAASI web page and included in this document (see App. \ref{sec:appendix:schemafiles}). +\end{description} +% +% +% -------------------------------------------------------------------------- +\subsection{Closing words} +\label{subsec:xacmlsoap:closingwords} +% -------------------------------------------------------------------------- +If your RBAC is configured well and found to work properly, you now should be able to determin decisions of RBAC via a SOAP service using standardised SAML/XACML. But remember that this project is still very young. So at the moment it is not possible to tell the SOAP servive to examine certificates send within the SAML request to decide if the client is trusted. +% +% +\begin{appendix} +\tiny +% +% +% -------------------------------------------------------------------------- +\section{Configuration files} +\label{sec:appendix:configurationfiles} +% -------------------------------------------------------------------------- +% +% +% -------------------------------------------------------------------------- +\subsection{rbac.conf.dist} +\label{subsec:appendix:configurationfiles:rbacconfdist} +% -------------------------------------------------------------------------- +\begin{verbatim} +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + + <section name="user"> + <var name="host">ldap.example.org</var> + <var name="port">389</var> + <var name="version">3</var> + <var name="tls">no</var> + <var name="base">ou=users,ou=rbac,dc=example,dc=org</var> + <var name="binddn">cn=application,ou=dsa,dc=example,dc=org</var> + <var name="password">secret</var> + <var name="filter">(objectClass=inetorgperson)</var> + <var name="namingattribute">uid</var> + </section> + + <section name="role"> + <var name="host">ldap.example.org</var> + <var name="port">389</var> + <var name="version">3</var> + <var name="tls">no</var> + <var name="base">ou=roles,ou=rbac,dc=example,dc=org</var> + <var name="binddn">cn=application,ou=dsa,dc=example,dc=org</var> + <var name="password">secret</var> + <var name="namingattribute">rbacname</var> + <var name="filter">(objectClass=rbacrole)</var> + + <!-- May also be member to have greater compatibility with + allready existing entries in your LDAP-server //--> + <var name="assignedattribute">rbacperformer</var> + </section> + + <section name="project"> + <var name="base">ou=Projekt-Teilnehmer,ou=roles,ou=rbac,dc=example,dc=org</var> + </section> + + <section name="session"> + <var name="host">ldap.example.org</var> + <var name="port">389</var> + <var name="version">3</var> + <var name="tls">no</var> + <var name="base">ou=sessions,ou=rbac,dc=example,dc=org</var> + <var name="binddn">cn=application,ou=dsa,dc=example,dc=org</var> + <var name="password">secret</var> + <var name="namingattribute">rbacname</var> + <var name="filter">(objectClass=rbacsession)</var> + </section> + + <section name="resource"> + <var name="host">ldap.example.org</var> + <var name="port">389</var> + <var name="version">3</var> + <var name="tls">no</var> + <var name="base">ou=rbac,dc=example,dc=org</var> + <var name="binddn">cn=application,ou=dsa,dc=example,dc=org</var> + <var name="password">secret</var> + <var name="namingattribute">rbacname</var> + <var name="aliasattribute">rbacname</var> + <var name="filter">(objectClass=rbacresource)</var> + </section> + + <section name="ssd"> + <var name="host">ldap.example.org</var> + <var name="port">389</var> + <var name="version">3</var> + <var name="tls">no</var> + <var name="base">ou=ssd,ou=rbac,dc=example,dc=org</var> + <var name="binddn">cn=application,ou=dsa,dc=example,dc=org</var> + <var name="password">secret</var> + <var name="filter">(objectClass=rbacssd)</var> + </section> + + <section name="dsd"> + <var name="host">ldap.example.org</var> + <var name="port">389</var> + <var name="version">3</var> + <var name="tls">no</var> + <var name="base">ou=dsd,ou=rbac,dc=example,dc=org</var> + <var name="binddn">cn=application,ou=dsa,dc=example,dc=org</var> + <var name="password">secret</var> + <var name="filter">(objectClass=rbacdsd)</var> + </section> + + + <section name="errorCode"> + <var name="OK">1</var> + <var name="RESOURCE_OPERATION_ERROR">2</var> + <var name="RESOURCE_UNKNOWN">4</var> + <var name="USER_SESSION_ERROR">8</var> + <var name="SESSION_ALLREADY_EXISTS">16</var> + <var name="SESSION_DOES_NOT_EXISTS">32</var> + <var name="USER_UNKNOWN">64</var> + <var name="USER_ROLE_ERROR">128</var> + <var name="USER_ALLREADY_EXISTS">256</var> + <var name="INVALID_USER_FORMAT">512</var> + <var name="ROLE_ALLREADY_EXISTS">1024</var> + <var name="ROLE_UNKNOWN">2048</var> + <var name="LDAP_ERROR">4096</var> + <var name="UNKNOWN_ERROR">8192</var> + <var name="SD_ALLREADY_EXISTS">16384</var> + <var name="SD_CARDINALITY">32768</var> + <var name="SD_UNKNOWN">65536</var> + </section> + + <section name="errorDescription"> + <var name="OK">Ok</var> + <var name="RESOURCE_OPERATION_ERROR">This resource-operation-combination is invalid.</var> + <var name="RESOURCE_UNKNOWN">The resource is not known or not uniqueue.</var> + <var name="USER_SESSION_ERROR">The user you gave is not the owner of this session.</var> + <var name="SESSION_ALLREADY_EXISTS">The session allready exists so you can not create it.</var> + <var name="SESSION_DOES_NOT_EXISTS">The session does not exist.</var> + <var name="USER_UNKNOWN">The user is not known.</var> + <var name="USER_ROLE_ERROR">This user-role-combination is invalid.</var> + <var name="USER_ALLREADY_EXISTS">The user allready exists.</var> + <var name="INVALID_USER_FORMAT">The user has to have the the format: <username>@<domain> + (foo@example.org)</var> + <var name="ROLE_ALLREADY_EXISTS">The role allready exists.</var> + <var name="ROLE_UNKNOWN">The role is unknown.</var> + <var name="LDAP_ERROR">An LDAP-Error occured, see description: </var> + <var name="UNKNOWN_ERROR">An error occured.</var> + <var name="SD_ALLREADY_EXISTS">The Separation of Duty Set allready exists.</var> + <var name="SD_CARDINALITY">The given cardinality is invalid! Make sure it is >= 2</var> + <var name="SD_UNKNOWN">The Separation of Duty set is unknown</var> + </section> + +</configuration> +\end{verbatim} +% +% +% -------------------------------------------------------------------------- +\subsection{system.conf.dist} +\label{subsec:appendix:configurationfiles:systemconfdist} +% -------------------------------------------------------------------------- +\begin{verbatim} +<?xml version="1.0" encoding="UTF-8"?> +<system> + + <!-- This is the system-configuration for the RBAC-Framework. + The RBAC libraries need an additional configuration-file + where you have to define all LDAP-specific settings. Tell + the RBAC-Framework where it can find this configuration. + Specify a full path or a path relative to your main + application. --> + <configuration file="PATH_TO/rbac.conf" /> + + + <!-- Here you can specify if you want to use Core RBAC or the + Limited Hierarchical RBAC. In order to work properly both + libraries need a couple of classes specified through + the "require" statements. Again you have to specify a full + path or a path relative to your main application. --> + <rbac class="RBAClimitedHirarchical"> + <require file="PATH_TO/iContext.interface.php" /> + <require file="PATH_TO/iHelper.interface.php" /> + <require file="PATH_TO/iCrypto.interface.php" /> + <require file="PATH_TO/iLDAP.interface.php" /> + <require file="PATH_TO/iRBACcore.interface.php" /> + <require file="PATH_TO/iRBAClimitedHirarchical.interface.php" /> + + <require file="PATH_TO/RBACException.class.php" /> + <require file="PATH_TO/RBACExtension.class.php" /> + <require file="PATH_TO/Context.class.php" /> + <require file="PATH_TO/Helper.class.php" /> + <require file="PATH_TO/LDAP.class.php" /> + <require file="PATH_TO/Crypto.class.php" /> + <require file="PATH_TO/SimpleConfig.class.php" /> + <require file="PATH_TO/RBACcore.class.php" /> + <require file="PATH_TO/RBAClimitedHirarchical.class.php" /> + </rbac> + + + <!-- Specify the extensions you want to use through the + RBAC-Framework. Give a full path or a path relative + to your main application. --> + <extension class="SSD" file="PATH_TO/SSD.class.php" /> + <extension class="DSD" file="PATH_TO/DSD.class.php" /> + <extension class="UserEntry" file="PATH_TO/UserEntry.class.php" /> + <extension class="Logger" file="PATH_TO/Logger.class.php" /> + +</system> +\end{verbatim} +% +% +% -------------------------------------------------------------------------- +\section{xacml.wsdl} +\label{sec:appendix:xacmlwsdl} +% -------------------------------------------------------------------------- +\begin{verbatim} +<?xml version="1.0" encoding="UTF-8"?> + +<wsdl:definitions name="xacml" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:tns="http://daasi.de/namespaces/rbac/xacml" + xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + targetNamespace="http://daasi.de/namespaces/rbac/xacml" + xmlns:xacml-samlp="urn:oasis:xacml:2.0:saml:protocol:schema:os" + xmlns:xacml-saml="urn:oasis:xacml:2.0:saml:assertion:schema:os"> + + + <!-- + #################### + # Type Definitions # + #################### + //--> + <wsdl:types> + <xsd:schema targetNamespace="http://daasi.de/namespaces/rbac/xacml"> + <xsd:import namespace="urn:oasis:xacml:2.0:saml:assertion:schema:os" + schemaLocation="http://www.daasi.de/schema/oasis/access_control-xacml-2.0-saml-assertion-schema-os.xsd" /> + <xsd:import namespace="urn:oasis:xacml:2.0:saml:protocol:schema:os" + schemaLocation="http://www.daasi.de/schema/oasis/access_control-xacml-2.0-saml-protocol-schema-os.xsd"/> + + </xsd:schema> + + </wsdl:types> + + + <!-- + ################# + # WSDL-Messages # + ################# + //--> + <!-- #### checkXACMLaccess #### //--> + <wsdl:message name="checkXACMLaccessRequest"> + <wsdl:part element="xacml-samlp:XACMLAuthzDecisionQuery" name="checkXACMLaccessInput" /> + </wsdl:message> + <wsdl:message name="checkXACMLaccessResponse"> + <wsdl:part element="xacml-saml:XACMLAuthzDecisionStatement" name="checkXACMLaccessOutput" /> + </wsdl:message> + + + <!-- + ######################### + # Port-Type-Definitions # + ######################### + //--> + <wsdl:portType name="port_xacml"> + + <!-- #### checkXACMLaccess #### //--> + <wsdl:operation name="checkXACMLaccess"> + <wsdl:input message="tns:checkXACMLaccessRequest" /> + <wsdl:output message="tns:checkXACMLaccessResponse" /> + </wsdl:operation> + + </wsdl:portType> + + + <!-- + ########### + # Binding # + ########### + //--> + <wsdl:binding name="binding_xacml" type="tns:port_xacml"> + <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> + + <!-- #### checkXACMLaccess #### //--> + <wsdl:operation name="checkXACMLaccess"> + <soap:operation soapAction="http://daasi.de/rbac/xacml/checkXACMLaccess" /> + <wsdl:input><soap:body use="literal" /></wsdl:input> + <wsdl:output><soap:body use="literal" /></wsdl:output> + </wsdl:operation> + + </wsdl:binding> + + + <!-- + ##################### + # Servicedefinition # + ##################### + //--> + <wsdl:service name="xacml"> + <wsdl:port binding="tns:binding_xacml" name="tns:xacml"> + <soap:address location="http://<YOUR_LOCATION>/xacml.php" /> + </wsdl:port> + </wsdl:service> + +</wsdl:definitions> +\end{verbatim} +% +% +% -------------------------------------------------------------------------- +\section{Schema files} +\label{sec:appendix:schemafiles} +% -------------------------------------------------------------------------- +% +% +% -------------------------------------------------------------------------- +\subsection{XACML Saml Protocol} +\label{sec:appendix:schemafiles:xacmlsamlprotocol} +% -------------------------------------------------------------------------- +\begin{verbatim} +<?xml version="1.0" encoding="UTF-8"?> +<schema + targetNamespace="urn:oasis:xacml:2.0:saml:protocol:schema:os" + xmlns:tns="urn:oasis:xacml:2.0:saml:protocol:schema:os" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns="http://www.w3.org/2001/XMLSchema" + xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" + xmlns:xacml-context="urn:oasis:names:tc:xacml:2.0:context:schema:os" + xmlns:xacml="urn:oasis:names:tc:xacml:2.0:policy:schema:os" + elementFormDefault="unqualified" + attributeFormDefault="unqualified" + blockDefault="substitution" + version="2.0"> + <xs:import namespace="urn:oasis:names:tc:SAML:2.0:protocol" + schemaLocation="http://www.daasi.de/schema/oasis/saml-schema-protocol-2.0.xsd"/> + <xs:import namespace="urn:oasis:names:tc:xacml:2.0:context:schema:os" + schemaLocation="http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-context-schema-os.xsd"/> + <xs:annotation> + <xs:documentation> + Document identifier: access_control-xacml-2.0-saml-protocol-schema-os.xsd + Location: http://docs.oasis-open.org/xacml/2.0/ + access_control-xacml-2.0-saml-protocol-schema-os.xsd + </xs:documentation> + </xs:annotation> + <!-- --> + <xs:element name="XACMLAuthzDecisionQuery" + type="tns:XACMLAuthzDecisionQueryType"/> + <xs:complexType name="XACMLAuthzDecisionQueryType"> + <xs:complexContent> + <xs:extension base="samlp:RequestAbstractType"> + <xs:sequence> + <xs:element ref="xacml-context:Request"/> + </xs:sequence> + <xs:attribute name="InputContextOnly" + type="boolean" + use="optional" + default="false"/> + <xs:attribute name="ReturnContext" + type="boolean" + use="optional" + default="false"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <!-- --> + <xs:element name="XACMLPolicyQuery" + type="tns:XACMLPolicyQueryType"/> + <xs:complexType name="XACMLPolicyQueryType"> + <xs:complexContent> + <xs:extension base="samlp:RequestAbstractType"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="xacml-context:Request"/> + <xs:element ref="xacml:Target"/> + <xs:element ref="xacml:PolicySetIdReference"/> + <xs:element ref="xacml:PolicyIdReference"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> +</schema> +\end{verbatim} +% +% +% -------------------------------------------------------------------------- +\subsection{XACML Saml Assertion} +\label{sec:appendix:schemafiles:xacmlsamlassertion} +% -------------------------------------------------------------------------- +\begin{verbatim} +<?xml version="1.0" encoding="UTF-8"?> +<schema + targetNamespace="urn:oasis:xacml:2.0:saml:assertion:schema:os" + xmlns:tns="urn:oasis:xacml:2.0:saml:assertion:schema:os" + xmlns="http://www.w3.org/2001/XMLSchema" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" + xmlns:xacml-context="urn:oasis:names:tc:xacml:2.0:context:schema:os" + xmlns:xacml="urn:oasis:names:tc:xacml:2.0:policy:schema:os" + elementFormDefault="unqualified" + attributeFormDefault="unqualified" + blockDefault="substitution" + version="2.0"> + <xs:import namespace="urn:oasis:names:tc:SAML:2.0:assertion" + schemaLocation="http://www.daasi.de/schema/oasis/saml-schema-assertion-2.0.xsd"/> + <xs:import namespace="urn:oasis:names:tc:xacml:2.0:context:schema:os" + schemaLocation="http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-context-schema-os.xsd"/> + <xs:annotation> + <xs:documentation> + Document identifier: access_control-xacml-2.0-saml-assertion-schema-cd-02.xsd + Location: http://docs.oasis-open.org/xacml/2.0/ + access_control-xacml-2.0-saml-assertion-schema-cd-os.xsd + </xs:documentation> + </xs:annotation> + <!-- --> + <xs:element name="XACMLAuthzDecisionStatement" + type="tns:XACMLAuthzDecisionStatementType"/> + <xs:complexType name="XACMLAuthzDecisionStatementType"> + <xs:complexContent> + <xs:extension base="saml:StatementAbstractType"> + <xs:sequence> + <xs:element ref="xacml-context:Response"/> + <xs:element ref="xacml-context:Request" minOccurs="0"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + <!-- --> + <xs:element name="XACMLPolicyStatement" + type="tns:XACMLPolicyStatementType"/> + <xs:complexType name="XACMLPolicyStatementType"> + <xs:complexContent> + <xs:extension base="saml:StatementAbstractType"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="xacml:Policy"/> + <xs:element ref="xacml:PolicySet"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> +</schema> +\end{verbatim} +% +% +% +% +% -------------------------------------------------------------------------- +\subsection{RBAC with XACML via SOAP} +\label{sec:appendix:rbacwithxacmlviasoap} +% -------------------------------------------------------------------------- +% +% +% -------------------------------------------------------------------------- +\subsection{SOAP request} +\label{sec:appendix:rbacwithxacmlviasoap:soaprequest} +% -------------------------------------------------------------------------- +\begin{verbatim} +<SOAP-ENV:Envelope + xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" + xmlns:ns1="urn:oasis:names:tc:xacml:2.0:context:schema:os" + xmlns:ns2="urn:oasis:xacml:2.0:saml:protocol:schema:os"> + +<SOAP-ENV:Body> + <ns2:XACMLAuthzDecisionQuery ID="abcde1234" Version="2.0" ReturnContext="true"> + <ns1:Request> + <ns1:Subject> + <ns1:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string"> + <ns1:AttributeValue> + SID_ryytp55xUIvmoXEv663QWeYoj0t2s6COeX56nbGpUkxj1R7pCXNqT49umfFs1I9JvI + </ns1:AttributeValue> + </ns1:Attribute> + </ns1:Subject> + <ns1:Resource> + <ns1:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#anyURI"> + <ns1:AttributeValue> + textgrid:TGPR3:Die+Leiden+des+jungen+Werther+-+Zweyter+Theil:20080327T170038:xml%2Ftei:1 + </ns1:AttributeValue> + </ns1:Attribute> + </ns1:Resource> + <ns1:Action> + <ns1:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"> + <ns1:AttributeValue> + read + </ns1:AttributeValue> + </ns1:Attribute> + </ns1:Action> + <ns1:Environment/> + </ns1:Request> + </ns2:XACMLAuthzDecisionQuery> +</SOAP-ENV:Body> + +</SOAP-ENV:Envelope> +\end{verbatim} +% +% +% -------------------------------------------------------------------------- +\subsection{SOAP response} +\label{sec:appendix:rbacwithxacmlviasoap:soapresponse} +% -------------------------------------------------------------------------- +\begin{verbatim} +<SOAP-ENV:Envelope + xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" + xmlns:ns1="urn:oasis:names:tc:xacml:2.0:context:schema:os" + xmlns:ns2="urn:oasis:xacml:2.0:saml:assertion:schema:os> + +<SOAP-ENV:Body> + <ns2:XACMLAuthzDecisionStatement> + <ns1:Response> + <ns1:Result> + <ns1:Decision> + Permit + </ns1:Decision> + </ns1:Result> + </ns1:Response> + <ns1:Request> + <ns1:Subject> + <ns1:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" + DataType="http://www.w3.org/2001/XMLSchema#string"> + <ns1:AttributeValue> + SID_ryytp55xUIvmoXEv663QWeYoj0t2s6COeX56nbGpUkxj1R7pCXNqT49umfFs1I9JvI + </ns1:AttributeValue> + </ns1:Attribute> + </ns1:Subject> + <ns1:Resource> + <ns1:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" + DataType="http://www.w3.org/2001/XMLSchema#anyURI"> + <ns1:AttributeValue> + textgrid:TGPR3:Die+Leiden+des+jungen+Werther+-+Zweyter+Theil:20080327T170038:xml%2Ftei:1 + </ns1:AttributeValue> + </ns1:Attribute> + </ns1:Resource> + <ns1:Action> + <ns1:Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" + DataType="http://www.w3.org/2001/XMLSchema#string"> + <ns1:AttributeValue> + read + </ns1:AttributeValue> + </ns1:Attribute> + </ns1:Action> + <ns1:Environment/> + </ns1:Request> + </ns2:XACMLAuthzDecisionStatement> +</SOAP-ENV:Body> + +</SOAP-ENV:Envelope> +\end{verbatim} +% +% +\end{appendix} +% +% +\bibliography{literature} +\bibliographystyle{alpha} +% \end{document} \ No newline at end of file diff --git a/info.textgrid.middleware.tgauth.rbac/documentation/literature.bib b/info.textgrid.middleware.tgauth.rbac/documentation/literature.bib new file mode 100644 index 0000000000000000000000000000000000000000..0950266c83ab231e8a2e8abfd70e169235cc627b --- /dev/null +++ b/info.textgrid.middleware.tgauth.rbac/documentation/literature.bib @@ -0,0 +1,119 @@ +% Literaturverzeichnis +% -------------------- +@proceedings{rbac2004, + title = {Role Based Access Control}, + year = {2004}, + organization = {ANSI incits} +} + +@techreport{widmer2006, + author = {Markus Widmer}, + title = {Role Based Access Control mit OpenLDAP}, + institution = {Universit\"at T\"ubingen}, + year = {2005} +} + +@techreport{saml2006, + author = {Nick Ragouzis and John Hughes and Rob Philpott and Eve Maler}, + title = {Security Assertion Markup Language (SAML) V2.0 Technical Overview}, + institution = {OASIS}, + year = 2006 +} + +@techreport{chadwickmsod, + author = {David M Chadwick}, + title = {Multi-session Separation of Duties (MSoD) for RBAC}, + institution = {University of Kent}, + year = 2006 +} + +@misc{openldap, + key = {OpenLDAP Project}, + title = {OpenLDAP Software 2.3 Administrators Guide}, + month = 10, + year = 2007 +} + +@proceedings{rfc4511, + title = {RFC 4511, Lightweight Directory Access Protocol (LDAP)}, + year = 2006, + organization = {Network Working Group}, + author = {J. Sermersheim} +} + +@proceedings{rfc4515, + title = {RFC 4515, String Representation of Search Filters}, + year = 2006, + organization = {Network Working Group}, + author = {M. Smith} +} + +@proceedings{rfc2141, + title ={RFC 2141, URN Syntax}, + year = 1997, + organization = {Network Working Group}, + author = {R. Moats} +} + +@proceedings{wsdl1.1, + title = {Web Services Description Language (WSDL) 1.1}, + year = 2001, + organization = {W3C}, + author = {Erik Christensen and Francisco Curbera and Greg Meredith and Sanjiva Weerawarana} +} + +@proceedings{soap, + title = {SOAP Version 1.2 Part 1: Messaging Framework (Second Edition)}, + year = 2007, + organization = {W3C}, + author = {Martin Gudgin and Marc Hadley and Noah Mendelsohn and Jean-Jacques Moreau and Henrik Frystyk Nielsen and Anish Karmarkar and Yves Lafon} +} + +@book{pdsa2, + title = {Pattern-Oriented Software Architecture}, + author = {D. Schmidt and M. Stal and H. Rohnert and F. Buschmann}, + publisher = {Wiley \& Sons Ltd.}, + year = 2000, + volume = {2}, + isbn = {0-471-60695-2} +} + +@book{oli78, + author = {Oliver Ian}, + title = {Klassische Programmiertechnik - Eine Sammlung der hervorragendsten Algorithmen}, + publisher = {Prentice Hall}, + year = 1994 +} + +@book{thegrid, + author = {Ian Foster and Carl Kesselman}, + title = {The Grid: Blueprint for a new computing infrastructure}, + publisher = {Elsevier Inc.}, + year = 2004 +} + +@inproceedings{tgehum2006, + title = {TextGrid and eHumanities}, + year = 2006, + author = {Peter Gietz and Andreas Aschenbrenner and Stefan B\"udenbender and Fotis Jannidis and Marc W. K\"uster and Christoph Ludwig and Wolfgang Pempe and Thorsten Vitt and Werner Wegstein and Andrea Zielinski}, + booktitle = {Proc. of Second IEEE International Conference on e-Science, December 4-6, 2006, Amsterdam}, + publisher = {IEEE CS Press} +} + +@techreport{tgarch2007, + title = {TextGrid Architektur}, + author = {Andreas Aschenbrenner and Peter Gietz and Martin Haase and Frank Knoll and +Christoph Ludwig and Wolfgang Pempe and Markus Sosto and Thorsten Vitt}, + institution = {Nieders\"achsische Saats- und Universit\"atsbibliothek, G\"ottingen und DAASI International GmbH}, + year = 2007, + url = {http://www.textgrid.de} +} + +@techreport{xacmlsaml2005, + title = {SAML 2.0 profile of XACML v2.0}, + author = {Anne Anderson and Hal Lockhart}, + url = {http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-saml-profile-spec-os.pdf}, + year = 2005, + institution = {OASIS}, + publisher = {OASIS} +} \ No newline at end of file diff --git a/info.textgrid.middleware.tgauth.rbac/lib/Authentication.class.php b/info.textgrid.middleware.tgauth.rbac/lib/Authentication.class.php new file mode 100755 index 0000000000000000000000000000000000000000..13f94594b57d5e23c017c29980f4e8c6bf56f3d1 --- /dev/null +++ b/info.textgrid.middleware.tgauth.rbac/lib/Authentication.class.php @@ -0,0 +1,100 @@ +<?php +// #################################################################### +// Version: 0.1.0 +// Author: Markus Widmer +// Created: 19.01.2007 +// Modified: 07.10.2007 + + + + +class Authentication { + + // ## Class-variables ############################################### + private $connection; + + + + + // ## Constructor ################################################### + public function __construct( CConnection $inConnection ) { + + // To use the connection it has to have an established + // connection to the database. + if( $inConnection->handle->hasConnection() ) { + + $this->connection = $inConnection; + + } + else { + + throw new Exception( "Authentication::__construct() Unable to use this connection!" ); + + } + + } + + + + + // ## ldap ########################################################## + public function ldap( $inUsername, $inPassword, $inAttribute = "uid", Array $inArrProvide = null ) { + + $log = new Log(); + $filter = ""; // The LDAP filter to search for the user + $dn = ""; // The DN of the user + $result = false; // The default return value is false + + + // The type of connection has to be a LDAP connection + if( $this->connection instanceof CLDAPConnection ) { + + // If the username is just a name, search for it + // in the directory before trying to bind. + if( !preg_match( "/^(.+=.+)+,(.+=.+)$/", $inUsername ) ) { + + // Search for a user that fits the username + $log->debug( $this->connection->filter . "\n" ); + $filter = "(&" . $this->connection->filter; + $filter .= "(" . $inAttribute . "=" . $inUsername . "))"; + + + // Ask the directory + $arrUserEntry = $this->connection->handle->search( $this->connection->base, $filter, "sub", Array( $inAttribute ) ); + + + if( sizeof( $arrUserEntry ) == 1 ) { + + if( $this->connection->handle->bind( $arrUserEntry[0]['dn'], $inPassword ) ) { + + $result = $arrUserEntry[0]['dn']; + + } + + } + + } + else { + + if( $this->connection->handle->bind( $inUsername, $inPassword ) ) { + + $result = $inUsername; + + } + + } + + } + else { + + throw new Exception( "Authentication::setMethod() Cannot use this connection in LDAP-mode." ); + + } + + + return $result; + + } + +} +?> diff --git a/info.textgrid.middleware.tgauth.rbac/lib/CConnection.container.php b/info.textgrid.middleware.tgauth.rbac/lib/CConnection.container.php new file mode 100755 index 0000000000000000000000000000000000000000..6e95f2ef22b953969c9bad0a26ed254f2b0075bf --- /dev/null +++ b/info.textgrid.middleware.tgauth.rbac/lib/CConnection.container.php @@ -0,0 +1,21 @@ +<?php +// #################################################################### +// Version: 0.1.0 +// Author: Markus Widmer +// Created: 02.04.2008 +// Modified: 03.04.2008 + + + + +class CConnection { + + // ## Class-variable ################################################ + public $handle; + public $host; + public $port; + public $bind; + public $password; + +} +?> diff --git a/info.textgrid.middleware.tgauth.rbac/lib/CLDAPConnection.container.php b/info.textgrid.middleware.tgauth.rbac/lib/CLDAPConnection.container.php new file mode 100755 index 0000000000000000000000000000000000000000..3ac966eb1295212964adac9f5e759cfd8c6fd594 --- /dev/null +++ b/info.textgrid.middleware.tgauth.rbac/lib/CLDAPConnection.container.php @@ -0,0 +1,19 @@ +<?php +// #################################################################### +// Version: 0.1.0 +// Author: Markus Widmer +// Created: 02.04.2008 +// Modified: 03.04.2008 + + + + +class CLDAPConnection extends CConnection { + + // ## Klassenvariablen ############################################## + public $tls; + public $filter; + public $version; + +} +?> diff --git a/info.textgrid.middleware.tgauth.rbac/lib/CSQLConnection.container.php b/info.textgrid.middleware.tgauth.rbac/lib/CSQLConnection.container.php new file mode 100755 index 0000000000000000000000000000000000000000..ab6e20111c6ef400528754fdde4632f95d332034 --- /dev/null +++ b/info.textgrid.middleware.tgauth.rbac/lib/CSQLConnection.container.php @@ -0,0 +1,18 @@ +<?php +// #################################################################### +// Version: 0.1.0 +// Author: Markus Widmer +// Created: 02.04.2008 +// Modified: 03.04.2008 + + + + +class CSQLConnection extends CConnection { + + // ## Klassenvariablen ############################################## + public $table; + public $database; + +} +?> diff --git a/info.textgrid.middleware.tgauth.rbac/lib/DataBase.class.php b/info.textgrid.middleware.tgauth.rbac/lib/DataBase.class.php index d2fedf673c0c98b99a2b1c49d2fa3ed01b30aedb..f5c343b7ac1078b94a95e6585b3eee3090963b0d 100755 --- a/info.textgrid.middleware.tgauth.rbac/lib/DataBase.class.php +++ b/info.textgrid.middleware.tgauth.rbac/lib/DataBase.class.php @@ -1,9 +1,9 @@ <?php // #################################################################### -// Version: 0.3.3 +// Version: 0.4.0 // Author: Markus Widmer // Created: 09.11.2006 -// Modified: 02.04.2008 +// Modified: 12.07.2008 @@ -108,12 +108,13 @@ class DataBase implements iDataBase { $helper = new Helper(); // Konvertierungsklasse +/* if( $helper->isUtf8( $inFilter ) ) { $inFilter = utf8_decode( $inFilter ); } - +*/ // Eventuell eine Liste von Spalten zusammenstellen, // die zurueckgegeben werden sollen @@ -185,7 +186,7 @@ class DataBase implements iDataBase { } - array_push( &$result, $mysqlResult ); + $result[] = $mysqlResult; } @@ -237,7 +238,7 @@ class DataBase implements iDataBase { } - array_push( &$result, $mysqlResult ); + $result[] = $mysqlResult; } @@ -293,7 +294,7 @@ class DataBase implements iDataBase { // Es wird darauf geprueft, ob wirklich alle Felder, die einen // primaeren Schluessel darstellen, angegeben sind. $keyInData = $keyInData && isset( $inData[$column[$i]['Field']] ) && preg_match( "/.+/", $inData[$column[$i]['Field']] ); - array_push( &$columnPrimaryKey, $column[$i]['Field'] ); + $columnPrimaryKey[] = $column[$i]['Field']; if( $keyInData ) { @@ -330,7 +331,7 @@ class DataBase implements iDataBase { $checkResult = Array(); while( $mysqlResult = mysql_fetch_array( $mysqlQuery, MYSQL_ASSOC ) ) { - array_push( &$checkResult, $mysqlResult ); + $checkResult[] = $mysqlResult; } @@ -408,7 +409,6 @@ class DataBase implements iDataBase { } - // Verbindung mit der Datenbank aufbauen if( $this->hasConnection ) { @@ -417,7 +417,7 @@ class DataBase implements iDataBase { // ist keine Spalte dabei, die ein "auto_increment" enthaelt. // 2. Es sind alle Schluessel vorhanden und der Datensatz existiert bereits in der // Tabelle - if( (!$keyInData && ($columnAutoincrement != "")) || ($keyInData && $allreadyExists) ) { + if( ($keyInData && ($columnAutoincrement == "")) || ($keyInData && $allreadyExists) ) { // Wenn es sich um einen "insert"-Befehl handelt, dann soll die Datenbank // gesperrt werden, um anschliessend den neu eingefuegten Datensatz wieder @@ -429,14 +429,14 @@ class DataBase implements iDataBase { } - trigger_error( "Query: " . $queryString . "\n", E_USER_NOTICE ); + trigger_error( "DataBase::store() Query: " . $queryString . "\n", E_USER_NOTICE ); // Sollte ein Wert UTF8-codiert sein, so muss dies der Datenbank // gesagt werden if( $useUtf8 ) { - trigger_error( "DataBase::store(): Using UTF8 for submission.\n", E_USER_NOTICE ); + trigger_error( "DataBase::store() Using UTF8 for submission.\n", E_USER_NOTICE ); mysql_query( "SET CHARACTER SET \"utf8\"" ); @@ -460,7 +460,7 @@ class DataBase implements iDataBase { $lastInsertResult = Array(); while( $mysqlResult = mysql_fetch_array( $mysqlQuery, MYSQL_ASSOC ) ) { - array_push( &$lastInsertResult, $mysqlResult ); + $lastInsertResult[] = $mysqlResult; } @@ -564,7 +564,7 @@ class DataBase implements iDataBase { } - array_push( &$returnResult, $mysqlResult ); + $returnResult[] = $mysqlResult; } diff --git a/info.textgrid.middleware.tgauth.rbac/lib/Date.class.php b/info.textgrid.middleware.tgauth.rbac/lib/Date.class.php new file mode 100755 index 0000000000000000000000000000000000000000..97439a8488fc1802dd9f19c8e5c759014d73a575 --- /dev/null +++ b/info.textgrid.middleware.tgauth.rbac/lib/Date.class.php @@ -0,0 +1,384 @@ +<?php +// #################################################################### +// Version: 0.2.0 +// Autor: Markus Widmer +// Erstellungsdatum: 16.09.2007 +// Letzte Aenderung: 21.01.2008 + + + + +class Date implements iDate { + + // ## Klassenvariablen ############################################## + private $language = ""; + private $timestamp; + private $arrDate; + + + + + // ## Konstruktor ################################################### + public function __construct( $inTimestamp, $inLanguage = false ) { + + $inTimestamp ? $this->timestamp = $inTimestamp : $this->timestamp = time(); + $inLanguage ? $this->language = $inLanguage : $this->language = "en"; + + + if( $inTimestamp != 0 ) { + + $this->timestamp = $inTimestamp; + $this->fillArrDate(); + + } + else { + + $arrDate = Array(); + + } + + } + + + + + // ## parseGeneralizedTime ########################################## + public function parseGeneralizedTime( $inGeneralizedTime ) { + + $year; // Jahr + $month; // Monat + $day; // Tag + $minute; // Minute + $hour; // Stunde + $second; // Sekunde + + + if( preg_match( "/[0-9]{14}Z/i", $inGeneralizedTime ) ) { + + $year = substr( $inGeneralizedTime, 0, 4 ); + $month = substr( $inGeneralizedTime, 4, 2 ); + $day = substr( $inGeneralizedTime, 6, 2 ); + $hour = substr( $inGeneralizedTime, 8, 2 ); + $minute = substr( $inGeneralizedTime, 10, 2 ); + $second = substr( $inGeneralizedTime, 12, 2 ); + + + $this->timestamp = mktime( $hour, $minute, $second, $month, $day, $year ); + $this->fillArrDate(); + + + return true; + + } + else { + + return false; + + } + + } + + + + + // ## parseMySQLDatetime ########################################### + public function parseMySQLDatetime( $inDatetime ) { + + $pregString = ""; + $tmp = Array(); + + + // Datumsformat mit Zeitangabe in der MySQL Datenbank + $pregString .= "/^[0-9]{4}[-]{1}[0-9]{1,2}[-]{1}[0-9]{1,2}"; + $pregString .= "[\s]+[0-9]{1,2}([:]{1}[0-9]{1,2}){2}$/"; + + + if( preg_match( $pregString, $inDatetime ) ) { + + // Leerzeichen so lange entfernen, bis nur noch + // einzelne Leerzeichen vorhanden sind. + while( preg_match( "/[\s]{2}/", $inDatetime ) ) { + + $inDatetime = preg_replace( "/[\s]{2}/", " ", $inDatetime ); + + } + + + $tmp = preg_split( "/[\s]/", $inDatetime ); + + + if( is_array( $tmp ) ) { + + isset( $tmp[0] ) ? $tmpDate = preg_split( "/[-]/", $tmp[0] ) : $tmpDate = Array(); + isset( $tmp[1] ) ? $tmpTime = preg_split( "/[:]/", $tmp[1] ) : $tmpTime = Array(); + + if( sizeof( $tmpDate ) == 3 ) { + + $this->timestamp = mktime( $tmpTime[0], $tmpTime[1], $tmpTime[2], $tmpDate[1], $tmpDate[2], $tmpDate[0] ); + $this->fillArrDate(); + + + return true; + + } + else { + + return false; + + } + + } + + + return true; + + } + else { + + return false; + + } + + } + + + + + // ## parseMySQLDatetime ########################################### + public function parseMySQLDate( $inDate ) { + + $pregString = ""; + $tmp = Array(); + + + // Datumsformat ohne Zeitangabe in der MySQL Datenbank + $pregString .= "/^[0-9]{4}[-]{1}[0-9]{1,2}[-]{1}[0-9]{1,2}$/"; + + + if( preg_match( $pregString, $inDate ) ) { + + // Alle Leerzeichen entfernen. + $inDate = preg_replace( "/[\s]/", "", $inDate ); + + + $tmpDate = preg_split( "/[-]/", $inDate ); + + if( sizeof( $tmpDate ) == 3 ) { + + $this->timestamp = mktime( 0, 0, 0, $tmpDate[1], $tmpDate[2], $tmpDate[0] ); + $this->fillArrDate(); + + + return true; + + } + else { + + return false; + + } + + } + + } + + + + + // ## setLanguage ################################################### + public function setLanguage( $inLanguage ) { + + $this->language = $inLanguage; + + } + + + + + // ## setTimestamp ################################################## + public function setTimestamp( $inTimestamp ) { + + if( is_int( $inTimestamp ) ) { + + $this->timestamp = $inTimestamp; + return true; + + } + else { + + return false; + + } + + } + + + + + // ## parseDateFirst ################################################ + public function parseDateFirst( $inText ) { + + $tmp = Array(); + $tmpDate = Array(); + $tmpTime = Array( "12", "0", "0" ); + $arrDateAndTime = Array(); + $pregString = ""; + $dateTime = ""; + + + if( preg_match( "/^de$/i", $this->language ) ) { + + // Deutsches Datumsformat + $pregString .= "/^[0-9]{1,2}[.]{1}[0-9]{1,2}[.]{1}[0-9]{4}"; + $pregString .= "([\s]+[0-9]{1,2}([:]{1}[0-9]{1,2}){1,2}?)?$/"; + + + if( preg_match( $pregString, $inText ) ) { + + while( preg_match( "/[\s]{2}/", $inText ) ) { + + $inText = preg_replace( "/[\s]{2}/", " ", $inText ); + + } + + + $tmp = preg_split( "/[\s]/", $inText ); + + } + else { + + return false; + + } + + + if( is_array( $tmp ) ) { + + isset( $tmp[0] ) ? $tmpDate = preg_split( "/[.]/", $tmp[0] ) : false; + isset( $tmp[1] ) ? $tmpTime = preg_split( "/[:]/", $tmp[1] ) : false; + + if( sizeof( $tmpDate ) == 3 ) { + + $this->timestamp = mktime( $tmpTime[0], $tmpTime[1], $tmpTime[2], $tmpDate[1], $tmpDate[0], $tmpDate[2] ); + $this->fillArrDate(); + + + return true; + + } + else { + + return false; + + } + + } + + } + else { + + return false; + + } + + } + + + + + // ## getArray ###################################################### + public function getArray() { + + return $this->arrDate; + + } + + + + + // ## getDateText ################################################### + public function getDateText() { + + if( preg_match( "/^de$/i", $this->language ) ) { + + return $this->arrDate['day'] . "." . $this->arrDate['month'] . "." . $this->arrDate['year']; + + } + else { + + return $this->arrDate['year'] . "-" . $this->arrDate['month'] . "-" . $this->arrDate['day']; + + } + + } + + + + + // ## getDateTimeText ############################################### + public function getDateTimeText() { + + if( preg_match( "/^de$/i", $this->language ) ) { + + return $this->arrDate['day'] . "." . $this->arrDate['month'] . "." . $this->arrDate['year'] . " " . $this->arrDate['hour'] + . ":" . $this->arrDate['minute'] . ":" . $this->arrDate['second']; + + } + else { + + return $this->arrDate['year'] . "-" . $this->arrDate['month'] . "-" . $this->arrDate['day'] . " " . $this->arrDate['hour'] + . ":" . $this->arrDate['minute'] . ":" . $this->arrDate['second']; + + } + + } + + + + + // ## getMySQLDate ################################################## + public function getMySQLDate() { + + return $this->arrDate['year'] . "-" . $this->arrDate['month'] . "-" . $this->arrDate['day']; + + } + + + + + // ## getMySQLDatetime ############################################## + public function getMySQLDatetime() { + + return $this->arrDate['year'] . "-" . $this->arrDate['month'] . "-" . $this->arrDate['day'] . " " . $this->arrDate['hour'] + . ":" . $this->arrDate['minute'] . ":" . $this->arrDate['second']; + + } + + + + + // ## getWeek ####################################################### + public function getWeek() { + + return $this->arrDate['week']; + + } + + + + + // ## fillArrDate ################################################### + private function fillArrDate() { + + $this->arrDate['year'] = date( "Y", $this->timestamp ); + $this->arrDate['month'] = date( "m", $this->timestamp ); + $this->arrDate['week'] = date( "W", $this->timestamp ); + $this->arrDate['day'] = date( "d", $this->timestamp ); + $this->arrDate['hour'] = date( "H", $this->timestamp ); + $this->arrDate['minute'] = date( "i", $this->timestamp ); + $this->arrDate['second'] = date( "s", $this->timestamp ); + + } + +} +?> diff --git a/info.textgrid.middleware.tgauth.rbac/lib/Helper.class.php b/info.textgrid.middleware.tgauth.rbac/lib/Helper.class.php index 8ff17a598582d206e1e47d5f21b620f295b98f82..2ef0f54050594e53c822673fab3144012dddbe15 100755 --- a/info.textgrid.middleware.tgauth.rbac/lib/Helper.class.php +++ b/info.textgrid.middleware.tgauth.rbac/lib/Helper.class.php @@ -1,9 +1,9 @@ <?php // #################################################################### -// Version: 0.6.2 +// Version: 0.6.3 // Author: Markus Widmer // Created: 28.11.2006 -// Modified: 09.04.2008 +// Modified: 27.04.2008 @@ -37,23 +37,21 @@ class Helper implements iHelper { + // ## isUtf8 ######################################################## public function isUtf8( $inString ) { -/* - return preg_match( "%^(?:" - . "[\x09\x0A\x0D\x20-\x7E]" # ASCII - . " | [\xC2-\xDF][\x80-\xBF]" # non-overlong 2-byte - . " | \xE0[\xA0-\xBF][\x80-\xBF]" # excluding overlongs - . " | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}" # straight 3-byte - . " | \xED[\x80-\x9F][\x80-\xBF]" # excluding surrogates - . " | \xF0[\x90-\xBF][\x80-\xBF]{2}" # planes 1-3 - . " | [\xF1-\xF3][\x80-\xBF]{3}" # planes 4-15 - . " | \xF4[\x80-\x8F][\x80-\xBF]{2}" # plane 16 - . " )*$%xs", $inString ); -*/ + return (utf8_encode( utf8_decode( $inString ) ) == $inString); + + } + + + - return (utf8_encode( utf8_decode( $inString ) ) === $inString); + // ## ensureUtf8 #################################################### + public function ensureUtf8( $inString ) { + + return ( $this->isUtf8( $inString ) ? $inString : utf8_encode( $inString ) ); } @@ -185,6 +183,15 @@ class Helper implements iHelper { + // ## stripQuotes ################################################### + public function stripQuotes( $inString, $inReplace = "" ) { + + return rawurldecode( preg_replace( "/(%5C%22)|(%5C%27)/", $inReplace, rawurlencode( $inString ) ) ); + + } + + + /* // ## generalizedtimeToTextDateTime ################################# public function generalizedtimeToTextDateTime( $inDate, $inCountry ) { diff --git a/info.textgrid.middleware.tgauth.rbac/lib/LDAP.class.php b/info.textgrid.middleware.tgauth.rbac/lib/LDAP.class.php index 5522d1e8afb9f10712b5d2dcd2a52ec8d991fb3b..d28c17f7a69a60300982f1af8107dbd0b316cb73 100755 --- a/info.textgrid.middleware.tgauth.rbac/lib/LDAP.class.php +++ b/info.textgrid.middleware.tgauth.rbac/lib/LDAP.class.php @@ -179,12 +179,12 @@ class LDAP implements iLDAP { // ## getEntry ###################################################### - public function getEntry( $inDn ) { + public function getEntry( $inDn, Array $inArrAttribute = null ) { - $ldapSearch = false; // Such-Handler - $ldapEntries = Array(); // Unbearbeitete Ergebnisse - $arrResult = Array(); // Suchergebniss - $i = 0; // Schleifenvariable + $ldapSearch = false; // Handle + $ldapEntries = Array(); // Unmodified search results + $arrResult = Array(); // Wanted search result + $i = 0; // Loop // Im LDAP suchen funktioniert nur ueber eine @@ -201,7 +201,16 @@ class LDAP implements iLDAP { trigger_error( "LDAP::getEntry(): Searching for: " . $inDn . "\n", E_USER_NOTICE ); - $ldapSearch = @ldap_read( $this->connection, $inDn, "(objectClass=*)" ); + if( $inArrAttribute != null ) { + + $ldapSearch = @ldap_read( $this->connection, $inDn, "(objectClass=*)", $inArrAttribute ); + + } + else { + + $ldapSearch = @ldap_read( $this->connection, $inDn, "(objectClass=*)" ); + + } if( $ldapSearch ) { diff --git a/info.textgrid.middleware.tgauth.rbac/lib/Node.class.php b/info.textgrid.middleware.tgauth.rbac/lib/Node.class.php index ab024c7a7d3843c0c8156bd303894ad70f66c168..22b7e37d1ea59f8cf43073856d64981a4344c1a1 100755 --- a/info.textgrid.middleware.tgauth.rbac/lib/Node.class.php +++ b/info.textgrid.middleware.tgauth.rbac/lib/Node.class.php @@ -1,9 +1,9 @@ <?php // #################################################################### -// Version: 0.3.0 +// Version: 0.3.1 // Autor: Markus Widmer // Erstellungsdatum: 11.10.2006 -// Letzte Aenderung: 15.02.2008 +// Letzte Aenderung: 12.07.2008 @@ -12,6 +12,8 @@ class Node implements iNode { // ## Klassenvariablen ############################################## private $value = false; private $name = "NODE"; + private $namespace = ""; + private $arrNamespaceAlias = Array(); private $child = Array(); private $attribute = Array(); @@ -33,16 +35,26 @@ class Node implements iNode { // ## setName ####################################################### - public function setName( $inName ) { + public function setName( $inName, $inNamespace = null ) { - // Der Name darf weder ein Objekt, ein Array oder eine - // ausfuehrbare Funktion sein, um gespeichert zu werden. + // The name must not be an array or an object to be + // stored. if( !is_object( $inName ) && !is_array( $inName ) ) { $this->name = strtolower( $inName ); + // If a namespace is given, store it as well + if( ($inNamespace != null) + && !is_array( $inNamespace ) + && !is_object( $inNamespace ) ) { + + $this->namespace = $inNamespace; + + } + + return true; } @@ -150,6 +162,7 @@ class Node implements iNode { + // ## getValue ###################################################### public function getValue() { @@ -159,6 +172,42 @@ class Node implements iNode { + + // ## setNamespace ################################################## + public function setNamespace( $inNamespace ) { + + if( !is_object( $inNamespace ) + && !is_array( $inNamespace ) ) { + + $this->namespace = $inNamespace; + + } + + } + + + + + // ## getNamespace ################################################## + public function getNamespace() { + + return $this->namespace; + + } + + + + + // ## setNamespaceAlias ############################################# + public function setNamespaceAlias( $inAlias, $inNamespace ) { + + $this->arrNamespaceAlias[$inAlias] = $inNamespace; + + } + + + + // ## addChild ###################################################### public function addChild( iNode $inNode ) { @@ -205,7 +254,7 @@ class Node implements iNode { // ## getChild ###################################################### - public function getChild( $inName, $inNumber ) { + public function getChild( $inName, $inNumber, $inNamespace = null ) { // Es wird auf jeden Fall ein korrekter Knoten // zurueckgegeben, auch wenn keiner gefunden @@ -214,33 +263,41 @@ class Node implements iNode { $wantedNode->setName( $inName ); - // Die Suche nach dem Knoten beginnen und alle - // Kinderknoten ansehen. + // Start the search for the node by looking at every child $i = 0; $n = 0; $flagFound = false; while( ($i < sizeof( $this->child )) && !$flagFound ) { - // Einen Knoten holen + // Get one child node $child = $this->child[$i]; - // Name ist korrekt... + // Name is correct... if( preg_match( "/^" . $child->getName() . "$/i", $inName ) ) { - // Nummer ist korrekt... - if( $inNumber == $n ) { + // If a namespace is given and the node has this + // namespace then it is considered to be the + // one we are looking for. Otherwise it is ignored. + if( ( $inNamespace != null + && ( hash( "md5", $child->getNamespace() ) == hash( "md5", $inNamespace ) ) + || ( isset( $this->arrNamespaceAlias[strtolower($inNamespace)] ) + && hash( "md5", $child->getNamespace() ) == hash( "md5", $this->arrNamespaceAlias[strtolower($inNamespace)] ) ) ) + || ($inNamespace == null) ) { - $flagFound = true; - $wantedNode = $child; + // Number is korrekt... + if( $inNumber == $n ) { - } + $flagFound = true; + $wantedNode = $child; - // Nummer ist nicht korrekt... - else { + } + else { - $n++; + $n++; + + } } @@ -261,7 +318,7 @@ class Node implements iNode { // ## searchChild ################################################### - public function searchChild( $inName, $inAttribute, $inRegex ) { + public function searchChild( $inName, $inAttribute, $inRegex, $inNamespace = null ) { $arrNode = Array(); // Der Rueckgabewert $child = new Node(); // Temporaerer Knoten @@ -270,7 +327,8 @@ class Node implements iNode { for( $i = 0; $i < $this->countChilds( $inName ); $i++ ) { - $child = $this->getChild( $inName, $i ); + $child = $this->getChild( $inName, $i, $inNamespace ); + if( preg_match( $inRegex, $child->getAttribute( $inAttribute ) ) ) { @@ -289,7 +347,7 @@ class Node implements iNode { // ## countChilds ################################################### - public function countChilds( $inName ) { + public function countChilds( $inName, $inNamespace = null ) { $number = 0; // Anzahl der Knoten $i = 0; // Schleifenvariable diff --git a/info.textgrid.middleware.tgauth.rbac/lib/XML.class.php b/info.textgrid.middleware.tgauth.rbac/lib/XML.class.php index 36ece3351d2defecc462e25d520d307d8cbbfaa5..95f612fce8694cdecfe285fe0d9fab39896c97a6 100755 --- a/info.textgrid.middleware.tgauth.rbac/lib/XML.class.php +++ b/info.textgrid.middleware.tgauth.rbac/lib/XML.class.php @@ -95,10 +95,12 @@ class XML implements iXML { // The data needs only to encoded if it is not - // already. In any case they are pared into an array. - // To avoid the need of the Helper class at this point, - // the check will be done directly! - if( utf8_encode( utf8_decode( $inData ) ) === $inData ) { + // already. In any case they are parsed into an array. + // The decision is made funded on the information given + // in the XML file itself. If no information is given, + // we do not encode but use the data as it is. + if( (sizeof( $arrXmlHeader ) == 1) + && !preg_match( "/encoding\s*=\s*.?utf[-]?8/i", $arrXmlHeader[0] ) ) { xml_parse_into_struct( $parser, utf8_encode( $inData ), &$arrVal, &$index ); @@ -164,17 +166,23 @@ class XML implements iXML { // ## parseArrayToNode ############################################## - private function parseArrayToNode( Array $inArray, $inLevel ) { + private function parseArrayToNode( Array $inArray, $inLevel, $inArrNamespace = null ) { $node = new Node(); // Zum Anlegen neuer Knoten $arrNode = Array(); // Array der neu angelegten Knoten $arrAttribute = Array(); // Zwischenspeicher fuer die Attribute + $arrSplit = Array(); $flagFound = false; // Flag, das zur Suche nach dem Knotenende verwendet wird $i = 0; // Schleifenvariable $j = 0; // Schleifenvariable $c = 0; // Schleifenvariable + // Setting the array to be an empty array if it is + // not already set. + $inArrNamespace == null ? $inArrNamespace = Array() : false; + + $i = 0; while( $i < sizeof( $inArray ) ) { @@ -182,7 +190,7 @@ class XML implements iXML { && ($inArray[$i]['level'] == $inLevel) ) { $node = new Node(); - $node->setName( $inArray[$i]['tag'] ); + if( !isset( $inArray[$i]['value'] ) ) { @@ -194,21 +202,72 @@ class XML implements iXML { $node->setValue( trim( $inArray[$i]['value'] ) ); - // Noch die Attribute auslesen und speichern + // Every attribute except the xmlns attributes + // are stored as normal attributes. The xmlns + // is stored as special value in the node. if( isset( $inArray[$i]['attributes'] ) ) { $arrAttribute = $inArray[$i]['attributes']; foreach( $arrAttribute as $key => $value ) { - $node->setAttribute( strtolower( $key ), $value ); + $arrMatch = Array(); + if( preg_match( "/^xmlns:(.+)$/i", $key, &$arrMatch ) ) { + + $inArrNamespace[$arrMatch[1]] = $value; + + } + elseif( preg_match( "/^xmlns$/i", $key ) ) { + + $inArrNamespace['defaultNamespace'] = $value; + + } + else { + + $node->setAttribute( strtolower( $key ), $value ); + + } } } - // Neuen Knoten in den Array einfuegen + // To open the possibility to use the alias instead of the + // namespace while asking a node for childs, the aliases + // in the XML file are passed as well to every node. + foreach( $inArrNamespace as $key => $value ) { + + $node->setNamespaceAlias( strtolower( $key ), $value ); + + } + + + $arrSplit = preg_split( "/[:]/", $inArray[$i]['tag'] ); + + if( (sizeof( $arrSplit ) > 1) + && (isset( $inArrNamespace[$arrSplit[0]] )) ) { + + $node->setName( $arrSplit[1], $inArrNamespace[$arrSplit[0]] ); + + } + else { + + if( isset( $inArrNamespace['defaultNamespace'] ) ) { + + $node->setName( $inArray[$i]['tag'], $inArrNamespace['defaultNamespace'] ); + + } + else { + + $node->setName( $inArray[$i]['tag'] ); + + } + + } + + + // Add the new node to the array $arrNode[] = $node; } @@ -237,37 +296,86 @@ class XML implements iXML { } - # Eine Ebene tiefer bearbeiten. Dazu den Array entsprechend - # "ausschneiden". - $child = $this->parseArrayToNode( array_slice( $inArray, $i + 1, $j - $i - 1 ), $inLevel + 1 ); + # Create a new node + $node = new Node(); - # Neuen Knoten erstellen und Daten hinzufuegen - $node = new Node(); - $node->setName( $inArray[$i]['tag'] ); + // Every attribute except the xmlns attributes + // are stored as normal attributes. The xmlns + // is stored as special value in the node. + if( isset( $inArray[$i]['attributes'] ) ) { - for( $c = 0; $c < sizeof( $child ); $c++ ) { + $arrAttribute = $inArray[$i]['attributes']; - $node->addChild( $child[$c] ); + foreach( $arrAttribute as $key => $value ) { + + $arrMatch = Array(); + if( preg_match( "/^xmlns:(.+)$/i", $key, &$arrMatch ) ) { + + $inArrNamespace[$arrMatch[1]] = $value; + + } + elseif( preg_match( "/^xmlns$/i", $key ) ) { + + $inArrNamespace['defaultNamespace'] = $value; + + } + else { + + $node->setAttribute( strtolower( $key ), $value ); + + } + + } } - // Noch die Attribute auslesen und speichern - if( isset( $inArray[$i]['attributes'] ) ) { + // To open the possibility to use the alias instead of the + // namespace while asking a node for childs, the aliases + // in the XML file are passed as well to every node. + foreach( $inArrNamespace as $key => $value ) { - $arrAttribute = $inArray[$i]['attributes']; + $node->setNamespaceAlias( strtolower( $key ), $value ); - foreach( $arrAttribute as $key => $value ) { + } + + + $arrSplit = preg_split( "/[:]/", $inArray[$i]['tag'] ); + + if( (sizeof( $arrSplit ) > 1) + && (isset( $inArrNamespace[$arrSplit[0]] )) ) { - $node->setAttribute( strtolower( $key ), $value ); + $node->setName( $arrSplit[1], $inArrNamespace[$arrSplit[0]] ); + + } + else { + + if( isset( $inArrNamespace['defaultNamespace'] ) ) { + + $node->setName( $inArray[$i]['tag'], $inArrNamespace['defaultNamespace'] ); } + else { + + $node->setName( $inArray[$i]['tag'] ); + + } + + } + + + $child = $this->parseArrayToNode( array_slice( $inArray, $i + 1, $j - $i - 1 ), $inLevel + 1, $inArrNamespace ); + + + for( $c = 0; $c < sizeof( $child ); $c++ ) { + + $node->addChild( $child[$c] ); } - // Neuen Knoten in den Array einfuegen + // Add the new node to the array $arrNode[] = $node; } @@ -277,7 +385,6 @@ class XML implements iXML { } - // Erhoehen der Schleifenvariable $i++; } diff --git a/info.textgrid.middleware.tgauth.rbac/lib/iDate.interface.php b/info.textgrid.middleware.tgauth.rbac/lib/iDate.interface.php new file mode 100755 index 0000000000000000000000000000000000000000..8e25f35d53e99f4c4b09106d1302bff88f08d0f6 --- /dev/null +++ b/info.textgrid.middleware.tgauth.rbac/lib/iDate.interface.php @@ -0,0 +1,19 @@ +<?php +interface iDate { + + public function __construct( $inTimestamp, $inLanguage = false ); + public function parseMySQLDatetime( $inDatetime ); + public function parseMySQLDate( $inDate ); + public function parseGeneralizedTime( $inGeneralizedTime ); + public function setLanguage( $inLanguage ); + public function setTimestamp( $inTimestamp ); + public function parseDateFirst( $inText ); + public function getArray(); + public function getDateText(); + public function getDateTimeText(); + public function getMySQLDate(); + public function getMySQLDatetime(); + public function getWeek(); + +} +?> diff --git a/info.textgrid.middleware.tgauth.rbac/lib/iXML.interface.php b/info.textgrid.middleware.tgauth.rbac/lib/iXML.interface.php index da0f18a8d6e28e30c9dcaa900cf400f752c2fe77..132a5d0039be10feef6febbc3308691ec6115b75 100755 --- a/info.textgrid.middleware.tgauth.rbac/lib/iXML.interface.php +++ b/info.textgrid.middleware.tgauth.rbac/lib/iXML.interface.php @@ -2,6 +2,7 @@ interface iXML { public function parse( $inData, $inName = "default" ); + public function parseFile( $inFilename, $inName = "default" ); public function getRoot( $inName = "default" ); } diff --git a/info.textgrid.middleware.tgauth.rbac/rbac/RBAC.class.php b/info.textgrid.middleware.tgauth.rbac/rbac/RBAC.class.php index f928ffe6b462c2de81af7be474e70f1d64ce8163..7120a3591c9e558b5e760222092c384bd73a4032 100755 --- a/info.textgrid.middleware.tgauth.rbac/rbac/RBAC.class.php +++ b/info.textgrid.middleware.tgauth.rbac/rbac/RBAC.class.php @@ -1,9 +1,9 @@ <?php // #################################################################### -// Version: 0.2.0 +// Version: 0.2.1 // Autor: Markus Widmer // Erstellungsdatum: 31.10.2007 -// Letzte Aenderung: 03.11.2007 +// Letzte Aenderung: 21.06.2008 @@ -284,7 +284,7 @@ class RBAC { foreach( $this->arrEvent[$inForFunction][$inEvent] as $index => $eventListener ) { - $evalString = "\$newContext = \$this->arrExtension[" . $eventListener['class'] . "]->" . $eventListener['call'] . "( \$newContext );"; + $evalString = "\$newContext = \$this->arrExtension['" . $eventListener['class'] . "']->" . $eventListener['call'] . "( \$newContext );"; eval( $evalString ); diff --git a/info.textgrid.middleware.tgauth.rbac/rbac/RBACcore.class.php b/info.textgrid.middleware.tgauth.rbac/rbac/RBACcore.class.php index f91433dff91b3c9f9e82d6ce7da119c917be7eda..effadab89f2c0e179f99487ce3469b58bb3139a4 100755 --- a/info.textgrid.middleware.tgauth.rbac/rbac/RBACcore.class.php +++ b/info.textgrid.middleware.tgauth.rbac/rbac/RBACcore.class.php @@ -1,9 +1,9 @@ <?php // #################################################################### -// Version: 0.2.5 +// Version: 0.2.6 // Author: Markus Widmer // Created: 31.07.2007 -// Modified: 16.05.2008 +// Modified: 09.07.2008 // Requiring these interfaces if the RBAC-Framework @@ -818,9 +818,6 @@ class RBACcore implements iRBACcore { } - - - if( isset( $arrRoleEntry['dn'] ) ) { $arrUser = $arrRoleEntry[$this->conf->getValue( "role", "assignedattribute" )]; @@ -1205,7 +1202,14 @@ class RBACcore implements iRBACcore { // through role hirarchy. $filter = "(&" . $this->conf->getValue( "resource", "filter" ); $filter .= "(|(" . $this->conf->getValue( "resource", "namingattribute" ) . "=" . $inResource . ")"; - $filter .= " (" . $this->conf->getValue( "resource", "aliasattribute" ) . "=" . $inResource . "))(|"; + + if( preg_match( "/.+/", $this->conf->getValue( "resource", "aliasattribute" ) ) ) { + + $filter .= " (" . $this->conf->getValue( "resource", "aliasattribute" ) . "=" . $inResource . ")"; + + } + + $filter .= ")(|"; for( $i = 0; $i < sizeof( $arrSessionRole ); $i++ ) { @@ -1896,7 +1900,14 @@ class RBACcore implements iRBACcore { // Create a filter to get the resource $filter = "(&" . $this->conf->getValue( "resource", "filter" ); $filter .= "(|(" . $this->conf->getValue( "resource", "namingattribute" ) . "=" . $inResource . ")"; - $filter .= " (" . $this->conf->getValue( "resource", "aliasattribute" ) . "=" . $inResource . ")))"; + + if( preg_match( "/.+/", $this->conf->getValue( "resource", "aliasattribute" ) ) ) { + + $filter .= " (" . $this->conf->getValue( "resource", "aliasattribute" ) . "=" . $inResource . ")"; + + } + + $filter .= "))"; // Get the resource @@ -1905,7 +1916,7 @@ class RBACcore implements iRBACcore { // Get the role - $arrRoleEntry = $this->conn['resource']->getEntry( $inRole ); + $arrRoleEntry = $this->conn['role']->getEntry( $inRole ); // The resource has to exist and has to be uniqueue @@ -2008,7 +2019,14 @@ class RBACcore implements iRBACcore { // Create a filter to get the resource $filter = "(&" . $this->conf->getValue( "resource", "filter" ); $filter .= "(|(" . $this->conf->getValue( "resource", "namingattribute" ) . "=" . $inResource . ")"; - $filter .= "(" . $this->conf->getValue( "resource", "aliasattribute" ) . "=" . $inResource . ")))"; + + if( preg_match( "/.+/", $this->conf->getValue( "resource", "aliasattribute" ) ) ) { + + $filter .= "(" . $this->conf->getValue( "resource", "aliasattribute" ) . "=" . $inResource . ")"; + + } + + $filter .= "))"; // Get the resource