Skip to content
Snippets Groups Projects
RBAC.class.php 12.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • Martin Haase's avatar
    Martin Haase committed
    <?php
    // #######################################################   
    // Author: Martin Haase / DAASI International GmbH / TextGrid    
    // Creation date: 2010-10-13     
    // Modification date: 2010-10-13
    // Version: 0.1  
    // based on TextGrid-Webauth.php     
    // #######################################################   
    
    mb_internal_encoding("UTF-8");
    
    class RBAC {
    
      // Global variables  
    
    Martin Haase's avatar
    Martin Haase committed
      protected $rbacbase;
      protected $sessionCreatorUid;
      protected $sessionCreatorPw;
      protected $setnamessecret;
      
    
      protected $soapExtra;
      protected $soapPolicy;
      protected $soapReview;
      protected $soapAdministration;
    
      protected $userAttributes;
    
    Martin Haase's avatar
    Martin Haase committed
    
    
    Martin Haase's avatar
    Martin Haase committed
      protected $SLCdata;
    
    
    Martin Haase's avatar
    Martin Haase committed
      public function __construct( $configfilepath , $authZinstance ) {
        require_once( "soapTypes.inc.php" );
    
        $config = new DOMDocument();
        $config->load($configfilepath);
        $xpath = new DOMXPath($config);
        $xpath->registerNamespace("c", "http://textgrid.info/namespaces/middleware/tgwebauth");
    
    
        $this->rbacbase = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:rbacbase")->item(0)->nodeValue;
    
        if (!isset ($this->rbacbase) || strlen($this->rbacbase) == 0) {
    
    Martin Haase's avatar
    Martin Haase committed
    	echo "Error: '${authZinstance}' has no RBAC base configured!<br/>\n";
    	return null;
        }
    
        $this->authZinstance = $authZinstance;
    
    Martin Haase's avatar
    Martin Haase committed
        $this->sessionCreatorUid = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:user")->item(0)->nodeValue;
        $this->sessionCreatorPw = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:password")->item(0)->nodeValue;
        $this->setnamessecret = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:setnamessecret")->item(0)->nodeValue;
    
    
        $this->SLCdata = array();
        $slcSupportEnabling = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/@enable");
        if ($slcSupportEnabling->length > 0 && $slcSupportEnabling->item(0)->nodeValue === 'true') {
          $this->SLCdata['slcMode'] = TRUE;
          $this->SLCdata['slcEntitlementAttributeName'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:entitlementAttr/@name")->item(0)->nodeValue;
          $this->SLCdata['slcEntitlementAttributeValue'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:entitlementAttr")->item(0)->nodeValue;
          $this->SLCdata['slcPortalDelegationURL'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:portalDelegationURL")->item(0)->nodeValue;
          $this->SLCdata['slcNoDelegationURL'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:noDelegationURL")->item(0)->nodeValue;
        } else {
          $this->SLCdata['slcMode'] = FALSE;
        }
    
    
        // -----------------------------------------------------
        // You'll need these services
        // -----------------------------------------------------
    
    Martin Haase's avatar
    Martin Haase committed
    
    
        $this->soapExtra = new SoapClient( $this->rbacbase . "wsdl/tgextra.wsdl" );
        $this->soapPolicy = new SoapClient( $this->rbacbase . "wsdl/tgsystem.wsdl" );
        $this->soapReview = new SoapClient( $this->rbacbase . "wsdl/tgreview.wsdl" );
        $this->soapAdministration = new SoapClient( $this->rbacbase . "wsdl/tgadministration.wsdl" );
    
    
    Martin Haase's avatar
    Martin Haase committed
      }
    
    
      public function slcData() {
        return $this->SLCdata;
      }
    
    
    Martin Haase's avatar
    Martin Haase committed
      public function createSession ( $remote_user ) {
    
        $rbachash = array("scstatus" => "", // will collect all messages during authentication    
    		      "Sid" => "none", // this will hold the final sessionId then
    		      "rbacbase" => $this->rbacbase,
    
    		      'authZinstance' => $this->authZinstance
    
    Martin Haase's avatar
    Martin Haase committed
    		      );
    
        // ------------------------------------------------------------
        // check whether remote_user is set and has user@domain format
        if (preg_match('/([^@]+)@([^@]+)/', $remote_user, $matches) == 1) { 
    	$identified_user = array("authnmethod" => "eduPersonPrincipalName",
    				 "user" => $matches[1],
    				 "scope" => $matches[2] );
    
    	$identified_user['user'] = $this->escapeForDN ($identified_user['user']);
    	$identified_user['scope'] = $this->escapeForDN ($identified_user['scope']);
    
    	$remote_user = $identified_user['user'] . "@" . $identified_user['scope'];
    
    	$rbachash["identified_user"] = $identified_user;
    	$rbachash["remote_user"] =  $remote_user; // TG User ID
    
        } else {
          return array("success" => FALSE,
    		   "detail" => "User ID not given by home institution.<br/>\n"
    		   ."Your school (its Identity Provider) did not provide a useable User ID to TextGrid (".$remote_user .").<br/>\n"
    		   ."Please contact your school's computing centre and ask them to release to TextGrid's Service Provider "
    		   ."the eduPersonPrincipalName attribute.<br/>Thank you.",
    		   "rbachash" => $rbachash);
          exit;
        }
    
        $rbachash["scstatus"] .= "Authentication Method: ". $identified_user['authnmethod'] . "; ";
    
    Martin Haase's avatar
    Martin Haase committed
    
    
        // -----------------------------------------------------
        // Before you can create a session you have to
        // authenticate. If this was successful you get a
        // session-ID that you should keep
        // -----------------------------------------------------
        $serviceAuthReq = new authenticateRequest();
        $serviceAuthReq->username = $this->sessionCreatorUid;
        $serviceAuthReq->password = $this->sessionCreatorPw;
    
        try {
    
          $serviceAuthResponse = $this->soapExtra->authenticate( $serviceAuthReq );
    
    Martin Haase's avatar
    Martin Haase committed
    
          if( preg_match( "/[0-9a-z]{2,}/i", $serviceAuthResponse->auth ) ) {
    
    	$rbachash["scstatus"] .= "WebAuth authenticated at RBAC, received a service SessionId. " ;
    
    Martin Haase's avatar
    Martin Haase committed
          }
    
        } catch( SoapFault $f ) {
          return array("success" => FALSE,
    		   "detail" => "SOAP FAULT (authenticate)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail,
    		   "rbachash" => $rbachash);
          exit;
        }
    
    
        // -----------------------------------------------------
        // Now you can try to add an active role to your session creator session
        // -----------------------------------------------------
        $addRoleReq = new addActiveRoleRequest();
    
        $addRoleReq->username = $this->sessionCreatorUid;
    
    Martin Haase's avatar
    Martin Haase committed
        $addRoleReq->role = "sessionCreator,Anwendung";
        $addRoleReq->auth = $serviceAuthResponse->auth;
    
        try {
    
          $addRoleResponse = $this->soapExtra->tgAddActiveRole( $addRoleReq );
    
    Martin Haase's avatar
    Martin Haase committed
    
          if( $addRoleResponse->result ) {
    
    	$rbachash["scstatus"] .= "Added active role of application; ";
    
    Martin Haase's avatar
    Martin Haase committed
          } else {
    	return array("success" => FALSE,
    		     "rbachash" => $rbachash,
    		     "detail" => "Internal Error, Could not add Role for application.");
    	exit;
          } 
        } catch( SoapFault $f ) {
          return array("success" => FALSE,
    		   "rbachash" => $rbachash,
    		   "detail" => "SOAP FAULT (tgAddActiveRole)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail);
          exit;
        }
    
        // -----------------------------------------------------
        // Check whether user exists already in RBAC
        // -----------------------------------------------------
        $userexistreq = new userExistsRequest();
        $userexistreq->auth = $serviceAuthResponse->auth;
        $userexistreq->username = $remote_user;
    
        try {
    
          $existresult = $this->soapExtra->userExists($userexistreq);
    
    Martin Haase's avatar
    Martin Haase committed
          if (! $existresult->result) {
    	
    	// -----------------------------------------------
    	// User does not exist, so add 'em
    	$adduserrequest = new addUserRequest();
    	$adduserrequest->intSid = $serviceAuthResponse->auth;
    	$adduserrequest->username = $remote_user;
    	$adduserrequest->password = "gnuelpfix"; // this is not relevant and will never be checked
    	
    	try {
    
    	  $addedUser = $this->soapAdministration->addUser($adduserrequest);
    
    Martin Haase's avatar
    Martin Haase committed
    	  if ($addedUser) {
    
    	    $rbachash["scstatus"] .= "Added user information to authorization database; ";
    
    Martin Haase's avatar
    Martin Haase committed
    	  } else {
    	    return array("success" => FALSE,
    			 "rbachash" => $rbachash,
    			 "detail" => "Could not add your user ID to authorization database." );
    	    exit;
    	  }
          
    	} catch(SoapFault $f) {
    	  return array("success" => FALSE,
    		       "rbachash" => $rbachash,
    		       "detail" => "SOAP FAULT (AddUser)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail );
    	  exit;
    	}
          } else {
    
    	$rbachash["scstatus"] .=  "user exists in authentication database; ";
    
    Martin Haase's avatar
    Martin Haase committed
          }
        } catch (SoapFault $f) {
          return array("success" => FALSE,
    		   "rbachash" => $rbachash,
    		   "detail" => "SOAP FAULT (UserExists)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail );
          exit;
        }
    
        // -----------------------------------------------------
        // If this was successful you can create the session for remote_user
        // need to add active roles to the session 
        // -----------------------------------------------------
        $creReq = new createSessionRequest();
        $creReq->intSid = $serviceAuthResponse->auth;
        //$creReq->username = "mhaase@uni-tuebingen.de";
        $creReq->username = $remote_user;
    
        //$creReq->roleset = Array( "Projektleiter,Projekt-1,Projekt-Teilnehmer" );
        //$creReq->roleset = Array( "Bearbeiter,Projekt-1,Projekt-Teilnehmer" );
    
        //---------------------------
        // get ALL available roles...
        $rolesobject = new authorizedRolesRequest();
        $rolesobject->intSid = $serviceAuthResponse->auth;
        $rolesobject->username = $remote_user;
    
        try {
    
          $roleResponse = $this->soapReview->authorizedRoles($rolesobject);
    
    Martin Haase's avatar
    Martin Haase committed
    
    
          $rbachash["scstatus"] .=  "Received all available roles for user; ";
    
    Martin Haase's avatar
    Martin Haase committed
        } catch (Soapfault $f) {
          return array("success" => FALSE,
    		   "rbachash" => $rbachash,
    		   "detail" => "SOAP FAULT (authorizedRoles)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail );
          exit;
        }
        if (is_Array($roleResponse->role)) {
          $creReq->roleset = $roleResponse->role;
        } elseif (is_string($roleResponse->role)) {
          $creReq->roleset = Array($roleResponse->role);
        } else {
          $creReq->roleset = Array();
        }
    
        // ------------------------------------------------
        // Get a newly generated sid from the RBAC system
        try {
    
          $Sid = $this->soapExtra->getSid();
    
    Martin Haase's avatar
    Martin Haase committed
          $Sid = $Sid->sid;
          $rbachash["Sid"] = $Sid;
        } catch (Soapfault $f) {
          return array("success" => FALSE,
    		   "rbachash" => $rbachash,
    		   "detail" => "RBAC down? Could not generate a new SessionID!" );
          exit;
        }
    
        // -------------------------------------
        // Creating the session...
        $creReq->sid = $Sid;
        try {
    
          $creResponse = $this->soapPolicy->createSession( $creReq );
    
    Martin Haase's avatar
    Martin Haase committed
    
          if( $creResponse->result ) {
    
    
    	$rbachash["scstatus"] .= "Created sessions with active roles; ";
    
    Martin Haase's avatar
    Martin Haase committed
          } else {
    	return array("success" => FALSE,
    		     "rbachash" => $rbachash,
    		     "detail" => "Failed to create a new Session!" );
    	exit;
          }
    
        } catch (SoapFault $f) {
          return array("success" => FALSE,
    		   "rbachash" => $rbachash,
    		   "detail" => "SOAP FAULT (CreateSession)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail );
          exit;
        }
    
        // --------------------------------------------------------
        // now all went well, createSession worked, return success
        return array("success" => TRUE,
    		 "rbachash" => $rbachash);
      }
    
      // see RFC XYZ, DN Syntax
      function escapeForDN ($string) {
        return preg_replace('/[";+<>,\\\]/', "X", $string);
      }
    
    
      function getUserAttributes ( $Sid ) {
        $getMyUAR = new StdClass();
        $getMyUAR->auth = $Sid;
    
        try {
          $ua = $this->soapExtra->getMyUserAttributes($getMyUAR);
          $this->userAttributes = $ua->attribute;
          return $ua->attribute;
        } catch (SoapFault $f) {
          return array("success" => FALSE,
    
    Martin Haase's avatar
    Martin Haase committed
    		   "detail" => "SOAP FAULT (getMyUserAttributes)!: " . serialize ($f) );
    
        }
    
      }
    
      function enoughUserAttributes ( $Sid ) {
        if (!isset($this->userAttributes)) {
          $this->getUserAttributes( $Sid );  
        }
        //       $file = fopen ("/tmp/xxxR.log", "w+");
        //   fwrite ($file, serialize ($this->userAttributes ) ."\n");
        //   fclose ($file);
    
        foreach ($this->userAttributes as $a) {
          if ($a->mandatory) {
    	if (!isset($a->value)) {
    	  return FALSE;
    	} else {
    	  if (is_string($a->value) && strlen($a->value) < 1) {
    	    return FALSE;
    	  }
    	}
          }
        }
    
    Martin Haase's avatar
    Martin Haase committed
      function updateAttributes ( $attrs, $map, $Sid ) {
        $newattributes = array();
        foreach ($map as $name => $value) {
          if (isset($attrs[$value])) {
    	$na = new StdClass();
    	$na->name = $name;
    	$na->value = $attrs[$value];
    	$newattributes[] = $na;
          }
        }
        return $this->setAttributes ($newattributes, $Sid, TRUE);
    
    Martin Haase's avatar
    Martin Haase committed
    
    
      function setAttributes ( $attrs, $Sid, $loginmode ) {
        $setMyUserAttributesRequest = new StdClass();
        $setMyUserAttributesRequest->attribute = $attrs; 
        $setMyUserAttributesRequest->auth = $Sid;
        if ($loginmode) {
          $setMyUserAttributesRequest->webAuthSecret = $this->setnamessecret;
        } else {
          $setMyUserAttributesRequest->webAuthSecret = "";
        }
    
    Martin Haase's avatar
    Martin Haase committed
    
    
        try {
          $res = $this->soapExtra->setMyUserAttributes($setMyUserAttributesRequest);
          return $res;
        } catch (SoapFault $f) {
          return array("success" => FALSE,
    		   "detail" => "SOAP FAULT (setMyUserAttributes)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail );
        }
    
    Martin Haase's avatar
    Martin Haase committed
      }
    
    Martin Haase's avatar
    Martin Haase committed
    }
    
    
    Martin Haase's avatar
    Martin Haase committed
    ?>