diff --git a/.gitignore b/.gitignore index ca089f967a73f425cf203e4d8d4ea5339ebf6e4b..2b083ce9aec60dee499bc227be0e5fa04f61d3c0 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,9 @@ nbproject /database/logs.db /public_html/deployment/dummy.db /public_html/deployment/classes/ramdb.class.php -/public_html/~cache/ \ No newline at end of file +/public_html/~cache/ +/public_html/deployment/classes/spooler-handler.class.php +/public_html/deployment/pages/act_jstest.php +/public_html/deployment/classes/html-adminltetest.tpl.php +/public_html/deployment/adminlte/ +/config/inc_user2projects.php \ No newline at end of file diff --git a/config/inc_roles.php b/config/inc_roles.php new file mode 100644 index 0000000000000000000000000000000000000000..3c1b62437c6917085e0dc6e3d178926630f68b36 --- /dev/null +++ b/config/inc_roles.php @@ -0,0 +1,84 @@ +<?php +/* + * IML DEPLOYMENT GUI + * ROLES and its permissions + * + * - page_login permission for all to show login form + * + */ + +return array( + "all" => array( + "page_login" + ), + "authenticated" => array( + "page_overview", + + "page_build", + "page_cleanup", + "page_setup", + + // see $oProject->renderLink() and $oProject->[äction] + "project-action-default", + "project-action-accept-preview", + "project-action-build", + "project-action-cleanup", + "project-action-deploy-preview", + "project-action-overview", + "project-action-phase", + "project-action-setup", + ), + + + "admin" => array( + + "page_build", + "page_cleanup", + "page_delete", + "page_setup", + + // see $oProject->renderLink() and $oProject->[äction] + "project-action-default", + "project-action-accept", + "project-action-build", + "project-action-cleanup", + "project-action-create", + "project-action-deploy", + "project-action-new", + "project-action-overview", + "project-action-phase", + "project-action-setup", + ), + + // ----- wenn es mal eine feinere Granulierung braucht, muss man eine + // User-Admin programmieren + + /* + "authenticated_" => array( + "page_overview", + ), + "developer_" => array( + "page_build", + "page_cleanup", + "page_setup", + // see $oProject->renderLink() and $oProject->[äction] + "project-action-default", + "project-action-accept-preview", + "project-action-build", + "project-action-cleanup", + "project-action-deploy-preview", + "project-action-overview", + "project-action-phase", + "project-action-setup", + ), + "projectmanager_" => array( + "project-action-default", + "project-action-accept-preview", + "project-action-accept-stage", + // "project-action-deploy", + "project-action-overview", + "project-action-phase", + ), + */ + +); diff --git a/config/inc_user2roles.php b/config/inc_user2roles.php new file mode 100644 index 0000000000000000000000000000000000000000..19e2b5621bbcc7d0234e861b9c581c494f1b185f --- /dev/null +++ b/config/inc_user2roles.php @@ -0,0 +1,18 @@ +<?php +/* + * IML DEPLOYMENT GUI + * USERS and assigned roles + * + * remark: Every user logged in is member of "authenticated" + */ + +return array( + // "authenticated" => array(), + // "developer" => array(), + // "projectmanager" => array(), + "admin" => array( + "hahn", + "dschueler", + ), + +); diff --git a/config/lang/de.json b/config/lang/de.json index b6379dace8cb85a2517861a68ab8abcc8641fca0..d24fa994bea92439c53095d54f96369433ff6c19 100644 --- a/config/lang/de.json +++ b/config/lang/de.json @@ -13,6 +13,7 @@ "menu-project-settings": "Projekteinstellungen", "menu-project-delete": "Projekt löschen", "menu-project-phases": "Phasen", + "menu-login": "Anmelden/ Abmelden", "menu-help": "Hilfe", "menu-help-classes": "verwendete Klassen", @@ -181,6 +182,15 @@ "page-deploy-info-ignore-deploytime": "Deploy-Zeitfenster ignorieren.<br>Nicht jedes Update muss sauber durchlaufen. Nur aktivieren, wenn einer der Entwickler und/ oder ein Sysadmin zur Hand ist.", "page-deploy-buttonlabel": "Auf [%s] ausrollen", + "page-login-info": "Anmeldung", + "page-login-info-introtext": "Sie sind nicht angemeldet. Geben Sie Benutzernamen und Passwort ein, um sich anzumelden.", + "page-login-auth-failed": "Tut mir leid, die Anmeldung ist fehlgeschlagen.", + "page-login-userloggedin": "Sie sind mit den folgenden Benutzernamen angemeldet:", + "page-login-usergroups": "Ihnen zugeordnete Gruppen:", + "page-login-userprojects": "... und Projekte:", + "page-login-username": "Benutzername", + "page-login-password": "Passwort", + "page-overview-no-phase": "Es wurde noch keine URL in keiner der Phasen definiert", "page-overview-phase-infos": "Für dieses Projekt sind folgende Phasen konfiguriert:", @@ -232,6 +242,8 @@ "inactive": "inaktiv", "info": "Info", "infos": "Infos", + "login": "Anmelden", + "logoff": "Abmelden", "ok": "OK", "new-project": "neues Projekt", "new-project-hint": "ein neues Projekt anlegen", diff --git a/config/lang/en.json b/config/lang/en.json index c5d69d34108ed90a94649a231cd039262ff27bf0..5ea90cf4fe0be92e3c4ccb76c51cf6564a1d9351 100644 --- a/config/lang/en.json +++ b/config/lang/en.json @@ -12,6 +12,7 @@ "menu-project-settings": "Project settings", "menu-project-delete": "Delete project", "menu-project-phases": "Phases", + "menu-login": "Login/ Logoff", "menu-help": "Help", "menu-help-classes": "Used classes", @@ -182,6 +183,15 @@ "page-deploy-info-ignore-deploytime": "Ignore deploy time window.<br>Not each update mus run successfully. Do not activate this option if no developer and/ or a sysadmin is available.", "page-deploy-buttonlabel": "install to [%s]", + "page-login-info": "Login", + "page-login-info-introtext": "You are not logged in. Enter your username and password.", + "page-login-auth-failed": "Sorry the authentication failed.", + "page-login-userloggedin": "You are logged in as the following user:", + "page-login-usergroups": "You are in the following groups:", + "page-login-userprojects": "... and these projects:", + "page-login-username": "Username", + "page-login-password": "Password", + "page-overview-no-phase": "This project has no active phase. No url was entered to any phase.", "page-overview-phase-infos": "This project has these phases:", @@ -234,6 +244,8 @@ "inactive": "inactive", "info": "Info", "infos": "Infos", + "login": "Login", + "logoff": "Logoff", "ok": "OK", "new-project": "new project", "new-project-hint": "create a new project", diff --git a/public_html/deployment/classes/actionlog.class.php b/public_html/deployment/classes/actionlog.class.php index 4afecb48d17207514a765269e47885a75711e801..0a8991616d26ef670de108649e8d8e07f38e0602 100644 --- a/public_html/deployment/classes/actionlog.class.php +++ b/public_html/deployment/classes/actionlog.class.php @@ -58,6 +58,7 @@ class Actionlog { * create sqlite database - called in constructor if the file does not exist */ private function _createDb() { + echo "try to create file $this->_dbfile ...<br>\n"; return $this->_makeQuery($this->_sCreate); } diff --git a/public_html/deployment/classes/base.class.php b/public_html/deployment/classes/base.class.php index 8ef4c3559a3e833105a9312dbe5aecf0c54ded5a..0a647f270142ef7d438d24d78bac841bff94d873 100644 --- a/public_html/deployment/classes/base.class.php +++ b/public_html/deployment/classes/base.class.php @@ -14,13 +14,9 @@ class base { /** * init user with optional given user * @param type $sUser - */ - public function __construct(){ + public function __construct($a=false){ $this->oUser=new user(); - - if (method_exists($this, "_construct2")){ - $this->_construct2(); - } } + */ } diff --git a/public_html/deployment/classes/formgen.class.php b/public_html/deployment/classes/formgen.class.php index 24cc4ebde35452b56bb6aa83e6e3f708dfcf0aff..bff052c643fdac5bbfd2c466bdc96426d015ebd4 100644 --- a/public_html/deployment/classes/formgen.class.php +++ b/public_html/deployment/classes/formgen.class.php @@ -249,8 +249,9 @@ class formgen { break; case "text": + case "password": $this->_checkReqiredKeys($elementData, array("name")); - $sFormElement.=' <input type="text" id="' . $sId . '" class="form-control col-sm-10" '; + $sFormElement.=' <input type="'.$elementData["type"].'" id="' . $sId . '" class="form-control col-sm-10" '; $aAllowedHtmlAttributes["text"] = explode(",", ""); $sFormElement.=$this->_addHtmlAtrributes(explode(",", "$sDefaultAttributes,name,list,disabled,onkeyup,onkeydown,onchange,pattern,placeholder,required,size,value"), $elementData); // $sFormElement.=$this->_addHtmlAtrributes(array("name", "value", "size", "placeholder", "required"), $elementData); diff --git a/public_html/deployment/classes/ldap.class.php b/public_html/deployment/classes/ldap.class.php new file mode 100644 index 0000000000000000000000000000000000000000..4d9b1f3ed428aebdc170735fb4d74f8160e69ab9 --- /dev/null +++ b/public_html/deployment/classes/ldap.class.php @@ -0,0 +1,474 @@ +<?php + +/** + * IML LDAP CONNECTOR FOR USER AUTHENTICATION + * + * @author axel.hahn@iml.unibe.ch + */ +class imlldap { + + private $_aLdap = array( + 'server' => false, + 'port' => false, + 'DnLookupUser' => false, // ldap rdn oder dn + 'PwLookupUser' => false, + 'DnUserNode' => false, // ou=People... + 'DnAppNode' => false, // cn=AppGroup... + 'protoVersion' => 3, + 'debugLevel' => 0, + ); + private $_ldapConn = false; + private $_ldapBind = false; + var $bDebug = false; + + /** + * constructor + * @param array $aConfig optional set ldap connection + */ + public function __construct($aConfig = array()) { + if (!function_exists("ldap_connect")){ + die(__CLASS__ . " ERROR: php-ldap module is not installed on this server."); + } + if (count($aConfig)) { + $this->setConfig($aConfig); + } + } + + public function __destruct() { + $this->close(); + } + + + // ---------------------------------------------------------------------- + // write debug text + // ---------------------------------------------------------------------- + + /** + * turn debug messages on; + * if this detail level is not enough, set a value with key debugLevel in + * ldap config array + * @see setConfig() + */ + public function debugOn(){ + $this->bDebug=true; + if($this->_aLdap['debugLevel']){ + $this->_w(__FUNCTION__ . ' setting debug level ' . $this->_aLdap['debugLevel']); + ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, $this->_aLdap['debugLevel']); + } + } + + /** + * turn debug messages off + */ + public function debugOff(){ + $this->bDebug=false; + ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 0); + } + + + private function _w($sText) { + if (!$this->bDebug) { + return false; + } + echo __CLASS__ . ' DEBUG: ' . $sText . "<br>\n"; + return true; + } + + // ---------------------------------------------------------------------- + // setup + // ---------------------------------------------------------------------- + + /** + * set a ldap config + * + * @param array $aConfig new config items + * 'server' => 'ldaps://ldap.example.com', + * 'port' => 636, + * 'DnLookupUser' => 'cn=Lookup,ou=ServiceAccounts,dc=org,dc=example.com', // ldap rdn oder dn + * 'PwLookupUser' => 'IkHEFFzlZ...99j0h8WdI0LrLhxU', // password + * 'DnUserNode' => 'ou=People,ou=ORG,dc=org,dc=example.com', + * 'DnAppNode' => '' optional dn ... if a user must be member of a given group + * 'protoVersion' => 3 + * 'debugLevel' => 0 // for debugging set higher 0 AND call debugOn() + */ + public function setConfig($aConfig = array()) { + if (is_array($aConfig)) { + foreach (array_keys($this->_aLdap) as $sKey) { + if (array_key_exists($sKey, $aConfig)) { + $this->_w(__FUNCTION__ . ' setting ldap '.$sKey.' = '. $aConfig[$sKey]); + $this->_aLdap[$sKey] = $aConfig[$sKey]; + } + } + } + + } + + // ---------------------------------------------------------------------- + // ldap lowlevel functions + // ---------------------------------------------------------------------- + + /** + * close an existing ldap connection + */ + public function close() { + if ($this->_ldapConn) { + $this->_w(__FUNCTION__ . ' closing connection.'); + ldap_close($this->_ldapConn); + } else { + $this->_w(__FUNCTION__ . ' SKIP close.'); + } + + $this->_ldapConn = false; + } + + /** + * connect to ldap + */ + public function connect() { + + if (!array_key_exists('server', $this->_aLdap) || !$this->_aLdap['server']) { + die(__CLASS__ . " ERROR: no ldap server was setup set. Use setConfig() first."); + } + + if ($this->_ldapConn) { + $this->close(); + } + + $this->_w(__FUNCTION__ . ' connect to ' . $this->_aLdap['server'] . ':' . $this->_aLdap['port']); + $this->_ldapConn = ldap_connect($this->_aLdap['server'], $this->_aLdap['port']); + if (!$this->_ldapConn) { + die(__CLASS__ . " ERROR: ldap connect failed."); + } + $this->_w(__FUNCTION__ . ' OK, connected.'); + + if($this->_aLdap['protoVersion']){ + $this->_w(__FUNCTION__ . ' setting protocol version .' . $this->_aLdap['protoVersion']); + ldap_set_option($this->_ldapConn, LDAP_OPT_PROTOCOL_VERSION, $this->_aLdap['protoVersion']); + } + + ldap_set_option($this->_ldapConn, LDAP_OPT_REFERRALS, 0); // for AD MS Windows + } + + /** + * ldap bind connects with a ldap user. + * If the ldap connection was not opened yet the connection will be established. + * If a binding exists it will be unbind + * + * @see connect() + * @see unbind() + * + * @param string $sUser username + * @param string $sPw password + */ + public function bind($sUser, $sPw='') { + + if(!$this->_ldapConn){ + $this->connect(); + } + if($this->_ldapBind){ + $this->unbind(); + } + + if(!$sUser){ + $this->_w(__FUNCTION__ . ' ERROR: no user was set as first param.'); + die("ERROR: no user was given to connect to ldap."); + } + $this->_w(__FUNCTION__ . ' with user ' . $sUser. ' PW '.$sPw); + + $this->_ldapBind = @ldap_bind($this->_ldapConn, $sUser, $sPw); + if (!$this->_ldapBind) { + $this->_w(__FUNCTION__ . ' failed with er error ' . ldap_error($this->_ldapConn)); + return false; + } + $this->_w(__FUNCTION__ . ' OK, successful.'); + return true; + } + + /** + * ldap unbind ... if a bind exists + */ + public function unbind() { + if ($this->_ldapBind && !is_bool($this->_ldapBind)) { + $this->_w(__FUNCTION__ . ' ...'); + ldap_unbind($this->_ldapBind); + } else { + $this->_w(__FUNCTION__ . ' SKIP.'); + } + $this->_ldapBind = false; + } + + // ---------------------------------------------------------------------- + // ldap highlevel functions + // ---------------------------------------------------------------------- + + /** + * search in ldap directory and get result as array + * + * @param string $sSearchFilter filter in ldap filter syntax + * @param array $aAttributesToGet flat array of attributes to fetch + * @return array + */ + public function search($sSearchFilter, $aAttributesToGet=array("*")) { + if (!$this->_ldapBind) { + $this->bind($this->_aLdap['DnLookupUser'], $this->_aLdap['PwLookupUser']); + } + + $this->_w(__FUNCTION__ . ' DN = '.$this->_aLdap['DnUserNode'] . ' filter = '.$sSearchFilter); + + $oLdapSearch = ldap_search( + $this->_ldapConn, + $this->_aLdap['DnUserNode'], + $sSearchFilter, + $aAttributesToGet + ); + + $aItems = $oLdapSearch?ldap_get_entries($this->_ldapConn, $oLdapSearch):false; + return $aItems; + } + + /** + * search user by a given username or email address. + * It returns false if the user does not exist or is + * not member of the group 'DnAppNode' (if it was set). + * + * @param type $sUser user id or email to search + * @param type $aAttributesToGet i.e. array("ou", "sn", "vorname", "mail", "uid", "memberOf") + * @return boolean + */ + public function getUserInfo($sUser, $aAttributesToGet=array("*")) { + if (!$this->_ldapBind) { + $this->bind($this->_aLdap['DnLookupUser'], $this->_aLdap['PwLookupUser']); + } + + // generate search filter + $sSearchFilter = (strpos($sUser, '@'))?"(mail=$sUser)" : "(uid=$sUser)"; + if($this->_aLdap['DnAppNode']){ + $sSearchFilter.='(memberof='.$this->_aLdap['DnAppNode'] .')'; + } + $sSearchFilter='(&'.$sSearchFilter.')'; + + $aItems = $this->search($sSearchFilter, $aAttributesToGet); + + if(count($aItems)==2){ + $this->_w(__FUNCTION__ . ' OK: I got a single result: ' . print_r($aItems[0],1) ); + return $aItems[0]; + } + return false; + } + + /** + * search for a DN entry with the lookup user by a given username or + * email address. It returns false if the user does not exist or is + * not member of the group 'DnAppNode' (if it was set). + * + * @param type $sUser + * @return string + */ + public function getUserDn($sUser) { + $this->_w(__FUNCTION__ . '('.$sUser.')'); + $aItem=$this->getUserInfo($sUser, array("dn")); + if(is_array($aItem) && array_key_exists('dn', $aItem)){ + $this->_w(__FUNCTION__ . ' OK: dn was found ' . $aItem['dn']); + return $aItem['dn']; + } + return false; + } + + /** + * set a password for a given user; + * this requires a ldap bind with master/ admin account + * + * @param string $sUser username or email + * @param string $sPW password + * @return boolean + */ + public function setPassword($sUser, $sPW){ + if (!$this->_ldapBind) { + $this->bind($this->_aLdap['DnLookupUser'], $this->_aLdap['PwLookupUser']); + } + $sDn=$this->getUserDn($sUser); + if ($sDn){ + return ldap_mod_replace ($this->_ldapConn, $sDn, array('userpassword' => "{MD5}".base64_encode(pack("H*",md5($sPW))))); + } + $this->_w(__FUNCTION__ . ' dn not found (user does not exist in ldap) ' . $sUser); + return false; + } + + /** + * update an ldap object + * this requires a ldap bind with master/ admin account + * + * @param string $sDn dn to update + * @param string $aItem array of new ldap properties + * @return boolean + */ + public function objAdd($sDn, $aItem){ + $this->_w(__FUNCTION__ . '("'.$sDn.'", [array])'); + if (!$this->_ldapBind) { + $this->bind($this->_aLdap['DnLookupUser'], $this->_aLdap['PwLookupUser']); + } + return ldap_add($this->_ldapConn, $sDn, $aItem); + } + + /** + * update an ldap attribute + * this requires a ldap bind with master/ admin account + * + * @param string $sDn dn to update + * @param string $aItem array of new ldap properties + * @return boolean + */ + public function objAddAttr($sDn, $aItem){ + $this->_w(__FUNCTION__ . '("'.$sDn.'", [array])'); + if (!$this->_ldapBind) { + $this->bind($this->_aLdap['DnLookupUser'], $this->_aLdap['PwLookupUser']); + } + if ($sDn && is_array($aItem)){ + $this->_w(__FUNCTION__ . ' ' . $this->_ldapConn ? 'Verbindung da' : 'kein LDAP Connect'); + $this->_w(__FUNCTION__ . ' ldap_mod_add($this->_ldapConn, "'.$sDn.'", ' . print_r($aItem,1) . ')'); + if (!ldap_mod_add($this->_ldapConn, $sDn, $aItem)){ + $this->_w(__FUNCTION__ . ' ERROR: ' . ldap_error($this->_ldapConn)); + return false; + } return true; + } + $this->_w(__FUNCTION__ . ' dn not found (item does not exist in ldap) or item was not ann array ' . print_r($aItem,1)); + return false; + } + + /** + * update an ldap object + * this requires a ldap bind with master/ admin account + * + * @param string $sDn full DN where to update the item + * @param array $aItem updated entry + * @return boolean + */ + public function objUpdate($sDn, $aItem){ + $this->_w(__FUNCTION__ . '("'.$sDn.'", [array])'); + if (!$this->_ldapBind) { + $this->bind($this->_aLdap['DnLookupUser'], $this->_aLdap['PwLookupUser']); + } + if ($sDn && is_array($aItem)){ + return ldap_mod_replace($this->_ldapConn, $sDn, $aItem); + } + $this->_w(__FUNCTION__ . ' dn not found (item does not exist in ldap) ' . print_r($aItem,1)); + return false; + } + + + /** + * delete an ldap object + * this requires a ldap bind with master/ admin account + * + * @param string $sDn full DN to remove + * @return boolean + */ + public function objDelete($sDn){ + $this->_w(__FUNCTION__ . '("'.$sDn.'")'); + if (!$this->_ldapBind) { + $this->bind($this->_aLdap['DnLookupUser'], $this->_aLdap['PwLookupUser']); + } + + if ($sDn){ + if (!ldap_delete($this->_ldapConn, $sDn)){ + $this->_w(__FUNCTION__ . ' ERROR: ' . ldap_error($this->_ldapConn)); + return false; + } return true; + } + $this->_w(__FUNCTION__ . ' missing parameter for DN'); + return false; + } + + /** + * delete attributes of an ldap object + * this requires a ldap bind with master/ admin account + * + * TODO: Test me + * + * @param string $sDn DN + * @param string $aItem item to remove + * @return boolean + */ + public function objDeleteAttr($sDn, $aItem){ + $this->_w(__FUNCTION__ . '("'.$sDn.'", [array])'); + if (!$this->_ldapBind) { + $this->bind($this->_aLdap['DnLookupUser'], $this->_aLdap['PwLookupUser']); + } + if ($sDn && is_array($aItem)){ + $this->_w(__FUNCTION__ . ' ' . $this->_ldapConn ? 'Verbindung da' : 'kein LDAP Connect'); + $this->_w(__FUNCTION__ . ' ldap_mod_del($this->_ldapConn, "'.$sDn.'", ' . print_r($aItem,1) . ')'); + if (!ldap_mod_del($this->_ldapConn, $sDn, $aItem)){ + $this->_w(__FUNCTION__ . ' ERROR: ' . ldap_error($this->_ldapConn)); + return false; + } return true; + } + $this->_w(__FUNCTION__ . ' dn not found (item does not exist in ldap) or item was not ann array ' . print_r($aItem,1)); + return false; + } + + /** + * create a new user item + * this requires a ldap bind with master/ admin account + * + * @param array $aItem ldap properties + * @param string $sDn optional DN where to create the user + * @return boolean + */ + public function userAdd($aItem, $sDn=false){ + if (!$sDn){ + $sDn='cn='.$aItem['cn'].','.$this->_aLdap['DnUserNode']; + } + $this->_w(__FUNCTION__ . '([array], "'.$sDn.'")'); + if ($sDn){ + return $this->objAdd($sDn, $aItem); + } + $this->_w(__FUNCTION__ . ' node dn where to put the user was not found; set a value DnUserNode in ldap config or set it as 2nd parameter ' . print_r($aItem,1)); + return false; + } + + /** + * delete a user + * this requires a ldap bind with master/ admin account + * + * @param string $sUser user to update + * @param string $sPW new password to set + * @return boolean + */ + public function userDelete($sUserDn){ + $this->_w(__FUNCTION__ . '('.$sUserDn.')'); + return $this->objDelete($sUserDn); + } + + /** + * update an ldap object + * this requires a ldap bind with master/ admin account + * + * @param string $sUser user to update + * @param string $sPW new password to set + * @return boolean + */ + public function userUpdate($aItem){ + $this->_w(__FUNCTION__ . '([array])'); + $sDn=$this->getUserDn($aItem['uid']); + if ($sDn){ + return $this->objUpdate($sDn, $aItem); + } + $this->_w(__FUNCTION__ . ' dn not found (user does not exist in ldap) ' . $sDn); + return false; + } + /** + * verify user and password + * @param string $sUser username or email + * @param string $sPW password + * @return boolean + */ + public function verifyPassword($sUser, $sPW){ + $sDn=$this->getUserDn($sUser); + if ($sDn){ + return $this->bind($sDn, $sPW); + } + $this->_w(__FUNCTION__ . ' dn not found (user does not exist in ldap) ' . $sUser); + return false; + } + +} diff --git a/public_html/deployment/classes/project.class.php b/public_html/deployment/classes/project.class.php index bc3bd40658d35dbe9765a4e5b11e391b252c7b10..282bcfb66c6f40bdca5fffa068a98095e8280435 100644 --- a/public_html/deployment/classes/project.class.php +++ b/public_html/deployment/classes/project.class.php @@ -91,6 +91,7 @@ class project extends base { * @param string $sId id of the project */ public function __construct($sId = false) { + $this->oUser=new user(); $this->_readConfig(); if ($sId) { $this->setProjectById($sId); @@ -545,6 +546,9 @@ class project extends base { */ public function cleanupArchive($bDeleteAll = false) { $aUnused = array(); + if (!$this->oUser->hasPermission("project-action-cleanup")){ + return $this->oUser->showDenied(); + } $sDir = $this->_getProjectArchiveDir(); $this->getVersions(); @@ -583,6 +587,9 @@ class project extends base { */ public function cleanupBuilds() { $this->log(__FUNCTION__ . " start"); + if (!$this->oUser->hasPermission("project-action-cleanup")){ + return $this->oUser->showDenied(); + } $sDir = $this->_getBuildDir(); $aDirlist = array(); $aDelete = array(); @@ -613,6 +620,9 @@ class project extends base { */ public function cleanupVcsCache($iAge = 0) { $this->log(__FUNCTION__ . " start"); + if (!$this->oUser->hasPermission("project-action-cleanup")){ + return $this->oUser->showDenied(); + } $this->_initVcs(); if ($this->_oVcs) { if (!method_exists($this->_oVcs, "cleanupCache")) { @@ -834,6 +844,12 @@ class project extends base { * @param type $sPhase current phase */ public function canAcceptPhase($sPhase = false) { + if (!$this->oUser->hasPermission("project-action-accept") + && !$this->oUser->hasPermission("project-action-accept-$sPhase") + ){ + // echo $this->oUser->showDenied(); + return false; + } if (!$sPhase) { // for better performance: skip check on overview page @@ -1221,6 +1237,9 @@ class project extends base { */ public function build($sTmpFile = false) { $this->log(__FUNCTION__ . " start"); + if (!$this->oUser->hasPermission("project-action-build")){ + return $this->oUser->showDenied(); + } global $aParams; $sReturn = false; @@ -1621,6 +1640,11 @@ class project extends base { */ public function deploy($sPhase, $bIgnoreDeploytimes = false) { $this->log(__FUNCTION__ . " start"); + if (!$this->oUser->hasPermission("project-action-deploy") + && !$this->oUser->hasPermission("project-action-deploy-$sPhase") + ){ + return $this->oUser->showDenied(); + } $aActionList = array( 'iActive' => 0, 'label' => t("deploy"), @@ -1788,6 +1812,12 @@ class project extends base { */ public function accept($sPhase) { $this->log(__FUNCTION__ . " start"); + if (!$this->oUser->hasPermission("project-action-accept") + && !$this->oUser->hasPermission("project-action-accept-$sPhase") + ){ + return $this->oUser->showDenied(); + } + $sReturn = "<h2>" . t("accept") . " " . $this->getLabel() . " :: $sPhase</h2>"; $this->_logaction(t('starting') . " accept($sPhase)", __FUNCTION__); @@ -1820,6 +1850,9 @@ class project extends base { */ public function saveConfig($aData = false) { $this->log(__FUNCTION__ . " start"); + if (!$this->oUser->hasPermission("project-action-setup")){ + return $this->oUser->showDenied(); + } $this->_logaction(t('starting') . " saveConfig(...)", __FUNCTION__); if (!$aData) { $aData = $_POST; @@ -1859,6 +1892,9 @@ class project extends base { */ public function create($sId) { $this->log(__FUNCTION__ . " start"); + if (!$this->oUser->hasPermission("project-action-create")){ + return $this->oUser->showDenied(); + } $this->_logaction(t('starting') . " create($sId)", __FUNCTION__); if (!$sId) { $sError = t("class-project-error-create-missing-id"); @@ -1924,6 +1960,9 @@ class project extends base { */ public function delete($aOptions = array()) { $this->log(__FUNCTION__ . " start"); + if (!$this->oUser->hasPermission("project-action-delete")){ + return $this->oUser->showDenied(); + } $sCfgfile = $this->_getConfigFile($this->_aConfig["id"]); if (!file_exists($sCfgfile)) { return t("class-project-error-delete-project-no-configfile"); @@ -2072,15 +2111,13 @@ class project extends base { 'label' => t('setup') ), ); - // TODO: remove $sRole and use user roles /* - $sNeedsRole = ( - array_key_exists($sFunction, $aLinkdata) && array_key_exists('role', $aLinkdata[$sFunction]) - ) ? $aLinkdata[$sFunction]['role'] : ''; - if (!$this->oUser->hasRole($sNeedsRole)){ - return false; - } - */ + if (!$this->oUser->hasRole("project-action-$sFunction")){ + // $sClass .= ' disabled'; + // return '<span title="no permission [project-action-'.$sFunction.']">[ ]</span>'; + } + * + */ // fuer wen ist der Link $sRole = ''; $sOnMouseover = ''; @@ -2124,6 +2161,10 @@ class project extends base { if ($sVersion) { $sLink.="$sVersion/"; } + if (!$this->oUser->hasPermission("project-action-$sFunction")){ + // $sClass .= ' disabled'; + return '<span title="no permission [project-action-'.$sFunction.'] for '.$this->oUser->getUsername().'">[ <i class="' . $sIconClass . '"></i> ' . $sLabel . ' ]</span>'; + } return '<a href="' . $sLink . '" ' . $sOnMouseover . ' title="' . $sHint . '" class="btn btn-default ' . $sClass . '"><i class="' . $sIconClass . '"></i> ' . $sLabel . '</a>'; } @@ -2560,6 +2601,9 @@ class project extends base { * @return string */ public function renderProjectSetup() { + if (!$this->oUser->hasPermission("project-action-setup")){ + return $this->oUser->showDenied(); + } $sMessages = ''; require_once ("formgen.class.php"); @@ -2823,6 +2867,9 @@ class project extends base { */ public function renderNewProject() { global $aParams; + if (!$this->oUser->hasPermission("project-action-create")){ + return $this->oUser->showDenied(); + } require_once ("formgen.class.php"); $i = 0; diff --git a/public_html/deployment/classes/projectlist.class.php b/public_html/deployment/classes/projectlist.class.php index 30f68880c0bc380b759afaa71e24229ce44479b5..aaed114de3c4bfa03a30ec53e04bc4190c1eac63 100644 --- a/public_html/deployment/classes/projectlist.class.php +++ b/public_html/deployment/classes/projectlist.class.php @@ -27,7 +27,8 @@ class projectlist extends base{ /** * constructor2 called from constructor of base class */ - public function _construct2() { + public function __construct() { + $this->oUser=new user(); // define } @@ -50,9 +51,6 @@ class projectlist extends base{ */ public function renderOverview() { - if (!$this->oUser->hasRole("viewProjectOverview")){ - return $this->oUser->showDenied(); - } $sOut = ''; // table $sOut2 = ''; // tiles $oPrj = false; @@ -363,5 +361,3 @@ class projectlist extends base{ } } - -?> \ No newline at end of file diff --git a/public_html/deployment/classes/user.class.php b/public_html/deployment/classes/user.class.php index 9cbddf405d08ea0a38741e53834a1975a7e8b37e..f412e8edb4fb8878c04842e8a8865dfb00adc3ae 100644 --- a/public_html/deployment/classes/user.class.php +++ b/public_html/deployment/classes/user.class.php @@ -8,10 +8,35 @@ */ class user { + /** + * login name of the current user + * @var string + */ private $_sUsername=false; + + /** + * list of groups of the current user + * @var array + */ private $_aUserGroups=array(); - private $_aUserRoles=array(); - private $_sLastCheckedRole=false; + + /** + * list of roles based on the groups + * @var array + */ + private $_aUserPermmissions=array(); + + /** + * list of projects the current user is involved in + * @var array + */ + private $_aProjects=array(); + + /** + * name of the last checked role + * @var string + */ + private $_sLastCheckedPermission=false; /** * init user with optional given user @@ -21,18 +46,35 @@ class user { $this->setUser($sUser); } + + // ---------------------------------------------------------------------- + // private functions + // ---------------------------------------------------------------------- + + /** * detect a user * @return type */ private function _autoDetectUser(){ $sUser=false; - if (is_array($_SERVER) && array_key_exists("PHP_AUTH_USER", $_SERVER)){ + if (is_array($_SESSION) && array_key_exists("PHP_AUTH_USER", $_SESSION)){ + $sUser=$_SESSION["PHP_AUTH_USER"]; + } + if (!$sUser && is_array($_SERVER) && array_key_exists("PHP_AUTH_USER", $_SERVER)){ $sUser=$_SERVER["PHP_AUTH_USER"]; } return $sUser; } + // UNUSED SO FAR + private function _getUser2Projects(){ + return require(__DIR__ . '/../../../config/inc_user2projects.php'); + } + + private function _getUser2Roles(){ + return require(__DIR__ . '/../../../config/inc_user2roles.php'); + } /** * TODO: reimplement * get the user groups of the current user from an internal source. @@ -43,7 +85,13 @@ class user { $aGroups=array(); if ($this->_sUsername){ $aGroups[]="authenticated"; - $aGroups[]=$this->_sUsername; + // $aGroups[]='#'.$this->_sUsername; + $aUserDefinitions=$this->_getUser2Roles(); + foreach (array_keys($aUserDefinitions) as $sGroup){ + if (array_search($this->_sUsername, $aUserDefinitions[$sGroup])!==false){ + $aGroups[]=$sGroup; + } + } } $this->_aUserGroups=$aGroups; return $this->_aUserGroups; @@ -55,44 +103,111 @@ class user { * The function returns a flat aray with names of the roles * @return array */ - private function _getUserRoles(){ + private function _getUserPermission(){ $aRoles=array(); + $aRolesDefinitions=require(__DIR__ . '/../../../config/inc_roles.php'); // anonymous roles: - // $aRoles[]="view"; - $aRoles[]="viewProjectOverview"; + $aRoles=array_merge($aRoles, $aRolesDefinitions['all']); - if ($this->hasGroup("authenticated")){ - if ($this->hasGroup("developer")){ - $aRoles[]="build"; - /* - $aRoles[]="deploy"; - $aRoles[]="accept"; - $aRoles[]="setup-project"; - * - */ - } - if ($this->hasGroup("admin")){ - // $aRoles[]="setup-all"; + foreach (array_keys($aRolesDefinitions) as $sGroup){ + if ($this->hasGroup($sGroup)){ + $aRoles=array_merge($aRoles, $aRolesDefinitions[$sGroup]); } } - $this->_aUserRoles=$aRoles; - return $this->_aUserRoles; + $this->_aUserPermmissions= array_unique($aRoles); + return $this->_aUserPermmissions; } + + // ---------------------------------------------------------------------- + // public ACTIONS + // ---------------------------------------------------------------------- + + /** - * TODO: implement authentication somewhere - * set a new authenticated user - * @param string $sUser username + * authenticate a user with the configured methods + * @global array $aConfig global config + * @global array $aParams params (i.e. GET and POST) + * @return boolean */ - public function setUser($sUser=false){ - if (!$sUser){ - $sUser=$this->_autoDetectUser(); + public function authenticate(){ + global $aConfig, $aParams; + + if(!array_key_exists('auth', $aConfig) || !count($aConfig['auth']) || !array_key_exists('user', $aParams)){ + return false; + } + $sUser=$aParams['user']; + $sPassword=array_key_exists('password', $aParams)?$aParams['password']:false; + + foreach (array_keys($aConfig['auth']) as $sAuthMethod){ + $oUserAuth=false; + switch ($sAuthMethod){ + case 'ldap': + require_once("userauth.ldap.class.php"); + $oUserAuth=new userauthLdap($aConfig['auth']['ldap']); + break; + // implement other methods here + // see userauth.ldap.class.php as simple example + + default: + echo 'WARNING: authmethod '.$sAuthMethod.' in your config is not implemented in '.basename(__FILE__).' and is useless so far.<br>'; + } + // if authentication fails then continue and try next method + if ($oUserAuth && $oUserAuth->authenticate($sUser, $sPassword)){ + + // set a session - it must correspondent with _autoDetectUser() + $_SESSION["PHP_AUTH_USER"]=$sUser; + $this->setUser(); + return true; + } } - $this->_sUsername=$sUser; + return false; + } + + /** + * logoff user + * @return boolean + */ + public function logoff(){ + unset($_SESSION["PHP_AUTH_USER"]); + $this->setUser(); + return true; + } + + /** + * set a authenticated user and get its roles + */ + public function setUser(){ + $this->_sUsername=$this->_autoDetectUser(); $this->_getUserGroups(); - $this->_getUserRoles(); + $this->_getUserPermission(); + } + + /** + * return html code to display a denied message + * @return type + */ + public function showDenied(){ + return '<div class="alert alert-danger" role="alert">' + . t("class-user-error-deny-no-role").'<br>('.$this->_sLastCheckedPermission.')</div><br>' + . '<a href="/deployment/all/login/" class="btn btn-primary">'.t('menu-login').'</a>' + ; + } + + // ---------------------------------------------------------------------- + // public GETTER + // ---------------------------------------------------------------------- + + + // UNUSED SO FAR + public function getUser2Projects(){ + return $this->_getUser2Projects(); + } + + public function getUser2Roles(){ + return $this->_getUser2Roles(); } /** @@ -113,8 +228,8 @@ class user { * get a flat array with roles of the current user * @return string */ - public function getUserRoles(){ - return $this->_aUserRoles; + public function getUserPermission(){ + return $this->_aUserPermmissions; } /** @@ -127,20 +242,15 @@ class user { } /** * check if the current user has a given role name - * @param string $sRolename name of the role to check + * @param string $sPermission name of the role to check * @return type */ - public function hasRole($sRolename){ - $this->_sLastCheckedRole=$sRolename; - return (array_search($sRolename, $this->_aUserRoles)!==false); + public function hasPermission($sPermission){ + $this->_sLastCheckedPermission=$sPermission; + $bReturn=array_search($sPermission, $this->_aUserPermmissions)!==false; + // $this->log(__FUNCTION__ . "($sRolename) -> " . $bReturn ? 'true' : 'false'); + return $bReturn; } - /** - * return html code to display a denied message - * @return type - */ - public function showDenied(){ - return '<div class="error">'.t("class-user-error-deny-no-role").' ('.$this->_sLastCheckedRole.')</div>'; - } } diff --git a/public_html/deployment/classes/userauth.interface.php b/public_html/deployment/classes/userauth.interface.php new file mode 100644 index 0000000000000000000000000000000000000000..83a4a3acb9c1e5dab5938aa4ea8a39b66a05a19c --- /dev/null +++ b/public_html/deployment/classes/userauth.interface.php @@ -0,0 +1,14 @@ +<?php +/** + * interface for user authentication + * @author axel.hahn@iml.unibe.ch + */ +interface iUserAuth { + + /** + * verify if a given user and password combination is correct + */ + public function authenticate($sUser, $sPassword); + + +} \ No newline at end of file diff --git a/public_html/deployment/classes/userauth.ldap.class.php b/public_html/deployment/classes/userauth.ldap.class.php new file mode 100644 index 0000000000000000000000000000000000000000..ac3086a23689673d06c2961ef0e51dba50a88933 --- /dev/null +++ b/public_html/deployment/classes/userauth.ldap.class.php @@ -0,0 +1,50 @@ +<?php + +require_once("userauth.interface.php"); +require_once("ldap.class.php"); + +/** + * user authentication :: LDAP + * implements userauth interface + * + * @author hahn + */ +class userauthLdap implements iUserAuth { + + /** + * object for ldap actions + * @var object + */ + private $_oLdap=false; + + // ---------------------------------------------------------------------- + // + // ---------------------------------------------------------------------- + public function __construct() { + global $aConfig; + $this->_oLdap=new imlldap($aConfig['auth']['ldap']); + + // first test of ldap connection + // $this->_oLdap->debugOn(); + $this->_oLdap->connect(); + return true; + } + + public function __destruct() { + $this->_oLdap->close(); + } + + // ---------------------------------------------------------------------- + // implementation + // ---------------------------------------------------------------------- + /** + * verify if a given user and password combination is correct + * @param string $sUser username + * @param password $sPassword password + * @return boolean + */ + public function authenticate($sUser, $sPassword){ + return $this->_oLdap->verifyPassword($sUser, $sPassword); + } + +} diff --git a/public_html/deployment/inc_functions.php b/public_html/deployment/inc_functions.php index b051396c506ddfd5021d98ecebc0bd391407fcc3..d3e15460b33ad124ae0d09b29e01e36aade439bf 100644 --- a/public_html/deployment/inc_functions.php +++ b/public_html/deployment/inc_functions.php @@ -10,15 +10,57 @@ 2013-11-08 Axel <axel.hahn@iml.unibe.ch> ###################################################################### */ - -if (!isset($aConfig) || !is_array($aConfig)) { - die("FATAL ERROR: \$aConfig does not exist. The config was not included before including " . __FILE__ . " in the request/ script.\n"); -} - global $aParams; $aParams = array(); +// ---------------------------------------------------------------------- +// verifiy config +// ---------------------------------------------------------------------- + $aErrors=array(); + if (!isset($aConfig) || !is_array($aConfig)) { + $aErrors[]="* \$aConfig does not exist. The config was not included before including " . __FILE__ . " in the request/ script.\n"; + } else { + + foreach (array( + 'appRootDir', + 'configDir', + 'workDir', + 'dataDir', + 'buildDir', + 'buildDefaultsDir', + 'packageDir', + 'archiveDir', + ) as $sKey){ + if (!is_dir($aConfig[$sKey])){ + $aErrors[]="* \$aConfig['$sKey'] pints to a non existing directory (".$aConfig[$sKey].").\n"; + } else { + if (!is_writable($aConfig[$sKey])){ + $aErrors[]="* \$aConfig['$sKey'] = ".$aConfig[$sKey]." is NOT writable.\n"; + } + } + } + } + foreach (array( + $aConfig['dataDir'].'/database', + $aConfig['dataDir'].'/projects', + $aConfig['dataDir'].'/sshkeys', + ) as $sDir2Check){ + if (!is_dir($sDir2Check)){ + $aErrors[]="* directory not found: $sDir2Check\n"; + } else { + if (!is_writable($sDir2Check)){ + $aErrors[]="* $sDir2Check is NOT writable.\n"; + } + } + } + + + + if (count($aErrors)){ + die("FATAL ERROR on config.<br>" . implode("<br>\n", $aErrors)); + } + // remark: $_SERVER does not exist in CLI if (isset($_SERVER) && is_array($_SERVER) && array_key_exists("REQUEST_URI", $_SERVER)) { @@ -150,9 +192,11 @@ function getTopArea() { </nobr> </div> - <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> + '; + if($oUser->getUsername() || true ){ + $sReturn.=' <ul class="nav navbar-nav"> <li class="dropdown'; @@ -221,6 +265,7 @@ function getTopArea() { } } } + } $sReturn.=' </ul> @@ -230,9 +275,8 @@ function getTopArea() { <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" ><span class="glyphicon glyphicon-user"></span> ' . $oUser->getUsername() . ' <b class="caret"></b></a> - <ul class="dropdown-menu" role="menu" style="width: 300px;"> - <li>groups: <pre>' . print_r($oUser->getUserGroups(), true) . '</pre></li> - <li>roles: <pre>' . print_r($oUser->getUserRoles(), true) . '</pre></li> + <ul class="dropdown-menu" role="menu"> + <li><a href="' . $sBaseUrl . 'all/login/">' . t("menu-login") . '</a></li> </ul> </li> @@ -257,151 +301,12 @@ function getTopArea() { </div><div id="header2">'; if (!array_key_exists("prj", $aParams)) { - $sReturn.='<img src="' . $sImageBase . $aImages['overview'] . '" id="imgtop" alt="">' - . '<h1>' . t("overview-label") . '</h1><span class="description">' . t("overview-hint") . '</span>'; - } else { - if ($aParams["prj"] <> "all") { - $oPrj = new project($aParams["prj"]); - $sReturn.='<img src="' . $sImageBase . $aImages['project'] . '" id="imgtop" alt=""> - <h1>' . $oPrj->getLabel() . '</h1><span class="description">' . $oPrj->getDescription() . '</span>'; - if (array_key_exists("action", $aParams)) { - // $sReturn.='<h2>Aktion: '.$aParams["action"].'</h2>'; - } - } - } - $sReturn.='</div>'; - - return $sReturn; -} -/** - * auto generate upper part of the page with header and navigation - * @global type $aParams - * @return type - */ -function getTopArea__bs3() { - global $aParams, $sImageBase, $aImages, $aConfig; - $sReturn = ''; - require_once("./classes/project.class.php"); - require_once("./classes/user.class.php"); - $oUser = new user(); - - $sMyPhase = "[phase]"; - $sMyRev = " [no rev] "; - $sJsonfile = $_SERVER["DOCUMENT_ROOT"] . "ci-webgui.json"; - if (file_exists($sJsonfile)) { - $aJson = json_decode(file_get_contents($sJsonfile), true); - if (array_key_exists("date", $aJson)) - $sMyRev = $aJson["date"]; - } - - $sBaseUrl = '/deployment/'; - $sWikiBaseUrl = 'https://secure.iml.unibe.ch/wiki/doku.php'; - $sReturn = ' - <span id="top"></span> - <nav class="navbar navbar-default" role="navigation"> - <div class="container-fluid"> - <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> - - <ul class="nav navbar-nav"> - <li><span class="brand">IML Deployment<br>GUI</span></li> - <li class="dropdown'; - if (!array_key_exists("prj", $aParams)) - $sReturn.=' active'; - $sReturn.='">' . str_replace('</a>', ' <b class="caret"></b></a>', aHome("")) . ' - <ul class="dropdown-menu" role="menu"> - <li><a href="' . $sBaseUrl . 'all/setup/">' . t("menu-settings") . '</a></li> - <li><a href="' . $sBaseUrl . 'all/setup/actionlog/">' . t("menu-logs") . '</a></li> - <li><a href="' . $sBaseUrl . 'all/setup/new/">' . t("menu-new-project") . '</a></li> - </ul> - </li> - - <!-- list of projects --> - <li class="dropdown"> - <a href="#" class="dropdown-toggle" data-toggle="dropdown">' . t("menu-projects") . '<b class="caret"></b></a> - <ul class="dropdown-menu" role="menu"> - '; - $oPrj1 = new project(); - foreach ($oPrj1->getProjects() as $sPrj) { - $oPrj = new project($sPrj); - $sReturn.='<li><a href="' . $sBaseUrl . $sPrj . '/">' . $oPrj->getLabel() . '</a></li>'; - } - $sReturn.=' - </ul> - </li>'; - if (array_key_exists("prj", $aParams) && $aParams["prj"] <> "all") { - $oPrj = new project($aParams["prj"]); - $sReturn.=' - <li class="active">' . aPrjHome(" ") . '</li> - '; - if (array_key_exists("action", $aParams) and FALSE) { - $sReturn.='<li><a href="#">Aktion: ' . $aParams["action"] . '</a></li>'; - } else { - $sReturn.=' - <li class="dropdown"> - <a href="#" class="dropdown-toggle" data-toggle="dropdown">' . t("menu-project-actions") . '<b class="caret"></b></a> - <ul class="dropdown-menu"> - <!-- - <li><a href="' . $sBaseUrl . $aParams["prj"] . '/build/">' . t("menu-project-build") . '</a></li> - <li><a href="' . $sBaseUrl . $aParams["prj"] . '/cleanup/">' . t("menu-project-cleanup") . '</a></li> - --> - <li><a href="' . $sBaseUrl . $aParams["prj"] . '/setup/">' . t("menu-project-settings") . '</a></li> - <li><a href="' . $sBaseUrl . $aParams["prj"] . '/delete/">' . t("menu-project-delete") . '</a></li> - '; - $sReturn.='</ul></li>'; - - $aPhases = $oPrj->getActivePhases(); - if (count($aPhases)) { - $sReturn.='<li class="dropdown"> - <a href="#" class="dropdown-toggle" data-toggle="dropdown">' . t("menu-project-phases") . '<b class="caret"></b></a> - <ul class="dropdown-menu">'; - foreach ($aPhases as $sPhase) { - $sReturn.='<li><a href="' . $sBaseUrl . $aParams["prj"] . '/phase/' . $sPhase . '/">' . $sPhase . '</a></li>'; - } - $sReturn.='</ul></li>'; - } - } - } - - $sReturn.=' - <!-- - <li> - <a href="#" >Irgend...</a> - </li> - --> - </ul> - <ul class="nav navbar-nav navbar-right"> - <!-- userdata --> - <li class="dropdown"> - <a href="#" class="dropdown-toggle" data-toggle="dropdown">user: ' . $oUser->getUsername() . '<b class="caret"></b></a> - <ul class="dropdown-menu" style="width: 300px;"> - <li>groups: <pre>' . print_r($oUser->getUserGroups(), true) . '</pre></li> - <li>roles: <pre>' . print_r($oUser->getUserRoles(), true) . '</pre></li> - </ul> - </li> - - - <li class="dropdown"> - <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-question-sign"></i> ' . t("menu-help") . '<b class="caret"></b></a> - <ul class="dropdown-menu"> - <li><a href="' . $sWikiBaseUrl . '/it/entwicklung/continuous_deployment">WIKI: Übersicht Continous Deployment</a></li> - <li><a href="' . $sWikiBaseUrl . '/it/entwicklung/continuous_deployment#konventionen">WIKI: Konventionen für Entwickler</a></li> - <li><a href="' . $sWikiBaseUrl . '/it/infrastruktur/dienste/puppet/snippets#iml-deployment">WIKI (Admin): Puppet-Snippets für den Sysadmin</a></li> - <li><a href="' . $sWikiBaseUrl . '/it/infrastruktur/dienste/imldeployment">WIKI (Admin): Verzeichnisse und Dateien</a></li> - <li><a href="/deployment/all/doc/">' . t("menu-help-classes") . '</a></li> - </ul> - </li> - </ul> - </div> - <span class="version ">' . $sMyRev . ' @ ' . php_uname("n") . '</span> - </div></nav><div id="header2">'; - - if (!array_key_exists("prj", $aParams)) { - $sReturn.='<img src="' . $sImageBase . $aImages['overview'] . '" id="imgtop" alt="">' + $sReturn.='<!-- <img src="' . $sImageBase . $aImages['overview'] . '" id="imgtop" alt=""> -->' . '<h1>' . t("overview-label") . '</h1><span class="description">' . t("overview-hint") . '</span>'; } else { if ($aParams["prj"] <> "all") { $oPrj = new project($aParams["prj"]); - $sReturn.='<img src="' . $sImageBase . $aImages['project'] . '" id="imgtop" alt=""> + $sReturn.='<!-- <img src="' . $sImageBase . $aImages['project'] . '" id="imgtop" alt="">--> <h1>' . $oPrj->getLabel() . '</h1><span class="description">' . $oPrj->getDescription() . '</span>'; if (array_key_exists("action", $aParams)) { // $sReturn.='<h2>Aktion: '.$aParams["action"].'</h2>'; diff --git a/public_html/deployment/index.php b/public_html/deployment/index.php index 7b96bad1ff4995a8aa745b5e45da1aab576c6d71..2c3f9044377c9796c49df58e1779dbcd3342308d 100644 --- a/public_html/deployment/index.php +++ b/public_html/deployment/index.php @@ -16,9 +16,11 @@ 2013-11-08 Axel <axel.hahn@iml.unibe.ch> ###################################################################### */ +session_start(); require_once("./classes/page.class.php"); require_once("../../config/inc_projects_config.php"); require_once("./classes/logger.class.php"); +require_once("./classes/user.class.php"); global $oCLog; $oCLog = new logger(); $oCLog->enableDebugByIp($aConfig['showdebug']['ip']); @@ -49,33 +51,39 @@ $sHeader = '<style>'; foreach ($aConfig["phases"] as $sPhase => $aData) { $sHeader.=array_key_exists("bgdark", $aData["css"]) ? 'th.' . $sPhase . '{' . $aData["css"]["bgdark"] . '}' : ''; $sHeader.=array_key_exists("bglight", $aData["css"]) ? 'td.' . $sPhase . ', div.' . $sPhase . '{' . $aData["css"]["bglight"] . '}' : ''; - $sHeader.=array_key_exists("bgbutton", $aData["css"]) ? 'a.' . $sPhase . '{' . $aData["css"]["bgbutton"] . '}' : ''; + $sHeader.=array_key_exists("bgbutton", $aData["css"]) ? 'a.' . $sPhase . ',a.' . $sPhase . ':hover{' . $aData["css"]["bgbutton"] . '}' : ''; } $sHeader.='</style>'; $sTopArea=getTopArea(); $sTopAction=getAction(); // ------ action +$oUser=new user(); +if ($oUser->hasPermission('page_'.$sAction)){ -$sActionFile = __DIR__ . '/pages/act_' . $sAction . ".php"; + $sActionFile = __DIR__ . '/pages/act_' . $sAction . ".php"; -$oCLog->add("including $sActionFile"); -ob_start(); -if (!@include($sActionFile)) { - include("./pages/error_404.php"); + $oCLog->add("including $sActionFile"); + ob_start(); + if (!@include($sActionFile)) { + include("./pages/error_404.php"); + } + $sPhpOut = ob_get_contents(); + ob_end_clean(); + $oCLog->add("including done $sActionFile"); + + $oCLog->add("adding actionlog.class"); + + require_once("./classes/actionlog.class.php"); + $oLog=new Actionlog($sPrj); + $aFilter=array('limit'=>'0, 10'); + if ($sPrj && $sPrj!="all")$aFilter['project']=$sPrj; + $sPhpOut.='<div class="logs">' . $oLog->renderLogs($aFilter).'</div>'; + $oCLog->add("adding actionlog.class done"); +} else { + $sPhpOut.=$oUser->showDenied(); + // return false; } -$sPhpOut = ob_get_contents(); -ob_end_clean(); -$oCLog->add("including done $sActionFile"); - -$oCLog->add("adding actionlog.class"); - -require_once("./classes/actionlog.class.php"); -$oLog=new Actionlog($sPrj); -$aFilter=array('limit'=>'0, 10'); -if ($sPrj && $sPrj!="all")$aFilter['project']=$sPrj; -$sPhpOut.='<div class="logs">' . $oLog->renderLogs($aFilter).'</div>'; -$oCLog->add("adding actionlog.class done"); $oCLog->add("Finally: rendering page ..."); @@ -102,4 +110,3 @@ $oPage->addJsOnReady(''); $oPage->setContent($sPhpOut); echo $oPage->render(); -?> diff --git a/public_html/deployment/pages/act_login.php b/public_html/deployment/pages/act_login.php new file mode 100644 index 0000000000000000000000000000000000000000..376c1a32de141e7889d2ac93d51adbdf7258b2de --- /dev/null +++ b/public_html/deployment/pages/act_login.php @@ -0,0 +1,126 @@ +<?php + +/* ###################################################################### + + IML DEPLOYMENT + + webgui - login + + --------------------------------------------------------------------- + 2015-04-21 Axel <axel.hahn@iml.unibe.ch> + ###################################################################### */ + +require_once("./inc_functions.php"); +$sOut = ''; + +require_once("./classes/user.class.php"); +$oUser = new user(); + +// ---------------------------------------------------------------------- +// actions +// ---------------------------------------------------------------------- + +// if logoff was sent ... +if ($oUser->getUsername() && array_key_exists('logoff', $aParams)) { + $oUser->logoff(); + header('Location: ?'); +} + +// if user is logged off and credentials were sent: try to authenticate +if (!$oUser->getUsername() && array_key_exists('user', $aParams)) { + $oUser->authenticate(); +} + + // if user is logged in and credentials were sent: reload to remove post vars + if ($oUser->getUsername() && array_key_exists('user', $aParams)) { + header('Location: ?'); + } + +// ---------------------------------------------------------------------- +// show infos or login form +// ---------------------------------------------------------------------- + +// if user is logged in, then show user infos +if ($oUser->getUsername()) { + $sGrouplist=''; + foreach ($oUser->getUserGroups() as $sGroupname){ + $sGrouplist.='<li>' . $sGroupname . '</li>'; + } + $sOut.='<div style="width: 50%; margin-left: 25%;">' + . '<h2>' . t("page-login-info") . '</h2>' + . '<p>' + . t("page-login-userloggedin") . '<br><br>' + . '<strong>' . $oUser->getUsername() . '</strong><br><br>' + . t("page-login-usergroups") . '<br>' + . '<ul>'.$sGrouplist . '</ul><br>' + . '<pre style="float: left; margin-right: 1em;">roles:<br>' . print_r($oUser->getUserPermission(), true) . '</pre>' + . '<div style="clear: both; margin-bottom: 1em;"></div>' + . '<a href="?logoff=1" class="btn btn-default"><span class="glyphicon glyphicon-off"></span> ' . t('logoff') . '</a>' + // . ' ' . aPrjHome() . '' + . '</p>' + . '</div>'; +} else { + $i = 0; + require_once ("./classes/formgen.class.php"); + + $aForms = array( + 'login' => array( + 'meta' => array( + 'method' => 'POST', + 'action' => '?', + ), + 'validate' => array(), + 'form' => array( + 'input' . $i++ => array( + 'type' => 'text', + 'name' => 'user', + 'label' => t('page-login-username'), + 'required' => 'required', + 'validate' => 'isastring', + 'size' => 10, + 'value' => $aParams['user'], + 'placeholder' => t('page-login-username'), + ), + 'input' . $i++ => array( + 'type' => 'password', + 'name' => 'password', + 'label' => t('page-login-password'), + 'required' => 'required', + 'validate' => 'isastring', + 'size' => 10, + 'value' => $aParams['password'], + 'placeholder' => t('page-login-password'), + ), + 'input' . $i++ => array( + 'type' => 'markup', + 'value' => '<div style="clear: both; margin-bottom: 3em;"></div>' + . '<div style="text-align: center">' + ), + 'input' . $i++ => array( + 'type' => 'submit', + 'name' => 'btnsave', + 'label' => t("login"), + 'value' => '<i class="glyphicon glyphicon-ok"></i> ' . t("login"), + ), + 'input' . $i++ => array( + 'type' => 'markup', + 'value' => '</div>' + ), + ), + ) + ); + + $oForm = new formgen($aForms); + $sOut.='<div style="width: 50%; margin-left: 25%;">' + . '<h2>' . t("page-login-info") . '</h2>' + . '<p>' . t("page-login-info-introtext") . '</p>'; + if (array_key_exists('user', $aParams)) { + $sOut.='<div class="alert alert-danger" role="alert">'.t('page-login-auth-failed').'</div>'; + } + $sOut.= $oForm->renderHtml("login") + . '</div>'; +} +$sOut.= '<div id="navbuttom">' . aPrjHome() . '</div>'; + +// -- Ausgabe +echo $sOut; diff --git a/public_html/deployment/pages/act_setup.php b/public_html/deployment/pages/act_setup.php index 2394f6f2c0c161ef153f631221e45e81db50a5a7..215f90832a9d2e5908dad04e7fb4888494bda3d0 100644 --- a/public_html/deployment/pages/act_setup.php +++ b/public_html/deployment/pages/act_setup.php @@ -145,6 +145,43 @@ if ($aParams["prj"] == "all") { $sOut.=$oPrj->renderNewProject(); } // ------------------------------------------------------------ + // users and roles + // ------------------------------------------------------------ + /* + if ($aParams["par3"]=="users") { + $sOut.='<h2>'.t("page-setup-info-users-and-roles").'</h2>' + . '<p>'.t("page-setup-info-users-and-roles-introtext").'</p><hr>'; + + $oUserCfg=new user(); + $aUser2Roles=$oUserCfg->getUser2Roles(); + // $aUser2Projects=$oUserCfg->getUser2Projects(); + + $aUsers=array(); + $sOut.=print_r($aUser2Roles,1).'<br>'; + $sRoles=''; + foreach ($aUser2Roles as $sRole=>$aUserlist){ + $sRoles.='<strong>'.$sRole.'</strong><br>'; + if (count($aUserlist)){ + foreach ($aUserlist as $aUseritem){ + $aUsers[$aUseritem]=1; + $sRoles.='<span class="user user-'.md5($aUseritem).'">'.$aUseritem.'</span> | '; + } + } else { + $sRoles.='---'; + } + $sRoles.='<br><br>'; + } + + $sUsers=''; + foreach(array_keys($aUsers) as $aUseritem){ + $sUClass='.user-'.md5($aUseritem); + $sUsers.='<a href="#" onclick="$(\''.$sUClass.'\').css(\'background\', \'#fe8\');">'.$aUseritem.'</a>'; + } + $sOut.=$sUsers . $sRoles; + } + * + */ + // ------------------------------------------------------------ // check lang-texts // ------------------------------------------------------------ if ($aParams["par3"]=="checklang") { @@ -233,4 +270,3 @@ $sOut.= '<div id="navbuttom">' . aPrjHome() . '</div>'; // -- Ausgabe echo $sOut; -?> diff --git a/public_html/webservice/sws-config.json b/public_html/webservice/sws-config.json index 0048074041f605b3c320c8f40a4b0b5a27a5ccb3..a7b7e3273c59e06c4baf89e8dfb4962564307f84 100644 --- a/public_html/webservice/sws-config.json +++ b/public_html/webservice/sws-config.json @@ -1,6 +1,7 @@ { "options": { - "enableGui": 0 + "enableGui": 1, + "enableDump": 1 }, "classes": { "Actionlog": {